[clutter] test-interactive: Allow querying the interactive test for a description



commit d640c56cef4738b2c9b75b034b81438390538561
Author: Emmanuele Bassi <ebassi linux intel com>
Date:   Tue Sep 27 17:40:51 2011 +0100

    test-interactive: Allow querying the interactive test for a description
    
    It would be nice if the interactive tests had a way to be queried for a
    description, instead of "Just Knowing" what they are meant to be doing.

 tests/interactive/Makefile.am |   25 ++++-
 tests/interactive/test-main.c |  210 +++++++++++++++++++++++++++++++++++++----
 2 files changed, 211 insertions(+), 24 deletions(-)
---
diff --git a/tests/interactive/Makefile.am b/tests/interactive/Makefile.am
index 75da2ad..73d24eb 100644
--- a/tests/interactive/Makefile.am
+++ b/tests/interactive/Makefile.am
@@ -74,11 +74,13 @@ endif
 # For convenience, this provides a way to easily run individual unit tests:
 wrappers: stamp-test-interactive
 	@true
-stamp-test-interactive: Makefile test-interactive$(EXEEXT)
+stamp-test-interactive: Makefile
 	@wrapper=$(abs_builddir)/wrapper.sh ; \
 	chmod +x $$wrapper && \
 	( echo "/stamp-test-interactive" ; \
+	  echo "/stamp-test-unit-names" ; \
 	  echo "/test-interactive" ; \
+	  echo "/test-unit-names.h" ; \
 	  echo "*.o" ; \
 	  echo ".gitignore" ) > .gitignore ; \
 	for i in $(UNIT_TESTS); \
@@ -93,6 +95,21 @@ stamp-test-interactive: Makefile test-interactive$(EXEEXT)
 	done \
 	&& echo timestamp > $(@F)
 
+test-unit-names.h: stamp-test-unit-names
+	@true
+
+stamp-test-unit-names: Makefile
+	@( echo "/* ** This file is autogenerated. Do not edit. ** */" ; \
+	  echo "" ; \
+	  echo "const char *test_unit_names[] = {" ) > test-unit-names.h ; \
+	for i in $(UNIT_TESTS); \
+	do \
+		test_bin=$${i%*.c} ; \
+		echo "  \"$$test_bin\"," >> test-unit-names.h ; \
+	done \
+	&& echo "};" >> test-unit-names.h \
+	&& echo timestamp > $(@F)
+
 clean-wrappers:
 	@for i in $(UNIT_TESTS); \
 	do \
@@ -115,7 +132,7 @@ common_ldadd = $(top_builddir)/clutter/libclutter- CLUTTER_SONAME_INFIX@- CLUTTE
 
 noinst_PROGRAMS = test-interactive
 
-test_interactive_SOURCES = test-main.c $(UNIT_TESTS)
+test_interactive_SOURCES = test-main.c test-unit-names.h $(UNIT_TESTS)
 test_interactive_CFLAGS = $(CLUTTER_CFLAGS) $(MAINTAINER_CFLAGS)
 test_interactive_CPPFLAGS = \
 	-DTESTS_DATADIR=\""$(abs_top_srcdir)/tests/data"\" \
@@ -126,8 +143,8 @@ test_interactive_LDFLAGS = -export-dynamic
 test_interactive_LDADD = $(CLUTTER_LIBS) $(common_ldadd) -lm
 
 EXTRA_DIST = wrapper.sh.in
-DISTCLEANFILES = wrapper.sh .gitignore
+DISTCLEANFILES = wrapper.sh .gitignore test-unit-names.h
 
-BUILT_SOURCES = wrappers
+BUILT_SOURCES = wrappers test-unit-names.h
 
 clean-local: clean-wrappers
diff --git a/tests/interactive/test-main.c b/tests/interactive/test-main.c
index 2a0cd74..10d0322 100644
--- a/tests/interactive/test-main.c
+++ b/tests/interactive/test-main.c
@@ -1,37 +1,207 @@
+#include <stdlib.h>
+#include <string.h>
 #include <glib.h>
 #include <gmodule.h>
 
+#include "test-unit-names.h"
 
