[gtk+] Add a test framework for CSS nodes



commit d2c1203ef15b9daeb7e653d80ed621e972ebe4b3
Author: Matthias Clasen <mclasen redhat com>
Date:   Mon Dec 28 02:02:57 2015 -0500

    Add a test framework for CSS nodes
    
    No actual tests yet.

 configure.ac                               |    1 +
 testsuite/css/Makefile.am                  |    2 +-
 testsuite/css/nodes/Makefile.am            |   55 ++++++
 testsuite/css/nodes/test-css-nodes.c       |  265 ++++++++++++++++++++++++++++
 testsuite/css/nodes/test-css-nodes.test.in |    3 +
 5 files changed, 325 insertions(+), 1 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index fb27eaa..1533a75 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1894,6 +1894,7 @@ testsuite/a11y/Makefile
 testsuite/a11y/state/Makefile
 testsuite/css/Makefile
 testsuite/css/parser/Makefile
+testsuite/css/nodes/Makefile
 testsuite/gdk/Makefile
 testsuite/gtk/Makefile
 testsuite/reftests/Makefile
diff --git a/testsuite/css/Makefile.am b/testsuite/css/Makefile.am
index d38fa8e..4ecb9df 100644
--- a/testsuite/css/Makefile.am
+++ b/testsuite/css/Makefile.am
@@ -2,7 +2,7 @@ include $(top_srcdir)/Makefile.decl
 
 NULL =
 
-SUBDIRS = parser
+SUBDIRS = parser nodes
 
 check_PROGRAMS = $(TEST_PROGS)
 test_in_files =
