[gjs/wip/installed-tests] wip



commit 56d3b55b2ec3d5530daabfa5f0e157a0174d3f59
Author: Colin Walters <walters verbum org>
Date:   Thu Apr 18 05:40:23 2013 -0400

    wip

 Makefile-test.am                                   | 177 +-----
 installed-tests/.gitignore                         |  40 ++
 installed-tests/Makefile-test.am                   |  77 +++
 installed-tests/Makefile.am                        |  19 +
 installed-tests/autogen.sh                         |   2 +
 installed-tests/configure.ac                       |  49 ++
 {test => installed-tests/test}/gjs-unit.c          | 150 +----
 {test => installed-tests/test}/gjs.supp            |   0
 .../test}/js/modules/alwaysThrows.js               |   0
 .../test}/js/modules/foobar.js                     |   0
 .../test}/js/modules/modunicode.js                 |   0
 .../test}/js/modules/mutualImport/a.js             |   0
 .../test}/js/modules/mutualImport/b.js             |   0
 .../test}/js/modules/subA/.hidden/hidden.js        |   0
 .../test}/js/modules/subA/.secret.js               |   0
 {test => installed-tests/test}/js/modules/subA/foo |   0
 .../test}/js/modules/subA/subB/__init__.js         |   0
 .../test}/js/modules/subA/subB/baz.js              |   0
 .../test}/js/modules/subA/subB/foobar.js           |   0
 installed-tests/test/js/test0010basic.js           |   8 +
 installed-tests/test/js/test0020importer.js        |   9 +
 installed-tests/test/js/test0030basicBoxed.js      |  11 +
 .../test}/js/test0040mainloop.js                   |   4 +-
 installed-tests/test/js/testByteArray.js           | 122 ++++
 {test => installed-tests/test}/js/testCairo.js     |   0
 {test => installed-tests/test}/js/testClass.js     |  45 +-
 installed-tests/test/js/testEverythingBasic.js     | 624 ++++++++++++++++++++
 .../test}/js/testEverythingEncapsulated.js         | 133 +++--
 {test => installed-tests/test}/js/testGDBus.js     | 186 +++---
 .../test}/js/testGIMarshalling.js                  |   0
 .../test}/js/testGObjectClass.js                   |   0
 installed-tests/test/js/testJS1_8.js               |  54 ++
 installed-tests/test/js/testJSDefault.js           |  16 +
 installed-tests/test/js/testLang.js                | 128 +++++
 {test => installed-tests/test}/js/testLocale.js    |  22 +-
 {test => installed-tests/test}/js/testMainloop.js  |  18 +-
 {test => installed-tests/test}/js/testMetaClass.js |  44 +-
 installed-tests/test/js/testParamSpec.js           |  96 ++++
 {test => installed-tests/test}/js/testSignals.js   |  38 +-
 installed-tests/test/js/testSystem.js              |  15 +
 {test => installed-tests/test}/js/testTweener.js   |  80 +--
 installed-tests/test/js/testUnicode.js             |  14 +
 installed-tests/test/js/testself.js                |  38 ++
 {test => installed-tests/test}/unittest.gdb        |   0
 test/js/test0010basic.js                           |   7 -
 test/js/test0020importer.js                        |   7 -
 test/js/test0030basicBoxed.js                      |  10 -
 test/js/testByteArray.js                           | 120 ----
 test/js/testEverythingBasic.js                     | 625 ---------------------
 test/js/testImporter.js                            | 148 -----
 test/js/testJS1_8.js                               |  52 --
 test/js/testJSDefault.js                           |  13 -
 test/js/testLang.js                                | 126 -----
 test/js/testParamSpec.js                           |  99 ----
 test/js/testSystem.js                              |  13 -
 test/js/testUnicode.js                             |  12 -
 test/js/testself.js                                |  36 --
 57 files changed, 1619 insertions(+), 1868 deletions(-)
---
diff --git a/Makefile-test.am b/Makefile-test.am
index 60beeab..b3e1b9a 100644
--- a/Makefile-test.am
+++ b/Makefile-test.am
@@ -1,8 +1,6 @@
 RUN_WITH_DBUS = ${top_srcdir}/test/run-with-dbus --session --system
 GTESTER = ${TESTS_ENVIRONMENT} ${RUN_WITH_DBUS} gtester
 
-TEST_GIRS =
-
 ########################################################################
 TEST_PROGS += gjs-tests
 
@@ -22,69 +20,11 @@ gjs_tests_LDADD =           \
 gjs_tests_SOURCES =            \
        test/gjs-tests.c
 
-TEST_PROGS += gjs-unit
-
-gjs_unit_CPPFLAGS =            \
-       $(AM_CPPFLAGS)          \
-       $(gjs_directory_defines)\
-       $(GJS_CFLAGS)
-gjs_unit_LDADD =               \
-       libgjs.la               \
-       $(GJS_LIBS)
-
-## -rdynamic makes backtraces work
-## we -export-dynamic so we can dlopen ourselves and use gobject-introspection
-gjs_unit_LDFLAGS=-export-dynamic -rdynamic
-gjs_unit_SOURCES =     \
-       test/gjs-unit.c
-
-# noinst_ always builds a static library
-testlib_LTLIBRARIES = libregress.la libwarnlib.la libgimarshallingtests.la
-testlibdir = $(prefix)/unused
-install-testlibLTLIBRARIES: # prevent it from being installed
-
-nodist_libregress_la_SOURCES = $(GI_DATADIR)/tests/regress.c $(GI_DATADIR)/tests/regress.h
-libregress_la_CPPFLAGS =
-libregress_la_CFLAGS = $(GJS_CFLAGS)
-libregress_la_LDFLAGS = -avoid-version $(GJS_LIBS)
-libregress_scannerflags_includes = --include=Gio-2.0
-if ENABLE_CAIRO
-libregress_la_CFLAGS += $(GJS_CAIRO_CFLAGS)
-libregress_la_LDFLAGS +=  $(GJS_CAIRO_LIBS)
-libregress_scannerflags_includes += --include=cairo-1.0
-else
-libregress_la_CPPFLAGS += -D_GI_DISABLE_CAIRO
-endif
-nodist_libwarnlib_la_SOURCES = $(GI_DATADIR)/tests/warnlib.c $(GI_DATADIR)/tests/warnlib.h
-libwarnlib_la_CFLAGS = $(GJS_CFLAGS)
-libwarnlib_la_LDFLAGS = -avoid-version $(GJS_LIBS)
-nodist_libgimarshallingtests_la_SOURCES = $(GI_DATADIR)/tests/gimarshallingtests.c 
$(GI_DATADIR)/tests/gimarshallingtests.h
-libgimarshallingtests_la_CFLAGS = $(GJS_CFLAGS)
-libgimarshallingtests_la_LDFLAGS = -avoid-version $(GJS_LIBS)
-
-Regress-1.0.gir: libregress.la
-Regress_1_0_gir_LIBS = libregress.la
-Regress_1_0_gir_FILES = $(nodist_libregress_la_SOURCES)
-Regress_1_0_gir_SCANNERFLAGS = --warn-all --warn-error $(libregress_scannerflags_includes) 
$(libregress_la_CPPFLAGS)
-TEST_GIRS += Regress-1.0.gir
-
-WarnLib-1.0.gir: libwarnlib.la
-WarnLib_1_0_gir_LIBS = libwarnlib.la
-WarnLib_1_0_gir_INCLUDES = Gio-2.0
-WarnLib_1_0_gir_FILES = $(nodist_libwarnlib_la_SOURCES)
-WarnLib_1_0_gir_SCANNERFLAGS = --c-include="warnlib.h" --symbol-prefix=warnlib_
-TEST_GIRS += WarnLib-1.0.gir
-
-GIMarshallingTests-1.0.gir: libgimarshallingtests.la
-GIMarshallingTests_1_0_gir_LIBS = libgimarshallingtests.la
-GIMarshallingTests_1_0_gir_INCLUDES = Gio-2.0
-GIMarshallingTests_1_0_gir_FILES = $(nodist_libgimarshallingtests_la_SOURCES)
-GIMarshallingTests_1_0_gir_SCANNERFLAGS = --symbol-prefix=gi_marshalling_tests --warn-all --warn-error
-TEST_GIRS += GIMarshallingTests-1.0.gir
+check-local: gjs-tests
+       @test -z "${TEST_PROGS}" || ${GTESTER} --verbose ${TEST_PROGS} ${TEST_PROGS_OPTIONS}
 
-$(foreach gir,$(TEST_GIRS),$(eval $(call introspection-scanner,$(gir))))
+check: check-local
 
-########################################################################
 TESTS_ENVIRONMENT =                                                    \
        TOP_SRCDIR=$(top_srcdir)                                        \
        DBUS_SESSION_BUS_ADDRESS=''                                     \
@@ -96,114 +36,3 @@ TESTS_ENVIRONMENT =                                                 \
        GI_TYPELIB_PATH=$(builddir)                                     \
        LD_LIBRARY_PATH="$(LD_LIBRARY_PATH):$(FIREFOX_JS_LIBDIR)"       \
        G_FILENAME_ENCODING=latin1      # ensure filenames are not utf8
-
-if !ENABLE_CAIRO
-TESTS_ENVIRONMENT += GJS_TEST_SKIP_CAIRO=1
-endif
-
-tests_dependencies = $(gjsnative_LTLIBRARIES) ${TEST_PROGS} $(TEST_GIRS:.gir=.typelib)
-
-test: $(tests_dependencies)
-       @test -z "${TEST_PROGS}" || ${GTESTER} --verbose ${TEST_PROGS} ${TEST_PROGS_OPTIONS}
-
-check: test
-
-gdb-check gdb-test: $(tests_dependencies)
-       failed=; for prog in ${TEST_PROGS}; do \
-         ${TESTS_ENVIRONMENT} GJS_TEST_TIMEOUT=0 $(RUN_WITH_DBUS) libtool --mode=execute gdb -x \
-             $(top_srcdir)/test/unittest.gdb --args $$prog; \
-         done
-
-valgrind-check valgrind-test: $(tests_dependencies)
-       @test -z "${TEST_PROGS}" || { \
-         failed=; for prog in ${TEST_PROGS}; do \
-           ${TESTS_ENVIRONMENT} G_SLICE=always-malloc  \
-           $(RUN_WITH_DBUS) \
-           $(LIBTOOL) --mode=execute valgrind          \
-           --log-file=valgrind.$$prog.log              \
-           --error-exitcode=1                          \
-           --trace-children=yes                        \
-           --tool=memcheck                             \
-           --leak-check=full                           \
-           --suppressions=$(top_srcdir)/test/gjs.supp  \
-           $$VALGRIND_ARGS                             \
-           $$prog \
-           && $(GREP) -q 'definitely lost: 0 bytes in 0 blocks' valgrind.$$prog.log \
-           || failed="$$failed $$prog"; \
-         done; \
-         test -z "$$failed" || { \
-           echo "valgrind failed for:$$failed"; exit 1; \
-         }; \
-       }
-
-.PHONY: test gdb-check gdb-test valgrind-check valgrind-test
-
-CLEANFILES +=                                  \
-       $(TEST_PROGS:%=valgrind.%.log)          \
-       uninstalled-test-bus.conf               \
-       uninstalled-system-test-bus.conf
-
-clean-local:
-       -rm -rf test_user_data
-
-EXTRA_DIST +=                                  \
-       test/js/modules/alwaysThrows.js         \
-       test/js/modules/foobar.js               \
-       test/js/modules/mutualImport/a.js       \
-       test/js/modules/mutualImport/b.js       \
-       test/js/modules/modunicode.js           \
-       test/js/modules/subA/.secret.js         \
-       test/js/modules/subA/.hidden/hidden.js  \
-       test/js/modules/subA/foo                \
-       test/js/modules/subA/subB/__init__.js   \
-       test/js/modules/subA/subB/foobar.js     \
-       test/js/modules/subA/subB/baz.js        \
-       test/js/test0010basic.js                \
-       test/js/test0020importer.js             \
-       test/js/test0030basicBoxed.js           \
-       test/js/test0040mainloop.js             \
-       test/js/testself.js                     \
-       test/js/testByteArray.js                \
-       test/js/testCairo.js                    \
-       test/js/testClass.js                    \
-       test/js/testGDBus.js                    \
-       test/js/testEverythingBasic.js          \
-       test/js/testEverythingEncapsulated.js   \
-       test/js/testGIMarshalling.js            \
-       test/js/testImporter.js                 \
-       test/js/testJS1_8.js                    \
-       test/js/testJSDefault.js                \
-       test/js/testLang.js                     \
-       test/js/testLocale.js                   \
-       test/js/testMainloop.js                 \
-       test/js/testSignals.js                  \
-       test/js/testSystem.js                   \
-       test/js/testTweener.js                  \
-       test/js/testUnicode.js                  \
-       test/run-with-dbus                      \
-       test/test-bus.conf
-
-########################################################################
-if ENABLE_COVERAGE
-lcov:
-       test -d lcov || mkdir lcov
-       $(LCOV) --compat-libtool --directory . --capture -o lcov/lcov.info
-       $(GENHTML) --legend -o lcov lcov/lcov.info
-
-lcov-clean:
-       find . -name '*.gcda' -delete
-       rm -rf lcov
-
-lcov-realclean: lcov-clean
-       find . -name '*.gcno' -delete
-
-clean-local: lcov-realclean
-
-.PHONY: lcov lcov-clean lcov-realclean
-else
-lcov:
-       @echo >&1 "*** ERROR: 'configure --enable-coverage' required"
-       @exit 1
-
-.PHONY: lcov
-endif
diff --git a/installed-tests/.gitignore b/installed-tests/.gitignore
new file mode 100644
index 0000000..d8dc1df
--- /dev/null
+++ b/installed-tests/.gitignore
@@ -0,0 +1,40 @@
+*.la
+*.lo
+*.o
+*.gir
+*.typelib
+*~
+.deps/
+.libs/
+INSTALL
+Makefile
+Makefile.in
+aclocal.m4
+autom4te.cache
+compile
+config.guess
+config.h
+config.h.in
+config.log
+config.status
+config.sub
+configure
+depcomp
+gjs-1.0.pc
+gjs-console
+gjs-internals-1.0.pc
+gjs-gi-1.0.pc
+gjs-tests
+gjs-unit
+gjs/gjs.stp
+gjs_gi_probes.h
+install-sh
+libtool
+ltmain.sh
+missing
+stamp-h1
+test_user_data
+uninstalled-test-bus.conf
+uninstalled-system-test-bus.conf
+valgrind.gjs-tests.log
+valgrind.gjs-unit.log
diff --git a/installed-tests/Makefile-test.am b/installed-tests/Makefile-test.am
new file mode 100644
index 0000000..df62e4e
--- /dev/null
+++ b/installed-tests/Makefile-test.am
@@ -0,0 +1,77 @@
+bin_PROGRAMS += gjs-installed-test-suite
+
+gjs_installed_test_suite_CFLAGS = $(AM_CFLAGS) $(GJS_CFLAGS)
+gjs_installed_test_suite_LDADD = $(GJS_LIBS)
+gjs_installed_test_suite_LDFLAGS = -rpath $(pkglibdir)
+gjs_installed_test_suite_SOURCES = test/gjs-unit.c
+
+privlib_LTLIBRARIES += libregress.la libwarnlib.la libgimarshallingtests.la
+
+nodist_libregress_la_SOURCES = $(GI_DATADIR)/tests/regress.c $(GI_DATADIR)/tests/regress.h
+libregress_la_CPPFLAGS = $(AM_CPPFLAGS)
+libregress_la_CFLAGS = $(GJS_CFLAGS)
+libregress_la_LDFLAGS = -avoid-version $(GJS_LIBS)
+libregress_scannerflags_includes = --include=Gio-2.0
+if ENABLE_CAIRO
+libregress_la_CFLAGS += $(GJS_CAIRO_CFLAGS)
+libregress_la_LDFLAGS +=  $(GJS_CAIRO_LIBS)
+libregress_scannerflags_includes += --include=cairo-1.0
+else
+libregress_la_CPPFLAGS += -D_GI_DISABLE_CAIRO
+endif
+nodist_libwarnlib_la_SOURCES = $(GI_DATADIR)/tests/warnlib.c $(GI_DATADIR)/tests/warnlib.h
+libwarnlib_la_CFLAGS = $(GJS_CFLAGS)
+libwarnlib_la_LDFLAGS = -avoid-version $(GJS_LIBS)
+nodist_libgimarshallingtests_la_SOURCES = $(GI_DATADIR)/tests/gimarshallingtests.c 
$(GI_DATADIR)/tests/gimarshallingtests.h
+libgimarshallingtests_la_CFLAGS = $(GJS_CFLAGS)
+libgimarshallingtests_la_LDFLAGS = -avoid-version $(GJS_LIBS)
+
+Regress-1.0.gir: libregress.la
+Regress_1_0_gir_LIBS = libregress.la
+Regress_1_0_gir_FILES = $(nodist_libregress_la_SOURCES)
+Regress_1_0_gir_SCANNERFLAGS = --warn-all --warn-error $(libregress_scannerflags_includes) 
$(libregress_la_CPPFLAGS)
+INTROSPECTION_GIRS += Regress-1.0.gir
+
+WarnLib-1.0.gir: libwarnlib.la
+WarnLib_1_0_gir_LIBS = libwarnlib.la
+WarnLib_1_0_gir_INCLUDES = Gio-2.0
+WarnLib_1_0_gir_FILES = $(nodist_libwarnlib_la_SOURCES)
+WarnLib_1_0_gir_SCANNERFLAGS = --c-include="warnlib.h" --symbol-prefix=warnlib_
+INTROSPECTION_GIRS += WarnLib-1.0.gir
+
+GIMarshallingTests-1.0.gir: libgimarshallingtests.la
+GIMarshallingTests_1_0_gir_LIBS = libgimarshallingtests.la
+GIMarshallingTests_1_0_gir_INCLUDES = Gio-2.0
+GIMarshallingTests_1_0_gir_FILES = $(nodist_libgimarshallingtests_la_SOURCES)
+GIMarshallingTests_1_0_gir_SCANNERFLAGS = --symbol-prefix=gi_marshalling_tests --warn-all --warn-error
+INTROSPECTION_GIRS += GIMarshallingTests-1.0.gir
+
+typelibdir = $(pkglibdir)
+typelib_DATA = $(INTROSPECTION_GIRS:.gir=.typelib)
+
+jstestsdir = $(pkglibdir)/js
+jstests_DATA =                                 \
+       test/js/test0010basic.js                \
+       test/js/test0020importer.js             \
+       test/js/test0030basicBoxed.js           \
+       test/js/test0040mainloop.js             \
+       test/js/testself.js                     \
+       test/js/testByteArray.js                \
+       test/js/testClass.js                    \
+       test/js/testGDBus.js                    \
+       test/js/testEverythingBasic.js          \
+       test/js/testEverythingEncapsulated.js   \
+       test/js/testGIMarshalling.js            \
+       test/js/testJS1_8.js                    \
+       test/js/testJSDefault.js                \
+       test/js/testLang.js                     \
+       test/js/testLocale.js                   \
+       test/js/testMainloop.js                 \
+       test/js/testSignals.js                  \
+       test/js/testSystem.js                   \
+       test/js/testTweener.js                  \
+       test/js/testUnicode.js
+
+if ENABLE_CAIRO
+jstests_DATA += test/js/testCairo.js
+endif
diff --git a/installed-tests/Makefile.am b/installed-tests/Makefile.am
new file mode 100644
index 0000000..9ab19bf
--- /dev/null
+++ b/installed-tests/Makefile.am
@@ -0,0 +1,19 @@
+bin_PROGRAMS =
+lib_LTLIBRARIES =
+noinst_HEADERS =
+noinst_LTLIBRARIES =
+privlibdir = $(pkglibdir)
+privlib_LTLIBRARIES =
+BUILT_SOURCES =
+CLEANFILES =
+EXTRA_DIST =
+TEST_PROGS =
+INTROSPECTION_GIRS =
+ACLOCAL_AMFLAGS = ${ACLOCAL_FLAGS}
+AM_CPPFLAGS = -DPKGLIBDIR=\"$(pkglibdir)\"
+AM_CFLAGS = $(WARN_CFLAGS)
+
+include Makefile-test.am
+
+include $(INTROSPECTION_MAKEFILE)
+
diff --git a/installed-tests/autogen.sh b/installed-tests/autogen.sh
new file mode 100755
index 0000000..c187584
--- /dev/null
+++ b/installed-tests/autogen.sh
@@ -0,0 +1,2 @@
+#!/bin/sh
+exec autoreconf -vfi
diff --git a/installed-tests/configure.ac b/installed-tests/configure.ac
new file mode 100644
index 0000000..0c9fc99
--- /dev/null
+++ b/installed-tests/configure.ac
@@ -0,0 +1,49 @@
+#                                               -*- Autoconf -*-
+# Process this file with autoconf to produce a configure script.
+
+AC_PREREQ(2.61)
+AC_INIT([gjs-installed-tests], 1.36.0, [http://bugzilla.gnome.org/enter_bug.cgi?product=gjs])
+AM_INIT_AUTOMAKE([dist-bzip2 no-dist-gzip foreign])
+AC_CONFIG_SRCDIR([autogen.sh])
+AC_CONFIG_HEADER([config.h])
+
+AM_MAINTAINER_MODE([enable])
+m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])])
+
+# our first pkg-config invocation is conditional, ensure macros still work
+PKG_PROG_PKG_CONFIG
+
+AC_PROG_CC
+AM_PROG_CC_C_O
+AC_PROG_LIBTOOL
+AM_DISABLE_STATIC
+
+GNOME_COMPILE_WARNINGS([maximum])
+GNOME_MAINTAINER_MODE_DEFINES
+
+PKG_CHECK_MODULES([GJS], [gio-unix-2.0 >= 2.36 gjs-internals-1.0 >= 1.36.0])
+
+GOBJECT_INTROSPECTION_REQUIRE([1.36.0])
+GI_DATADIR=$($PKG_CONFIG --variable=gidatadir gobject-introspection-1.0)
+AC_SUBST(GI_DATADIR)
+
+AC_ARG_WITH(cairo,
+           AS_HELP_STRING([--without-cairo], [Use cairo @<:@default=yes@:>@]),
+           [], [with_cairo=yes])
+AS_IF([test x$with_cairo = xyes], [
+  PKG_CHECK_MODULES([GJS_CAIRO], [$gjs_cairo_packages], have_cairo=yes, have_cairo=no)
+])
+AM_CONDITIONAL(ENABLE_CAIRO, test x$have_cairo = xyes)
+AS_IF([test x$have_cairo = xyes], [
+  AC_DEFINE([ENABLE_CAIRO],[1],[Define if you want to build with cairo support])
+])
+
+AC_CONFIG_FILES([Makefile])
+AC_OUTPUT
+
+AC_MSG_RESULT([
+        $PACKAGE_NAME $VERSION
+
+       GJS_CFLAGS:             ${GJS_CFLAGS}
+       GJS_LIBS:               ${GJS_LIBS}
+])
diff --git a/test/gjs-unit.c b/installed-tests/test/gjs-unit.c
similarity index 50%
rename from test/gjs-unit.c
rename to installed-tests/test/gjs-unit.c
index 3ae68ba..572763d 100644
--- a/test/gjs-unit.c
+++ b/installed-tests/test/gjs-unit.c
@@ -25,8 +25,8 @@
 
 #include <glib.h>
 #include <glib/gstdio.h>
