Skip to content

Commit

Permalink
Implement support for raw frontmatter flag
Browse files Browse the repository at this point in the history
  • Loading branch information
jugglinmike committed Jul 21, 2015
1 parent f0154d2 commit 7e0b66d
Show file tree
Hide file tree
Showing 8 changed files with 124 additions and 45 deletions.
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -123,8 +123,11 @@ All runners have the same basic interface. Supporting new hosts, transpilers, or
#### Runner(args)
Runners are constructed by passing the current configuration object.

#### Runner.prototype.needsCtrlFlow
Boolean flag indicating whether control-flow-related code should be injected during test compilation (see `Runner.prototype.compile`).

#### Runner.prototype.compile(test)
Modifies the test contents to run in the target host. By default, it will append a call to $DONE if not already present, append any the environment dependencies (eg. $DONE, $LOG, etc) found in `this.deps`, append helpers, and add "use strict" if required.
Modifies the test contents to run in the target host. By default, it will append a call to $DONE if not already present, append the appropriate environment dependencies (eg. `$DONE`, `$LOG`, `$ERROR`, etc), append helpers, and add "use strict" if required.

#### Runner.prototype.link(test)
Recursively appends helpers required in the front-matter of the test.
Expand Down
97 changes: 71 additions & 26 deletions lib/runner.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,68 @@ function Runner(opts) {
throw new Error("Helper directory " + opts.includesDir + " not found");
}


this.helpers = loadHelpers(opts.includesDir);

this._errorSrc = this.test262ErrorSrc + "\n;" + this.errorFnSrc;

if (this.needsCtrlFlow) {
if (!this.logFnSrc) {
throw new Error('`$LOG` function not implemented.');
}

if (!this.doneFnSrc) {
throw new Error('`$DONE` function not implemented.');
}

this._ctrlFlowSrc = this.logFnSrc + "\n;" + this.doneFnSrc;
}
};

Runner.prototype.deps = [];
/**
* Boolean attribute which controls whether the runner should inject code for
* control flow. If true, the runner's `doneFnSrc` and `logFnSrc` will be
* inserted into each test prior to execution.
*/
Runner.prototype.needsCtrlFlow = true;

/**
* JavaScript source code that defines a function binding for the identifier
* `$LOG`. This must be defined by Runner subclasses that require control flow.
*/
Runner.prototype.logFnSrc = null;

/**
* JavaScript source code that defines a function binding for the identifier
* `$DONE`. This must be defined by Runner subclasses that require control
* flow.
*/
Runner.prototype.doneFnSrc = null;

/**
* JavaScript source code that defines a constructor function bound to the
* identifier `Test262Error`.
*/
Runner.prototype.test262ErrorSrc = function() {
function Test262Error(message) {
if (message) this.message = message;
}

Test262Error.prototype.name = "Test262Error";

Test262Error.prototype.toString = function () {
return "Test262Error: " + this.message;
};
}.toString().slice(14, -1);

/**
* JavaScript source code that defines a function binding for the identifier
* `$ERROR`.
*/
Runner.prototype.errorFnSrc = function $ERROR(err) {
if(typeof err === "object" && err !== null && "name" in err)
throw err;
else throw new Test262Error(err);
}.toString();

