[gnome-shell] Add run-js-test executable to run tests



commit c98103ffc81eff4416f3fe04b12e21545b9131b7
Author: Owen W. Taylor <otaylor fishsoup net>
Date:   Sun Oct 31 15:28:06 2010 -0400

    Add run-js-test executable to run tests
    
    ST makes use of GTK+ for input methods and for icon themes; therefore
    we have need to initialize GTK+ in order to test these parts of Clutter.
    
    Instead of LD_PRELOADING our module, use a separately compiled executable
    that links to the UI components in GNOME Shell, initializes Clutter and
    GTK+ and hooks them together.
    
    Getting all the symbols from St and the GUI components exported for
    use via GJS requires a bit of contortion: we need to actually link the
    St convenience library into a shared library and link the executable
    to that since there is no way with libtool to take a convenience library
    and put all its symbols into an executable --whole-archive style.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=633657

 .gitignore             |    1 +
 configure.ac           |    2 +
 src/Makefile.am        |   31 ++++++++++
 src/run-js-test.c      |  144 ++++++++++++++++++++++++++++++++++++++++++++++++
 tests/run-test.sh.in   |    9 +--
 tests/testcommon/ui.js |    1 -
 6 files changed, 182 insertions(+), 6 deletions(-)
---
diff --git a/.gitignore b/.gitignore
index eca8c90..f717e24 100644
--- a/.gitignore
+++ b/.gitignore
@@ -46,6 +46,7 @@ src/Makefile.in
 src/gnomeshell-taskpanel
 src/gnome-shell
 src/gnome-shell-clock-preferences
+src/run-js-test
 src/test-recorder
 src/test-recorder.ogg
 src/test-theme
diff --git a/configure.ac b/configure.ac
index d935d0f..a02faf5 100644
--- a/configure.ac
+++ b/configure.ac
@@ -93,6 +93,8 @@ PKG_CHECK_MODULES(GDMUSER, dbus-glib-1 gtk+-3.0)
 PKG_CHECK_MODULES(TRAY, gtk+-3.0)
 PKG_CHECK_MODULES(GVC, libpulse libpulse-mainloop-glib gobject-2.0)
 
+PKG_CHECK_MODULES(JS_TEST, clutter-x11-1.0 gjs-1.0 gobject-introspection-1.0 gtk+-3.0)
+
 MUTTER_BIN_DIR=`$PKG_CONFIG --variable=exec_prefix mutter-plugins`/bin
 # FIXME: metacity-plugins.pc should point directly to its .gir file
 MUTTER_LIB_DIR=`$PKG_CONFIG --variable=libdir mutter-plugins`
diff --git a/src/Makefile.am b/src/Makefile.am
index 6bdc0d2..5d05b57 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -117,6 +117,8 @@ libgnome_shell_la_SOURCES =		\
 libgnome_shell_la_gir_sources = \
 	$(filter-out %-private.h $(shell_recorder_non_gir_sources), $(shell_public_headers_h) $(libgnome_shell_la_SOURCES))
 
+########################################
+
 shell_recorder_sources =        \
 	shell-recorder.c	\
 	shell-recorder.h
@@ -139,6 +141,35 @@ test_recorder_SOURCES =     \
 	test-recorder.c
 endif BUILD_RECORDER
 
+########################################
+
+# In order to run the interactive tests for GUI components, we need to have
+# an executable that exports the St components. Libtool doesn't have a way
+# to include all the symbols from a convenience library into a executable
+# so what we do is build a small uninstalled library that pulls in the
+# St convenience library and link the test running program to that.
+
+noinst_LTLIBRARIES += libjs-test.la
+
+libjs_test_la_LDFLAGS = -rpath $(libdir)
+libjs_test_la_CPPFLAGS = $(JS_TEST_CFLAGS)
+libjs_test_la_LIBADD = $(JS_TEST_LIBS) libst-1.0.la
+
+# The tests use or reference a couple of Shell classes
+libjs_test_la_SOURCES = 		\
+	shell-generic-container.c	\
+	shell-perf-log.c
+
+noinst_PROGRAMS += run-js-test
+
+run_js_test_CPPFLAGS = $(JS_TEST_CFLAGS)
+run_js_test_LDADD = $(EST_UI_LIBS) libjs-test.la
+run_js_test_LDFLAGS = -export-dynamic
+
+run_js_test_SOURCES =			\
+	run-js-test.c
+
+########################################
 
 shell-marshal.h: stamp-shell-marshal.h
 	@true