+#include <girepository.h>
 #include <gjs/gjs-module.h>
-#include <util/crash.h>
 #include <locale.h>
 
 #include <string.h>
@@ -35,44 +35,18 @@ typedef struct {
     GjsContext *context;
 } GjsTestJSFixture;
 
-static char *top_srcdir;
-
-
 static void
 setup(GjsTestJSFixture *fix,
       gconstpointer     test_data)
 {
-    gboolean success;
-    GError *error = NULL;
-    int code;
-    char *filename;
-    char *search_path[2];
     const char *test_filename = test_data;
     const char *js_version;
 
     js_version = gjs_context_scan_file_for_js_version(test_filename);
 
-    search_path[0] = g_build_filename(top_srcdir, "test", "modules", NULL);
-    search_path[1] = NULL;
-
     fix->context = g_object_new (GJS_TYPE_CONTEXT,
-                                 "search-path", search_path,
                                  "js-version", js_version,
                                  NULL);
-    g_free(search_path[0]);
-
-    /* Load jsUnit.js directly into global scope, rather than
-     * requiring each test to import it as a module, among other
-     * things this lets us test importing modules without relying on
-     * importing a module, but also it's just less typing to have
-     * "assert*" without a prefix.
-     */
-    filename = g_build_filename(top_srcdir, "modules", "jsUnit.js", NULL);
-    success = gjs_context_eval_file(fix->context, filename, &code, &error);
-    g_free(filename);
-
-    if (!success)
-        g_error("%s", error->message);
 }
 
 static void
@@ -118,142 +92,25 @@ read_all_dir_sorted (const char *dirpath)
     return result;
 }
 
