diff --git a/.gitignore b/.gitignore index eca8c9034..f717e24bb 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 d935d0fcf..a02faf584 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 6bdc0d261..5d05b5768 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 000000000..5be4eaddd --- /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 +#include +#include +#include +#include +#include +#include + +#include + +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 = ""; + } else if (argc <= 1) { + script = g_strdup ("const Console = imports.console; Console.interact();"); + len = strlen (script); + filename = ""; + } 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 1ee197eb2..af905cbc8 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 7110c65a1..82d5861d5 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();