summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilip Chimento <philip@endlessm.com>2013-09-05 17:21:25 -0700
committerPhilip Chimento <philip@endlessm.com>2013-09-16 10:30:42 -0700
commitd88e6674fd6fcad3bdd841c75c81fec1815615c8 (patch)
treee8ee2e9d1a99479d859831b1c7dc436def2cb34d
parent1c4bc890875ee5e7edad81fd6a8b5644058e936d (diff)
First attempt at an EOS test runner
This adds a script eos-run-test which is adapted from gjs_run_tests, but does not try to discover the tests itself. Instead, in keeping with Automake's test suite facilities, it takes the filename of a test to run. [endlessm/eos-sdk#290]
-rw-r--r--.gitignore1
-rw-r--r--Makefile.am11
-rw-r--r--configure.ac1
-rw-r--r--test/Makefile.am5
-rw-r--r--test/tools/eos-run-test/sanitycheck.js3
-rw-r--r--tools/Makefile.am.inc3
-rw-r--r--tools/eos-run-test.in150
7 files changed, 173 insertions, 1 deletions
diff --git a/.gitignore b/.gitignore
index 73220f3..5f1f7aa 100644
--- a/.gitignore
+++ b/.gitignore
@@ -8,6 +8,7 @@ endless/eosresource.c
endless/eosresource-private.h
data/eos-wikipedia-domain.gresource
wikipedia/config.js
+tools/eos-run-test
*.py[cod]
diff --git a/Makefile.am b/Makefile.am
index feee832..b2dce68 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -146,6 +146,10 @@ gjsoverridedir = ${datadir}/gjs-1.0/overrides
dist_gjsoverride_DATA = \
overrides/Endless.js
+# # # SDK TOOLS # # #
+
+include $(top_srcdir)/tools/Makefile.am.inc
+
# # # INSTALLED M4 MACROS # # #
m4dir = ${datadir}/aclocal
@@ -158,6 +162,11 @@ m4_DATA = \
include $(top_srcdir)/test/Makefile.am
# Run tests when running 'make check'
-TESTS = test/run-tests
+TESTS = \
+ test/run-tests \
+ test/tools/eos-run-test/sanitycheck.js \
+ $(NULL)
+TEST_EXTENSIONS = .js
+JS_LOG_COMPILER = tools/eos-run-test
LOG_COMPILER = gtester
AM_LOG_FLAGS = -k --verbose
diff --git a/configure.ac b/configure.ac
index eb450a6..a74e3e0 100644
--- a/configure.ac
+++ b/configure.ac
@@ -210,6 +210,7 @@ AC_CONFIG_FILES([
docs/reference/endless/version.xml
$EOS_SDK_API_NAME.pc
])
+AC_CONFIG_FILES([tools/eos-run-test], [chmod +x tools/eos-run-test])
AC_CONFIG_HEADERS([config.h]) dnl Header with system-dependent #defines
# Do the output
AC_OUTPUT
diff --git a/test/Makefile.am b/test/Makefile.am
index b4217c1..dcf6ee4 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -24,3 +24,8 @@ test_run_tests_LDADD = $(TEST_LIBS)
test_smoke_tests_hello_SOURCES = test/smoke-tests/hello.c
test_smoke_tests_hello_CPPFLAGS = $(TEST_FLAGS)
test_smoke_tests_hello_LDADD = $(TEST_LIBS)
+
+javascript_tests = \
+ test/tools/eos-run-test/sanitycheck.js \
+ $(NULL)
+EXTRA_DIST += $(javascript_tests)
diff --git a/test/tools/eos-run-test/sanitycheck.js b/test/tools/eos-run-test/sanitycheck.js
new file mode 100644
index 0000000..4bb3a80
--- /dev/null
+++ b/test/tools/eos-run-test/sanitycheck.js
@@ -0,0 +1,3 @@
+function testNothing() {
+ assertEquals(2, 2);
+} \ No newline at end of file
diff --git a/tools/Makefile.am.inc b/tools/Makefile.am.inc
new file mode 100644
index 0000000..1a790ce
--- /dev/null
+++ b/tools/Makefile.am.inc
@@ -0,0 +1,3 @@
+# Copyright 2013 Endless Mobile, Inc.
+
+bin_SCRIPTS = tools/eos-run-test
diff --git a/tools/eos-run-test.in b/tools/eos-run-test.in
new file mode 100644
index 0000000..888e53b
--- /dev/null
+++ b/tools/eos-run-test.in
@@ -0,0 +1,150 @@
+#!/usr/bin/gjs
+const Format = imports.format;
+const Gio = imports.gi.Gio;
+const GLib = imports.gi.GLib;
+const JsUnit = imports.jsUnit;
+const Lang = imports.lang;
+const System = imports.system;
+
+String.prototype.format = Format.format;
+// Monkeypatch System.programInvocationName if not in this version of GJS
+if(!('programInvocationName' in System))
+ System.programInvocationName = 'eos-run-test';
+
+const PACKAGE_VERSION = '@PACKAGE_VERSION@';
+const JS_EXTENSION = '.js';
+
+/**
+ * usage:
+ *
+ * Print command-line help message.
+ */
+function usage() {
+ print('Run a jsUnit unit test.\n');
+ print('Usage: %s [options] TEST_FILES\n'.format(
+ System.programInvocationName));
+ print('Options:');
+ print(' --help This help message');
+ print(' --version Print version and exit');
+ throw(0); // FIXME System.exit(0);
+}
+
+/**
+ * version:
+ *
+ * Print command-line version output.
+ */
+function version() {
+ print('%s %s - Discover unit tests in a source tree'.format(
+ System.programInvocationName, PACKAGE_VERSION));
+ throw(0); // FIXME System.exit(0);
+}
+
+if(ARGV.indexOf('--help') != -1)
+ usage();
+if(ARGV.indexOf('--version') != -1)
+ version();
+if(ARGV.length < 1)
+ usage();
+
+// Import JsUnit into global namespace
+if(!('assertEquals' in this))
+ Lang.copyPublicProperties(JsUnit, this);
+
+function printError(error) {
+ const SYNTAX_ERROR = '[object Error]';
+ print(" " + error.message);
+
+ if(error.stackTrace) {
+ let stackTrace = error.stackTrace.split('\n');
+ stackTrace.forEach(function(line) {
+ if(line.length > 0){
+ let prefix = ' --';
+ if (error.type == SYNTAX_ERROR)
+ prefix += '> ';
+
+ print(prefix + line);
+ }
+ });
+ }
+}
+
+function executeTest(testModule, test) {
+ let result = { name: test };
+ print("Running:", test);
+ if(testModule.setUp) {
+ testModule.setUp();
+ }
+ let startTime = GLib.get_real_time();
+ try {
+ testModule[test]();
+ } catch(e) {
+ print(" ERROR! >>>>>", test, "<<<<<");
+
+ result.error = {
+ type: Object.toString(e),
+ message: e.message || e.jsUnitMessage,
+ stackTrace: e.stack || e.stackTrace
+ };
+ printError(result.error);
+ print('\n');
+ } finally {
+ if(testModule.tearDown) {
+ testModule.tearDown();
+ }
+ }
+
+ result.time = GLib.get_real_time() - startTime;
+ return result;
+}
+
+function executeTestsForFile(file) {
+ let testFile = file.get_basename();
+ let testModuleName = testFile.slice(0, testFile.indexOf('.js'));
+ print('File:', testFile);
+ let oldSearchPath = imports.searchPath;
+ imports.searchPath.unshift(file.get_parent().get_path());
+ let testModule = imports[testModuleName];
+ imports.searchPath = oldSearchPath;
+
+ let results = [];
+ Object.keys(testModule).forEach(function(key) {
+ if(key.indexOf('test') === 0) {
+ results.push(executeTest(testModule, key));
+ }
+ });
+
+ return results;
+}
+
+function getTotalsFromResults(results) {
+ let testsRunCount = 0;
+ let testsFailedCount = 0;
+ let testsPassedCount = 0;
+
+ results.forEach(function(result) {
+ if ('error' in result) {
+ testsFailedCount++;
+ }
+ testsRunCount++;
+ });
+
+ testsPassedCount = testsRunCount - testsFailedCount;
+ return {
+ testsRunCount: testsRunCount,
+ testsFailedCount: testsFailedCount,
+ testsPassedCount: testsPassedCount
+ };
+}
+
+let fileToTest = Gio.File.new_for_path(ARGV[0]);
+let results = executeTestsForFile(fileToTest);
+let totals = getTotalsFromResults(results);
+let totalsString = "Ran %d tests (%d Passed, %d Failed)".format(
+ totals.testsRunCount, totals.testsPassedCount, totals.testsFailedCount);
+print(totalsString);
+
+if (totals.testsFailedCount > 0){
+ printerr("Test(s) did not complete successfully");
+ throw(1); // FIXME System.exit(1);
+}