diff options
author | Philip Chimento <philip@endlessm.com> | 2013-09-05 17:21:25 -0700 |
---|---|---|
committer | Philip Chimento <philip@endlessm.com> | 2013-09-16 10:30:42 -0700 |
commit | d88e6674fd6fcad3bdd841c75c81fec1815615c8 (patch) | |
tree | e8ee2e9d1a99479d859831b1c7dc436def2cb34d | |
parent | 1c4bc890875ee5e7edad81fd6a8b5644058e936d (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-- | .gitignore | 1 | ||||
-rw-r--r-- | Makefile.am | 11 | ||||
-rw-r--r-- | configure.ac | 1 | ||||
-rw-r--r-- | test/Makefile.am | 5 | ||||
-rw-r--r-- | test/tools/eos-run-test/sanitycheck.js | 3 | ||||
-rw-r--r-- | tools/Makefile.am.inc | 3 | ||||
-rw-r--r-- | tools/eos-run-test.in | 150 |
7 files changed, 173 insertions, 1 deletions
@@ -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); +} |