[gtk+/wip/otte/shader: 74/98] testsuite: Add a simple test runner for errors



commit 0194e3d777ccf2124bbe2346413507fbe30d6301
Author: Benjamin Otte <otte redhat com>
Date:   Tue Oct 17 01:42:33 2017 +0200

    testsuite: Add a simple test runner for errors
    
    The test runner does nothing more but try to parse a given source and
    check that that fails.
    
    If it succeeds or crashes, the test fails.

 gsk/gsksldeclaration.c       |    7 ++
 gsk/gskslstatement.c         |   14 +++-
 testsuite/gsksl/meson.build  |    9 +++
 testsuite/gsksl/test-error.c |  163 ++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 189 insertions(+), 4 deletions(-)
---
diff --git a/gsk/gsksldeclaration.c b/gsk/gsksldeclaration.c
index 8be61c0..9a85dc8 100644
--- a/gsk/gsksldeclaration.c
+++ b/gsk/gsksldeclaration.c
@@ -251,6 +251,13 @@ gsk_sl_declaration_parse_variable (GskSlScope           *scope,
     }
   gsk_sl_preprocessor_consume (preproc, NULL);
 
+  if (qualifier->storage == GSK_SL_STORAGE_GLOBAL_CONST &&
+      initial_value == NULL)
+    {
+      gsk_sl_preprocessor_error (preproc, DECLARATION, "Variables with \"const\" qualifier must be 
initialized with a constant value.");
+      initial_value = gsk_sl_value_new (type);
+    }
+
   variable = gsk_sl_declaration_new (&GSK_SL_DECLARATION_VARIABLE);
   variable->variable = gsk_sl_variable_new (name, type, qualifier, NULL);
   gsk_sl_scope_add_variable (scope, variable->variable);
diff --git a/gsk/gskslstatement.c b/gsk/gskslstatement.c
index cc54593..c758df2 100644
--- a/gsk/gskslstatement.c
+++ b/gsk/gskslstatement.c
@@ -506,7 +506,7 @@ gsk_sl_statement_parse_declaration (GskSlScope           *scope,
                                     GskSlType            *type)
 {
   GskSlStatementDeclaration *declaration;
-  GskSlValue *value = NULL;
+  GskSlValue *initial_value = NULL;
   const GskSlToken *token;
   char *name;
 
@@ -539,7 +539,7 @@ gsk_sl_statement_parse_declaration (GskSlScope           *scope,
               unconverted = gsk_sl_expression_get_constant (declaration->initial);
               if (unconverted)
                 {
-                  value = gsk_sl_value_new_convert (unconverted, type);
+                  initial_value = gsk_sl_value_new_convert (unconverted, type);
                   gsk_sl_value_free (unconverted);
                 }
             }
@@ -548,10 +548,16 @@ gsk_sl_statement_parse_declaration (GskSlScope           *scope,
   else
     {
       name = NULL;
-      value = NULL;
     }
 
-  declaration->variable = gsk_sl_variable_new (name, type, qualifier, value);
+  if (qualifier->storage == GSK_SL_STORAGE_LOCAL_CONST &&
+      initial_value == NULL)
+    {
+      gsk_sl_preprocessor_error (stream, DECLARATION, "Variables with \"const\" qualifier must be 
initialized with a value.");
+      initial_value = gsk_sl_value_new (type);
+    }
+
+  declaration->variable = gsk_sl_variable_new (name, type, qualifier, initial_value);
   g_free (name);
   gsk_sl_scope_add_variable (scope, declaration->variable);
 
diff --git a/testsuite/gsksl/meson.build b/testsuite/gsksl/meson.build
index 6c206c4..ac9b67c 100644
--- a/testsuite/gsksl/meson.build
+++ b/testsuite/gsksl/meson.build
@@ -1,3 +1,12 @@
+test_env = environment()
+test_env.set('G_TEST_SRCDIR', meson.current_source_dir())
+test_env.set('G_TEST_BUILDDIR', meson.current_build_dir())
+test_env.set('GTK_IM_MODULE', 'gtk-im-context-simple')
+test_env.set('GSETTINGS_BACKEND', 'memory')
+test_env.set('G_ENABLE_DIAGNOSTIC', '0')
 
 test_parser = executable('test-parser', 'test-parser.c', dependencies: libgtk_dep)
 test('gsksl/parser', test_parser)
+
+test_errors = executable('test-error', 'test-error.c', dependencies: libgtk_dep)
+test('gsksl/error', test_errors)
diff --git a/testsuite/gsksl/test-error.c b/testsuite/gsksl/test-error.c
new file mode 100644
index 0000000..b957270
--- /dev/null
+++ b/testsuite/gsksl/test-error.c
@@ -0,0 +1,163 @@
+/*
+ * Copyright (C) 2017 Red Hat Inc.
+ *
+ * Author:
+ *      Benjamin Otte <otte 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 "config.h"
+
+#include <string.h>
+#include <glib/gstdio.h>
+#include <gsk/gsk.h>
+#include <gtk/gtk.h>
+
+static GskSlCompiler *compiler;
+
+static void
+test_glsl_file (GFile *file)
+{
+  GskSlProgram *program;
+
+  program = gsk_sl_compiler_compile_file (compiler, file);
+  if (program != NULL)
+    {
+      g_object_unref (program);
+      g_test_message ("Unexpected success while compiling file.");
+      g_test_fail ();
+    }
+}
+
+
+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_glsl_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, ".glsl") &&
+          !g_str_has_suffix (filename, ".frag") &&
+          !g_str_has_suffix (filename, ".vert"))
+        {
+          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)
+{
+  int result;
+
+  gtk_test_init (&argc, &argv);
+
+  compiler = gsk_sl_compiler_new ();
+
+  if (argc < 2)
+    {
+      const char *basedir;
+      char *errordir;
+      GFile *dir;
+
+      basedir = g_test_get_dir (G_TEST_DIST);
+      errordir = g_build_filename (basedir, "errors", NULL);
+      dir = g_file_new_for_path (errordir);
+      add_tests_for_files_in_directory (dir);
+
+      g_object_unref (dir);
+      g_free (errordir);
+    }
+  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);
+        }
+    }
+
+  result = g_test_run ();
+
+  g_object_unref (compiler);
+  
+  return result;
+}
+


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