diff --git a/src/run-js-test.c b/src/run-js-test.c
new file mode 100644
index 0000000..5be4ead
--- /dev/null
+++ b/src/run-js-test.c
@@ -0,0 +1,144 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/*
+ * Based on gjs/console.c from GJS
+ *
+ * Copyright (c) 2008  litl, LLC
+ * Copyright (c) 2010  Red Hat, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include <config.h>
+#include <gtk/gtk.h>
+#include <gdk/gdkx.h>
+#include <clutter/x11/clutter-x11.h>
+#include <string.h>
+#include <stdlib.h>
+#include <locale.h>
+
+#include <gjs/gjs.h>
+
+static char **include_path = NULL;
+static char *command = NULL;
+
+static GOptionEntry entries[] = {
+  { "command", 'c', 0, G_OPTION_ARG_STRING, &command, "Program passed in as a string", "COMMAND" },
+  { "include-path", 'I', 0, G_OPTION_ARG_STRING_ARRAY, &include_path, "Add the directory DIR to the list of directories to search for js files.", "DIR" },
+  { NULL }
+};
+
+static GdkFilterReturn
+event_filter (GdkXEvent *xevent,
+              GdkEvent  *event,
+              gpointer   data)
+{
+  XEvent *xev = (XEvent *)xevent;
+
+  if (clutter_x11_handle_event (xev) == CLUTTER_X11_FILTER_CONTINUE)
+    return GDK_FILTER_CONTINUE;
+  else
+    return GDK_FILTER_REMOVE;
+}
+
+int
+main(int argc, char **argv)
+{
+  char *command_line;
+  GOptionContext *context;
+  ClutterActor *stage;
+  GError *error = NULL;
+  GjsContext *js_context;
+  char *script;
+  const char *filename;
+  char *title;
+  gsize len;
+  int code;
+
+  g_thread_init (NULL);
+
+  gtk_init (&argc, &argv);
+
+  clutter_x11_set_display (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()));
+  clutter_x11_disable_event_retrieval ();
+
+  clutter_init (&argc, &argv);
+
+  gdk_window_add_filter (NULL, event_filter, NULL);
+
+  context = g_option_context_new (NULL);
+
+  /* pass unknown through to the JS script */
+  g_option_context_set_ignore_unknown_options (context, TRUE);
+
+  g_option_context_add_main_entries (context, entries, NULL);
+  if (!g_option_context_parse (context, &argc, &argv, &error))
+    g_error ("option parsing failed: %s", error->message);
+
+  setlocale (LC_ALL, "");
+  g_type_init ();
+
+  command_line = g_strjoinv (" ", argv);
+  g_debug ("Command line: %s", command_line);
+  g_free (command_line);
+
+  g_debug ("Creating new context to eval console script");
+  js_context = gjs_context_new_with_search_path (include_path);
+
+  /* prepare command line arguments */
+  if (!gjs_context_define_string_array (js_context, "ARGV",
+                                        argc - 2, (const char**)argv + 2,
+                                        &error)) {
+    g_printerr ("Failed to defined ARGV: %s", error->message);
+    exit (1);
+  }
+
+  if (command != NULL) {
+    script = command;
+    len = strlen (script);
+    filename = "<command line>";
+  } else if (argc <= 1) {
+    script = g_strdup ("const Console = imports.console; Console.interact();");
+    len = strlen (script);
+    filename = "<stdin>";
+  } else /*if (argc >= 2)*/ {
+    error = NULL;
+    if (!g_file_get_contents (argv[1], &script, &len, &error)) {
+      g_printerr ("%s\n", error->message);
+      exit (1);
+    }
+    filename = argv[1];
+  }
+
+  stage = clutter_stage_get_default ();
+  title = g_filename_display_basename (filename);
+  clutter_stage_set_title (CLUTTER_STAGE (stage), title);
+  g_free (title);
+
+  /* evaluate the script */
+  error = NULL;
+  if (!gjs_context_eval (js_context, script, len,
+                         filename, &code, &error)) {
+    g_free (script);
+    g_printerr ("%s\n", error->message);
+    exit (1);
+  }
+
+  g_free (script);
+  exit (code);
+}
diff --git a/tests/run-test.sh.in b/tests/run-test.sh.in
index 1ee197e..af905cb 100644
--- a/tests/run-test.sh.in
+++ b/tests/run-test.sh.in
@@ -11,7 +11,7 @@ debug=
 for arg in $@ ; do
     case $arg in
 	-g|--debug)
-	    debug="gdb --args"
+	    debug="libtool --mode=execute gdb --args"
 	    ;;
 	-v|--verbose)
 	    verbose=true
@@ -34,15 +34,14 @@ GI_TYPELIB_PATH="@MUTTER_LIB_DIR@/mutter:$builddir/../src"
 GJS_DEBUG_OUTPUT=stderr
 $verbose || GJS_DEBUG_TOPICS="JS ERROR;JS LOG"
 GNOME_SHELL_TESTSDIR="$srcdir/"
-LD_PRELOAD="$builddir/../src/.libs/libgnome-shell.so"
 
 export GI_TYPELIB_PATH GJS_DEBUG_OUTPUT GJS_DEBUG_TOPICS GNOME_SHELL_JS GNOME_SHELL_TESTSDIR LD_PRELOAD
 
-gjs_args=
+run_js_test_args=
 for i in $srcdir $srcdir/../js @GJS_JS_DIR@ @GJS_JS_NATIVE_DIR@ ; do
-    gjs_args="$gjs_args -I $i"
+    run_js_test_args="$run_js_test_args -I $i"
 done
 
 for test in $tests ; do
-    $debug gjs-console $gjs_args $test || exit $?
+    $debug $builddir/../src/run-js-test $run_js_test_args $test || exit $?
 done
diff --git a/tests/testcommon/ui.js b/tests/testcommon/ui.js
index 7110c65..82d5861 100644
--- a/tests/testcommon/ui.js
+++ b/tests/testcommon/ui.js
@@ -8,7 +8,6 @@ const Shell = imports.gi.Shell;
 const Environment = imports.ui.environment;
 
 function init() {
-    Clutter.init(null, null);
     Environment.init();
 
     let stage = Clutter.Stage.get_default();



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