#!/usr/bin/env 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; 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'); System.exit(0); } /** * version: * * Print command-line version output. */ function version() { print('%s %s - Run jsUnit tests in a GJS source file'.format( System.programInvocationName, PACKAGE_VERSION)); 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"); System.exit(1); }