test262-stream
Version:
A Node.js API for traversing the Test262 test suite
320 lines (251 loc) • 9.31 kB
JavaScript
const fs = require('fs');
const mkdirp = require('mkdirp');
const path = require('path');
const rimraf = require('rimraf');
const tape = require('tape');
const TestStream = require('..');
const scenarios = /^(strict mode|default)$/;
const RECORDING = !!process.env.RECORD;
// Properties to exclude when validating metadata. The values are
// inconsequential; they have been selected to aid in discoverability in the
// programatically-generated "expectations" files.
const blankOut = {
contents: '(The value of this property is over-sized, so it is validated independently.)'
};
function makeDataHandler(t, ids, fixtureDir) {
const test262Dir = path.join(fixtureDir, 'fake-test262');
const expectedContentDir = path.join(fixtureDir, 'expected-content');
const expectedMetadataDir = path.join(fixtureDir, 'expected-metadata');
if (RECORDING) {
rimraf.sync(expectedContentDir);
rimraf.sync(expectedMetadataDir);
}
return (test) => {
if (typeof test !== 'object' || test === null) {
t.ok(false, 'Emits object values');
return;
}
const actualContents = test.contents;
const actualMetadata = Object.assign({}, test, blankOut);
if (!fs.existsSync(path.join(test262Dir, test.file))) {
t.ok(false, 'Source file does not exist: ' + test.file);
return;
}
// `RegExp.prototype.test` acceptes `undefined`, so an explicit type
// check is necessary.
t.equal(typeof test.scenario, 'string', '`scenario` property is a string value');
t.ok(scenarios.test(test.scenario), '`scenario` property is a valid value');
const id = test.file.replace(/\.js$/, '_' + test.scenario.replace(' ', '_'));
const expectedContentFile = path.join(expectedContentDir, id) + '.js';
const expectedMetadataFile = path.join(expectedMetadataDir, id) + '.json';
t.not(ids.indexOf(id) === -1, 'Emits each test exactly once');
ids.push(id);
if (RECORDING) {
mkdirp.sync(path.dirname(expectedContentFile));
fs.writeFileSync(expectedContentFile, actualContents, 'utf-8');
mkdirp.sync(path.dirname(expectedMetadataFile));
fs.writeFileSync(expectedMetadataFile, JSON.stringify(actualMetadata, null, 2), 'utf-8');
return;
}
if (!fs.existsSync(expectedContentFile)) {
t.ok(false, 'Expected content file not found: ' + expectedContentFile);
return;
}
if (!fs.existsSync(expectedMetadataFile)) {
t.ok(false, 'Expected metadata file not found: ' + expectedMetadataFile);
return;
}
t.deepEqual(actualContents, fs.readFileSync(expectedContentFile, 'utf-8'));
t.deepEqual(actualMetadata, require(expectedMetadataFile));
};
}
tape('valid source directory', t => {
const fixtureDir = path.join(__dirname, 'collateral', 'valid-default');
const stream = new TestStream(path.join(fixtureDir, 'fake-test262'));
const ids = [];
stream.on('data', makeDataHandler(t, ids, fixtureDir));
stream.on('error', (error) => {
t.ok(error);
t.end(error);
});
stream.on('end', () => {
t.equal(ids.length, 16, 'Reports every available test');
t.end();
});
});
tape('valid source directory (with paths)', t => {
const fixtureDir = path.join(__dirname, 'collateral', 'valid-with-paths');
const paths = ['test/bothStrict.js', 'test/strict/no', 'test/async'];
const stream = new TestStream(path.join(fixtureDir, 'fake-test262'), { paths });
const ids = [];
stream.on('data', makeDataHandler(t, ids, fixtureDir));
stream.on('error', (error) => {
t.ok(error);
t.end(error);
});
stream.on('end', () => {
t.equal(ids.length, 8, 'Reports every available test');
t.end();
});
});
tape('valid source directory (with custom includes)', t => {
const fixtureDir = path.join(__dirname, 'collateral', 'valid-with-includes');
const includesDir = path.join(fixtureDir, 'custom-includes');
const stream = new TestStream(path.join(fixtureDir, 'fake-test262'), { includesDir });
const ids = [];
stream.on('data', makeDataHandler(t, ids, fixtureDir));
stream.on('error', (error) => {
t.ok(error);
t.end(error);
});
stream.on('end', () => {
t.equal(ids.length, 4, 'Reports every available test');
t.end();
});
});
tape('missing `assert.js`', t => {
const stream = new TestStream(path.join(__dirname, 'collateral', 'invalid-missing-harness'));
stream.on('data', () => {
t.end(new Error('Stream should not emit a `data` event'));
});
stream.on('end', () => {
t.end(new Error('Stream should not emit an `end` event'));
});
stream.on('error', (error) => {
t.ok(error, '`error` event should be published with an object');
t.end();
});
});
tape.skip('non-existent source directory', t => {
const stream = new TestStream(path.join(__dirname, 'collateral', 'this-directory-does-not-exist'));
stream.on('data', () => {
t.end(new Error('Stream should not emit a `data` event'));
});
stream.on('end', () => {
t.end(new Error('Stream should not emit an `end` event'));
});
stream.on('error', (error) => {
t.ok(error, '`error` event should be published with an object');
t.end();
});
});
tape('valid source directory (with a supported version)', t => {
const fixtureDir = path.join(__dirname, 'collateral', 'valid-version-supported');
const stream = new TestStream(path.join(fixtureDir, 'fake-test262'));
const ids = [];
stream.on('data', makeDataHandler(t, ids, fixtureDir));
stream.on('error', (error) => {
t.ok(error);
t.end(error);
});
stream.on('end', () => {
t.equal(ids.length, 1, 'Reports every available test');
t.end();
});
});
tape('invalid source directory (with an unsupported version)', t => {
const fixtureDir = path.join(__dirname, 'collateral', 'invalid-version-unsupported');
const stream = new TestStream(path.join(fixtureDir, 'fake-test262'));
stream.on('data', () => {
t.end(new Error('Stream should not emit a `data` event'));
});
stream.on('end', () => {
t.end(new Error('Stream should not emit an `end` event'));
});
stream.on('error', (error) => {
t.ok(error, '`error` event should be published with an object');
t.end();
});
});
tape('invalid source directory (accepting newer version)', t => {
const fixtureDir = path.join(__dirname, 'collateral', 'valid-version-ignored');
const stream = new TestStream(path.join(fixtureDir, 'fake-test262'), {
acceptVersion: '999.0.0'
});
const ids = [];
stream.on('data', makeDataHandler(t, ids, fixtureDir));
stream.on('error', (error) => {
t.ok(error);
t.end(error);
});
stream.on('end', () => {
t.equal(ids.length, 1, 'Reports every available test');
t.end();
});
});
tape('invalid source directory (with a version that differs from the "accepted" versoin)', t => {
const fixtureDir = path.join(__dirname, 'collateral', 'invalid-version-other-accepted');
const stream = new TestStream(path.join(fixtureDir, 'fake-test262'), {
acceptVersion: '3.0.1'
});
stream.on('data', () => {
t.end(new Error('Stream should not emit a `data` event'));
});
stream.on('end', () => {
t.end(new Error('Stream should not emit an `end` event'));
});
stream.on('error', (error) => {
t.ok(error, '`error` event should be published with an object');
t.end();
});
});
tape('omit runtime', t => {
const fixtureDir = path.join(__dirname, 'collateral', 'valid-omit-runtime');
const stream = new TestStream(path.join(fixtureDir, 'fake-test262'), {
omitRuntime: true
});
const ids = [];
stream.on('data', makeDataHandler(t, ids, fixtureDir));
stream.on('error', (error) => {
t.ok(error);
t.end(error);
});
stream.on('end', () => {
t.equal(ids.length, 16, 'Reports every available test');
t.end();
});
});
tape('completion detection when final files visited are not tests', t => {
const fixtureDir = path.join(__dirname, 'collateral', 'valid-extra-files');
const stream = new TestStream(path.join(fixtureDir, 'fake-test262'));
const ids = [];
global.mike = true;
stream.on('data', makeDataHandler(t, ids, fixtureDir));
stream.on('error', (error) => {
t.ok(error);
t.end(error);
});
stream.on('end', () => {
t.equal(ids.length, 2, 'Reports every available test');
t.end();
});
});
tape('valid source directory (with hashbang tests)', t => {
const fixtureDir = path.join(__dirname, 'collateral', 'valid-with-hashbang');
const stream = new TestStream(path.join(fixtureDir, 'fake-test262'));
const ids = [];
stream.on('data', makeDataHandler(t, ids, fixtureDir));
stream.on('error', (error) => {
t.ok(error);
t.end(error);
});
stream.on('end', () => {
t.equal(ids.length, 10, 'Reports every available test');
t.end();
});
});
tape('copyright and insertionIndex integrity', t => {
const fixtureDir = path.join(__dirname, 'collateral', 'valid-insertionindex-with-copyright');
const stream = new TestStream(path.join(fixtureDir, 'fake-test262'));
const ids = [];
stream.on('data', makeDataHandler(t, ids, fixtureDir));
stream.on('error', (error) => {
t.ok(error);
t.end(error);
});
stream.on('end', () => {
t.equal(ids.length, 3, 'Reports every available test');
t.end();
});
});
;