-int
-main (int argc, char **argv)
+#define MAX_DESC_SIZE   72
+
+static GModule *module = NULL;
+
+static gpointer
+get_symbol_with_suffix (const char *unit_name,
+                        const char *suffix)
 {
-  GModule *module;
-  char *unit_test;
   char *main_symbol_name;
   gpointer func;
-  int (*unit_test_main) (int argc, char **argv);
-  int ret;
 
-  if (argc < 2)
-    g_error ("Usage: %s unit_test", argv[0]);
-  
+  main_symbol_name = g_strconcat (unit_name, "_", suffix, NULL);
+  main_symbol_name = g_strdelimit (main_symbol_name, "-", '_');
+
+  g_module_symbol (module, main_symbol_name, &func);
+
+  g_free (main_symbol_name);
+
+  return func;
+}
+
+static gpointer
+get_unit_name_main (const char *unit_name)
+{
+  return get_symbol_with_suffix (unit_name, "main");
+}
+static char *
+get_unit_name_description (const char *unit_name,
+                           gssize      max_len)
+{
+  const char *description;
+  gpointer func;
+  char *retval;
+
+  func = get_symbol_with_suffix (unit_name, "describe");
+  if (func == NULL)
+    description = "No description found";
+  else
+    {
+      const char *(* unit_test_describe) (void);
+
+      unit_test_describe = func;
+
+      description = unit_test_describe ();
+    }
+
+  if (max_len > 0 && strlen (description) >= max_len)
+    {
+      GString *buf = g_string_sized_new (max_len);
+      char *newline;
+
+      newline = strchr (description, '\n');
+      if (newline != NULL)
+        {
+          g_string_append_len (buf, description,
+                               MIN (newline - description - 1, max_len - 3));
+        }
+      else
+        g_string_append_len (buf, description, max_len - 3);
+
+      g_string_append (buf, "...");
+
+      retval = g_string_free (buf, FALSE);
+    }
+  else
+    retval = g_strdup (description);
+
+  return retval;
+}
+
+static gboolean list_all = FALSE;
+static gboolean describe = FALSE;
+static char **unit_names = NULL;
+
+static GOptionEntry entries[] = {
+  {
+    "describe", 'd',
+    0,
+    G_OPTION_ARG_NONE, &describe,
+    "Describe the interactive unit test", NULL,
+  },
+  {
+    "list-all", 'l',
+    0,
+    G_OPTION_ARG_NONE, &list_all,
+    "List all available units", NULL,
+  },
+  {
+    G_OPTION_REMAINING, 0,
+    0,
+    G_OPTION_ARG_STRING_ARRAY, &unit_names,
+    "The interactive unit test", "UNIT_NAME"
+  },
+  { NULL }
+};
+
+int
+main (int argc, char **argv)
+{
+  int ret, i, n_unit_names;
+  GOptionContext *context;
+
+  context = g_option_context_new (" - Interactive test suite");
+  g_option_context_add_main_entries (context, entries, NULL);
+  g_option_context_set_help_enabled (context, TRUE);
+  g_option_context_set_ignore_unknown_options (context, TRUE);
+  if (!g_option_context_parse (context, &argc, &argv, NULL))
+    {
+      g_print ("Usage: test-interactive <unit_test>\n");
+      return EXIT_FAILURE;
+    }
+
+  g_option_context_free (context);
+
   module = g_module_open (NULL, 0);
   if (!module)
-    g_error ("Failed to open self for symbol lookup");
+    g_error ("*** Failed to open self for symbol lookup");
 
-  unit_test = g_path_get_basename (argv[1]);
+  ret = EXIT_SUCCESS;
 
-  main_symbol_name = g_strdup_printf ("%s_main", unit_test);
-  main_symbol_name = g_strdelimit (main_symbol_name, "-", '_');
+  if (list_all)
+    {
+      g_print ("* Available unit tests:\n");
 
-  if (!g_module_symbol (module, main_symbol_name, &func))
-    g_error ("Failed to look up main symbol for the test: %s", unit_test);
+      for (i = 0; i < G_N_ELEMENTS (test_unit_names); i++)
+        {
+          char *str;
+          gsize len;
 
-  unit_test_main = func;
-  ret = unit_test_main (argc - 1, argv + 1);
-  
-  g_free (unit_test);
-  g_free (main_symbol_name);
+          len = MAX_DESC_SIZE - strlen (test_unit_names[i]);
+          str = get_unit_name_description (test_unit_names[i], len - 2);
+
+          g_print ("  - %s:%*s%s\n",
+                   test_unit_names[i],
+                   (int) len - strlen (str), " ",
+                   str);
+
+          g_free (str);
+        }
+
+      ret = EXIT_SUCCESS;
+      goto out;
+    }
+
+  n_unit_names = g_strv_length (unit_names);
+  for (i = 0; i < n_unit_names; i++)
+    {
+      const char *unit_name = unit_names[i];
+      char *unit_test = NULL;
+      gboolean found;
+      int j;
+
+      unit_test = g_path_get_basename (unit_name);
+
+      found = FALSE;
+      for (j = 0; j < G_N_ELEMENTS (test_unit_names); j++)
+        {
+          if (strcmp (test_unit_names[j], unit_test) == 0)
+            {
+              found = TRUE;
+              break;
+            }
+        }
+
+      if (!found)
+        g_error ("*** Unit '%s' does not exist", unit_test);
+
+      if (describe)
+        {
+          char *str;
+
+          str = get_unit_name_description (unit_test, -1);
+
+          g_print ("* %s:\n%s\n\n", unit_test, str);
+
+          g_free (str);
+
+          ret = EXIT_SUCCESS;
+        }
+      else
+        {
+          int (* unit_test_main) (int argc, char **argv);
+          gpointer func;
+
+          func = get_unit_name_main (unit_test);
+          if (func == NULL)
+            g_error ("*** Unable to find the main entry point for '%s'", unit_test);
+
+          unit_test_main = func;
+
+          ret = unit_test_main (argc, argv);
+        }
+
+      g_free (unit_test);
+    }
+
+out:
   g_module_close (module);
 
   return ret;



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