Branch: refs/heads/master Author: Thomas Martitz thomas.martitz@mailbox.org Committer: Thomas Martitz thomas.martitz@mailbox.org Date: Wed, 08 Jun 2022 05:54:00 UTC Commit: 20bd9c44ea638fb7c29dc6df374f39df4947cd3f https://github.com/geany/geany/commit/20bd9c44ea638fb7c29dc6df374f39df4947cd...
Log Message: ----------- Add a unit test program to check the new sidebar documents tree view
The test program checks if open documents are grouped correctly by their parent directory. The older modes (plain document list and two-level tree) also get a distinct test. For this to work some symbols must become visible from libgeany.
The test uses g_strv_length() which is relatively new. Autoconf and meson checks are added as needed.
Modified Paths: -------------- configure.ac m4/geany-gtk.m4 meson.build src/Makefile.am src/libmain.c src/main.h src/sidebar.c src/sidebar.h src/ui_utils.c tests/Makefile.am tests/meson.build tests/test_sidebar.c
Modified: configure.ac 1 lines changed, 1 insertions(+), 0 deletions(-) =================================================================== @@ -89,6 +89,7 @@ GEANY_CHECK_REVISION([dnl force debug mode for a VCS working copy CFLAGS="-g -DGEANY_DEBUG $CFLAGS"])
GEANY_CHECK_GTK +GEANY_CHECK_GTK_FUNCS([g_strv_equal])
# --disable-deprecated switch for GTK purification AC_ARG_ENABLE([deprecated],
Modified: m4/geany-gtk.m4 15 lines changed, 15 insertions(+), 0 deletions(-) =================================================================== @@ -16,3 +16,18 @@ AC_DEFUN([GEANY_CHECK_GTK],
GEANY_STATUS_ADD([Using GTK version], [${GTK_VERSION}]) ]) + +dnl GEANY_CHECK_GTK_FUNCS +dnl Like AC_CHECK_FUNCS but adds GTK flags so that tests for GLib/GTK functions may succeed. +AC_DEFUN([GEANY_CHECK_GTK_FUNCS], +[ + AC_REQUIRE([GEANY_CHECK_GTK]) + + CFLAGS_save=$CFLAGS + CFLAGS=$GTK_CFLAGS + LIBS_save=$LIBS + LIBS=$GTK_LIBS + AC_CHECK_FUNCS([$1]) + CFLAGS=$CFLAGS_save + LIBS=$LIBS_save +])
Modified: meson.build 6 lines changed, 3 insertions(+), 3 deletions(-) =================================================================== @@ -85,7 +85,7 @@ check_functions = [ ['truncate', '#include <unistd.h>'], ['wcrtomb', '#include <wchar.h>'], ['wcscoll', '#include <wchar.h>'], - + ['g_strv_equal', '#include <glib.h>'] ]
foreach h : check_headers @@ -100,7 +100,7 @@ endforeach foreach f : check_functions define = 'HAVE_' + f.get(0).underscorify().to_upper() ccprefix = '\n'.join([gnu_source ? '#define _GNU_SOURCE' : '', f.get(1)]) - if cc.has_function(f.get(0), prefix : ccprefix) + if cc.has_function(f.get(0), prefix: ccprefix, dependencies: deps) cdata.set(define, 1) else cdata.set(define, false) @@ -846,7 +846,7 @@ libgeany = shared_library('geany', ) dep_libgeany = declare_dependency( link_with: libgeany, - include_directories: [igeany] + include_directories: [iscintilla, itagmanager, igeany] )
executable('geany',
Modified: src/Makefile.am 5 lines changed, 2 insertions(+), 3 deletions(-) =================================================================== @@ -20,14 +20,14 @@ AM_CPPFLAGS = \ -DGTK \ -DGEANY_PRIVATE \ -DG_LOG_DOMAIN=""Geany"" \ - @GTK_CFLAGS@ @GTHREAD_CFLAGS@ \ + @GTK_CFLAGS@ \ $(MAC_INTEGRATION_CFLAGS)
bin_PROGRAMS = geany lib_LTLIBRARIES = libgeany.la
geany_SOURCES = main.c -geany_LDADD = libgeany.la $(GTK_LIBS) $(GTHREAD_LIBS) $(INTLLIBS) +geany_LDADD = libgeany.la $(GTK_LIBS) $(INTLLIBS) geany_LDFLAGS =
if ENABLE_BINRELOC @@ -124,7 +124,6 @@ libgeany_la_LIBADD = \ $(top_builddir)/scintilla/libscintilla.la \ $(builddir)/tagmanager/libtagmanager.la \ @GTK_LIBS@ \ - @GTHREAD_LIBS@ \ $(MAC_INTEGRATION_LIBS) \ $(INTLLIBS)
Modified: src/libmain.c 25 lines changed, 16 insertions(+), 9 deletions(-) =================================================================== @@ -1018,20 +1018,12 @@ static const gchar *get_locale(void)
GEANY_EXPORT_SYMBOL -gint main_lib(gint argc, gchar **argv) +void main_init_headless(void) { - GeanyDocument *doc; - gint config_dir_result; - const gchar *locale; - gchar *utf8_configdir; - gchar *os_info; - #if ! GLIB_CHECK_VERSION(2, 36, 0) g_type_init(); #endif
- log_handlers_init(); - app = g_new0(GeanyApp, 1); memset(&main_status, 0, sizeof(GeanyStatus)); memset(&prefs, 0, sizeof(GeanyPrefs)); @@ -1043,6 +1035,21 @@ gint main_lib(gint argc, gchar **argv) memset(&template_prefs, 0, sizeof(GeanyTemplatePrefs)); memset(&ui_prefs, 0, sizeof(UIPrefs)); memset(&ui_widgets, 0, sizeof(UIWidgets)); +} + + +GEANY_EXPORT_SYMBOL +gint main_lib(gint argc, gchar **argv) +{ + GeanyDocument *doc; + gint config_dir_result; + const gchar *locale; + gchar *utf8_configdir; + gchar *os_info; + + main_init_headless(); + + log_handlers_init();
setup_paths();
Modified: src/main.h 2 lines changed, 2 insertions(+), 0 deletions(-) =================================================================== @@ -76,6 +76,8 @@ void main_load_project_from_command_line(const gchar *locale_filename, gboolean
gint main_lib(gint argc, gchar **argv);
+void main_init_headless(void); + #endif /* GEANY_PRIVATE */
G_END_DECLS
Modified: src/sidebar.c 32 lines changed, 7 insertions(+), 25 deletions(-) =================================================================== @@ -51,14 +51,6 @@ SidebarTreeviews tv = {NULL, NULL, NULL}; /* while typeahead searching, editor should not get focus */ static gboolean may_steal_focus = FALSE;
-enum -{ - OPENFILES_PATHS_NONE, - OPENFILES_PATHS_LIST, - OPENFILES_PATHS_TREE, - OPENFILES_PATHS_COUNT -}; - static struct { GtkWidget *close; @@ -84,19 +76,6 @@ enum OPENFILES_ACTION_RELOAD };
- -/* documents tree model columns */ -enum -{ - DOCUMENTS_ICON, - DOCUMENTS_SHORTNAME, /* dirname for parents, basename for children */ - DOCUMENTS_DOCUMENT, - DOCUMENTS_COLOR, - DOCUMENTS_FILENAME, /* full filename */ - DOCUMENTS_FOLD, /* fold state stored when folding parent rows */ -}; - - static GtkTreeStore *store_openfiles; static GtkWidget *openfiles_popup_menu; static GtkWidget *tag_window; /* scrolled window that holds the symbol list GtkTreeView */ @@ -300,8 +279,8 @@ static gint documents_sort_func(GtkTreeModel *model, GtkTreeIter *iter_a, return cmp; }
- -static void sidebar_create_store_openfiles(void) +GEANY_EXPORT_SYMBOL +GtkTreeStore *sidebar_create_store_openfiles(void) { GtkTreeSortable *sortable; GtkTreeStore *store; @@ -316,6 +295,7 @@ static void sidebar_create_store_openfiles(void) gtk_tree_sortable_set_sort_column_id(sortable, DOCUMENTS_SHORTNAME, GTK_SORT_ASCENDING);
store_openfiles = store; + return store; }
@@ -907,6 +887,7 @@ static void expand_iter(GtkTreeIter *iter)
/* Also sets doc->priv->iter. * This is called recursively in sidebar_openfiles_update_all(). */ +GEANY_EXPORT_SYMBOL void sidebar_openfiles_add(GeanyDocument *doc) { GtkTreeIter *iter = &doc->priv->iter; @@ -934,8 +915,9 @@ void sidebar_openfiles_add(GeanyDocument *doc) -1); g_free(basename);
- /* expand new parent if necessary */ - if (expand) + /* Expand new parent if necessary. Beware: this is executed by unit tests + * which don't create the tree view. */ + if (expand && G_LIKELY(tv.tree_openfiles)) expand_iter(&parent); }
Modified: src/sidebar.h 25 lines changed, 25 insertions(+), 0 deletions(-) =================================================================== @@ -27,6 +27,8 @@
#include "gtkcompat.h"
+#ifdef GEANY_PRIVATE + G_BEGIN_DECLS
typedef struct SidebarTreeviews @@ -48,6 +50,25 @@ enum SYMBOLS_N_COLUMNS };
+enum +{ + OPENFILES_PATHS_NONE, + OPENFILES_PATHS_LIST, + OPENFILES_PATHS_TREE, + OPENFILES_PATHS_COUNT +}; + +/* documents tree model columns */ +enum +{ + DOCUMENTS_ICON, + DOCUMENTS_SHORTNAME, /* dirname for parents, basename for children */ + DOCUMENTS_DOCUMENT, + DOCUMENTS_COLOR, + DOCUMENTS_FILENAME, /* full filename */ + DOCUMENTS_FOLD, /* fold state stored when folding parent rows */ +}; + void sidebar_init(void);
void sidebar_finalize(void); @@ -70,6 +91,10 @@ void sidebar_focus_openfiles_tab(void);
void sidebar_focus_symbols_tab(void);
+GtkTreeStore *sidebar_create_store_openfiles(void); +#endif + G_END_DECLS
+ #endif /* GEANY_SIDEBAR_H */
Modified: src/ui_utils.c 2 lines changed, 1 insertions(+), 1 deletions(-) =================================================================== @@ -68,7 +68,7 @@ "filetype: %f " \ "scope: %S")
-GeanyInterfacePrefs interface_prefs; +GEANY_EXPORT_SYMBOL GeanyInterfacePrefs interface_prefs; GeanyMainWidgets main_widgets;
UIPrefs ui_prefs;
Modified: tests/Makefile.am 12 lines changed, 7 insertions(+), 5 deletions(-) =================================================================== @@ -1,13 +1,15 @@
SUBDIRS = ctags
-AM_CPPFLAGS = -DGEANY_PRIVATE -DG_LOG_DOMAIN=""Geany"" @GTK_CFLAGS@ @GTHREAD_CFLAGS@ -AM_CPPFLAGS += -I$(top_srcdir)/src +AM_CPPFLAGS = -DGTK -DGEANY_PRIVATE -DG_LOG_DOMAIN=""Geany"" +AM_CPPFLAGS += -I$(top_srcdir)/scintilla/include -I$(top_srcdir)/scintilla/lexilla/include +AM_CPPFLAGS += -I$(top_srcdir)/src/tagmanager -I$(top_srcdir)/src +AM_CFLAGS = $(GTK_CFLAGS) +AM_LDFLAGS = $(GTK_LIBS) $(INTLLIBS) -no-install
-AM_LDFLAGS = $(GTK_LIBS) $(GTHREAD_LIBS) $(INTLLIBS) -no-install - -check_PROGRAMS = test_utils +check_PROGRAMS = test_utils test_sidebar
test_utils_LDADD = $(top_builddir)/src/libgeany.la +test_sidebar_LDADD = $(top_builddir)/src/libgeany.la
TESTS = $(check_PROGRAMS)
Modified: tests/meson.build 4 lines changed, 3 insertions(+), 1 deletions(-) =================================================================== @@ -1,5 +1,6 @@ test_deps = declare_dependency(compile_args: geany_cflags + [ '-DG_LOG_DOMAIN="Geany"' ], - dependencies: [deps, dep_libgeany]) + dependencies: [deps, dep_libgeany], + include_directories: '..')
ctags_tests = files([ 'ctags/1795612.js.tags', @@ -352,3 +353,4 @@ test('ctags/processing-order', runner, args: [join_paths(meson.build_root(), 'geany'), '--result', process_order_sources], env: ['top_srcdir='+meson.source_root(), 'top_builddir='+meson.build_root()]) test('utils', executable('test_utils', 'test_utils.c', dependencies: test_deps)) +test('sidebar', executable('test_sidebar', 'test_sidebar.c', dependencies: test_deps))
Modified: tests/test_sidebar.c 154 lines changed, 154 insertions(+), 0 deletions(-) =================================================================== @@ -0,0 +1,154 @@ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include "document.h" +#include "documentprivate.h" +#include "keyfile.h" +#include "main.h" +#include "sidebar.h" +#include "ui_utils.h" +#include "utils.h" + +#define SIDEBAR_TEST_ADD(path, func) g_test_add_func("/sidebar/" path, func); + +static void openfiles_add(const gchar **file_names) +{ + const gchar *file; + + while ((file = *file_names++)) + { + GeanyDocument *doc = g_new0(GeanyDocument, 1); + + doc->priv = g_new0(GeanyDocumentPrivate, 1); + doc->file_name = strdup(file); + + sidebar_openfiles_add(doc); + } +} + + +static gboolean tree_count_cb(GtkTreeModel *model, GtkTreePath *path, + GtkTreeIter *iter, gpointer data_in) +{ + gint *c = (gint *) data_in; + + *c = *c + 1; + return FALSE; +} + + +static gboolean tree_strings_cb(GtkTreeModel *model, GtkTreePath *path, + GtkTreeIter *iter, gpointer data_in) +{ + gchar **data = (gchar **) data_in; + gchar *file; + + gtk_tree_model_get(model, iter, DOCUMENTS_SHORTNAME, &file, -1); + data[g_strv_length(data)] = file; + + printf("%s\n", file); + return FALSE; +} + +void do_test_sidebar_openfiles(const gchar **test_data, const gchar **expected) +{ +#ifdef HAVE_G_STRV_EQUAL + int count = 0; + GtkTreeStore *store; + gchar **data; + + store = sidebar_create_store_openfiles(); + + openfiles_add(test_data); + + gtk_tree_model_foreach(GTK_TREE_MODEL(store), tree_count_cb, (gpointer) &count); + data = g_new0(gchar *, count + 1); + gtk_tree_model_foreach(GTK_TREE_MODEL(store), tree_strings_cb, (gpointer) data); + g_assert_true(g_strv_equal(expected, (const gchar * const *) data)); +#else + g_test_skip("Need g_strv_equal(), since GLib 2.60"); +#endif +} + +void test_sidebar_openfiles_none(void) +{ + const gchar *files[] = { + "/tmp/x", + "/tmp/b/a", + "/tmp/b/b", + NULL + }; + const gchar *expected[] = { + "a", + "b", + "x", + NULL + }; + + interface_prefs.openfiles_path_mode = OPENFILES_PATHS_NONE; + do_test_sidebar_openfiles(files, expected); +} + + +void test_sidebar_openfiles_path(void) +{ + const gchar *files[] = { + "/tmp/x", + "/tmp/b/a", + "/tmp/b/b", + NULL + }; + const gchar *expected[] = { + "/tmp", + "x", + "/tmp/b", + "a", + "b", + NULL + }; + + interface_prefs.openfiles_path_mode = OPENFILES_PATHS_LIST; + do_test_sidebar_openfiles(files, expected); +} + + +void test_sidebar_openfiles_tree(void) +{ + const gchar *files[] = { + "/tmp/x", + "/tmp/b/a", + "/tmp/b/b", + NULL + }; + const gchar *expected[] = { + "/tmp", + "x", + "b", + "a", + "b", + NULL + }; + + interface_prefs.openfiles_path_mode = OPENFILES_PATHS_TREE; + do_test_sidebar_openfiles(files, expected); +} + +int main(int argc, char **argv) +{ + g_test_init(&argc, &argv, NULL); + /* Not sure if we can really continue without DISPLAY. Fake X display perhaps? + * + * This test seems to work, at least. + */ + gtk_init_check(&argc, &argv); + + main_init_headless(); + + SIDEBAR_TEST_ADD("openfiles_none", test_sidebar_openfiles_none); + SIDEBAR_TEST_ADD("openfiles_path", test_sidebar_openfiles_path); + SIDEBAR_TEST_ADD("openfiles_tree", test_sidebar_openfiles_tree); + + return g_test_run(); +}
-------------- This E-Mail was brought to you by github_commit_mail.py (Source: https://github.com/geany/infrastructure).