diff --git a/duktape.js b/duktape.js index d8bc82f7c..620783570 100644 --- a/duktape.js +++ b/duktape.js @@ -8,7 +8,6 @@ * $ node duktape.js */ -var fs = require('fs'); var child_process = require('child_process'); var runner_support = require('./runner_support'); @@ -28,23 +27,16 @@ var dukKey = (function () { })(); console.log('Duktape result key is: test.res.' + dukKey); -function runTest(evalcode) { - var script = 'var evalcode = ' + JSON.stringify(evalcode) + ';\n' + - 'try {\n' + - ' var res = eval(evalcode);\n' + - ' if (res !== true && res !== 1) { throw new Error("failed: " + res); }\n' + - ' console.log("[SUCCESS]");\n' + - '} catch (e) {\n' + - ' console.log("[FAILURE]", e);\n' + - ' /*throw e;*/\n' + - '}\n'; +function dukRunner(testFilename) { + try { + var stdout = child_process.execFileSync(dukCommand, [ testFilename ], { + encoding: 'utf-8' + }); - fs.writeFileSync('duktest.js', script); - var stdout = child_process.execFileSync(dukCommand, [ 'duktest.js' ], { - encoding: 'utf-8' - }); - - return /^\[SUCCESS\]$/gm.test(stdout); + return /^\[SUCCESS\]$/m.test(stdout); + } catch (e) { + return false; + } } -runner_support.runTests(runTest, dukKey, 'Duktape'); \ No newline at end of file +runner_support.runTests(dukRunner, dukKey, 'Duktape'); \ No newline at end of file diff --git a/graalvm.js b/graalvm.js index 44ab92aa8..370e32d70 100644 --- a/graalvm.js +++ b/graalvm.js @@ -16,47 +16,21 @@ * $ GRAALVM_NODE=/bin/node node graalvm.js */ -var fs = require('fs'); var child_process = require('child_process'); var runner_support = require('./runner_support'); var jsCommand = 'js'; var jsArgs = [ '--js.intl-402' ]; -var nodeCommand = process.env['GRAALVM_NODE']; -var nodeArgs = []; - -var testScriptFilename = 'graalvmtest.js'; var flagsForSuite = { - 'data-es5': [], - 'data-es6': [ [ '--js.ecmascript-version=6' ] ], - 'data-es2016plus': [ [ '--js.ecmascript-version=staging' ] ], - 'data-esnext': [ [ '--js.ecmascript-version=staging' ], [ '--experimental-options', '--js.new-set-methods' ] ], - 'data-esintl': [], - 'data-non-standard': [ [ '--experimental-options', '--js.nashorn-compat' ], [ '--experimental-options', '--js.v8-compat' ], [ '--experimental-options', '--js.global-property' ] ] + 'es5': [], + 'es6': [ [ '--js.ecmascript-version=6' ] ], + 'es2016plus': [ [ '--js.ecmascript-version=staging' ] ], + 'esnext': [ [ '--js.ecmascript-version=staging' ], [ '--experimental-options', '--js.new-set-methods' ] ], + 'esintl': [], + 'non-standard': [ [ '--experimental-options', '--js.nashorn-compat' ], [ '--experimental-options', '--js.v8-compat' ], [ '--experimental-options', '--js.global-property' ] ] }; -var prelude = - 'if (typeof global === "undefined") {\n' + - ' this.lacksGlobal = true;\n' + - ' global = this;\n' + - '}\n' + - 'if (typeof globalThis === "undefined") {\n' + - ' this.lacksGlobalThis = true;\n' + - ' globalThis = this;\n' + - '}\n' + - 'var __script_executed = {};\n' + - 'global.__script_executed = __script_executed;\n' + - 'global.test = function test(expression) {\n' + - ' if (expression) {\n' + - ' console.log("[SUCCESS]");\n' + - ' }\n' + - '}\n' + - 'global.asyncTestPassed = function asyncTestPassed() {\n' + - ' console.log("[SUCCESS]");\n' + - '}\n' + - runner_support.createIterableHelper; - // Key for .res (e.g. test.res.graalvm), automatic based on GraalVM version. var graalvmKey = (function () { var stdout = child_process.execFileSync(jsCommand, [ '--version' ], { @@ -69,9 +43,9 @@ var graalvmKey = (function () { })(); console.log('GraalVM result key is: test.res.graalvm' + graalvmKey); -function exec(launcherCommand, launcherArgs, flags) { +function exec(flags, testFilename) { try { - var stdout = child_process.execFileSync(launcherCommand, launcherArgs.concat(flags, [ testScriptFilename ]), { + var stdout = child_process.execFileSync(jsCommand, jsArgs.concat(flags, [ testFilename ]), { encoding: 'utf-8', stdio: ['ignore', 'pipe', 'ignore'] }); @@ -82,14 +56,14 @@ function exec(launcherCommand, launcherArgs, flags) { } } -function executeTestScript(launcherCommand, launcherArgs, suite) { - if (exec(launcherCommand, launcherArgs, [])) { +function graalvmRunner(testFilename, suite) { + if (exec([], testFilename)) { return true; } for (var i = 0; i < flagsForSuite[suite].length; i++) { var flags = flagsForSuite[suite][i]; - if (exec(launcherCommand, launcherArgs, flags)) { + if (exec(flags, testFilename)) { return { val: 'flagged', note_id: ('graalvm-' + flags.join('-')).replace(/[=\.]/g, '-').replace(/-+/g, '-'), @@ -101,29 +75,6 @@ function executeTestScript(launcherCommand, launcherArgs, suite) { return false; } -function runTest(evalcode, suite, testPath) { - if (/\bsetTimeout\b/.test(evalcode) && !nodeCommand) { - console.log(testPath + ': could not run test using setTimeout (set GRAALVM_NODE to GraalVM\'s `node` binary and rerun to get results)'); - return 'skip'; - } - - var script = - prelude + '\n' + - 'var evalcode = ' + JSON.stringify(evalcode) + ';\n' + - 'var result = eval(evalcode);\n' + - 'if (result) {\n' + - ' console.log("[SUCCESS]");\n' + - '}\n'; - - fs.writeFileSync(testScriptFilename, script); - - if (evalcode.match(/\bsetTimeout\b/)) { - return executeTestScript(nodeCommand, nodeArgs, suite); - } else { - return executeTestScript(jsCommand, jsArgs, suite); - } -} - function resultsMatch(expect, actual) { if (expect === actual) { return true; @@ -134,4 +85,4 @@ function resultsMatch(expect, actual) { return false; } -runner_support.runTests(runTest, graalvmKey, 'GraalVM', { resultsMatch: resultsMatch }); \ No newline at end of file +runner_support.runTests(graalvmRunner, graalvmKey, 'GraalVM', { resultsMatch: resultsMatch }); \ No newline at end of file diff --git a/hermes.js b/hermes.js index 97c246226..260da7cd5 100644 --- a/hermes.js +++ b/hermes.js @@ -9,7 +9,6 @@ * suitename can be 'all' */ -var fs = require('fs'); var child_process = require('child_process'); var console = require('console'); var runner_support = require('./runner_support'); @@ -47,7 +46,6 @@ var argv = require('yargs/yargs')(process.argv.slice(2)) var hermesCommand = argv.hermesBin; var suites = argv.suite; suites = suites === 'all' ? '' : suites; -var testName = argv.testName; // Key for .res (e.g. test.res.hermes0_7_0), automatic based on `hermes -version`. var hermesKey = (function () { @@ -63,63 +61,6 @@ var hermesKey = (function () { })(); console.log('Hermes result key is: test.res.' + hermesKey); -var asyncTestHelperHead = -'var asyncPassed = false;\n' + -'\n' + -'function asyncTestPassed() {\n' + -' asyncPassed = true;\n' + -'}\n' + -'\n' + -'function setTimeout(cb, time, cbarg) {\n' + -' if (!jobqueue[time]) {\n' + -' jobqueue[time] = [];\n' + -' }\n' + -' jobqueue[time].push({cb, cbarg, startTime: Date.now(), timeout: time});\n' + -'}\n' + -'\n' + -'var jobqueue = [];\n'; - -var asyncTestHelperTail = -'const thenCb = job => {\n' + -' job.cb(job.cbarg)\n' + -'}\n' + -'\n' + -'const catchCb = job => {\n' + -' jobRunner(job);\n' + -'}\n' + -'\n' + -'function jobRunner(job){\n' + -' return new Promise((resolve, reject) => {\n' + -' let diff = Date.now() - job.startTime;\n' + -' if (diff >= job.timeout) {\n' + -' if (!job.run) {\n' + -' job.run = true;\n' + -' resolve (job);\n' + -' }\n' + -' } else {\n' + -' reject (job)\n' + -' }\n' + -' })\n' + -' .then(thenCb)\n' + -' .catch(catchCb)\n' + -'}\n' + -'\n' + -'jobqueue.forEach(function(jobs, index) {\n' + -' for (var job of jobs) {\n' + -' jobRunner(job);\n' + -' }\n' + -'});\n' + -'\n' + -'function onCloseAsyncCheck() {\n' + -' if (!asyncPassed) {\n' + -' print("Async[FAILURE]");\n' + -' throw "Async check failed";\n' + -' }\n' + -' print("[SUCCESS]");\n' + -'}\n' + -'\n' + -'Promise.resolve().then(onCloseAsyncCheck);\n'; - function getArgs(testFilename) { var processArgs = [ /*'-enable-eval',*/ @@ -146,39 +87,15 @@ function getArgs(testFilename) { return processArgs; } -function runTest(evalcode) { - var testFilename = 'hermestest.js'; +function hermesRunner(testFilename) { var processArgs = getArgs(testFilename); - var script = ''; - - if (evalcode.includes('__createIterableObject')) { - script += runner_support.createIterableHelper; - } else if (evalcode.includes('global')) { - script += 'var global = this;\n'; - } - - if (evalcode.includes('asyncTestPassed')) { - script += asyncTestHelperHead + evalcode + asyncTestHelperTail; - } else { - script += 'var evalcode = ' + JSON.stringify(evalcode) + ';\n' + - 'try {\n' + - ' var res = eval(evalcode);\n' + - ' if (!res) { throw new Error("failed: " + res); }\n' + - ' print("[SUCCESS]");\n' + - '} catch (e) {\n' + - ' print("[FAILURE]", e);\n' + - ' /*throw e;*/\n' + - '}\n'; - } - - fs.writeFileSync(testFilename, script); try { var stdout = child_process.execFileSync(hermesCommand, processArgs, { encoding: 'utf-8' }); - return /^\[SUCCESS\]$/gm.test(stdout); + return /^\[SUCCESS\]$/m.test(stdout); } catch (e) { // console.log(e); return false; @@ -206,4 +123,4 @@ function resultsMatch(expect, actual) { return expect === actual; } -runner_support.runTests(runTest, hermesKey, 'Hermes', { resultsMatch: resultsMatch, suites: suites, testName: testName, bail: argv.bail }); \ No newline at end of file +runner_support.runTests(hermesRunner, hermesKey, 'Hermes', { resultsMatch: resultsMatch, suites: suites, testName: argv.testName, bail: argv.bail }); \ No newline at end of file diff --git a/jerryscript.js b/jerryscript.js index ac64954a4..a7c032b67 100644 --- a/jerryscript.js +++ b/jerryscript.js @@ -7,7 +7,6 @@ * $ node jerryscript.js /path/to/jerry [suitename] */ -var fs = require('fs'); var child_process = require('child_process'); var console = require('console'); var runner_support = require('./runner_support'); @@ -30,100 +29,18 @@ var jerryKey = (function () { console.log('JerryScript result key is: test.res.' + jerryKey); // jerryKey = "jerryscript2_4_0" // uncomment this line to test pre 2.4.0 -var asyncTestHelperHead = -'var asyncPassed = false;\n' + -'\n' + -'function asyncTestPassed() {\n' + -' asyncPassed = true;\n' + -'}\n' + -'\n' + -'function setTimeout(cb, time, cbarg) {\n' + -' if (!jobqueue[time]) {\n' + -' jobqueue[time] = [];\n' + -' }\n' + -' jobqueue[time].push({cb, cbarg, startTime: Date.now(), timeout: time});\n' + -'}\n' + -'\n' + -'var jobqueue = [];\n'; - -var asyncTestHelperTail = -'const thenCb = job => {\n' + -' job.cb(job.cbarg)\n' + -'}\n' + -'\n' + -'const catchCb = job => {\n' + -' jobRunner(job);\n' + -'}\n' + -'\n' + -'function jobRunner(job){\n' + -' return new Promise((resolve, reject) => {\n' + -' let diff = Date.now() - job.startTime;\n' + -' if (diff >= job.timeout) {\n' + -' if (!job.run) {\n' + -' job.run = true;\n' + -' resolve (job);\n' + -' }\n' + -' } else {\n' + -' reject (job)\n' + -' }\n' + -' })\n' + -' .then(thenCb)\n' + -' .catch(catchCb)\n' + -'}\n' + -'\n' + -'jobqueue.forEach(function(jobs, index) {\n' + -' for (var job of jobs) {\n' + -' jobRunner(job);\n' + -' }\n' + -'});\n' + -'\n' + -'function onCloseAsyncCheck() {\n' + -' if (!asyncPassed) {\n' + -' print("Async[FAILURE]");\n' + -' throw "Async check failed";\n' + -' }\n' + -' print("[SUCCESS]");\n' + -'}\n'; - -// Run test / subtests, recursively. Report results, indicate data files -// which are out of date. -function runTest(evalcode) { - var processArgs = ['jerrytest.js']; - var script = ''; - - if (evalcode.includes('__createIterableObject')) { - script += runner_support.createIterableHelper; - } else if (evalcode.includes('global')) { - script += 'var global = this;\n'; - } - - if (evalcode.includes('asyncTestPassed')) { - script += asyncTestHelperHead + '(function test() {' + evalcode + '})();' + asyncTestHelperTail; - processArgs.unshift('--call-on-exit','onCloseAsyncCheck'); - } else { - script += 'var evalcode = ' + JSON.stringify(evalcode) + ';\n' + - 'try {\n' + - ' var res = eval(evalcode);\n' + - ' if (!res) { throw new Error("failed: " + res); }\n' + - ' print("[SUCCESS]");\n' + - '} catch (e) {\n' + - ' print("[FAILURE]", e);\n' + - ' /*throw e;*/\n' + - '}\n'; - } - - fs.writeFileSync(processArgs[processArgs.length - 1], script); +function jerryRunner(testFilename) { try { - var stdout = child_process.execFileSync(jerryCommand, processArgs, { + var stdout = child_process.execFileSync(jerryCommand, [ testFilename ], { encoding: 'utf-8' }); //console.log(stdout); - return /^\[SUCCESS\]$/gm.test(stdout); + return /^\[SUCCESS\]$/m.test(stdout); } catch (e) { //console.log(e); return false; } } -runner_support.runTests(runTest, jerryKey, 'JerryScript', { suites: suites }); \ No newline at end of file +runner_support.runTests(jerryRunner, jerryKey, 'JerryScript', { suites: suites }); \ No newline at end of file diff --git a/nashorn.js b/nashorn.js index cdf70cf8d..68699fd85 100644 --- a/nashorn.js +++ b/nashorn.js @@ -40,23 +40,16 @@ var jjsKey = (function () { })(); console.log('jjs result key is: test.res.nashorn' + jjsKey); -function runTest(evalcode) { - var script = 'var evalcode = ' + JSON.stringify(evalcode) + ';\n' + - 'try {\n' + - ' var res = eval(evalcode);\n' + - ' if (res !== true && res !== 1) { throw new Error("failed: " + res); }\n' + - ' print("[SUCCESS]");\n' + - '} catch (e) {\n' + - ' print("[FAILURE] " + e);\n' + - ' /*throw e;*/\n' + - '}\n'; - - fs.writeFileSync('jjstest.js', script); - var stdout = child_process.execFileSync(jjsCommand, [ '--language=es6', 'jjstest.js' ], { - encoding: 'utf-8' - }); - - return /^\[SUCCESS\]$/gm.test(stdout); +function jjsRunner(testFilename) { + try { + var stdout = child_process.execFileSync(jjsCommand, [ '--language=es6', testFilename ], { + encoding: 'utf-8' + }); + + return /^\[SUCCESS\]$/m.test(stdout); + } catch (e) { + return false; + } } -runner_support.runTests(runTest, jjsKey, 'Nashorn'); \ No newline at end of file +runner_support.runTests(jjsRunner, jjsKey, 'Nashorn'); \ No newline at end of file diff --git a/rhino.js b/rhino.js index 0da481509..01756580b 100644 --- a/rhino.js +++ b/rhino.js @@ -36,8 +36,8 @@ var rhinoKey = (function () { var script = 'print(org.mozilla.javascript.ImplementationVersion.get());\n' + 'quit()\n'; - fs.writeFileSync('rhinotest.js', script); - var stdout = executeScript('rhinotest.js'); + fs.writeFileSync('rhinoversion.js', script); + var stdout = executeScript('rhinoversion.js'); console.log('rhino version is: ' + stdout); var match = stdout.match(/Rhino (\d+)\.(\d+)\.(\d+)/); @@ -45,21 +45,14 @@ var rhinoKey = (function () { })(); console.log('rhino result key is: test.res.rhino' + rhinoKey); -function runTest(evalcode) { - var script = 'var evalcode = ' + JSON.stringify(evalcode) + ';\n' + - 'try {\n' + - ' var res = eval(evalcode);\n' + - ' if (res !== true && res !== 1) { throw new Error("failed: " + res); }\n' + - ' print("[SUCCESS]");\n' + - '} catch (e) {\n' + - ' print("[FAILURE] " + e);\n' + - ' /*throw e;*/\n' + - '}\n'; +function rhinoRunner(testFilename) { + try { + var stdout = executeScript(testFilename); - fs.writeFileSync('rhinotest.js', script); - var stdout = executeScript('rhinotest.js'); - - return /^\[SUCCESS\]$/gm.test(stdout); + return /^\[SUCCESS\]$/m.test(stdout); + } catch (e) { + return false; + } } -runner_support.runTests(runTest, rhinoKey, 'Rhino'); \ No newline at end of file +runner_support.runTests(rhinoRunner, rhinoKey, 'Rhino'); \ No newline at end of file diff --git a/runner_support.js b/runner_support.js index 03e89551a..9f308b5f6 100644 --- a/runner_support.js +++ b/runner_support.js @@ -1,26 +1,25 @@ var fs = require('fs'); exports.createIterableHelper = -'if (typeof global === "undefined") {\n' + -' global = this;\n' + -'}\n' + -'global.__createIterableObject = function __createIterableObject(arr, methods) {\n' + +'function __createIterableObject(arr, methods) {\n' + ' methods = methods || {};\n' + ' if (typeof Symbol !== "function" || !Symbol.iterator)\n' + -' return {};\n' + +' return {};\n' + ' arr.length++;\n' + ' var iterator = {\n' + -' next: function() {\n' + -' return { value: arr.shift(), done: arr.length <= 0 };\n' + -' },\n' + -' "return": methods["return"],\n' + -' "throw": methods["throw"]\n' + +' next: function() {\n' + +' return { value: arr.shift(), done: arr.length <= 0 };\n' + +' },\n' + +' "return": methods["return"],\n' + +' "throw": methods["throw"]\n' + ' };\n' + ' var iterable = {};\n' + ' iterable[Symbol.iterator] = function(){ return iterator; };\n' + ' return iterable;\n' + -' };\n'; - +'}\n' + +'if (typeof global !== "undefined") {\n' + +' global.__createIterableObject = __createIterableObject;\n' + +'}\n'; exports.runTests = function runTests(runner, key, family, { resultsMatch = (expect, actual) => expect === actual, suites = [], testName, bail } = {}) { var testCount = 0; @@ -29,6 +28,45 @@ exports.runTests = function runTests(runner, key, family, { resultsMatch = (expe var environments = JSON.parse(fs.readFileSync('environments.json').toString()); + var testFilename = 'test.js'; + + var asyncTestHelperHead = + 'function asyncTestPassed() {\n' + + ' print("[SUCCESS]");\n' + + '}\n' + + '\n' + + 'var jobQueue = [];\n' + + '\n' + + 'function setTimeout(cb, time, cbarg) {\n' + + ' var runTime = Date.now() + time;\n' + + ' if (!jobQueue[runTime]) {\n' + + ' jobQueue[runTime] = [];\n' + + ' }\n' + + ' jobQueue[runTime].push(function() {\n' + + ' cb(cbarg);\n' + + ' });\n' + + '}\n'; + var asyncTestHelperTail = + 'function flushQueue() {\n' + + ' var curTime = Date.now();\n' + + ' var empty = true;\n' + + ' for (var runTime in jobQueue) {\n' + + ' empty = false;\n' + + ' if (curTime >= runTime) {\n' + + ' var jobs = jobQueue[runTime];\n' + + ' delete jobQueue[runTime];\n' + + ' jobs.forEach(function (job) {\n' + + ' job();\n' + + ' });\n' + + ' }\n' + + ' }\n' + + ' if (!empty) {\n' + + ' Promise.resolve().then(flushQueue);\n' + + ' }\n' + + '}\n' + + '\n' + + 'Promise.resolve().then(flushQueue);\n'; + // List of keys for inheriting results from previous versions. var keyList = (function () { var res = []; @@ -52,12 +90,12 @@ exports.runTests = function runTests(runner, key, family, { resultsMatch = (expe var src = exec.toString(); var functionBody = /^function\s*\w*\s*\(.*?\)\s*\{\s*\/\*([\s\S]*?)\*\/\s*\}$/m.exec(src); if (functionBody) { - return '(function () { ' + removeIndent(functionBody[1]) + ' })();'; + return '(function () { ' + removeIndent(functionBody[1]) + ' })()'; } else { return '(' + src + ')()'; } } else if (Array.isArray(exec)) { - return exec.map(function (e) { return testCode(e.script); }).join(" || "); + return exec.map(function (e) { return testCode(e.script); }).join("; "); } else { return undefined; } @@ -76,7 +114,59 @@ exports.runTests = function runTests(runner, key, family, { resultsMatch = (expe var evalcode = testCode(test.exec); - var actual = evalcode ? runner(evalcode, parents[0], testPath) : 'skip'; + var actual; + if (evalcode) { + var script = ''; + if (/\blacksGlobal\b/.test(evalcode)) { + script += 'this.lacksGlobal = typeof global === "undefined";\n'; + } + if (/\bglobal\b/.test(evalcode)) { + script += 'if (typeof global === "undefined") {\n' + + ' global = this;\n' + + '}\n'; + } + if (/\blacksGlobalThis\b/.test(evalcode)) { + script += 'this.lacksGlobalThis = typeof globalThis === "undefined";\n'; + } + if (/\bglobalThis\b/.test(evalcode)) { + script += 'if (typeof globalThis === "undefined") {\n' + + ' globalThis = this;\n' + + '}\n'; + } + if (/\b__script_executed\b/.test(evalcode)) { + script += 'var __script_executed = {};\n' + + 'global.__script_executed = __script_executed;\n' + + 'if (typeof global !== "undefined") {\n' + + ' global.__script_executed = __script_executed;\n' + + '}\n'; + } + if (/\b__createIterableObject\b/.test(evalcode)) { + script += exports.createIterableHelper; + } + + if (/\basyncTestPassed\b/.test(evalcode)) { + script += asyncTestHelperHead + '\n' + evalcode + '\n\n' + asyncTestHelperTail; + } else if (/\bglobal\.test\b/.test(evalcode)) { + script += 'global.test = function (expression) {\n' + + ' if (expression) {\n' + + ' console.log("[SUCCESS]");\n' + + ' }\n' + + '}\n' + + evalcode; + } else { + script += 'var result = ' + evalcode + ';\n' + + 'if (result) {\n' + + ' print("[SUCCESS]");\n' + + '}\n'; + } + + fs.writeFileSync(testFilename, script); + + actual = runner(testFilename, parents[0]); + } else { + actual = 'skip'; + } + if (actual !== 'skip') { testCount++;