-/* Always return an absolute filename and treat all absolute path elements as
- * absolute, not just the first one, e.g.
- *     ("/foo", "/bar", NULL) returns "/bar"
- * (g_build_filename would return "/foo/bar")
- * Returned path may still include '..' path elements.
- */
-static char *
-build_absolute_filename(const char *first_element,
-                        ...)
-{
-    const char *element;
-    va_list ap;
-    char *cwd;
-    char *path;
-    GPtrArray *array;
-
-    cwd = g_get_current_dir();
-
-    array = g_ptr_array_new();
-
-    g_ptr_array_add(array, cwd);
-
-    va_start(ap, first_element);
-
-    element = first_element;
-    while (element != NULL) {
-        if (g_path_is_absolute(element))
-            g_ptr_array_set_size(array, 0);
-
-        g_ptr_array_add(array, (char*)element);
-
-        element = va_arg(ap, const char *);
-    }
-    va_end(ap);
-
-    g_ptr_array_add(array, NULL);
-
-    path = g_build_filenamev((char **)array->pdata);
-
-    g_ptr_array_free(array, TRUE);
-
-    g_free(cwd);
-
-    return path;
-}
-
 int
 main(int argc, char **argv)
 {
-    /* These may be absolute or relative to top_builddir, depending whether
-     * GJS_TOP_SRCDIR is absolute or not */
-    const char * const path_directories[] = {
-        GJS_TOP_SRCDIR"/modules",
-        GJS_TOP_SRCDIR"/test/js/modules",
-        ".libs:",
-        NULL
-    };
-
     char *js_test_dir;
-    char *working_dir;
-    char *gjs_unit_path;
-    char *gjs_unit_dir;
-    char *top_builddir;
-    char *data_home;
-    GString *path;
-    size_t i;
     GSList *all_tests, *iter;
     GSList *test_filenames = NULL;
     int retval;
 
-    working_dir = g_get_current_dir();
-
-    gjs_unit_path = build_absolute_filename(argv[0], NULL);
-
-    gjs_unit_dir = g_path_get_dirname(gjs_unit_path);
-    g_free(gjs_unit_path);
-    /* the gjs-unit executable will be in <top_builddir>/.libs */
-    top_builddir = g_path_get_dirname(gjs_unit_dir);
-    g_free(gjs_unit_dir);
-    top_srcdir = build_absolute_filename(top_builddir, GJS_TOP_SRCDIR, NULL);
-
-    /* Normalize, not strictly necessary */
-    g_chdir(top_builddir);
-    g_free(top_builddir);
-    top_builddir = g_get_current_dir();
-
-    g_chdir(top_srcdir);
-    g_free(top_srcdir);
-    top_srcdir = g_get_current_dir();
-
-    g_chdir(working_dir);
-    g_free(working_dir);
-
-    /* we're always going to use uninstalled files, set up necessary
-     * environment variables, but don't overwrite if already set */
-
-    data_home = g_build_filename(top_builddir, "test_user_data", NULL);
-    path = g_string_new(NULL);
-    for(i = 0; i < G_N_ELEMENTS(path_directories); i++) {
-        char *directory;
-
-        if (i != 0)
-            g_string_append_c(path, ':');
-
-        directory = build_absolute_filename(top_builddir, path_directories[i], NULL);
-        g_string_append(path, directory);
-        g_free(directory);
-    }
-
-    g_setenv("TOP_SRCDIR", top_srcdir, FALSE);
-    g_setenv("BUILDDIR", top_builddir, FALSE);
-    g_free(top_builddir);
-    g_setenv("XDG_DATA_HOME", data_home, FALSE);
-    g_free(data_home);
-    g_setenv("GJS_PATH", path->str, FALSE);
-    g_string_free(path, TRUE);
     /* The tests are known to fail in the presence of the JIT;
      * we leak objects.
      * https://bugzilla.gnome.org/show_bug.cgi?id=616193
      */
     g_setenv("GJS_DISABLE_JIT", "1", FALSE);
 
-    {
-        const char *timeout_str = g_getenv("GJS_TEST_TIMEOUT");
-        if (timeout_str != NULL) {
-            guint timeout = (guint)g_ascii_strtoull(timeout_str, NULL, 10);
-            if (timeout > 0)
-                gjs_crash_after_timeout(timeout);
-        }
-    }
-
     setlocale(LC_ALL, "");
     g_test_init(&argc, &argv, NULL);
 
-    /* iterate through all 'test*.js' files in ${top_srcdir}/test/js */
-    js_test_dir = g_build_filename(top_srcdir, "test", "js", NULL);
+    g_irepository_prepend_search_path(PKGLIBDIR);
+    js_test_dir = g_build_filename(PKGLIBDIR, "js", NULL);
 
     all_tests = read_all_dir_sorted(js_test_dir);
     for (iter = all_tests; iter; iter = iter->next) {
@@ -286,6 +143,5 @@ main(int argc, char **argv)
     retval =  g_test_run ();
     g_slist_foreach(test_filenames, (GFunc)g_free, test_filenames);
     g_slist_free(test_filenames);
-    g_free(top_srcdir);
     return retval;
 }
diff --git a/test/gjs.supp b/installed-tests/test/gjs.supp
similarity index 100%
rename from test/gjs.supp
rename to installed-tests/test/gjs.supp
diff --git a/test/js/modules/alwaysThrows.js b/installed-tests/test/js/modules/alwaysThrows.js
similarity index 100%
rename from test/js/modules/alwaysThrows.js
rename to installed-tests/test/js/modules/alwaysThrows.js
diff --git a/test/js/modules/foobar.js b/installed-tests/test/js/modules/foobar.js
similarity index 100%
rename from test/js/modules/foobar.js
rename to installed-tests/test/js/modules/foobar.js
diff --git a/test/js/modules/modunicode.js b/installed-tests/test/js/modules/modunicode.js
similarity index 100%
rename from test/js/modules/modunicode.js
rename to installed-tests/test/js/modules/modunicode.js
diff --git a/test/js/modules/mutualImport/a.js b/installed-tests/test/js/modules/mutualImport/a.js
similarity index 100%
rename from test/js/modules/mutualImport/a.js
rename to installed-tests/test/js/modules/mutualImport/a.js
diff --git a/test/js/modules/mutualImport/b.js b/installed-tests/test/js/modules/mutualImport/b.js
similarity index 100%
rename from test/js/modules/mutualImport/b.js
rename to installed-tests/test/js/modules/mutualImport/b.js
diff --git a/test/js/modules/subA/.hidden/hidden.js b/installed-tests/test/js/modules/subA/.hidden/hidden.js
similarity index 100%
rename from test/js/modules/subA/.hidden/hidden.js
rename to installed-tests/test/js/modules/subA/.hidden/hidden.js
diff --git a/test/js/modules/subA/.secret.js b/installed-tests/test/js/modules/subA/.secret.js
similarity index 100%
rename from test/js/modules/subA/.secret.js
rename to installed-tests/test/js/modules/subA/.secret.js
diff --git a/test/js/modules/subA/foo b/installed-tests/test/js/modules/subA/foo
similarity index 100%
rename from test/js/modules/subA/foo
rename to installed-tests/test/js/modules/subA/foo
diff --git a/test/js/modules/subA/subB/__init__.js b/installed-tests/test/js/modules/subA/subB/__init__.js
similarity index 100%
rename from test/js/modules/subA/subB/__init__.js
rename to installed-tests/test/js/modules/subA/subB/__init__.js
diff --git a/test/js/modules/subA/subB/baz.js b/installed-tests/test/js/modules/subA/subB/baz.js
similarity index 100%
rename from test/js/modules/subA/subB/baz.js
rename to installed-tests/test/js/modules/subA/subB/baz.js
diff --git a/test/js/modules/subA/subB/foobar.js b/installed-tests/test/js/modules/subA/subB/foobar.js
similarity index 100%
rename from test/js/modules/subA/subB/foobar.js
rename to installed-tests/test/js/modules/subA/subB/foobar.js
diff --git a/installed-tests/test/js/test0010basic.js b/installed-tests/test/js/test0010basic.js
new file mode 100644
index 0000000..3d09d76
--- /dev/null
+++ b/installed-tests/test/js/test0010basic.js
@@ -0,0 +1,8 @@
+const JSUnit = imports.jsUnit;
+// application/javascript;version=1.8
+function testBasic1() {
+    var foo = 1+1;
+    JSUnit.assertEquals(2, foo);
+}
+
+JSUnit.gjstestRun(this, JSUnit.setUp, JSUnit.tearDown);
diff --git a/installed-tests/test/js/test0020importer.js b/installed-tests/test/js/test0020importer.js
new file mode 100644
index 0000000..0fb6003
--- /dev/null
+++ b/installed-tests/test/js/test0020importer.js
@@ -0,0 +1,9 @@
+// application/javascript;version=1.8
+const JSUnit = imports.jsUnit;
+
+function testImporter1() {
+    var GLib = imports.gi.GLib;
+    JSUnit.assertEquals(GLib.MAJOR_VERSION, 2);
+}
+
+JSUnit.gjstestRun(this, JSUnit.setUp, JSUnit.tearDown);
diff --git a/installed-tests/test/js/test0030basicBoxed.js b/installed-tests/test/js/test0030basicBoxed.js
new file mode 100644
index 0000000..96ba7b8
--- /dev/null
+++ b/installed-tests/test/js/test0030basicBoxed.js
@@ -0,0 +1,11 @@
+// application/javascript;version=1.8
+const JSUnit = imports.jsUnit;
+const Regress = imports.gi.Regress;
+
+function testBasicBoxed() {
+    var a = new Regress.TestSimpleBoxedA();
+    a.some_int = 42;
+    JSUnit.assertEquals(a.some_int, 42);
+}
+
+JSUnit.gjstestRun(this, JSUnit.setUp, JSUnit.tearDown);
diff --git a/test/js/test0040mainloop.js b/installed-tests/test/js/test0040mainloop.js
similarity index 82%
rename from test/js/test0040mainloop.js
rename to installed-tests/test/js/test0040mainloop.js
index 0b49a3f..23d5de9 100644
--- a/test/js/test0040mainloop.js
+++ b/installed-tests/test/js/test0040mainloop.js
@@ -1,4 +1,5 @@
 // application/javascript;version=1.8
+const JSUnit = imports.jsUnit;
 var Mainloop = imports.mainloop;
 
 function testBasicMainloop() {
@@ -13,4 +14,5 @@ function testDanglingIdle() {
     Mainloop.idle_add(function() { return true; });
 }
 
-gjstestRun();
+JSUnit.gjstestRun(this, JSUnit.setUp, JSUnit.tearDown);
+
diff --git a/installed-tests/test/js/testByteArray.js b/installed-tests/test/js/testByteArray.js
new file mode 100644
index 0000000..0ef8503
--- /dev/null
+++ b/installed-tests/test/js/testByteArray.js
@@ -0,0 +1,122 @@
+// application/javascript;version=1.8
+// tests for imports.lang module
+
+const JSUnit = imports.jsUnit;
+const ByteArray = imports.byteArray;
+const Gio = imports.gi.Gio;
+
+function testEmptyByteArray() {
+    let a = new ByteArray.ByteArray();
+    JSUnit.assertEquals("length is 0 for empty array", 0, a.length);
+}
+
+function testInitialSizeByteArray() {
+    let a = new ByteArray.ByteArray(10);
+    JSUnit.assertEquals("length is 10 for initially-sized-10 array", 10, a.length);
+
+    let i;
+
+    for (i = 0; i < a.length; ++i) {
+        JSUnit.assertEquals("new array initialized to zeroes", 0, a[i]);
+    }
+
+    JSUnit.assertEquals("array had proper number of elements post-construct (counting for)",
+                 10, i);
+}
+
+function testAssignment() {
+    let a = new ByteArray.ByteArray(256);
+    JSUnit.assertEquals("length is 256 for initially-sized-256 array", 256, a.length);
+
+    let i;
+    let count;
+
+    count = 0;
+    for (i = 0; i < a.length; ++i) {
+        JSUnit.assertEquals("new array initialized to zeroes", 0, a[i]);
+        a[i] = 255 - i;
+        count += 1;
+    }
+
+    JSUnit.assertEquals("set proper number of values", 256, count);
+
+    count = 0;
+    for (i = 0; i < a.length; ++i) {
+        JSUnit.assertEquals("assignment set expected value", 255 - i, a[i]);
+        count += 1;
+    }
+
+    JSUnit.assertEquals("checked proper number of values", 256, count);
+}
+
+function testAssignmentPastEnd() {
+    let a = new ByteArray.ByteArray();
+    JSUnit.assertEquals("length is 0 for empty array", 0, a.length);
+
+    a[2] = 5;
+    JSUnit.assertEquals("implicitly made length 3", 3, a.length);
+    JSUnit.assertEquals("implicitly-created zero byte", 0, a[0]);
+    JSUnit.assertEquals("implicitly-created zero byte", 0, a[1]);
+    JSUnit.assertEquals("stored 5 in autocreated position", 5, a[2]);
+}
+
+function testAssignmentToLength() {
+    let a = new ByteArray.ByteArray(20);
+    JSUnit.assertEquals("length is 20 for new array", 20, a.length);
+
+    a.length = 5;
+
+    JSUnit.assertEquals("length is 5 after setting it to 5", 5, a.length);
+}
+
+function testNonIntegerAssignment() {
+    let a = new ByteArray.ByteArray();
+
+    a[0] = 5;
+    JSUnit.assertEquals("assigning 5 gives a byte 5", 5, a[0]);
+
+    a[0] = null;
+    JSUnit.assertEquals("assigning null gives a zero byte", 0, a[0]);
+
+    a[0] = 5;
+    JSUnit.assertEquals("assigning 5 gives a byte 5", 5, a[0]);
+
+    a[0] = undefined;
+    JSUnit.assertEquals("assigning undefined gives a zero byte", 0, a[0]);
+
+    a[0] = 3.14;
+    JSUnit.assertEquals("assigning a double rounds off", 3, a[0]);
+}
+
+function testFromString() {
+    let a = ByteArray.fromString('abcd');
+    JSUnit.assertEquals("from string 'abcd' gives length 4", 4, a.length);
+    JSUnit.assertEquals("'a' results in 97", 97, a[0]);
+    JSUnit.assertEquals("'b' results in 98", 98, a[1]);
+    JSUnit.assertEquals("'c' results in 99", 99, a[2]);
+    JSUnit.assertEquals("'d' results in 100", 100, a[3]);
+}
+
+function testFromArray() {
+    let a = ByteArray.fromArray([ 1, 2, 3, 4 ]);
+    JSUnit.assertEquals("from array [1,2,3,4] gives length 4", 4, a.length);
+    JSUnit.assertEquals("a[0] == 1", 1, a[0]);
+    JSUnit.assertEquals("a[1] == 2", 2, a[1]);
+    JSUnit.assertEquals("a[2] == 3", 3, a[2]);
+    JSUnit.assertEquals("a[3] == 4", 4, a[3]);
+}
+
+function testToString() {
+    let a = new ByteArray.ByteArray();
+    a[0] = 97;
+    a[1] = 98;
+    a[2] = 99;
+    a[3] = 100;
+
+    let s = a.toString();
+    JSUnit.assertEquals("toString() on 4 ascii bytes gives length 4", 4, s.length);
+    JSUnit.assertEquals("toString() gives 'abcd'", "abcd", s);
+}
+
+JSUnit.gjstestRun(this, JSUnit.setUp, JSUnit.tearDown);
+
diff --git a/test/js/testCairo.js b/installed-tests/test/js/testCairo.js
similarity index 100%
rename from test/js/testCairo.js
rename to installed-tests/test/js/testCairo.js
diff --git a/test/js/testClass.js b/installed-tests/test/js/testClass.js
similarity index 74%
rename from test/js/testClass.js
rename to installed-tests/test/js/testClass.js
index 14d8aaf..382a85f 100644
--- a/test/js/testClass.js
+++ b/installed-tests/test/js/testClass.js
@@ -1,11 +1,12 @@
 // application/javascript;version=1.8 -*- mode: js; indent-tabs-mode: nil -*-
 
+const JSUnit = imports.jsUnit;
 const Lang = imports.lang;
 
 function assertArrayEquals(expected, got) {
-    assertEquals(expected.length, got.length);
+    JSUnit.assertEquals(expected.length, got.length);
     for (let i = 0; i < expected.length; i ++) {
-        assertEquals(expected[i], got[i]);
+        JSUnit.assertEquals(expected[i], got[i]);
     }
 }
 
@@ -113,7 +114,7 @@ const CustomConstruct = new Lang.Class({
 
 function testClassFramework() {
     let newMagic = new MagicBase('A');
-    assertEquals('A',  newMagic.a);
+    JSUnit.assertEquals('A',  newMagic.a);
 }
 
 function testInheritance() {
@@ -125,61 +126,61 @@ function testInheritance() {
     buffer = [];
     let val = newMagic.foo(10, 20, buffer);
     assertArrayEquals([10, 20], buffer);
-    assertEquals(10*6, val);
+    JSUnit.assertEquals(10*6, val);
 }
 
 function testConstructor() {
-    assertEquals(Magic, Magic.prototype.constructor);
+    JSUnit.assertEquals(Magic, Magic.prototype.constructor);
 
     let newMagic = new Magic();
-    assertEquals(Magic, newMagic.constructor);
+    JSUnit.assertEquals(Magic, newMagic.constructor);
 }
 
 function testInstanceOf() {
     let newMagic = new Magic();
 
-    assertTrue(newMagic instanceof Magic);
-    assertTrue(newMagic instanceof MagicBase);
+    JSUnit.assertTrue(newMagic instanceof Magic);
+    JSUnit.assertTrue(newMagic instanceof MagicBase);
 }
 
 function testToString() {
     let newMagic = new MagicBase();
-    assertEquals('[object MagicBase]', newMagic.toString());
+    JSUnit.assertEquals('[object MagicBase]', newMagic.toString());
 
     let override = new ToStringOverride();
-    assertEquals('[object ToStringOverride]; hello', override.toString());
+    JSUnit.assertEquals('[object ToStringOverride]; hello', override.toString());
 }
 
 function testConfigurable() {
     let newMagic = new MagicBase();
 
     delete newMagic.foo;
-    assertNotUndefined(newMagic.foo);
+    JSUnit.assertNotUndefined(newMagic.foo);
 }
 
 function testAccessor() {
     let newAccessor = new Accessor(11);
 
-    assertEquals(11, newAccessor.value);
-    assertRaises(function() {
+    JSUnit.assertEquals(11, newAccessor.value);
+    JSUnit.assertRaises(function() {
         newAccessor.value = 12;
     });
 
     newAccessor.value = 42;
-    assertEquals(42, newAccessor.value);
+    JSUnit.assertEquals(42, newAccessor.value);
 }
 
 function testAbstract() {
-    assertRaises(function() {
+    JSUnit.assertRaises(function() {
         let newAbstract = new AbstractBase();
     });
 
     let newAbstract = new AbstractImpl();
-    assertEquals(42, newAbstract.foo);
-    assertEquals(42, newAbstract.bar);
+    JSUnit.assertEquals(42, newAbstract.foo);
+    JSUnit.assertEquals(42, newAbstract.bar);
 
     newAbstract = new AbstractImpl2();
-    assertEquals(42, newAbstract.foo);
+    JSUnit.assertEquals(42, newAbstract.foo);
 }
 
 function testCrossCall() {
@@ -190,16 +191,16 @@ function testCrossCall() {
 
     let res = newMagic.bar(10, buffer);
     assertArrayEquals([10, 20], buffer);
-    assertEquals(50, res);
+    JSUnit.assertEquals(50, res);
 }
 
 function testConstruct() {
     let instance = new CustomConstruct(1, 2);
 
-    assertTrue(instance instanceof Array);
-    assertTrue(!(instance instanceof CustomConstruct));
+    JSUnit.assertTrue(instance instanceof Array);
+    JSUnit.assertTrue(!(instance instanceof CustomConstruct));
 
     assertArrayEquals([1, 2], instance);
 }
 
-gjstestRun();
+JSUnit.gjstestRun(this, JSUnit.setUp, JSUnit.tearDown);
diff --git a/installed-tests/test/js/testEverythingBasic.js b/installed-tests/test/js/testEverythingBasic.js
new file mode 100644
index 0000000..3b715f8
--- /dev/null
+++ b/installed-tests/test/js/testEverythingBasic.js
@@ -0,0 +1,624 @@
+// application/javascript;version=1.8
+// This used to be called "Everything"
+
+const JSUnit = imports.jsUnit;
+const Everything = imports.gi.Regress;
+const WarnLib = imports.gi.WarnLib;
+
+// We use Gio to have some objects that we know exist
+const GLib = imports.gi.GLib;
+const Gio = imports.gi.Gio;
+const GObject = imports.gi.GObject;
+const Lang = imports.lang;
+
+const INT8_MIN = (-128);
+const INT16_MIN = (-32767-1);
+const INT32_MIN = (-2147483647-1);
+const INT64_MIN = (-9223372036854775807-1);
+
+const INT8_MAX = (127);
+const INT16_MAX = (32767);
+const INT32_MAX = (2147483647);
+const INT64_MAX = (9223372036854775807);
+
+const UINT8_MAX = (255);
+const UINT16_MAX = (65535);
+const UINT32_MAX = (4294967295);
+const UINT64_MAX = (18446744073709551615);
+
+function testLifeUniverseAndEverything() {
+    JSUnit.assertEquals(false, Everything.test_boolean(false));
+    JSUnit.assertEquals(true, Everything.test_boolean(true));
+
+    JSUnit.assertEquals(42, Everything.test_int8(42));
+    JSUnit.assertEquals(-42, Everything.test_int8(-42));
+
+    JSUnit.assertEquals(42, Everything.test_uint8(42));
+
+    JSUnit.assertEquals(42, Everything.test_int16(42));
+    JSUnit.assertEquals(-42, Everything.test_int16(-42));
+
+    JSUnit.assertEquals(42, Everything.test_uint16(42));
+
+    JSUnit.assertEquals(42, Everything.test_int32(42));
+    JSUnit.assertEquals(-42, Everything.test_int32(-42));
+
+    JSUnit.assertEquals(42, Everything.test_uint32(42));
+
+    JSUnit.assertEquals(42, Everything.test_int64(42));
+    JSUnit.assertEquals(-42, Everything.test_int64(-42));
+
+    JSUnit.assertEquals(42, Everything.test_uint64(42));
+
+    JSUnit.assertEquals(42, Everything.test_short(42));
+    JSUnit.assertEquals(-42, Everything.test_short(-42));
+
+    JSUnit.assertEquals(42, Everything.test_ushort(42));
+
+    JSUnit.assertEquals(42, Everything.test_int(42));
+    JSUnit.assertEquals(-42, Everything.test_int(-42));
+
+    JSUnit.assertEquals(42, Everything.test_uint(42));
+
+    JSUnit.assertEquals(42, Everything.test_long(42));
+    JSUnit.assertEquals(-42, Everything.test_long(-42));
+
+    JSUnit.assertEquals(42, Everything.test_ulong(42));
+
+    JSUnit.assertEquals(42, Everything.test_ssize(42));
+    JSUnit.assertEquals(-42, Everything.test_ssize(-42));
+
+    JSUnit.assertEquals(42, Everything.test_size(42));
+
+    JSUnit.assertEquals(42, Everything.test_float(42));
+    JSUnit.assertEquals(-42, Everything.test_float(-42));
+
+    JSUnit.assertEquals(42, Everything.test_double(42));
+    JSUnit.assertEquals(-42, Everything.test_double(-42));
+
+    JSUnit.assertEquals("c", Everything.test_unichar("c"));
+    JSUnit.assertEquals("", Everything.test_unichar(""));
+    JSUnit.assertEquals("\u2665", Everything.test_unichar("\u2665"));
+
+    let now = Math.floor(new Date().getTime() / 1000);
+    let bounced = Math.floor(Everything.test_timet(now));
+    JSUnit.assertEquals(bounced, now);
+}
+
+function testLimits() {
+    JSUnit.assertEquals(UINT8_MAX, Everything.test_uint8(UINT8_MAX));
+    JSUnit.assertEquals(UINT16_MAX, Everything.test_uint16(UINT16_MAX));
+    JSUnit.assertEquals(UINT32_MAX, Everything.test_uint32(UINT32_MAX));
+
+    // FAIL: expected 18446744073709552000, got 0
+    //assertEquals(UINT64_MAX, Everything.test_uint64(UINT64_MAX));
+
+    JSUnit.assertEquals(INT8_MIN, Everything.test_int8(INT8_MIN));
+    JSUnit.assertEquals(INT8_MAX, Everything.test_int8(INT8_MAX));
+    JSUnit.assertEquals(INT16_MIN, Everything.test_int16(INT16_MIN));
+    JSUnit.assertEquals(INT16_MAX, Everything.test_int16(INT16_MAX));
+    JSUnit.assertEquals(INT32_MIN, Everything.test_int32(INT32_MIN));
+    JSUnit.assertEquals(INT32_MAX, Everything.test_int32(INT32_MAX));
+    JSUnit.assertEquals(INT64_MIN, Everything.test_int64(INT64_MIN));
+
+    // FAIL: expected 9223372036854776000, got -9223372036854776000
+    //assertEquals(INT64_MAX, Everything.test_int64(INT64_MAX));
+}
+
+function testNoImplicitConversionToUnsigned() {
+    JSUnit.assertRaises(function() { return Everything.test_uint8(-42); });
+    JSUnit.assertRaises(function() { return Everything.test_uint16(-42); });
+    JSUnit.assertRaises(function() { return Everything.test_uint32(-42); });
+
+    JSUnit.assertRaises(function() { return Everything.test_uint64(-42); });
+
+    JSUnit.assertRaises(function() { return Everything.test_uint(-42); });
+    JSUnit.assertRaises(function() { return Everything.test_size(-42); });
+}
+
+
+function testBadConstructor() {
+    try {
+        Gio.AppLaunchContext();
+    } catch (e) {
+        JSUnit.assert(e.message.indexOf("Constructor called as normal method") >= 0);
+    }
+}
+
+function testStrv() {
+    JSUnit.assertTrue(Everything.test_strv_in(['1', '2', '3']));
+    // Second two are deliberately not strings
+    JSUnit.assertRaises(function() { Everything.test_strv_in(['1', 2, 3]); });
+
+    let strv = Everything.test_strv_out();
+    JSUnit.assertEquals(5, strv.length);
+    JSUnit.assertEquals("thanks", strv[0]);
+    JSUnit.assertEquals("for", strv[1]);
+    JSUnit.assertEquals("all", strv[2]);
+    JSUnit.assertEquals("the", strv[3]);
+    JSUnit.assertEquals("fish", strv[4]);
+
+    strv = Everything.test_strv_out_container();
+    JSUnit.assertEquals(3, strv.length);
+    JSUnit.assertEquals("1", strv[0]);
+    JSUnit.assertEquals("2", strv[1]);
+    JSUnit.assertEquals("3", strv[2]);
+}
+
+function testInAfterOut() {
+    const str = "hello";
+
+    let len = Everything.test_int_out_utf8(str);
+    JSUnit.assertEquals("testInAfterOut", str.length, len);
+}
+
+function testUtf8() {
+    const CONST_STR = "const \u2665 utf8";
+    const NONCONST_STR = "nonconst \u2665 utf8";
+
+    JSUnit.assertEquals(CONST_STR, Everything.test_utf8_const_return());
+    JSUnit.assertEquals(NONCONST_STR, Everything.test_utf8_nonconst_return());
+    Everything.test_utf8_const_in(CONST_STR);
+    JSUnit.assertEquals(NONCONST_STR, Everything.test_utf8_out());
+    JSUnit.assertEquals(NONCONST_STR, Everything.test_utf8_inout(CONST_STR));
+    JSUnit.assertEquals(NONCONST_STR, Everything.test_utf8_inout(CONST_STR));
+    JSUnit.assertEquals(NONCONST_STR, Everything.test_utf8_inout(CONST_STR));
+    JSUnit.assertEquals(NONCONST_STR, Everything.test_utf8_inout(CONST_STR));
+}
+
+function testFilenameReturn() {
+    var filenames = Everything.test_filename_return();
+    JSUnit.assertEquals(2, filenames.length);
+    JSUnit.assertEquals('\u00e5\u00e4\u00f6', filenames[0]);
+    JSUnit.assertEquals('/etc/fstab', filenames[1]);
+}
+
+function testStaticMeth() {
+    let v = Everything.TestObj.new_from_file("/enoent");
+    JSUnit.assertTrue(v instanceof Everything.TestObj);
+}
+
+function testClosure() {
+    let arguments_length = -1;
+    let someCallback = function() {
+                           arguments_length = arguments.length;
+                           return 42;
+                       };
+
+    let i = Everything.test_closure(someCallback);
+
+    JSUnit.assertEquals('callback arguments length', 0, arguments_length);
+    JSUnit.assertEquals('callback return value', 42, i);
+}
+
+function testClosureOneArg() {
+    let arguments_length = -1;
+    let someCallback = function(someValue) {
+                           arguments_length = arguments.length;
+                           JSUnit.assertEquals(1, arguments.length);
+                           return someValue;
+                       };
+
+    let i = Everything.test_closure_one_arg(someCallback, 42);
+
+    JSUnit.assertEquals('callback arguments length', 1, arguments_length);
+    JSUnit.assertEquals('callback with one arg return value', 42, i);
+}
+
+function testCallback() {
+    let callback = function() {
+                       return 42;
+                   };
+    JSUnit.assertEquals('Callback', Everything.test_callback(callback), 42);
+
+    JSUnit.assertEquals('CallbackNull', Everything.test_callback(null), 0);
+    JSUnit.assertRaises('CallbackUndefined', function () { Everything.test_callback(undefined) });
+}
+
+function testArrayCallback() {
+    function arrayEqual(ref, one) {
+        JSUnit.assertEquals(ref.length, one.length);
+        for (let i = 0; i < ref.length; i++)
+            JSUnit.assertEquals(ref[i], one[i]);
+    }
+
+    let callback = function(ints, strings) {
+        JSUnit.assertEquals(2, arguments.length);
+
+        arrayEqual([-1, 0, 1, 2], ints);
+        arrayEqual(["one", "two", "three"], strings);
+
+        return 7;
+    }
+    JSUnit.assertEquals(Everything.test_array_callback(callback), 14);
+    JSUnit.assertRaises(function () { Everything.test_array_callback(null) });
+}
+
+function testCallbackDestroyNotify() {
+    let testObj = {
+        called: 0,
+        test: function(data) {
+            this.called++;
+            return data;
+        }
+    };
+    JSUnit.assertEquals('CallbackDestroyNotify',
+                 Everything.test_callback_destroy_notify(Lang.bind(testObj,
+                     function() {
+                         return testObj.test(42);
+                     })), 42);
+    JSUnit.assertEquals('CallbackDestroyNotify', testObj.called, 1);
+    JSUnit.assertEquals('CallbackDestroyNotify', Everything.test_callback_thaw_notifications(), 42);
+}
+
+function testCallbackAsync() {
+    let test = function(userData) {
+                   return 44;
+               };
+    Everything.test_callback_async(test, 44);
+    let i = Everything.test_callback_thaw_async();
+    JSUnit.assertEquals('testCallbackAsyncFinish', 44, i);
+}
+
+function testIntValueArg() {
+    let i = Everything.test_int_value_arg(42);
+    JSUnit.assertEquals('Method taking a GValue', 42, i);
+}
+
+function testValueReturn() {
+    let i = Everything.test_value_return(42);
+    JSUnit.assertEquals('Method returning a GValue', 42, i);
+}
+
+/* GList types */
+function testGListOut() {
+    JSUnit.assertEquals("1,2,3", Everything.test_glist_nothing_return().join(','));
+    JSUnit.assertEquals("1,2,3", Everything.test_glist_nothing_return2().join(','));
+    JSUnit.assertEquals("1,2,3", Everything.test_glist_container_return().join(','));
+    JSUnit.assertEquals("1,2,3", Everything.test_glist_everything_return().join(','));
+}
+function testGListIn() {
+    const STR_LIST = ["1", "2", "3" ];
+    Everything.test_glist_nothing_in(STR_LIST);
+    Everything.test_glist_nothing_in2(STR_LIST);
+    //Everything.test_glist_container_in(STR_LIST);
+}
+
+/* GSList types */
+function testGSListOut() {
+    JSUnit.assertEquals("1,2,3", Everything.test_gslist_nothing_return().join(','));
+    JSUnit.assertEquals("1,2,3", Everything.test_gslist_nothing_return2().join(','));
+    JSUnit.assertEquals("1,2,3", Everything.test_gslist_container_return().join(','));
+    JSUnit.assertEquals("1,2,3", Everything.test_gslist_everything_return().join(','));
+}
+function testGSListIn() {
+    const STR_LIST = ["1", "2", "3" ];
+    Everything.test_gslist_nothing_in(STR_LIST);
+    Everything.test_gslist_nothing_in2(STR_LIST);
+    //Everything.test_gslist_container_in(STR_LIST);
+}
+
+/* Array tests */
+function testArrayIn() {
+    JSUnit.assertEquals(10, Everything.test_array_int_in([1,2,3,4]));
+    JSUnit.assertEquals(10, Everything.test_array_gint8_in([1,2,3,4]));
+    JSUnit.assertEquals(10, Everything.test_array_gint16_in([1,2,3,4]));
+    JSUnit.assertEquals(10, Everything.test_array_gint32_in([1,2,3,4]));
+    // FIXME: arrays of int64 are unimplemented
+    //assertEquals(10, Everything.test_array_gint64_in([1,2,3,4]));
+
+    // implicit conversions from strings to int arrays
+    JSUnit.assertEquals(10, Everything.test_array_gint8_in("\x01\x02\x03\x04"));
+    JSUnit.assertEquals(10, Everything.test_array_gint16_in("\x01\x02\x03\x04"));
+    JSUnit.assertEquals(2560, Everything.test_array_gint16_in("\u0100\u0200\u0300\u0400"));
+
+    // GType arrays
+    JSUnit.assertEquals('[GSimpleAction,GIcon,GBoxed,]',
+                 Everything.test_array_gtype_in([Gio.SimpleAction, Gio.Icon, GObject.TYPE_BOXED]));
+    JSUnit.assertRaises(function() {
+        Everything.test_array_gtype_in(42);
+    });
+    JSUnit.assertRaises(function() {
+        Everything.test_array_gtype_in([undefined]);
+    });
+    JSUnit.assertRaises(function() {
+        // 80 is G_TYPE_OBJECT, but we don't want it to work
+        Everything.test_array_gtype_in([80]);
+    });
+}
+
+function testArrayOut() {
+    function arrayEqual(ref, res) {
+        JSUnit.assertEquals(ref.length, res.length);
+        for (let i = 0; i < ref.length; i++)
+            JSUnit.assertEquals(ref[i], res[i]);
+    }
+
+    let array =  Everything.test_array_fixed_size_int_out();
+    JSUnit.assertEquals(0, array[0]);
+    JSUnit.assertEquals(4, array[4]);
+    array =  Everything.test_array_fixed_size_int_return();
+    JSUnit.assertEquals(0, array[0]);
+    JSUnit.assertEquals(4, array[4]);
+
+    array = Everything.test_array_int_none_out();
+    arrayEqual([1, 2, 3, 4, 5], array);
+
+    array = Everything.test_array_int_full_out();
+    arrayEqual([0, 1, 2, 3, 4], array);
+
+    array = Everything.test_array_int_null_out();
+    JSUnit.assertEquals(0, array.length);
+
+    Everything.test_array_int_null_in(null);
+}
+
+/* GHash type */
+
+// Convert an object to a predictable (not-hash-order-dependent) string
+function objToString(v) {
+    if (typeof(v) == "object") {
+        let keys = [];
+        for (let k in v)
+            keys.push(k);
+        keys.sort();
+        return "{" + keys.map(function(k) {
+            return k + ":" + objToString(v[k]);
+        }) + "}";
+    } else if (typeof(v) == "string") {
+        return '"' + v + '"';
+    } else {
+        return v;
+    }
+}
+
+function testGHashOut() {
+    const HASH_STR = '{baz:"bat",foo:"bar",qux:"quux"}';
+    JSUnit.assertEquals(null, Everything.test_ghash_null_return());
+    JSUnit.assertEquals(HASH_STR, objToString(Everything.test_ghash_nothing_return()));
+    JSUnit.assertEquals(HASH_STR, objToString(Everything.test_ghash_nothing_return2()));
+    JSUnit.assertEquals(HASH_STR, objToString(Everything.test_ghash_container_return()));
+    JSUnit.assertEquals(HASH_STR, objToString(Everything.test_ghash_everything_return()));
+}
+
+function testGHashIn() {
+    const STR_HASH = { foo: 'bar', baz: 'bat', qux: 'quux' };
+    Everything.test_ghash_null_in(null);
+    Everything.test_ghash_nothing_in(STR_HASH);
+    Everything.test_ghash_nothing_in2(STR_HASH);
+}
+
+function testNestedGHashOut() {
+    const HASH_STR = '{wibble:{baz:"bat",foo:"bar",qux:"quux"}}';
+    JSUnit.assertEquals(HASH_STR, objToString(Everything.test_ghash_nested_everything_return()));
+    JSUnit.assertEquals(HASH_STR, objToString(Everything.test_ghash_nested_everything_return2()));
+}
+
+/* Enums */
+function testEnumParam() {
+    let e;
+
+    e = Everything.test_enum_param(Everything.TestEnum.VALUE1);
+    JSUnit.assertEquals('Enum parameter', 'value1', e);
+    e = Everything.test_enum_param(Everything.TestEnum.VALUE3);
+    JSUnit.assertEquals('Enum parameter', 'value3', e);
+
+    e = Everything.test_unsigned_enum_param(Everything.TestEnumUnsigned.VALUE1);
+    JSUnit.assertEquals('Enum parameter', 'value1', e);
+    e = Everything.test_unsigned_enum_param(Everything.TestEnumUnsigned.VALUE2);
+    JSUnit.assertEquals('Enum parameter', 'value2', e);
+
+    JSUnit.assertNotUndefined("Enum $gtype", Everything.TestEnumUnsigned.$gtype);
+    JSUnit.assertTrue("Enum $gtype enumerable", "$gtype" in Everything.TestEnumUnsigned);
+}
+
+function testSignal() {
+    let handlerCounter = 0;
+    let o = new Everything.TestObj();
+    let theObject = null;
+
+    let handlerId = o.connect('test', function(signalObject) {
+                                          handlerCounter ++;
+                                          theObject = signalObject;
+                                          o.disconnect(handlerId);
+                                      });
+
+    o.emit('test');
+    JSUnit.assertEquals('handler callled', 1, handlerCounter);
+    JSUnit.assertEquals('Signal handlers gets called with right object', o, theObject);
+    o.emit('test');
+    JSUnit.assertEquals('disconnected handler not called', 1, handlerCounter);
+}
+
+function testInvalidSignal() {
+    let o = new Everything.TestObj();
+
+    JSUnit.assertRaises('connect to invalid signal',
+                 function() { o.connect('invalid-signal', function(o) {}); });
+    JSUnit.assertRaises('emit invalid signal',
+                 function() { o.emit('invalid-signal'); });
+}
+
+function testSignalWithStaticScopeArg() {
+    let o = new Everything.TestObj();
+    let b = new Everything.TestSimpleBoxedA({ some_int: 42,
+                                              some_int8: 43,
+                                              some_double: 42.5,
+                                              some_enum: Everything.TestEnum.VALUE3 });
+
+    o.connect('test-with-static-scope-arg', function(signalObject, signalArg) {
+                                                signalArg.some_int = 44;
+                                            });
+
+    o.emit('test-with-static-scope-arg', b);
+    JSUnit.assertEquals('signal handler was passed arg as reference', 44, b.some_int);
+}
+
+function testTortureSignature0() {
+    let [y, z, q] = Everything.test_torture_signature_0(42, 'foo', 7);
+    JSUnit.assertEquals(Math.floor(y), 42);
+    JSUnit.assertEquals(z, 84);
+    JSUnit.assertEquals(q, 10);
+}
+
+function testTortureSignature1Fail() {
+    JSUnit.assertRaises(function () {
+        let [success, y, z, q] = Everything.test_torture_signature_1(42, 'foo', 7);
+    });
+}
+
+function testTortureSignature1Success() {
+    let [success, y, z, q] = Everything.test_torture_signature_1(11, 'barbaz', 8);
+    JSUnit.assertEquals(Math.floor(y), 11);
+    JSUnit.assertEquals(z, 22);
+    JSUnit.assertEquals(q, 14);
+}
+
+function testTortureSignature2() {
+    let [y, z, q] = Everything.test_torture_signature_2(42, function () {
+        }, 'foo', 7);
+    JSUnit.assertEquals(Math.floor(y), 42);
+    JSUnit.assertEquals(z, 84);
+    JSUnit.assertEquals(q, 10);
+}
+
+function testObjTortureSignature0() {
+    let o = new Everything.TestObj();
+    let [y, z, q] = o.torture_signature_0(42, 'foo', 7);
+    JSUnit.assertEquals(Math.floor(y), 42);
+    JSUnit.assertEquals(z, 84);
+    JSUnit.assertEquals(q, 10);
+}
+
+function testObjTortureSignature1Fail() {
+    let o = new Everything.TestObj();
+    JSUnit.assertRaises(function () {
+        let [success, y, z, q] = o.torture_signature_1(42, 'foo', 7);
+    });
+}
+
+function testObjTortureSignature1Success() {
+    let o = new Everything.TestObj();
+    let [success, y, z, q] = o.torture_signature_1(11, 'barbaz', 8);
+    JSUnit.assertEquals(Math.floor(y), 11);
+    JSUnit.assertEquals(z, 22);
+    JSUnit.assertEquals(q, 14);
+}
+
+function testStrvInGValue() {
+    let v = Everything.test_strv_in_gvalue();
+
+    JSUnit.assertEquals(v.length, 3);
+    JSUnit.assertEquals(v[0], "one");
+    JSUnit.assertEquals(v[1], "two");
+    JSUnit.assertEquals(v[2], "three");
+}
+
+function testVariant() {
+    // Cannot access the variant contents, for now
+    let ivar = Everything.test_gvariant_i();
+    JSUnit.assertEquals('i', ivar.get_type_string());
+    JSUnit.assertTrue(ivar.equal(GLib.Variant.new_int32(1)));
+
+    let svar = Everything.test_gvariant_s();
+    JSUnit.assertEquals('s', String.fromCharCode(svar.classify()));
+    JSUnit.assertEquals('one', svar.get_string()[0]);
+
+    let asvvar = Everything.test_gvariant_asv();
+    JSUnit.assertEquals(2, asvvar.n_children());
+
+    let asvar = Everything.test_gvariant_as();
+    let as = asvar.get_strv();
+    JSUnit.assertEquals('one', as[0]);
+    JSUnit.assertEquals('two', as[1]);
+    JSUnit.assertEquals('three', as[2]);
+    JSUnit.assertEquals(3, as.length);
+}
+
+function testGError() {
+    JSUnit.assertEquals(Gio.io_error_quark(), Number(Gio.IOErrorEnum));
+
+    try {
+        let file = Gio.file_new_for_path("\\/,.^!@&$_don't exist");
+        file.read(null);
+    } catch (x) {
+        JSUnit.assertTrue(x instanceof Gio.IOErrorEnum);
+        JSUnit.assertTrue(x.matches(Gio.io_error_quark(), Gio.IOErrorEnum.NOT_FOUND));
+        JSUnit.assertTrue(x.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.NOT_FOUND));
+
+        JSUnit.assertEquals(Gio.io_error_quark(), x.domain);
+        JSUnit.assertEquals(Gio.IOErrorEnum.NOT_FOUND, x.code);
+    }
+
+    Everything.test_gerror_callback(function(e) {
+        JSUnit.assertTrue(e instanceof Gio.IOErrorEnum);
+        JSUnit.assertEquals(Gio.io_error_quark(), e.domain);
+        JSUnit.assertEquals(Gio.IOErrorEnum.NOT_SUPPORTED, e.code);
+        JSUnit.assertEquals('regression test error', e.message);
+    });
+    Everything.test_owned_gerror_callback(function(e) {
+        JSUnit.assertTrue(e instanceof Gio.IOErrorEnum);
+        JSUnit.assertEquals(Gio.io_error_quark(), e.domain);
+        JSUnit.assertEquals(Gio.IOErrorEnum.PERMISSION_DENIED, e.code);
+        JSUnit.assertEquals('regression test owned error', e.message);
+    });
+
+    // Calling matches() on an unpaired error used to JSUnit.assert:
+    // https://bugzilla.gnome.org/show_bug.cgi?id=689482
+    try {
+        WarnLib.throw_unpaired();
+        JSUnit.assertTrue(false);
+    } catch (e) {
+        JSUnit.assertFalse(e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.NOT_FOUND));
+    }
+}
+
+function testWrongClassGObject() {
+    /* Function calls */
+    // Everything.func_obj_null_in expects a Everything.TestObj
+    JSUnit.assertRaises(function() {
+        Everything.func_obj_null_in(new Gio.SimpleAction);
+    });
+    JSUnit.assertRaises(function() {
+        Everything.func_obj_null_in(new GLib.KeyFile);
+    });
+    JSUnit.assertRaises(function() {
+        Everything.func_obj_null_in(Gio.File.new_for_path('/'));
+    });
+    Everything.func_obj_null_in(new Everything.TestSubObj);
+
+    /* Method calls */
+    JSUnit.assertRaises(function() {
+        Everything.TestObj.prototype.instance_method.call(new Gio.SimpleAction);
+    });
+    JSUnit.assertRaises(function() {
+        Everything.TestObj.prototype.instance_method.call(new GLib.KeyFile);
+    });
+    Everything.TestObj.prototype.instance_method.call(new Everything.TestSubObj);
+}
+
+function testWrongClassGBoxed() {
+    let simpleBoxed = new Everything.TestSimpleBoxedA;
+    // simpleBoxed.equals expects a Everything.TestSimpleBoxedA
+    JSUnit.assertRaises(function() {
+        simpleBoxed.equals(new Gio.SimpleAction);
+    })
+    JSUnit.assertRaises(function() {
+        simpleBoxed.equals(new Everything.TestObj);
+    })
+    JSUnit.assertRaises(function() {
+        simpleBoxed.equals(new GLib.KeyFile);
+    })
+    JSUnit.assertTrue(simpleBoxed.equals(simpleBoxed));
+
+    JSUnit.assertRaises(function() {
+        Everything.TestSimpleBoxedA.prototype.copy.call(new Gio.SimpleAction);
+    });
+    JSUnit.assertRaises(function() {
+        Everything.TestSimpleBoxedA.prototype.copy.call(new GLib.KeyFile);
+    })
+    Everything.TestSimpleBoxedA.prototype.copy.call(simpleBoxed);
+}
+
+JSUnit.gjstestRun(this, JSUnit.setUp, JSUnit.tearDown);
+
diff --git a/test/js/testEverythingEncapsulated.js b/installed-tests/test/js/testEverythingEncapsulated.js
similarity index 53%
rename from test/js/testEverythingEncapsulated.js
rename to installed-tests/test/js/testEverythingEncapsulated.js
index 6dfea8c..e66ce54 100644
--- a/test/js/testEverythingEncapsulated.js
+++ b/installed-tests/test/js/testEverythingEncapsulated.js
@@ -1,37 +1,33 @@
 // application/javascript;version=1.8
 // This used to be called "Everything"
+const JSUnit = imports.jsUnit;
 const Everything = imports.gi.Regress;
 const GLib = imports.gi.GLib;
 
-if (!('assertEquals' in this)) { /* allow running this test standalone */
-    imports.lang.copyPublicProperties(imports.jsUnit, this);
-    gjstestRun = function() { return imports.jsUnit.gjstestRun(window); };
-}
-
 function testStruct() {
     let struct = new Everything.TestStructA();
     struct.some_int = 42;
     struct.some_int8 = 43;
     struct.some_double = 42.5;
     struct.some_enum = Everything.TestEnum.VALUE3;
-    assertEquals(42, struct.some_int);
-    assertEquals(43, struct.some_int8);
-    assertEquals(42.5, struct.some_double);
-    assertEquals(Everything.TestEnum.VALUE3, struct.some_enum);
+    JSUnit.assertEquals(42, struct.some_int);
+    JSUnit.assertEquals(43, struct.some_int8);
+    JSUnit.assertEquals(42.5, struct.some_double);
+    JSUnit.assertEquals(Everything.TestEnum.VALUE3, struct.some_enum);
     let b = struct.clone();
-    assertEquals(42, b.some_int);
-    assertEquals(43, b.some_int8);
-    assertEquals(42.5, b.some_double);
-    assertEquals(Everything.TestEnum.VALUE3, b.some_enum);
+    JSUnit.assertEquals(42, b.some_int);
+    JSUnit.assertEquals(43, b.some_int8);
+    JSUnit.assertEquals(42.5, b.some_double);
+    JSUnit.assertEquals(Everything.TestEnum.VALUE3, b.some_enum);
 
     struct = new Everything.TestStructB();
     struct.some_int8 = 43;
     struct.nested_a.some_int8 = 66;
-    assertEquals(43, struct.some_int8);
-    assertEquals(66, struct.nested_a.some_int8);
+    JSUnit.assertEquals(43, struct.some_int8);
+    JSUnit.assertEquals(66, struct.nested_a.some_int8);
     b = struct.clone();
-    assertEquals(43, b.some_int8);
-    assertEquals(66, struct.nested_a.some_int8);
+    JSUnit.assertEquals(43, b.some_int8);
+    JSUnit.assertEquals(66, struct.nested_a.some_int8);
 }
 
 function testStructConstructor()
@@ -42,23 +38,23 @@ function testStructConstructor()
                                               some_double: 42.5,
                                               some_enum: Everything.TestEnum.VALUE3 });
 
-    assertEquals(42, struct.some_int);
-    assertEquals(43, struct.some_int8);
-    assertEquals(42.5, struct.some_double);
-    assertEquals(Everything.TestEnum.VALUE3, struct.some_enum);
+    JSUnit.assertEquals(42, struct.some_int);
+    JSUnit.assertEquals(43, struct.some_int8);
+    JSUnit.assertEquals(42.5, struct.some_double);
+    JSUnit.assertEquals(Everything.TestEnum.VALUE3, struct.some_enum);
 
     // Make sure we catch bad field names
-    assertRaises(function() {
+    JSUnit.assertRaises(function() {
         let t = new Everything.TestStructA({ junk: 42 });
     });
 
     // Copy an object from another object of the same type, shortcuts to memcpy()
     let copy = new Everything.TestStructA(struct);
 
-    assertEquals(42, copy.some_int);
-    assertEquals(43, copy.some_int8);
-    assertEquals(42.5, copy.some_double);
-    assertEquals(Everything.TestEnum.VALUE3, copy.some_enum);
+    JSUnit.assertEquals(42, copy.some_int);
+    JSUnit.assertEquals(43, copy.some_int8);
+    JSUnit.assertEquals(42.5, copy.some_double);
+    JSUnit.assertEquals(Everything.TestEnum.VALUE3, copy.some_enum);
 }
 
 function testSimpleBoxed() {
@@ -67,10 +63,10 @@ function testSimpleBoxed() {
     simple_boxed.some_int8 = 43;
     simple_boxed.some_double = 42.5;
     simple_boxed.some_enum = Everything.TestEnum.VALUE3;
-    assertEquals(42, simple_boxed.some_int);
-    assertEquals(43, simple_boxed.some_int8);
-    assertEquals(42.5, simple_boxed.some_double);
-    assertEquals(Everything.TestEnum.VALUE3, simple_boxed.some_enum);
+    JSUnit.assertEquals(42, simple_boxed.some_int);
+    JSUnit.assertEquals(43, simple_boxed.some_int8);
+    JSUnit.assertEquals(42.5, simple_boxed.some_double);
+    JSUnit.assertEquals(Everything.TestEnum.VALUE3, simple_boxed.some_enum);
 }
 
 function testBoxedCopyConstructor()
@@ -81,24 +77,24 @@ function testBoxedCopyConstructor()
                                                          some_double: 42.5,
                                                          some_enum: Everything.TestEnum.VALUE3 });
 
-    assertEquals(42, simple_boxed.some_int);
-    assertEquals(43, simple_boxed.some_int8);
-    assertEquals(42.5, simple_boxed.some_double);
-    assertEquals(Everything.TestEnum.VALUE3, simple_boxed.some_enum);
+    JSUnit.assertEquals(42, simple_boxed.some_int);
+    JSUnit.assertEquals(43, simple_boxed.some_int8);
+    JSUnit.assertEquals(42.5, simple_boxed.some_double);
+    JSUnit.assertEquals(Everything.TestEnum.VALUE3, simple_boxed.some_enum);
 
     // Make sure we catch bad field names
-    assertRaises(function() {
+    JSUnit.assertRaises(function() {
         let t = new Everything.TestSimpleBoxedA({ junk: 42 });
     });
 
     // Copy an object from another object of the same type, shortcuts to the boxed copy
     let copy = new Everything.TestSimpleBoxedA(simple_boxed);
 
-    assertTrue(copy instanceof Everything.TestSimpleBoxedA);
-    assertEquals(42, copy.some_int);
-    assertEquals(43, copy.some_int8);
-    assertEquals(42.5, copy.some_double);
-    assertEquals(Everything.TestEnum.VALUE3, copy.some_enum);
+    JSUnit.assertTrue(copy instanceof Everything.TestSimpleBoxedA);
+    JSUnit.assertEquals(42, copy.some_int);
+    JSUnit.assertEquals(43, copy.some_int8);
+    JSUnit.assertEquals(42.5, copy.some_double);
+    JSUnit.assertEquals(Everything.TestEnum.VALUE3, copy.some_enum);
  }
 
 function testNestedSimpleBoxed() {
@@ -107,16 +103,16 @@ function testNestedSimpleBoxed() {
     // Test reading fields and nested fields
     simple_boxed.some_int8 = 42;
     simple_boxed.nested_a.some_int = 43;
-    assertEquals(42, simple_boxed.some_int8);
-    assertEquals(43, simple_boxed.nested_a.some_int);
+    JSUnit.assertEquals(42, simple_boxed.some_int8);
+    JSUnit.assertEquals(43, simple_boxed.nested_a.some_int);
 
     // Try assigning the nested struct field from an instance
     simple_boxed.nested_a = new Everything.TestSimpleBoxedA({ some_int: 53 });
-    assertEquals(53, simple_boxed.nested_a.some_int);
+    JSUnit.assertEquals(53, simple_boxed.nested_a.some_int);
 
     // And directly from a hash of field values
     simple_boxed.nested_a = { some_int: 63 };
-    assertEquals(63, simple_boxed.nested_a.some_int);
+    JSUnit.assertEquals(63, simple_boxed.nested_a.some_int);
 
     // Try constructing with a nested hash of field values
     let simple2 = new Everything.TestSimpleBoxedB({
@@ -127,31 +123,31 @@ function testNestedSimpleBoxed() {
             some_double: 43.5
         }
     });
-    assertEquals(42, simple2.some_int8);
-    assertEquals(43, simple2.nested_a.some_int);
-    assertEquals(44, simple2.nested_a.some_int8);
-    assertEquals(43.5, simple2.nested_a.some_double);
+    JSUnit.assertEquals(42, simple2.some_int8);
+    JSUnit.assertEquals(43, simple2.nested_a.some_int);
+    JSUnit.assertEquals(44, simple2.nested_a.some_int8);
+    JSUnit.assertEquals(43.5, simple2.nested_a.some_double);
 }
 
 function testBoxed() {
     let boxed = new Everything.TestBoxed();
     boxed.some_int8 = 42;
-    assertEquals(42, boxed.some_int8);
+    JSUnit.assertEquals(42, boxed.some_int8);
 }
 
 function testTestStructFixedArray() {
     let struct = new Everything.TestStructFixedArray();
     struct.frob();
-    assertEquals(7, struct.just_int);
-    assertEquals(42, struct.array[0]);
-    assertEquals(43, struct.array[1]);
-    assertEquals(51, struct.array[9]);
+    JSUnit.assertEquals(7, struct.just_int);
+    JSUnit.assertEquals(42, struct.array[0]);
+    JSUnit.assertEquals(43, struct.array[1]);
+    JSUnit.assertEquals(51, struct.array[9]);
 }
 
 function testComplexConstructor() {
     let boxed = new Everything.TestBoxedD('abcd', 8);
 
-    assertEquals(12, boxed.get_magic());
+    JSUnit.assertEquals(12, boxed.get_magic());
 }
 
 function testComplexConstructorBackwardCompatibility() {
@@ -162,17 +158,17 @@ function testComplexConstructorBackwardCompatibility() {
     // Clutter.Color and Clutter.ActorBox.
     let boxed = new Everything.TestBoxedB({ some_int8: 7, some_long: 5 });
 
-    assertEquals(7, boxed.some_int8);
-    assertEquals(5, boxed.some_long);
+    JSUnit.assertEquals(7, boxed.some_int8);
+    JSUnit.assertEquals(5, boxed.some_long);
 }
 
 function testVariantConstructor() {
     let str_variant = new GLib.Variant('s', 'mystring');
-    assertEquals('mystring', str_variant.get_string()[0]);
-    assertEquals('mystring', str_variant.deep_unpack());
+    JSUnit.assertEquals('mystring', str_variant.get_string()[0]);
+    JSUnit.assertEquals('mystring', str_variant.deep_unpack());
 
     let str_variant_old = GLib.Variant.new('s', 'mystring');
-    assertTrue(str_variant.equal(str_variant_old));
+    JSUnit.assertTrue(str_variant.equal(str_variant_old));
 
     let struct_variant = new GLib.Variant('(sogvau)',
                                          [ 'a string',
@@ -181,16 +177,17 @@ function testVariantConstructor() {
                                            new GLib.Variant('s', 'variant'),
                                            [ 7, 3 ]
                                          ]);
-    assertEquals(5, struct_variant.n_children());
+    JSUnit.assertEquals(5, struct_variant.n_children());
 
     let unpacked = struct_variant.deep_unpack();
-    assertEquals('a string', unpacked[0]);
-    assertEquals('/a/object/path', unpacked[1]);
-    assertEquals('asig', unpacked[2]);
-    assertTrue(unpacked[3] instanceof GLib.Variant);
-    assertEquals('variant', unpacked[3].deep_unpack());
-    assertTrue(unpacked[4] instanceof Array);
-    assertEquals(2, unpacked[4].length);
+    JSUnit.assertEquals('a string', unpacked[0]);
+    JSUnit.assertEquals('/a/object/path', unpacked[1]);
+    JSUnit.assertEquals('asig', unpacked[2]);
+    JSUnit.assertTrue(unpacked[3] instanceof GLib.Variant);
+    JSUnit.assertEquals('variant', unpacked[3].deep_unpack());
+    JSUnit.assertTrue(unpacked[4] instanceof Array);
+    JSUnit.assertEquals(2, unpacked[4].length);
 }
 
-gjstestRun();
+JSUnit.gjstestRun(this, JSUnit.setUp, JSUnit.tearDown);
+
diff --git a/test/js/testGDBus.js b/installed-tests/test/js/testGDBus.js
similarity index 72%
rename from test/js/testGDBus.js
rename to installed-tests/test/js/testGDBus.js
index d973c17..53dc766 100644
--- a/test/js/testGDBus.js
+++ b/installed-tests/test/js/testGDBus.js
@@ -1,4 +1,5 @@
 // application/javascript;version=1.8
+const JSUnit = imports.jsUnit;
 const Gio = imports.gi.Gio;
 const GLib = imports.gi.GLib;
 const Mainloop = imports.mainloop;
@@ -94,8 +95,8 @@ Test.prototype = {
         this._propWriteOnly = PROP_WRITE_ONLY_INITIAL_VALUE;
         this._propReadWrite = PROP_READ_WRITE_INITIAL_VALUE;
 
-       this._impl = Gio.DBusExportedObject.wrapJSObject(TestIface, this);
-       this._impl.export(Gio.DBus.session, '/org/gnome/gjs/Test');
+        this._impl = Gio.DBusExportedObject.wrapJSObject(TestIface, this);
+        this._impl.export(Gio.DBus.session, '/org/gnome/gjs/Test');
     },
 
     frobateStuff: function(args) {
@@ -176,7 +177,7 @@ Test.prototype = {
     /* This one is implemented asynchronously. Returns
      * the input arguments */
     echoAsync: function(parameters, invocation) {
-       var [someString, someInt] = parameters;
+        var [someString, someInt] = parameters;
         Mainloop.idle_add(function() {
             invocation.return_value(new GLib.Variant('(si)', [someString, someInt]));
             return false;
@@ -213,15 +214,15 @@ function testExportStuff() {
     new Test();
 
     own_name_id = Gio.DBus.session.own_name('org.gnome.gjs.Test',
-                                           Gio.BusNameOwnerFlags.NONE,
-                                           function(name) {
-                                               log("Acquired name " + name);
-                                               
-                                               Mainloop.quit('testGDBus');
-                                           },
-                                           function(name) {
-                                               log("Lost name " + name);
-                                           });
+                                            Gio.BusNameOwnerFlags.NONE,
+                                            function(name) {
+                                                log("Acquired name " + name);
+                                                
+                                                Mainloop.quit('testGDBus');
+                                            },
+                                            function(name) {
+                                                log("Lost name " + name);
+                                            });
 
     Mainloop.run('testGDBus');
 }
@@ -232,32 +233,32 @@ var proxy;
 function testInitStuff() {
     var theError;
     proxy = new ProxyClass(Gio.DBus.session,
-                          'org.gnome.gjs.Test',
-                          '/org/gnome/gjs/Test',
-                          function (obj, error) {
-                              theError = error;
-                              proxy = obj;
+                           'org.gnome.gjs.Test',
+                           '/org/gnome/gjs/Test',
+                           function (obj, error) {
+                               theError = error;
+                               proxy = obj;
 
-                              Mainloop.quit('testGDBus');
-                          });
+                               Mainloop.quit('testGDBus');
+                           });
 
     Mainloop.run('testGDBus');
 
-    assertNotNull(proxy);
-    assertNull(theError);
+    JSUnit.assertNotNull(proxy);
+    JSUnit.assertNull(theError);
 }
 
 function testFrobateStuff() {
     let theResult, theExcp;
     proxy.frobateStuffRemote({}, function(result, excp) {
-       [theResult] = result;
-       theExcp = excp;
-       Mainloop.quit('testGDBus');
+        [theResult] = result;
+        theExcp = excp;
+        Mainloop.quit('testGDBus');
     });
 
     Mainloop.run('testGDBus');
 
-    assertEquals("world", theResult.hello.deep_unpack());
+    JSUnit.assertEquals("world", theResult.hello.deep_unpack());
 }
 
 /* excp must be exactly the exception thrown by the remote method
@@ -265,15 +266,15 @@ function testFrobateStuff() {
 function testThrowException() {
     let theResult, theExcp;
     proxy.alwaysThrowExceptionRemote({}, function(result, excp) {
-       theResult = result;
-       theExcp = excp;
-       Mainloop.quit('testGDBus');
+        theResult = result;
+        theExcp = excp;
+        Mainloop.quit('testGDBus');
     });
 
     Mainloop.run('testGDBus');
 
-    assertNull(theResult);
-    assertNotNull(theExcp);
+    JSUnit.assertNull(theResult);
+    JSUnit.assertNotNull(theExcp);
 }
 
 /* We check that the exception in the answer is not null when we try to call
@@ -285,15 +286,15 @@ function testDoesNotExist() {
     delete Test.prototype.thisDoesNotExist;
 
     proxy.thisDoesNotExistRemote(function (result, excp) {
-       theResult = result;
-       theExcp = excp;
-       Mainloop.quit('testGDBus');
+        theResult = result;
+        theExcp = excp;
+        Mainloop.quit('testGDBus');
     });
 
     Mainloop.run('testGDBus');
 
-    assertNotNull(theExcp);
-    assertNull(theResult);
+    JSUnit.assertNotNull(theExcp);
+    JSUnit.assertNull(theResult);
 }
 
 function testNonJsonFrobateStuff() {
@@ -306,8 +307,8 @@ function testNonJsonFrobateStuff() {
 
     Mainloop.run('testGDBus');
 
-    assertEquals("42 it is!", theResult);
-    assertNull(theExcp);
+    JSUnit.assertEquals("42 it is!", theResult);
+    JSUnit.assertNull(theExcp);
 }
 
 function testNoInParameter() {
@@ -320,8 +321,8 @@ function testNoInParameter() {
 
     Mainloop.run('testGDBus');
 
-    assertEquals("Yes!", theResult);
-    assertNull(theExcp);
+    JSUnit.assertEquals("Yes!", theResult);
+    JSUnit.assertNull(theExcp);
 }
 
 function testMultipleInArgs() {
@@ -334,8 +335,8 @@ function testMultipleInArgs() {
 
     Mainloop.run('testGDBus');
 
-    assertEquals("1 2 3 4 5", theResult);
-    assertNull(theExcp);
+    JSUnit.assertEquals("1 2 3 4 5", theResult);
+    JSUnit.assertNull(theExcp);
 }
 
 function testNoReturnValue() {
@@ -348,8 +349,8 @@ function testNoReturnValue() {
 
     Mainloop.run('testGDBus');
 
-    assertEquals(undefined, theResult);
-    assertNull(theExcp);
+    JSUnit.assertEquals(undefined, theResult);
+    JSUnit.assertNull(theExcp);
 }
 
 function testEmitSignal() {
@@ -357,12 +358,12 @@ function testEmitSignal() {
     let signalReceived = 0;
     let signalArgument = null;
     let id = proxy.connectSignal('signalFoo',
-                                function(emitter, senderName, parameters) {
-                                    signalReceived ++;
-                                    [signalArgument] = parameters;
+                                 function(emitter, senderName, parameters) {
+                                     signalReceived ++;
+                                     [signalArgument] = parameters;
 
-                                    proxy.disconnectSignal(id);
-                                });
+                                     proxy.disconnectSignal(id);
+                                 });
     proxy.emitSignalRemote(function(result, excp) {
         [theResult] = result;
         theExcp = excp;
@@ -373,10 +374,10 @@ function testEmitSignal() {
 
     Mainloop.run('testGDBus');
 
-    assertUndefined('result should be undefined', theResult);
-    assertNull('no exception set', theExcp);
-    assertEquals('number of signals received', signalReceived, 1);
-    assertEquals('signal argument', signalArgument, "foobar");
+    JSUnit.assertUndefined('result should be undefined', theResult);
+    JSUnit.assertNull('no exception set', theExcp);
+    JSUnit.assertEquals('number of signals received', signalReceived, 1);
+    JSUnit.assertEquals('signal argument', signalArgument, "foobar");
 
 }
 
@@ -390,10 +391,10 @@ function testMultipleOutValues() {
 
     Mainloop.run('testGDBus');
 
-    assertEquals("Hello", theResult[0]);
-    assertEquals("World", theResult[1]);
-    assertEquals("!", theResult[2]);
-    assertNull(theExcp);
+    JSUnit.assertEquals("Hello", theResult[0]);
+    JSUnit.assertEquals("World", theResult[1]);
+    JSUnit.assertEquals("!", theResult[2]);
+    JSUnit.assertNull(theExcp);
 }
 
 function testOneArrayOut() {
@@ -406,10 +407,10 @@ function testOneArrayOut() {
 
     Mainloop.run('testGDBus');
 
-    assertEquals("Hello", theResult[0]);
-    assertEquals("World", theResult[1]);
-    assertEquals("!", theResult[2]);
-    assertNull(theExcp);
+    JSUnit.assertEquals("Hello", theResult[0]);
+    JSUnit.assertEquals("World", theResult[1]);
+    JSUnit.assertEquals("!", theResult[2]);
+    JSUnit.assertNull(theExcp);
 }
 
 function testArrayOfArrayOut() {
@@ -425,13 +426,13 @@ function testArrayOfArrayOut() {
     let a1 = theResult[0];
     let a2 = theResult[1];
 
-    assertEquals("Hello", a1[0]);
-    assertEquals("World", a1[1]);
+    JSUnit.assertEquals("Hello", a1[0]);
+    JSUnit.assertEquals("World", a1[1]);
 
-    assertEquals("World", a2[0]);
-    assertEquals("Hello", a2[1]);;
+    JSUnit.assertEquals("World", a2[0]);
+    JSUnit.assertEquals("Hello", a2[1]);;
 
-    assertNull(theExcp);
+    JSUnit.assertNull(theExcp);
 }
 
 function testMultipleArrayOut() {
@@ -447,13 +448,13 @@ function testMultipleArrayOut() {
     let a1 = theResult[0];
     let a2 = theResult[1];
 
-    assertEquals("Hello", a1[0]);
-    assertEquals("World", a1[1]);
+    JSUnit.assertEquals("Hello", a1[0]);
+    JSUnit.assertEquals("World", a1[1]);
 
-    assertEquals("World", a2[0]);
-    assertEquals("Hello", a2[1]);;
+    JSUnit.assertEquals("World", a2[0]);
+    JSUnit.assertEquals("Hello", a2[1]);;
 
-    assertNull(theExcp);
+    JSUnit.assertNull(theExcp);
 }
 
 /* We are returning an array but the signature says it's an integer,
@@ -468,8 +469,8 @@ function testArrayOutBadSig() {
     });
 
     Mainloop.run('testGDBus');
-    assertNull(theResult);
-    assertNotNull(theExcp);
+    JSUnit.assertNull(theResult);
+    JSUnit.assertNotNull(theExcp);
 }
 
 function testAsyncImplementation() {
@@ -484,10 +485,10 @@ function testAsyncImplementation() {
                      });
 
     Mainloop.run('testGDBus');
-    assertNull(theExcp);
-    assertNotNull(theResult);
-    assertEquals(theResult[0], someString);
-    assertEquals(theResult[1], someInt);
+    JSUnit.assertNull(theExcp);
+    JSUnit.assertNotNull(theResult);
+    JSUnit.assertEquals(theResult[0], someString);
+    JSUnit.assertEquals(theResult[1], someInt);
 }
 
 function testBytes() {
@@ -503,9 +504,9 @@ function testBytes() {
         });
 
         Mainloop.run('testGDBus');
-        assertNull(theExcp);
-        assertNotNull(theResult);
-        assertEquals(someBytes[i], theResult);
+        JSUnit.assertNull(theExcp);
+        JSUnit.assertNotNull(theResult);
+        JSUnit.assertEquals(someBytes[i], theResult);
     }
 }
 
@@ -517,12 +518,12 @@ function testStructArray() {
         Mainloop.quit('testGDBus');
     });
     Mainloop.run('testGDBus');
-    assertNull(theExcp);
-    assertNotNull(theResult);
-    assertEquals(theResult[0][0], 128);
-    assertEquals(theResult[0][1], 123456);
-    assertEquals(theResult[1][0], 42);
-    assertEquals(theResult[1][1], 654321);
+    JSUnit.assertNull(theExcp);
+    JSUnit.assertNotNull(theResult);
+    JSUnit.assertEquals(theResult[0][0], 128);
+    JSUnit.assertEquals(theResult[0][1], 123456);
+    JSUnit.assertEquals(theResult[1][0], 42);
+    JSUnit.assertEquals(theResult[1][1], 654321);
 }
 
 function testDictSignatures() {
@@ -541,19 +542,19 @@ function testDictSignatures() {
     });
 
     Mainloop.run('testGDBus');
-    assertNull(theExcp);
-    assertNotNull(theResult);
+    JSUnit.assertNull(theExcp);
+    JSUnit.assertNotNull(theResult);
 
     // verify the fractional part was dropped off int
-    assertEquals(11, theResult['anInteger'].deep_unpack());
+    JSUnit.assertEquals(11, theResult['anInteger'].deep_unpack());
 
     // and not dropped off a double
-    assertEquals(10.5, theResult['aDoubleBeforeAndAfter'].deep_unpack());
+    JSUnit.assertEquals(10.5, theResult['aDoubleBeforeAndAfter'].deep_unpack());
 
-    // this assertion is useless, it will work
+    // this JSUnit.assertion is useless, it will work
     // anyway if the result is really an int,
     // but it at least checks we didn't lose data
-    assertEquals(10.0, theResult['aDouble'].deep_unpack());
+    JSUnit.assertEquals(10.0, theResult['aDouble'].deep_unpack());
 }
 
 function testFinalize() {
@@ -563,4 +564,5 @@ function testFinalize() {
     Gio.DBus.session.unown_name(own_name_id);
 }
 
-gjstestRun();
+JSUnit.gjstestRun(this, JSUnit.setUp, JSUnit.tearDown);
+
diff --git a/test/js/testGIMarshalling.js b/installed-tests/test/js/testGIMarshalling.js
similarity index 100%
rename from test/js/testGIMarshalling.js
rename to installed-tests/test/js/testGIMarshalling.js
diff --git a/test/js/testGObjectClass.js b/installed-tests/test/js/testGObjectClass.js
similarity index 100%
rename from test/js/testGObjectClass.js
rename to installed-tests/test/js/testGObjectClass.js
diff --git a/installed-tests/test/js/testJS1_8.js b/installed-tests/test/js/testJS1_8.js
new file mode 100644
index 0000000..1cdb6b7
--- /dev/null
+++ b/installed-tests/test/js/testJS1_8.js
@@ -0,0 +1,54 @@
+// application/javascript;version=1.8
+
+// Test SpiderMonkey JS extensions; see
+// https://developer.mozilla.org/en/JavaScript/New_in_JavaScript/1.8
+
+// "const"
+const JSUnit = imports.jsUnit;
+const Everything = imports.gi.Regress;
+
+function testLet() {
+    // "let"
+    let foo = "bar";
+    let cow = "moo";
+
+    JSUnit.assertEquals(foo, "bar");
+}
+
+function testMultiReturn() {
+    // "destructuring bind"
+    let [y, z, q] = Everything.test_torture_signature_0(42, 'foo', 7);
+    JSUnit.assertEquals(z, 84);
+}
+
+function testYield() {
+    function fib() {
+        var i = 0, j = 1;
+        while (true) {
+            yield i;
+            var t = i;
+            i = j;
+            j += t;
+        }
+    }
+
+    var v = [];
+    var g = fib();
+    for (var i = 0; i < 10; i++) {
+        v.push(g.next());
+    }
+
+    JSUnit.assertEquals(v[0], 0);
+    JSUnit.assertEquals(v[1], 1);
+    JSUnit.assertEquals(v[2], 1);
+    JSUnit.assertEquals(v[3], 2);
+    JSUnit.assertEquals(v[4], 3);
+    JSUnit.assertEquals(v[5], 5);
+    JSUnit.assertEquals(v[6], 8);
+    JSUnit.assertEquals(v[7], 13);
+    JSUnit.assertEquals(v[8], 21);
+    JSUnit.assertEquals(v[9], 34);
+}
+
+JSUnit.gjstestRun(this, JSUnit.setUp, JSUnit.tearDown);
+
diff --git a/installed-tests/test/js/testJSDefault.js b/installed-tests/test/js/testJSDefault.js
new file mode 100644
index 0000000..ac04312
--- /dev/null
+++ b/installed-tests/test/js/testJSDefault.js
@@ -0,0 +1,16 @@
+// Test that we *don't* get SpiderMonkey extensions; see
+// testJS1_8.js.
+// application/javascript;version=ECMAv3
+
+const JSUnit = imports.jsUnit;
+
+function testLet() {
+    JSUnit.assertRaises('missing ; before statement', function () { eval("let result = 1+1; result;") });
+}
+
+function testYield() {
+    JSUnit.assertRaises('missing ; before statement', function() { eval("function foo () { yield 42; }; 
foo();"); });
+}
+
+JSUnit.gjstestRun(this, JSUnit.setUp, JSUnit.tearDown);
+
diff --git a/installed-tests/test/js/testLang.js b/installed-tests/test/js/testLang.js
new file mode 100644
index 0000000..b649805
--- /dev/null
+++ b/installed-tests/test/js/testLang.js
@@ -0,0 +1,128 @@
+// application/javascript;version=1.8
+// tests for imports.lang module
+
+const JSUnit = imports.jsUnit;
+const Lang = imports.lang;
+
+function testCountProperties() {
+    var foo = { 'a' : 10, 'b' : 11 };
+    JSUnit.assertEquals("number of props", 2, Lang.countProperties(foo));
+}
+
+function testCopyProperties() {
+    var foo = { 'a' : 10, 'b' : 11 };
+    var bar = {};
+
+    Lang.copyProperties(foo, bar);
+
+    JSUnit.assertTrue("a in bar", ('a' in bar));
+    JSUnit.assertTrue("b in bar", ('b' in bar));
+    JSUnit.assertEquals("a is 10", 10, bar.a);
+    JSUnit.assertEquals("b is 11", 11, bar.b);
+    JSUnit.assertEquals("2 items in bar", 2, Lang.countProperties(bar));
+}
+
+function testCopyPublicProperties() {
+    var foo = { 'a' : 10, 'b' : 11, '_c' : 12 };
+    var bar = {};
+
+    Lang.copyPublicProperties(foo, bar);
+
+    JSUnit.assertTrue("a in bar", ('a' in bar));
+    JSUnit.assertTrue("b in bar", ('b' in bar));
+    JSUnit.assertFalse("_c in bar", ('_c' in bar));
+    JSUnit.assertEquals("a is 10", 10, bar.a);
+    JSUnit.assertEquals("b is 11", 11, bar.b);
+    JSUnit.assertEquals("2 items in bar", 2, Lang.countProperties(bar));
+}
+
+function testCopyGetterSetterProperties() {
+    var foo = {
+        'a' : 10,
+        'b' : 11,
+        get c() {
+            return this.a;
+        },
+        set c(n) {
+            this.a = n;
+        }};
+    var bar = {};
+
+    Lang.copyProperties(foo, bar);
+
+    let getterFunc = bar.__lookupGetter__("c");
+    let setterFunc = bar.__lookupSetter__("c");
+
+    // this should return the value of 'a'
+    let c = bar.c;
+
+    // this should set 'a' value
+    bar.c = 13;
+
+    JSUnit.assertTrue("bar has 'c' getter", (getterFunc != null));
+    JSUnit.assertTrue("bar has 'c' setter", (setterFunc != null));
+    JSUnit.assertTrue("bar 'c' value is 10", (c == 10));
+    JSUnit.assertTrue("bar 'a' new value is 13", (bar.a == 13));
+}
+
+function testBind() {
+
+    function Obj() {
+    }
+
+    Obj.prototype = {
+        callback: function() {
+            this.obj = this;
+            this.args = arguments;
+            return true;
+        }
+    };
+
+    let callback;
+
+    let o = new Obj();
+    callback = Lang.bind(o, o.callback);
+    JSUnit.assertEquals(callback(), true);
+    JSUnit.assertNotEquals("o.obj in callback", undefined, o.obj);
+    JSUnit.assertEquals("o.obj in callback", o, o.obj);
+    JSUnit.assertEquals("o.args in callback", 0, o.args.length);
+    JSUnit.assertRaises(function() { return Lang.bind(o, undefined); });
+    JSUnit.assertRaises(function() { return Lang.bind(undefined, function() {}); });
+
+    let o2 = new Obj();
+    callback = Lang.bind(o2, o2.callback, 42, 1138);
+    JSUnit.assertEquals(callback(), true);
+    JSUnit.assertNotEquals("o2.args in callback", undefined, o2.args);
+    JSUnit.assertEquals("o2.args.length in callback", 2, o2.args.length);
+    JSUnit.assertEquals("o2.args[0] in callback", 42, o2.args[0]);
+    JSUnit.assertEquals("o2.args[1] in callback", 1138, o2.args[1]);
+
+    let o3 = new Obj();
+    callback = Lang.bind(o3, o3.callback, 42, 1138);
+    JSUnit.assertEquals(callback(1, 2, 3), true);
+    JSUnit.assertNotEquals("o3.args in callback", undefined, o3.args);
+    JSUnit.assertEquals("o3.args.length in callback", 5, o3.args.length);
+    JSUnit.assertEquals("o3.args[0] in callback", 1, o3.args[0]);
+    JSUnit.assertEquals("o3.args[1] in callback", 2, o3.args[1]);
+    JSUnit.assertEquals("o3.args[2] in callback", 3, o3.args[2]);
+    JSUnit.assertEquals("o3.args[3] in callback", 42, o3.args[3]);
+    JSUnit.assertEquals("o3.args[4] in callback", 1138, o3.args[4]);
+}
+
+function testDefineAccessorProperty() {
+    var obj = {};
+    var storage = 42;
+
+    JSUnit.assertEquals(obj.foo, undefined);
+
+    Lang.defineAccessorProperty(obj, 'foo',
+                                function () { return storage; },
+                                function (val) { storage = val; });
+
+    JSUnit.assertEquals(obj.foo, 42);
+    obj.foo = 43;
+    JSUnit.assertEquals(obj.foo, 43);
+}
+
+JSUnit.gjstestRun(this, JSUnit.setUp, JSUnit.tearDown);
+
diff --git a/test/js/testLocale.js b/installed-tests/test/js/testLocale.js
similarity index 63%
rename from test/js/testLocale.js
rename to installed-tests/test/js/testLocale.js
index 0b4f58f..ddd07b1 100644
--- a/test/js/testLocale.js
+++ b/installed-tests/test/js/testLocale.js
@@ -1,5 +1,6 @@
 // application/javascript;version=1.8
 // tests for JS_SetLocaleCallbacks().
+const JSUnit = imports.jsUnit;
 
 function testToLocaleDateString() {
     let date = new Date();
@@ -11,35 +12,36 @@ function testToLocaleDateString() {
 }
 
 function testToLocaleLowerCase() {
-    assertEquals("aaa", "AAA".toLocaleLowerCase());
+    JSUnit.assertEquals("aaa", "AAA".toLocaleLowerCase());
 
     // String conversion is implemented internally to GLib,
     // and is more-or-less independent of locale. (A few
     // characters are handled specially for a few locales,
     // like i in Turkish. But not A WITH ACUTE)
-    assertEquals("\u00e1", "\u00c1".toLocaleLowerCase());
+    JSUnit.assertEquals("\u00e1", "\u00c1".toLocaleLowerCase());
 
     // Unpaired surrogate, can't be converted to UTF-8
-    assertRaises(function() { "\ud800".toLocaleLowerCase(); });
+    JSUnit.assertRaises(function() { "\ud800".toLocaleLowerCase(); });
 }
 
 function testToLocaleUpperCase() {
-    assertEquals("AAA", "aaa".toLocaleUpperCase());
-    assertEquals("\u00c1", "\u00e1".toLocaleUpperCase());
-    assertRaises(function() { "\ud800".toLocaleUpperCase(); });
+    JSUnit.assertEquals("AAA", "aaa".toLocaleUpperCase());
+    JSUnit.assertEquals("\u00c1", "\u00e1".toLocaleUpperCase());
+    JSUnit.assertRaises(function() { "\ud800".toLocaleUpperCase(); });
 }
 
 function testToLocaleCompare() {
     // GLib calls out to libc for collation, so we can't really
     // assume anything - we could even be running in the
     // C locale. The below is pretty safe.
-    assertEquals(-1, "a".localeCompare("b"));
-    assertEquals( 0, "a".localeCompare("a"));
-    assertEquals( 1, "b".localeCompare("a"));
+    JSUnit.assertEquals(-1, "a".localeCompare("b"));
+    JSUnit.assertEquals( 0, "a".localeCompare("a"));
+    JSUnit.assertEquals( 1, "b".localeCompare("a"));
 
     // Again test error handling when conversion fails
     //assertRaises(function() { "\ud800".localeCompare("a"); });
     //assertRaises(function() { "a".localeCompare("\ud800"); });
 }
 
-gjstestRun();
+JSUnit.gjstestRun(this, JSUnit.setUp, JSUnit.tearDown);
+
diff --git a/test/js/testMainloop.js b/installed-tests/test/js/testMainloop.js
similarity index 84%
rename from test/js/testMainloop.js
rename to installed-tests/test/js/testMainloop.js
index 09d22af..792e006 100644
--- a/test/js/testMainloop.js
+++ b/installed-tests/test/js/testMainloop.js
@@ -1,4 +1,5 @@
 // application/javascript;version=1.8
+const JSUnit = imports.jsUnit;
 const Mainloop = imports.mainloop;
 
 function testTimeout() {
@@ -34,9 +35,9 @@ function testTimeout() {
     Mainloop.run('testtimeout');
 
     with (trackTimeout) {
-        assertEquals("run ten times", 10, runTenTimes);
-        assertEquals("run only once", 1, runOnlyOnce);
-        assertEquals("never run", 0, neverRun);
+        JSUnit.assertEquals("run ten times", 10, runTenTimes);
+        JSUnit.assertEquals("run only once", 1, runOnlyOnce);
+        JSUnit.assertEquals("never run", 0, neverRun);
     }
 }
 
@@ -77,10 +78,10 @@ function testIdle() {
 
     Mainloop.run('foobar');
 
-    assertEquals("one-shot ran once", 1, trackIdles.runOnceCount);
-    assertEquals("two-shot ran twice", 2, trackIdles.runTwiceCount);
-    assertEquals("removed never ran", 0, trackIdles.neverRunsCount);
-    assertEquals("quit after many ran 11", 11, trackIdles.quitAfterManyRunsCount);
+    JSUnit.assertEquals("one-shot ran once", 1, trackIdles.runOnceCount);
+    JSUnit.assertEquals("two-shot ran twice", 2, trackIdles.runTwiceCount);
+    JSUnit.assertEquals("removed never ran", 0, trackIdles.neverRunsCount);
+    JSUnit.assertEquals("quit after many ran 11", 11, trackIdles.quitAfterManyRunsCount);
 
     // check re-entrancy of removing closures while they
     // are being invoked
@@ -102,4 +103,5 @@ function testIdle() {
                       });
 }
 
-gjstestRun();
+JSUnit.gjstestRun(this, JSUnit.setUp, JSUnit.tearDown);
+
diff --git a/test/js/testMetaClass.js b/installed-tests/test/js/testMetaClass.js
similarity index 64%
rename from test/js/testMetaClass.js
rename to installed-tests/test/js/testMetaClass.js
index fd2df91..3ae3123 100644
--- a/test/js/testMetaClass.js
+++ b/installed-tests/test/js/testMetaClass.js
@@ -1,4 +1,5 @@
 // application/javascript;version=1.8 -*- mode: js; indent-tabs-mode: nil -*-
+const JSUnit = imports.jsUnit;
 
 if (!('assertEquals' in this)) { /* allow running this test standalone */
     imports.lang.copyPublicProperties(imports.jsUnit, this);
@@ -8,9 +9,9 @@ if (!('assertEquals' in this)) { /* allow running this test standalone */
 const Lang = imports.lang;
 
 function assertArrayEquals(expected, got) {
-    assertEquals(expected.length, got.length);
+    JSUnit.assertEquals(expected.length, got.length);
     for (let i = 0; i < expected.length; i ++) {
-        assertEquals(expected[i], got[i]);
+        JSUnit.assertEquals(expected[i], got[i]);
     }
 }
 
@@ -84,43 +85,44 @@ function testMetaClass() {
                        'CustomMetaTwo',
                        'CustomMetaSubclass'], Subclassed);
 
-    assertTrue(NormalClass instanceof Lang.Class);
-    assertTrue(MetaClass instanceof Lang.Class);
+    JSUnit.assertTrue(NormalClass instanceof Lang.Class);
+    JSUnit.assertTrue(MetaClass instanceof Lang.Class);
 
-    assertTrue(CustomMetaOne instanceof Lang.Class);
-    assertTrue(CustomMetaOne instanceof MetaClass);
+    JSUnit.assertTrue(CustomMetaOne instanceof Lang.Class);
+    JSUnit.assertTrue(CustomMetaOne instanceof MetaClass);
 
-    assertEquals(2, CustomMetaTwo.DYNAMIC_CONSTANT);
-    assertUndefined(CustomMetaOne.DYNAMIC_CONSTANT);
+    JSUnit.assertEquals(2, CustomMetaTwo.DYNAMIC_CONSTANT);
+    JSUnit.assertUndefined(CustomMetaOne.DYNAMIC_CONSTANT);
 }
 
 function testMetaInstance() {
     let instanceOne = new CustomMetaOne();
 
-    assertEquals(1, instanceOne.one);
-    assertEquals(2, instanceOne.two);
+    JSUnit.assertEquals(1, instanceOne.one);
+    JSUnit.assertEquals(2, instanceOne.two);
 
-    assertRaises(function() {
+    JSUnit.assertRaises(function() {
         instanceOne.dynamic_method();
     });
 
     let instanceTwo = new CustomMetaTwo();
-    assertEquals(1, instanceTwo.one);
-    assertEquals(2, instanceTwo.two);
-    assertEquals(73, instanceTwo.dynamic_method());
+    JSUnit.assertEquals(1, instanceTwo.one);
+    JSUnit.assertEquals(2, instanceTwo.two);
+    JSUnit.assertEquals(73, instanceTwo.dynamic_method());
 }
 
 function testMetaSubclass() {
-    assertTrue(CustomMetaSubclass instanceof MetaClass);
+    JSUnit.assertTrue(CustomMetaSubclass instanceof MetaClass);
 
     let instance = new CustomMetaSubclass();
 
-    assertEquals(1, instance.one);
-    assertEquals(2, instance.two);
-    assertEquals(3, instance.three);
+    JSUnit.assertEquals(1, instance.one);
+    JSUnit.assertEquals(2, instance.two);
+    JSUnit.assertEquals(3, instance.three);
 
-    assertEquals(73, instance.dynamic_method());
-    assertEquals(2, CustomMetaSubclass.DYNAMIC_CONSTANT);
+    JSUnit.assertEquals(73, instance.dynamic_method());
+    JSUnit.assertEquals(2, CustomMetaSubclass.DYNAMIC_CONSTANT);
 }
 
-gjstestRun();
+JSUnit.gjstestRun(this, JSUnit.setUp, JSUnit.tearDown);
+
diff --git a/installed-tests/test/js/testParamSpec.js b/installed-tests/test/js/testParamSpec.js
new file mode 100644
index 0000000..d75867b
--- /dev/null
+++ b/installed-tests/test/js/testParamSpec.js
@@ -0,0 +1,96 @@
+// application/javascript;version=1.8
+const JSUnit = imports.jsUnit;
+
+const Regress = imports.gi.Regress;
+const GObject = imports.gi.GObject;
+
+let name = 'foo-property';
+let nick = 'Foo property';
+let blurb = 'This is the foo property';
+let flags = GObject.ParamFlags.READABLE;
+
+function testStringParamSpec() {
+    let stringSpec = GObject.ParamSpec.string(name, nick, blurb, flags,
+                                              'Default Value');
+
+    JSUnit.assertEquals(name, stringSpec.name);
+    JSUnit.assertEquals(nick, stringSpec._nick);
+    JSUnit.assertEquals(blurb, stringSpec._blurb);
+    JSUnit.assertEquals(flags, stringSpec.flags);
+    JSUnit.assertEquals('Default Value', stringSpec.default_value);
+}
+
+function testIntParamSpec() {
+    let intSpec = GObject.ParamSpec.int(name, nick, blurb, flags,
+                                        -100, 100, -42);
+
+    JSUnit.assertEquals(name, intSpec.name);
+    JSUnit.assertEquals(nick, intSpec._nick);
+    JSUnit.assertEquals(blurb, intSpec._blurb);
+    JSUnit.assertEquals(flags, intSpec.flags);
+    JSUnit.assertEquals(-42, intSpec.default_value);
+}
+
+function testUIntParamSpec() {
+    let uintSpec = GObject.ParamSpec.uint(name, nick, blurb, flags,
+                                          20, 100, 42);
+
+    JSUnit.assertEquals(name, uintSpec.name);
+    JSUnit.assertEquals(nick, uintSpec._nick);
+    JSUnit.assertEquals(blurb, uintSpec._blurb);
+    JSUnit.assertEquals(flags, uintSpec.flags);
+    JSUnit.assertEquals(42, uintSpec.default_value);
+}
+
+function testInt64ParamSpec() {
+    let int64Spec = GObject.ParamSpec.int64(name, nick, blurb, flags,
+                                            0x4000,
+                                            0xffffffff,
+                                            0x2266bbff);
+
+    JSUnit.assertEquals(name, int64Spec.name);
+    JSUnit.assertEquals(nick, int64Spec._nick);
+    JSUnit.assertEquals(blurb, int64Spec._blurb);
+    JSUnit.assertEquals(flags, int64Spec.flags);
+    JSUnit.assertEquals(0x2266bbff, int64Spec.default_value);
+}
+
+function testUInt64ParamSpec() {
+    let uint64Spec = GObject.ParamSpec.uint64(name, nick, blurb, flags,
+                                              0,
+                                              0xffffffff,
+                                              0x2266bbff);
+
+    JSUnit.assertEquals(name, uint64Spec.name);
+    JSUnit.assertEquals(nick, uint64Spec._nick);
+    JSUnit.assertEquals(blurb, uint64Spec._blurb);
+    JSUnit.assertEquals(flags, uint64Spec.flags);
+    JSUnit.assertEquals(0x2266bbff, uint64Spec.default_value);
+}
+
+function testEnumParamSpec() {
+    let enumSpec = GObject.ParamSpec.enum(name, nick, blurb, flags,
+                                          Regress.TestEnum,
+                                          Regress.TestEnum.VALUE2);
+
+    JSUnit.assertEquals(name, enumSpec.name);
+    JSUnit.assertEquals(nick, enumSpec._nick);
+    JSUnit.assertEquals(blurb, enumSpec._blurb);
+    JSUnit.assertEquals(flags, enumSpec.flags);
+    JSUnit.assertEquals(Regress.TestEnum.VALUE2, enumSpec.default_value);
+}
+
+function testFlagsParamSpec() {
+    let flagsSpec = GObject.ParamSpec.flags(name, nick, blurb, flags,
+                                            Regress.TestFlags,
+                                            Regress.TestFlags.FLAG2);
+
+    JSUnit.assertEquals(name, flagsSpec.name);
+    JSUnit.assertEquals(nick, flagsSpec._nick);
+    JSUnit.assertEquals(blurb, flagsSpec._blurb);
+    JSUnit.assertEquals(flags, flagsSpec.flags);
+    JSUnit.assertEquals(Regress.TestFlags.FLAG2, flagsSpec.default_value);
+}
+
+JSUnit.gjstestRun(this, JSUnit.setUp, JSUnit.tearDown);
+
diff --git a/test/js/testSignals.js b/installed-tests/test/js/testSignals.js
similarity index 75%
rename from test/js/testSignals.js
rename to installed-tests/test/js/testSignals.js
index d1f7aa3..e0f4c83 100644
--- a/test/js/testSignals.js
+++ b/installed-tests/test/js/testSignals.js
@@ -1,4 +1,5 @@
 // application/javascript;version=1.8
+const JSUnit = imports.jsUnit;
 const Signals = imports.signals;
 
 function Foo() {
@@ -20,14 +21,14 @@ function testSimple() {
                              theFoo.b = b;
                          });
     foo.emit('bar', "This is a", "This is b");
-    assertEquals("This is a", foo.a);
-    assertEquals("This is b", foo.b);
+    JSUnit.assertEquals("This is a", foo.a);
+    JSUnit.assertEquals("This is b", foo.b);
     foo.disconnect(id);
     // this emission should do nothing
     foo.emit('bar', "Another a", "Another b");
     // so these values should be unchanged
-    assertEquals("This is a", foo.a);
-    assertEquals("This is b", foo.b);
+    JSUnit.assertEquals("This is a", foo.a);
+    JSUnit.assertEquals("This is b", foo.b);
 }
 
 function testDisconnectDuringEmit() {
@@ -58,7 +59,7 @@ function testDisconnectDuringEmit() {
     foo.disconnect(firstId);
 
     // poke in private implementation to sanity-check
-    assertEquals('no handlers left', 0, foo._signalConnections.length);
+    JSUnit.assertEquals('no handlers left', 0, foo._signalConnections.length);
 }
 
 function testMultipleSignals() {
@@ -80,18 +81,18 @@ function testMultipleSignals() {
                 });
     foo.emit('bar');
 
-    assertEquals(2, foo.barHandlersCalled);
-    assertEquals(0, foo.bonkHandlersCalled);
+    JSUnit.assertEquals(2, foo.barHandlersCalled);
+    JSUnit.assertEquals(0, foo.bonkHandlersCalled);
 
     foo.emit('bonk');
 
-    assertEquals(2, foo.barHandlersCalled);
-    assertEquals(1, foo.bonkHandlersCalled);
+    JSUnit.assertEquals(2, foo.barHandlersCalled);
+    JSUnit.assertEquals(1, foo.bonkHandlersCalled);
 
     foo.emit('bar');
 
-    assertEquals(4, foo.barHandlersCalled);
-    assertEquals(1, foo.bonkHandlersCalled);
+    JSUnit.assertEquals(4, foo.barHandlersCalled);
+    JSUnit.assertEquals(1, foo.bonkHandlersCalled);
 
     foo.disconnectAll();
 
@@ -99,8 +100,8 @@ function testMultipleSignals() {
     foo.emit('bar');
     foo.emit('bonk');
 
-    assertEquals(4, foo.barHandlersCalled);
-    assertEquals(1, foo.bonkHandlersCalled);
+    JSUnit.assertEquals(4, foo.barHandlersCalled);
+    JSUnit.assertEquals(1, foo.bonkHandlersCalled);
 }
 
 function testExceptionInCallback() {
@@ -120,13 +121,14 @@ function testExceptionInCallback() {
 
     // exception in callback does not effect other callbacks
     foo.emit('bar');
-    assertEquals(1, foo.bar1Called);
-    assertEquals(1, foo.bar2Called);
+    JSUnit.assertEquals(1, foo.bar1Called);
+    JSUnit.assertEquals(1, foo.bar2Called);
 
     // exception in callback does not disconnect the callback
     foo.emit('bar');
-    assertEquals(2, foo.bar1Called);
-    assertEquals(2, foo.bar2Called);
+    JSUnit.assertEquals(2, foo.bar1Called);
+    JSUnit.assertEquals(2, foo.bar2Called);
 }
 
-gjstestRun();
+JSUnit.gjstestRun(this, JSUnit.setUp, JSUnit.tearDown);
+
diff --git a/installed-tests/test/js/testSystem.js b/installed-tests/test/js/testSystem.js
new file mode 100644
index 0000000..f87a325
--- /dev/null
+++ b/installed-tests/test/js/testSystem.js
@@ -0,0 +1,15 @@
+// application/javascript;version=1.8
+
+const JSUnit = imports.jsUnit;
+const System = imports.system;
+
+function testAddressOf() {
+    let o1 = new Object();
+    let o2 = new Object();
+
+    JSUnit.assert(System.addressOf(o1) == System.addressOf(o1));
+    JSUnit.assert(System.addressOf(o1) != System.addressOf(o2));
+}
+
+JSUnit.gjstestRun(this, JSUnit.setUp, JSUnit.tearDown);
+
diff --git a/test/js/testTweener.js b/installed-tests/test/js/testTweener.js
similarity index 82%
rename from test/js/testTweener.js
rename to installed-tests/test/js/testTweener.js
index 6761875..72c3f93 100644
--- a/test/js/testTweener.js
+++ b/installed-tests/test/js/testTweener.js
@@ -1,4 +1,5 @@
 // application/javascript;version=1.8
+const JSUnit = imports.jsUnit;
 const Tweener = imports.tweener.tweener;
 const Mainloop = imports.mainloop;
 
@@ -60,13 +61,13 @@ function testSimpleTween() {
     Mainloop.run('testTweener');
 
     with (objectA) {
-        assertEquals("A: x coordinate", 10, x);
-        assertEquals("A: y coordinate", 10, y);
+        JSUnit.assertEquals("A: x coordinate", 10, x);
+        JSUnit.assertEquals("A: y coordinate", 10, y);
     }
 
     with (objectB) {
-        assertEquals("B: x coordinate", 5, x);
-        assertEquals("B: y coordinate", 5, y);
+        JSUnit.assertEquals("B: x coordinate", 5, x);
+        JSUnit.assertEquals("B: y coordinate", 5, y);
     }
 }
 
@@ -92,9 +93,9 @@ function testOnFunctions() {
     Mainloop.run('testOnFunctions');
 
     with (object) {
-        assertEquals("onStart was run", true, start);
-        assertEquals("onUpdate was run", true, update);
-        assertEquals("onComplete was run", true, complete);
+        JSUnit.assertEquals("onStart was run", true, start);
+        JSUnit.assertEquals("onUpdate was run", true, update);
+        JSUnit.assertEquals("onComplete was run", true, complete);
     }
 }
 
@@ -116,7 +117,7 @@ function testPause() {
     Tweener.addTween(objectB, { bar: 100, time: 0.1,
                                onComplete: function() { Mainloop.quit('testPause');}});
     Tweener.pauseTweens(objectA);
-    assertEquals(false, Tweener.pauseTweens(objectB, "quux")); // This should do nothing
+    JSUnit.assertEquals(false, Tweener.pauseTweens(objectB, "quux")); // This should do nothing
 
     /* Pause and resume should be equal to doing nothing */
     Tweener.pauseTweens(objectC, "baaz");
@@ -125,15 +126,15 @@ function testPause() {
     Mainloop.run('testPause');
 
     with (objectA) {
-        assertEquals(0, foo);
+        JSUnit.assertEquals(0, foo);
     }
 
     with (objectB) {
-        assertEquals(100, bar);
+        JSUnit.assertEquals(100, bar);
     }
 
     with (objectC) {
-        assertEquals(100, baaz);
+        JSUnit.assertEquals(100, baaz);
     }
 }
 
@@ -154,9 +155,9 @@ function testRemoveTweens() {
     Mainloop.run('testRemoveTweens');
 
     with (object) {
-        assertEquals(50, foo);
-        assertEquals(0, bar);
-        assertEquals(0, baaz);
+        JSUnit.assertEquals(50, foo);
+        JSUnit.assertEquals(0, bar);
+        JSUnit.assertEquals(0, baaz);
     }
 }
 
@@ -187,11 +188,11 @@ function testConcurrent() {
     Mainloop.run('testConcurrent');
 
     with (objectA) {
-        assertEquals(0, foo);
+        JSUnit.assertEquals(0, foo);
     }
 
     with (objectB) {
-        assertEquals(150, bar);
+        JSUnit.assertEquals(150, bar);
     }
 }
 
@@ -217,11 +218,11 @@ function testPauseAllResumeAll() {
     Mainloop.run('testPauseAllResumeAll');
 
     with (objectA) {
-        assertEquals(100, foo);
+        JSUnit.assertEquals(100, foo);
     }
 
     with (objectB) {
-        assertEquals(100, bar);
+        JSUnit.assertEquals(100, bar);
     }
 }
 
@@ -240,8 +241,8 @@ function testRemoveAll() {
 
     Mainloop.timeout_add(200,
                         function () {
-                            assertEquals(0, objectA.foo);
-                            assertEquals(0, objectB.bar);
+                            JSUnit.assertEquals(0, objectA.foo);
+                            JSUnit.assertEquals(0, objectB.bar);
                             Mainloop.quit('testRemoveAll');
                             return false;
                         });
@@ -258,7 +259,7 @@ function testImmediateTween() {
     Tweener.addTween(object, { foo: 200, time: 0.1,
                                onStart: function () {
                                    /* The immediate tween should set it to 50 before we run */
-                                   assertEquals(50, object.foo);
+                                   JSUnit.assertEquals(50, object.foo);
                                },
                                onComplete: function () {
                                    Mainloop.quit('testImmediateTween');
@@ -267,7 +268,7 @@ function testImmediateTween() {
     Mainloop.run('testImmediateTween');
 
     with (object) {
-        assertEquals(200, foo);
+        JSUnit.assertEquals(200, foo);
     }
 }
 
@@ -288,7 +289,7 @@ function testAddCaller() {
     Mainloop.run('testAddCaller');
 
     with (object) {
-        assertEquals(10, foo);
+        JSUnit.assertEquals(10, foo);
     }
 }
 
@@ -300,26 +301,26 @@ function testGetTweenCount() {
         quux: 0
     };
 
-    assertEquals(0, Tweener.getTweenCount(object));
+    JSUnit.assertEquals(0, Tweener.getTweenCount(object));
 
     Tweener.addTween(object, { foo: 100, time: 0.1 });
-    assertEquals(1, Tweener.getTweenCount(object));
+    JSUnit.assertEquals(1, Tweener.getTweenCount(object));
     Tweener.addTween(object, { bar: 100, time: 0.1 });
-    assertEquals(2, Tweener.getTweenCount(object));
+    JSUnit.assertEquals(2, Tweener.getTweenCount(object));
     Tweener.addTween(object, { baaz: 100, time: 0.1 });
-    assertEquals(3, Tweener.getTweenCount(object));
+    JSUnit.assertEquals(3, Tweener.getTweenCount(object));
     Tweener.addTween(object, { quux: 100, time: 0.1,
                                onComplete: function () {
                                    Mainloop.quit('testGetTweenCount');}});
-    assertEquals(4, Tweener.getTweenCount(object));
+    JSUnit.assertEquals(4, Tweener.getTweenCount(object));
 
     Tweener.removeTweens(object, "bar", "baaz");
 
-    assertEquals(2, Tweener.getTweenCount(object));
+    JSUnit.assertEquals(2, Tweener.getTweenCount(object));
 
     Mainloop.run('testGetTweenCount');
 
-    assertEquals(0, Tweener.getTweenCount(object));
+    JSUnit.assertEquals(0, Tweener.getTweenCount(object));
 }
 
 Tweener.registerSpecialProperty(
@@ -341,8 +342,8 @@ function testSpecialProperty() {
     Mainloop.run('testSpecialProperty');
 
     with (objectA) {
-        assertEquals("A: x coordinate", -10, x);
-        assertEquals("A: y coordinate", 10, y);
+        JSUnit.assertEquals("A: x coordinate", -10, x);
+        JSUnit.assertEquals("A: y coordinate", 10, y);
     }
 }
 
@@ -378,10 +379,10 @@ function testSpecialPropertyModifier() {
     Mainloop.run('testSpecialPropertyModifier');
 
     with (objectA) {
-        assertEquals("A: x coordinate", 10, x);
-        assertEquals("A: y coordinate", 10, y);
-        assertEquals("A: x was fractional", false, xFraction);
-        assertEquals("A: y was fractional", true, yFraction);
+        JSUnit.assertEquals("A: x coordinate", 10, x);
+        JSUnit.assertEquals("A: y coordinate", 10, y);
+        JSUnit.assertEquals("A: x was fractional", false, xFraction);
+        JSUnit.assertEquals("A: y was fractional", true, yFraction);
     }
 }
 
@@ -404,11 +405,12 @@ function testSpecialPropertySplitter() {
     Mainloop.run('testSpecialPropertySplitter');
 
     with (objectA) {
-        assertEquals("A: x coordinate", 10, x);
-        assertEquals("A: y coordinate", -10, y);
+        JSUnit.assertEquals("A: x coordinate", 10, x);
+        JSUnit.assertEquals("A: y coordinate", -10, y);
     }
 }
 
 installFrameTicker();
-gjstestRun();
+JSUnit.gjstestRun(this, JSUnit.setUp, JSUnit.tearDown);
+
 
diff --git a/installed-tests/test/js/testUnicode.js b/installed-tests/test/js/testUnicode.js
new file mode 100644
index 0000000..4d43b07
--- /dev/null
+++ b/installed-tests/test/js/testUnicode.js
@@ -0,0 +1,14 @@
+// application/javascript;version=1.8
+const JSUnit = imports.jsUnit;
+
+function testUnicode() {
+    JSUnit.assertEquals(6, 'Погода'.length);
+    JSUnit.assertEquals(1055, 'Погода'.charCodeAt(0));
+    JSUnit.assertEquals(1086, 'Погода'.charCodeAt(3));
+    JSUnit.assertEquals("\u65e5", "日本語".charAt(0));
+    JSUnit.assertEquals("\u672c", "日本語".charAt(1));
+    JSUnit.assertEquals("\u8a9e", "日本語".charAt(2));
+}
+
+JSUnit.gjstestRun(this, JSUnit.setUp, JSUnit.tearDown);
+
diff --git a/installed-tests/test/js/testself.js b/installed-tests/test/js/testself.js
new file mode 100644
index 0000000..4da9690
--- /dev/null
+++ b/installed-tests/test/js/testself.js
@@ -0,0 +1,38 @@
+// application/javascript;version=1.8
+const JSUnit = imports.jsUnit;
+
+var someUndefined;
+var someNumber = 1;
+var someOtherNumber = 42;
+var someString = "hello";
+var someOtherString = "world";
+
+JSUnit.assert(true);
+JSUnit.assertTrue(true);
+JSUnit.assertFalse(false);
+
+JSUnit.assertEquals(someNumber, someNumber);
+JSUnit.assertEquals(someString, someString);
+
+JSUnit.assertNotEquals(someNumber, someOtherNumber);
+JSUnit.assertNotEquals(someString, someOtherString);
+
+JSUnit.assertNull(null);
+JSUnit.assertNotNull(someNumber);
+JSUnit.assertUndefined(someUndefined);
+JSUnit.assertNotUndefined(someNumber);
+JSUnit.assertNaN(0/0);
+JSUnit.assertNotNaN(someNumber);
+
+// test assertRaises()
+JSUnit.assertRaises(function() { throw new Object(); });
+try {   // calling assertRaises with non-function is an error, not assertion failure
+    JSUnit.assertRaises(true);
+} catch(e) {
+    JSUnit.assertUndefined(e.isJsUnitException);
+}
+try {   // function not throwing an exception is assertion failure
+    JSUnit.assertRaises(function() { return true; });
+} catch(e) {
+    JSUnit.assertTrue(e.isJsUnitException);
+}
diff --git a/test/unittest.gdb b/installed-tests/test/unittest.gdb
similarity index 100%
rename from test/unittest.gdb
rename to installed-tests/test/unittest.gdb


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