Runner.prototype.compile = function(test) {
// add call to $DONE at the bottom of the test file if it's not
Expand All @@ -38,13 +95,19 @@ Runner.prototype.compile = function(test) {
test.contents += "\n;$DONE();\n"
}

test.contents = [
this.test262ErrorSrc, this.errorFnSrc, test.contents
].join(";\n");
if (test.attrs.flags.raw) {
if (this.needsCtrlFlow) {
test.contents += "\n;" + this._ctrlFlowSrc;
}

this.deps.forEach(function(dep) {
test.contents = dep + "\n" + test.contents;
})
return;
}

test.contents = this._errorSrc + "\n;" + test.contents;

if (this.needsCtrlFlow) {
test.contents = this._ctrlFlowSrc + "\n;" + test.contents;
}

this.link(test);

Expand Down Expand Up @@ -88,24 +151,6 @@ Runner.prototype.link = function(test) {
test.contents = includeContent + test.contents;
}

Runner.prototype.test262ErrorSrc = function() {
function Test262Error(message) {
if (message) this.message = message;
}

Test262Error.prototype.name = "Test262Error";

Test262Error.prototype.toString = function () {
return "Test262Error: " + this.message;
};
}.toString().slice(14, -1);

Runner.prototype.errorFnSrc = function $ERROR(err) {
if(typeof err === "object" && err !== null && "name" in err)
throw err;
else throw new Test262Error(err);
}.toString();

var errorLogRe = /^test262\/error (.*)$/;
// Result is expected to have the following keys:
// errorString: Error of the form ErrorName: ErrorMessage. Optional.
Expand Down
27 changes: 11 additions & 16 deletions lib/runners/console.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,6 @@ var fs = require('fs');
var cp = require('child_process');
var counter = 0;

var doneFn = function $DONE(err) {
if(err) $ERROR(err);
$LOG('test262/done');
}.toString()

var batchDoneFn = function $DONE(err) {
if(err) {
if(typeof err === "object" && err !== null && "name" in err) {
Expand All @@ -32,22 +27,16 @@ function ConsoleRunner(args) {
this.printCommand = args.consolePrintCommand || "console.log";

if(args.batch) {
// Done comes from the parent context
this.deps = [
this.logFn
]
// Control flow functions are defined by the parent context
this.needsCtrlFlow = false;

if(args.batchConfig) {
this._createEnv = args.batchConfig.createEnv;
this._runBatched = args.batchConfig.runBatched;
this._setRealmValue = args.batchConfig.setRealmValue;
}
} else {
this.deps = [
doneFn,
this.logFn
]
}

if(!this.command) throw "--consoleCommand option required for console runner";
if (!this._setRealmValue) {
this._setRealmValue = function(env, property, value) {
Expand All @@ -58,10 +47,16 @@ function ConsoleRunner(args) {
Runner.apply(this, arguments);
}
ConsoleRunner.prototype = Object.create(Runner.prototype);

ConsoleRunner.prototype.doneFnSrc = function $DONE(err) {
if(err) $ERROR(err);
$LOG('test262/done');
}.toString();

ConsoleRunner.prototype._print = function(str) {
return this.printCommand + '(' + str + ');\n';
}
Object.defineProperty(ConsoleRunner.prototype, 'logFn', {
Object.defineProperty(ConsoleRunner.prototype, 'logFnSrc', {
get: memoize(function() {
return 'function $LOG(str) { ' + this._print('str') + '}';
})
Expand Down Expand Up @@ -115,7 +110,7 @@ ConsoleRunner.prototype.execute = function(test, cb) {
ConsoleRunner.prototype.executeBatch = function(batch, batchDone) {
var runner = this;
var scriptFile = '__tmp' + counter++ + '.js';
var script = this.logFn + '\n' +
var script = this.logFnSrc + '\n' +
batchDoneFn + '\n' +
'var $setRealmValue = ' + this._setRealmValue + ';\n' +
this.runNextFn + '\n';
Expand Down
3 changes: 3 additions & 0 deletions lib/runners/node-ip.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ var Runner = require('../runner');

function NodeRunner() { Runner.apply(this, arguments); }
NodeRunner.prototype = Object.create(Runner.prototype);

NodeRunner.prototype.needsCtrlFlow = false;

NodeRunner.prototype.execute = function(test, cb) {
var contents = test.contents;
var error;
Expand Down
4 changes: 2 additions & 2 deletions lib/runners/node.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ function NodeRunner(args) {
args.consoleCommand = args.consoleCommand || "node";
var runner = this;

this.needsCtrlFlow = !!args.compileOnly;

ConsoleRunner.apply(this, arguments);

if(!args.compileOnly) {
this.deps = []; // all env deps provided by nodehost.js

// HACK: Probably doesn't handle quoted arguments and other
// complexities.
var parts = args.consoleCommand.split(" ");
Expand Down
14 changes: 14 additions & 0 deletions test/collateral/rawNoStrict.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/*---
description: Should not test in strict mode
flags: [raw]
---*/
var seemsStrict;
try {
x = 1;
} catch (err) {
seemsStrict = err.constructor === ReferenceError;
}

if (seemsStrict) {
throw new Error('Script erroneously interpreted in strict mode.');
}
15 changes: 15 additions & 0 deletions test/collateral/rawStrict.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/*---
description: Should not test in strict mode
flags: [raw]
---*/
'use strict';
var seemsStrict;
try {
x = 1;
} catch (err) {
seemsStrict = err.constructor === ReferenceError;
}

if (!seemsStrict) {
throw new Error('Script erroneously not interpreted in strict mode.');
}
4 changes: 4 additions & 0 deletions test/expected.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ var all = [
{ file: 'test/collateral/bothStrict.js', strictMode: true, pass: true },
{ file: 'test/collateral/strict.js', strictMode: true, pass: true },
{ file: 'test/collateral/noStrict.js', strictMode: false, pass: true },
{ file: 'test/collateral/rawStrict.js', strictMode: false, pass: true },
{ file: 'test/collateral/rawStrict.js', strictMode: true, pass: true },
{ file: 'test/collateral/rawNoStrict.js', strictMode: false, pass: true },
{ file: 'test/collateral/rawNoStrict.js', strictMode: true, pass: true },
{ file: 'test/collateral/error.js', strictMode: false, pass: false, errorMessage: 'failure message', errorName: 'Test262Error' },
{ file: 'test/collateral/error.js', strictMode: true, pass: false, errorMessage: 'failure message', errorName: 'Test262Error' },
{ file: 'test/collateral/thrownError.js', strictMode: false, pass: false, errorMessage: 'failure message', errorName: 'Error', topOfStack: "foo" },
Expand Down

0 comments on commit 7e0b66d

Please sign in to comment.