diff --git a/testsuite/css/nodes/Makefile.am b/testsuite/css/nodes/Makefile.am
new file mode 100644
index 0000000..c2273b7
--- /dev/null
+++ b/testsuite/css/nodes/Makefile.am
@@ -0,0 +1,55 @@
+include $(top_srcdir)/Makefile.decl
+
+NULL =
+
+CLEANFILES =
+
+TEST_PROGS += test-css-nodes
+test_in_files = test-css-nodes.test.in
+
+check_PROGRAMS = $(TEST_PROGS)
+
+test_css_nodes_CFLAGS = \
+        -I$(top_srcdir)                 \
+        -I$(top_builddir)/gdk           \
+        -I$(top_srcdir)/gdk             \
+        $(GTK_DEBUG_FLAGS)              \
+        $(GTK_DEP_CFLAGS)
+
+test_css_nodes_LDADD = \
+        $(top_builddir)/gdk/libgdk-3.la \
+        $(top_builddir)/gtk/libgtk-3.la \
+        $(GTK_DEP_LIBS)
+
+test_css_nodes_SOURCES = \
+        test-css-nodes.c
+
+test_data = \
+       $(NULL)
+
+EXTRA_DIST += $(test_in_files) $(test_data)
+
+if BUILDOPT_INSTALL_TESTS
+insttestdir=$(libexecdir)/installed-tests/$(PACKAGE)/css/nodes
+insttest_PROGRAMS = $(TEST_PROGS)
+insttest_DATA = $(test_data)
+
+substitutions = \
+        -e s,@libexecdir\@,$(libexecdir),g \
+        $(NULL)
+
+test_files = $(test_in_files:.test.in=.test)
+
+$(test_files): %.test: %.test.in
+        $(AM_V_GEN) sed $(substitutions) $< > $  tmp && mv $  tmp $@
+
+EXTRA_DIST += $(test_files)
+
+CLEANFILES += $(test_files)
+
+testmetadir = $(datadir)/installed-tests/$(PACKAGE)/css/nodes
+testmeta_DATA = $(test_files)
+endif
+
+
+-include $(top_srcdir)/git.mk
diff --git a/testsuite/css/nodes/test-css-nodes.c b/testsuite/css/nodes/test-css-nodes.c
new file mode 100644
index 0000000..d2cce05
--- /dev/null
+++ b/testsuite/css/nodes/test-css-nodes.c
@@ -0,0 +1,265 @@
+/*
+ * Copyright (C) 2015 Red Hat Inc.
+ *
+ * Author:
+ *      Matthias Clasen <mclasen redhat com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <string.h>
+#include <glib/gstdio.h>
+#include <gtk/gtk.h>
+
+
+static char *
+test_get_reference_file (const char *ui_file)
+{
+  GString *file = g_string_new (NULL);
+
+  if (g_str_has_suffix (ui_file, ".ui"))
+    g_string_append_len (file, ui_file, strlen (ui_file) - 3);
+  else
+    g_string_append (file, ui_file);
+  
+  g_string_append (file, ".nodes");
+
+  if (!g_file_test (file->str, G_FILE_TEST_EXISTS))
+    {
+      g_string_free (file, TRUE);
+      return g_strdup (ui_file);
+    }
+
+  return g_string_free (file, FALSE);
+}
+
+static char *
+diff_with_file (const char  *file1,
+                char        *text,
+                gssize       len,
+                GError     **error)
+{
+  const char *command[] = { "diff", "-u", file1, NULL, NULL };
+  char *diff, *tmpfile;
+  int fd;
+
+  diff = NULL;
+
+  if (len < 0)
+    len = strlen (text);
+  
+  /* write the text buffer to a temporary file */
+  fd = g_file_open_tmp (NULL, &tmpfile, error);
+  if (fd < 0)
+    return NULL;
+
+  if (write (fd, text, len) != (int) len)
+    {
+      close (fd);
+      g_set_error (error,
+                   G_FILE_ERROR, G_FILE_ERROR_FAILED,
+                   "Could not write data to temporary file '%s'", tmpfile);
+      goto done;
+    }
+  close (fd);
+  command[3] = tmpfile;
+
+  /* run diff command */
+  g_spawn_sync (NULL, 
+                (char **) command,
+                NULL,
+                G_SPAWN_SEARCH_PATH,
+                NULL, NULL,
+               &diff,
+                NULL, NULL,
+                error);
+
+done:
+  g_unlink (tmpfile);
+  g_free (tmpfile);
+
+  return diff;
+}
+
+static void
+load_ui_file (GFile *file, gboolean generate)
+{
+  GtkBuilder *builder;
+  GtkWidget *window;
+  GtkStyleContext *context;
+  char *output, *diff;
+  char *ui_file, *reference_file;
+  GError *error = NULL;
+
+  ui_file = g_file_get_path (file);
+
+  builder = gtk_builder_new_from_file (ui_file);
+  window = GTK_WIDGET (gtk_builder_get_object (builder, "window1"));
+
+  g_assert (window != NULL);
+
+  context = gtk_widget_get_style_context (window);
+
+  output = gtk_style_context_to_string (context, GTK_STYLE_CONTEXT_PRINT_RECURSE);
+
+  if (generate)
+    {
+      g_print ("%s", output);
+      goto out;
+    }
+
+  reference_file = test_get_reference_file (ui_file);
+
+  diff = diff_with_file (reference_file, output, -1, &error);
+  g_assert_no_error (error);
+
+  if (diff && diff[0])
+    {
+      g_test_message ("Resulting output doesn't match reference:\n%s", diff);
+      g_test_fail ();
+    }
+  g_free (reference_file);
+  g_free (diff);
+
+out:
+  g_free (output);
+  g_free (ui_file);
+}
+
+static void
+test_ui_file (GFile *file)
+{
+  load_ui_file (file, FALSE);
+}
+
+static void
+add_test_for_file (GFile *file)
+{
+  char *path;
+
+  path = g_file_get_path (file);
+
+  g_test_add_vtable (path,
+                     0,
+                     g_object_ref (file),
+                     NULL,
+                     (GTestFixtureFunc) test_ui_file,
+                     (GTestFixtureFunc) g_object_unref);
+
+  g_free (path);
+}
+
+static int
+compare_files (gconstpointer a, gconstpointer b)
+{
+  GFile *file1 = G_FILE (a);
+  GFile *file2 = G_FILE (b);
+  char *path1, *path2;
+  int result;
+
+  path1 = g_file_get_path (file1);
+  path2 = g_file_get_path (file2);
+
+  result = strcmp (path1, path2);
+
+  g_free (path1);
+  g_free (path2);
+
+  return result;
+}
+
+static void
+add_tests_for_files_in_directory (GFile *dir)
+{
+  GFileEnumerator *enumerator;
+  GFileInfo *info;
+  GList *files;
+  GError *error = NULL;
+
+  enumerator = g_file_enumerate_children (dir, G_FILE_ATTRIBUTE_STANDARD_NAME, 0, NULL, &error);
+  g_assert_no_error (error);
+  files = NULL;
+
+  while ((info = g_file_enumerator_next_file (enumerator, NULL, &error)))
+    {
+      const char *filename;
+
+      filename = g_file_info_get_name (info);
+
+      if (!g_str_has_suffix (filename, ".ui") ||
+          g_str_has_suffix (filename, ".nodes"))
+        {
+          g_object_unref (info);
+          continue;
+        }
+
+      files = g_list_prepend (files, g_file_get_child (dir, filename));
+
+      g_object_unref (info);
+    }
+
+  g_assert_no_error (error);
+  g_object_unref (enumerator);
+
+  files = g_list_sort (files, compare_files);
+  g_list_foreach (files, (GFunc) add_test_for_file, NULL);
+  g_list_free_full (files, g_object_unref);
+}
+
+int
+main (int argc, char **argv)
+{
+  g_setenv ("GTK_CSS_DEBUG", "1", TRUE);
+
+  gtk_test_init (&argc, &argv);
+
+  if (argc < 2)
+    {
+      const char *basedir;
+      GFile *dir;
+
+      basedir = g_test_get_dir (G_TEST_DIST);
+      dir = g_file_new_for_path (basedir);
+      add_tests_for_files_in_directory (dir);
+
+      g_object_unref (dir);
+    }
+  else if (strcmp (argv[1], "--generate") == 0)
+    {
+      if (argc >= 3)
+        {
+          GFile *file = g_file_new_for_commandline_arg (argv[2]);
+
+          load_ui_file (file, TRUE);
+
+          g_object_unref (file);
+        }
+    }
+  else
+    {
+      guint i;
+
+      for (i = 1; i < argc; i++)
+        {
+          GFile *file = g_file_new_for_commandline_arg (argv[i]);
+
+          add_test_for_file (file);
+
+          g_object_unref (file);
+        }
+    }
+
+  return g_test_run ();
+}
+
diff --git a/testsuite/css/nodes/test-css-nodes.test.in b/testsuite/css/nodes/test-css-nodes.test.in
new file mode 100644
index 0000000..3fced1a
--- /dev/null
+++ b/testsuite/css/nodes/test-css-nodes.test.in
@@ -0,0 +1,3 @@
+[Test]
+Exec=/bin/sh -c "cd @libexecdir@/installed-tests/gtk+/css/nodes && 
@libexecdir@/installed-tests/gtk+/css/nodes/test-css-nodes
+Type=session


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]