diff --git a/Makefile b/Makefile index 6d8b3d514..6077101ee 100644 --- a/Makefile +++ b/Makefile @@ -105,6 +105,7 @@ test: bin/traceur.js \ test-interpret-absolute test-inline-module-error \ test-version \ test/features \ + test/mocha \ test-experimental node_modules/.bin/mocha $(MOCHA_OPTIONS) $(TESTS) $(MAKE) test-interpret-throw @@ -118,6 +119,10 @@ test/features: bin/traceur.js bin/traceur-runtime.js $(FEATURE_TESTS) test/%-run: test/% bin/traceur.js node_modules/.bin/mocha $(MOCHA_OPTIONS) $< +test/mocha: bin/traceur.js + node_modules/.bin/mocha $(MOCHA_OPTIONS) \ + --compilers js:test/cjs-mocha-compiler.js --reporter dot test/feature/**/ + test/commonjs: test/commonjs-compiled node_modules/.bin/mocha $(MOCHA_OPTIONS) test/node-commonjs-test.js diff --git a/src/util/parseProlog.js b/src/util/parseProlog.js new file mode 100644 index 000000000..2b793d9ab --- /dev/null +++ b/src/util/parseProlog.js @@ -0,0 +1,69 @@ +// Copyright 2016 Traceur Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import {CommandOptions} from '../Options.js'; + +function forEachPrologLine(s, f) { + let inProlog = true; + for (let i = 0; inProlog && i < s.length; ) { + let j = s.indexOf('\n', i); + if (j == -1) + break; + if (s[i] === '/' && s[i + 1] === '/') { + let line = s.slice(i, j); + f(line); + i = j + 1; + } else { + inProlog = false; + } + } +} + +export default function parseProlog(source) { + let returnValue = { + onlyInBrowser: false, + skip: false, + get shouldHaveErrors() { + return this.expectedErrors.length !== 0; + }, + expectedErrors: [], + async: false + }; + forEachPrologLine(source, (line) => { + let m; + if (line.indexOf('// Only in browser.') === 0) { + returnValue.onlyInBrowser = true; + } else if (line.indexOf('// Skip') === 0) { + if (line.indexOf('// Skip.') === 0) { + returnValue.skip = true; + } else { + // eval remainder of line. + let skip = false; + try { + skip = eval(line.slice('// Skip'.length)); + } catch (ex) { + skip = true; + } + returnValue.skip = !!skip; + } + } else if (line.indexOf('// Async.') === 0) { + returnValue.async = true; + } else if ((m = /\/\ Options:\s*(.+)/.exec(line))) { + returnValue.traceurOptions = traceur.util.CommandOptions.fromString(m[1]); + } else if ((m = /\/\/ Error:\s*(.+)/.exec(line))) { + returnValue.expectedErrors.push(m[1]); + } + }); + return returnValue; +} diff --git a/test/cjs-mocha-compiler.js b/test/cjs-mocha-compiler.js new file mode 100644 index 000000000..a57710b23 --- /dev/null +++ b/test/cjs-mocha-compiler.js @@ -0,0 +1,53 @@ +'use strict'; + +var fs = require('fs'); +var traceurAPI = require('../src/node/api.js'); + +var org = require.extensions['.js']; +require.extensions['.js'] = function(module, path) { + if (!/\/node_modules\//.test(path)) { + var content = fs.readFileSync(path, 'utf8'); + if (shouldSkip(path, content)) { + return; + } + + // TODO(arv): Reuse parseProlog. + var compiled = traceurAPI.compile(content, { + modules: 'commonjs', + importRuntime: true, + }, path, path); + + + if (needsWrapper(path)) { + var header = 'var assert = require("chai").assert, test = require("mocha").test;' + 'test("' + path + '", function(){'; + var footer = '});'; + compiled = header + compiled + footer; + } + + try { + return module._compile(compiled, path); + } catch (ex) { + console.log(compiled, path); + throw ex; + } + } + return org(module, path); +}; + +function needsWrapper(path) { + return /\/test\/feature\//.test(path) && !/\/resources\//.test(path); +} + +const blackList = [ + '/Modules/ModuleName.js', +]; + +function shouldSkip(path, content) { + for (var i = 0; i < blackList.length; i++) { + if (path.indexOf(blackList[i]) !== -1) { + return true; + } + } + return /\/\/ (Error:|Options:|Skip.|Async.)/.test(content) || + /\.script\.js$/.test(path); +} diff --git a/test/feature/Modules/ImportDefault.js b/test/feature/Modules/ImportDefault.js index 2dfc7591c..fc3ad5f8d 100644 --- a/test/feature/Modules/ImportDefault.js +++ b/test/feature/Modules/ImportDefault.js @@ -1,3 +1,5 @@ +import {assert} from '../../asserts.js'; + import x from './resources/default.js'; assert.equal(x, 42); diff --git a/test/feature/Modules/resources/default-class.js b/test/feature/Modules/resources/default-class.js index 8c1e65c3b..ac5b10462 100644 --- a/test/feature/Modules/resources/default-class.js +++ b/test/feature/Modules/resources/default-class.js @@ -1,3 +1,5 @@ +import {assert} from '../../../asserts.js'; + export default class C { m() { return 'm'; diff --git a/test/feature/Modules/resources/default-function.js b/test/feature/Modules/resources/default-function.js index 352283809..267326281 100644 --- a/test/feature/Modules/resources/default-function.js +++ b/test/feature/Modules/resources/default-function.js @@ -1,3 +1,5 @@ +import {assert} from '../../../asserts.js'; + export default function f() { return 123; } diff --git a/test/feature/Syntax/NoNewLineHereEndOfFile.js b/test/feature/Syntax/NoNewLineHereEndOfFile.script.js similarity index 100% rename from test/feature/Syntax/NoNewLineHereEndOfFile.js rename to test/feature/Syntax/NoNewLineHereEndOfFile.script.js diff --git a/test/feature/TemplateLiterals/resources/m.js b/test/feature/TemplateLiterals/resources/m.js index 364751373..6ddd907d3 100644 --- a/test/feature/TemplateLiterals/resources/m.js +++ b/test/feature/TemplateLiterals/resources/m.js @@ -1,3 +1,5 @@ + +import {assert} from '../../../asserts.js'; import {f} from './f.js'; assert.equal('a', (f `a`)[0][0]); diff --git a/test/feature/TemplateLiterals/resources/n.js b/test/feature/TemplateLiterals/resources/n.js index 108fed14b..b9896e1f4 100644 --- a/test/feature/TemplateLiterals/resources/n.js +++ b/test/feature/TemplateLiterals/resources/n.js @@ -1,3 +1,4 @@ +import {assert} from '../../../asserts.js'; import {f} from './f.js'; assert.equal('b', (f `b`)[0][0]); diff --git a/test/featureTestRunner.js b/test/featureTestRunner.js index 28a7147ce..12318b444 100644 --- a/test/featureTestRunner.js +++ b/test/featureTestRunner.js @@ -18,64 +18,11 @@ import {NodeTraceurTestRunner} from './modular/NodeTraceurTestRunner.js'; import {BrowserTraceurTestRunner} from './modular/BrowserTraceurTestRunner.js'; import {Options} from '../src/Options.js'; import {ModuleStore} from '../src/loader/ModuleStore.js'; +import parseProlog from '../src/util/parseProlog.js'; import {assert} from './asserts.js'; export * from './asserts.js'; -function forEachPrologLine(s, f) { - let inProlog = true; - for (let i = 0; inProlog && i < s.length; ) { - let j = s.indexOf('\n', i); - if (j == -1) - break; - if (s[i] === '/' && s[i + 1] === '/') { - let line = s.slice(i, j); - f(line); - i = j + 1; - } else { - inProlog = false; - } - } -} - -export function parseProlog(source) { - let returnValue = { - onlyInBrowser: false, - skip: false, - get shouldHaveErrors() { - return this.expectedErrors.length !== 0; - }, - expectedErrors: [], - async: false - }; - forEachPrologLine(source, (line) => { - let m; - if (line.indexOf('// Only in browser.') === 0) { - returnValue.onlyInBrowser = true; - } else if (line.indexOf('// Skip') === 0) { - if (line.indexOf('// Skip.') === 0) { - returnValue.skip = true; - } else { - // eval remainder of line. - let skip = false; - try { - skip = eval(line.slice('// Skip'.length)); - } catch (ex) { - skip = true; - } - returnValue.skip = !!skip; - } - } else if (line.indexOf('// Async.') === 0) { - returnValue.async = true; - } else if ((m = /\/\ Options:\s*(.+)/.exec(line))) { - returnValue.traceurOptions = traceur.util.CommandOptions.fromString(m[1]); - } else if ((m = /\/\/ Error:\s*(.+)/.exec(line))) { - returnValue.expectedErrors.push(m[1]); - } - }); - return returnValue; -} - assert.type = function (actual, type) { assert.typeOf(actual, type.name); return actual;