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
This commit is contained in:
parent
86f3a637f1
commit
c98103ffc8
1
.gitignore
vendored
1
.gitignore
vendored
@ -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
|
||||
|
@ -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`
|
||||
|
@ -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
|
||||
|
144
src/run-js-test.c
Normal file
144
src/run-js-test.c
Normal file
@ -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);
|
||||
}
|
@ -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
|
||||
|
@ -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();
|
||||
|
Loading…
Reference in New Issue
Block a user