diff --git a/.gitignore b/.gitignore index f4bcb22de..ba962a71b 100644 --- a/.gitignore +++ b/.gitignore @@ -39,4 +39,5 @@ src/gnome-shell src/test-recorder src/test-recorder.ogg stamp-h1 +tests/run-test.sh xmldocs.make diff --git a/Makefile.am b/Makefile.am index baf7dcb5a..259c0302b 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,4 +1,4 @@ -SUBDIRS = data js src po +SUBDIRS = data js src tests po EXTRA_DIST = \ .project \ diff --git a/configure.ac b/configure.ac index 050b3756f..b1fd289c3 100644 --- a/configure.ac +++ b/configure.ac @@ -129,5 +129,6 @@ AC_OUTPUT([ js/misc/Makefile js/ui/Makefile src/Makefile + tests/Makefile po/Makefile.in ]) diff --git a/js/ui/Makefile.am b/js/ui/Makefile.am index a79051580..4f6490cac 100644 --- a/js/ui/Makefile.am +++ b/js/ui/Makefile.am @@ -9,6 +9,7 @@ dist_jsui_DATA = \ dash.js \ dnd.js \ docDisplay.js \ + environment.js \ genericDisplay.js \ lightbox.js \ link.js \ diff --git a/js/ui/environment.js b/js/ui/environment.js new file mode 100644 index 000000000..01e224615 --- /dev/null +++ b/js/ui/environment.js @@ -0,0 +1,32 @@ +/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */ + +const St = imports.gi.St; + +const Tweener = imports.ui.tweener; + +// "monkey patch" in some varargs ClutterContainer methods; we need +// to do this per-container class since there is no representation +// of interfaces in Javascript +function _patchContainerClass(containerClass) { + // This one is a straightforward mapping of the C method + containerClass.prototype.child_set = function(actor, props) { + let meta = this.get_child_meta(actor); + for (prop in props) + meta[prop] = props[prop]; + }; + + // clutter_container_add() actually is a an add-many-actors + // method. We conveniently, but somewhat dubiously, take the + // this opportunity to make it do something more useful. + containerClass.prototype.add = function(actor, props) { + this.add_actor(actor); + if (props) + this.child_set(actor, props); + }; +} + +_patchContainerClass(St.BoxLayout); + +function init() { + Tweener.init(); +} diff --git a/js/ui/main.js b/js/ui/main.js index f6a3c19dd..f400f9c84 100644 --- a/js/ui/main.js +++ b/js/ui/main.js @@ -13,13 +13,13 @@ const Signals = imports.signals; const St = imports.gi.St; const Chrome = imports.ui.chrome; +const Environment = imports.ui.environment; const Overview = imports.ui.overview; const Panel = imports.ui.panel; const RunDialog = imports.ui.runDialog; const LookingGlass = imports.ui.lookingGlass; const ShellDBus = imports.ui.shellDBus; const Sidebar = imports.ui.sidebar; -const Tweener = imports.ui.tweener; const WindowManager = imports.ui.windowManager; const DEFAULT_BACKGROUND_COLOR = new Clutter.Color(); @@ -37,28 +37,6 @@ let shellDBusService = null; let modalCount = 0; let modalActorFocusStack = []; -// "monkey patch" in some varargs ClutterContainer methods; we need -// to do this per-container class since there is no representation -// of interfaces in Javascript -function _patchContainerClass(containerClass) { - // This one is a straightforward mapping of the C method - containerClass.prototype.child_set = function(actor, props) { - let meta = this.get_child_meta(actor); - for (prop in props) - meta[prop] = props[prop]; - }; - - // clutter_container_add() actually is a an add-many-actors - // method. We conveniently, but somewhat dubiously, take the - // this opportunity to make it do something more useful. - containerClass.prototype.add = function(actor, props) { - this.add_actor(actor); - if (props) - this.child_set(actor, props); - }; -} -_patchContainerClass(St.BoxLayout); - function start() { // Add a binding for "global" in the global JS namespace; (gjs // keeps the web browser convention of having that namespace be @@ -75,7 +53,7 @@ function start() { // back into sync ones. DBus.session.flush(); - Tweener.init(); + Environment.init(); // Ensure ShellAppMonitor is initialized; this will // also initialize ShellAppSystem first. ShellAppSystem diff --git a/tests/Makefile.am b/tests/Makefile.am new file mode 100644 index 000000000..35ba1c76e --- /dev/null +++ b/tests/Makefile.am @@ -0,0 +1,20 @@ +noinst_SCRIPTS = run-test.sh +EXTRA_DIST = run-test.sh.in + +TEST_JS = \ + testcommon/ui.js \ + interactive/box-layout.js +EXTRA_DIST += $(TEST_JS) + +TEST_MISC = \ + testcommon/test.css +EXTRA_DIST += $(TEST_MISC) + +# We substitute in bindir so it works as an autostart +# file when built in a non-system prefix +run-test.sh: run-test.sh.in + $(AM_V_GEN) sed \ + -e "s|@GJS_JS_DIR[@]|$(GJS_JS_DIR)|" \ + -e "s|@GJS_JS_NATIVE_DIR[@]|$(GJS_JS_NATIVE_DIR)|" \ + -e "s|@srcdir[@]|$(srcdir)|" \ + $< > $@ && chmod a+x $@ diff --git a/tests/interactive/box-layout.js b/tests/interactive/box-layout.js new file mode 100644 index 000000000..ae4db6986 --- /dev/null +++ b/tests/interactive/box-layout.js @@ -0,0 +1,39 @@ +/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */ + +const Clutter = imports.gi.Clutter; +const St = imports.gi.St; + +const UI = imports.testcommon.ui; + +UI.init(); +let stage = Clutter.Stage.get_default(); + +let b = new St.BoxLayout({ vertical: true, + width: stage.width, + height: stage.height }); +stage.add_actor(b); + +let b2 = new St.BoxLayout(); +b.add(b2, { expand: true, fill: true }); + +let r1 = new St.BoxLayout({ style_class: 'red', + width: 10, + height: 10 }); +b2.add(r1, { expand: true }); + +let r2 = new St.BoxLayout({ style_class: 'green', + width: 10, + height: 10 }); +b2.add(r2, { expand: true, + x_fill: false, + x_align: St.Align.MIDDLE, + y_fill: false, + y_align: St.Align.MIDDLE }); + +let r3 = new St.BoxLayout({ style_class: 'blue', + width: 10, + height: 10 }); +b.add(r3); + +stage.show(); +Clutter.main(); diff --git a/tests/run-test.sh.in b/tests/run-test.sh.in new file mode 100644 index 000000000..ce1ce3e3b --- /dev/null +++ b/tests/run-test.sh.in @@ -0,0 +1,44 @@ +#!/bin/sh + +usage() { + echo >&2 "Usage run-test.sh [-v|--verbose] ..." + exit 1 +} + +tests= +verbose=false +for arg in $@ ; do + case $arg in + -v|--verbose) + verbose=true + ;; + -*) + usage + ;; + *) + tests="$tests $arg" + ;; + esac +done + +builddir=`dirname $0` +builddir=`cd $builddir && pwd` +srcdir=$builddir/@srcdir@ +srcdir=`cd $srcdir && pwd` + +GI_TYPELIB_PATH="$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= +for i in $srcdir $srcdir/../js @GJS_JS_DIR@ @GJS_JS_NATIVE_DIR@ ; do + gjs_args="$gjs_args -I $i" +done + +for test in $tests ; do + gjs-console $gjs_args $test || exit $? +done diff --git a/tests/testcommon/test.css b/tests/testcommon/test.css new file mode 100644 index 000000000..f81679117 --- /dev/null +++ b/tests/testcommon/test.css @@ -0,0 +1,13 @@ +@import "../../data/gnome-shell.css"; + +*.red { + background-color: red; +} + +*.green { + background-color: green; +} + +*.blue { + background-color: blue; +} diff --git a/tests/testcommon/ui.js b/tests/testcommon/ui.js new file mode 100644 index 000000000..219bf4782 --- /dev/null +++ b/tests/testcommon/ui.js @@ -0,0 +1,16 @@ +/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */ + +const Clutter = imports.gi.Clutter; +const GLib = imports.gi.GLib; +const St = imports.gi.St; + +const Environment = imports.ui.environment; + +function init() { + Clutter.init(null, null); + Environment.init(); + + let style = St.Style.get_default(); + let stylesheetPath = GLib.getenv("GNOME_SHELL_TESTSDIR") + "/testcommon/test.css"; + style.load_from_file(stylesheetPath); +}