Skip to content

Commit

Permalink
Better factoring of batch mode runners
Browse files Browse the repository at this point in the history
They all will share a similar structure, and I think this design
will work for any hosts that 1) have some mechanism to return the
global of the new environment and 2) some mechanism to evaluate a
test in that env
  • Loading branch information
bterlson committed Nov 15, 2014
1 parent 19478c1 commit 35d9d0d
Show file tree
Hide file tree
Showing 2 changed files with 106 additions and 63 deletions.
109 changes: 104 additions & 5 deletions lib/runners/console.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,22 +19,71 @@ var errorFn = function $ERROR(err) {
else $LOG("test262/error Error: " + err);
}.toString()

var batchDoneFn = function $DONE(err) {
if(err) { if(typeof err === "object" && err !== null && "name" in err)
$LOG("test262/error " + err.name + ": " + err.message)
else $LOG("test262/error Error: " + err);
}
$LOG('test262/done');
$LOG('test262/test-end');
if(tests.length > 0) runNext();
}.toString()


function ConsoleRunner(args) {
this.command = args.consoleCommand;
this.printCommand = args.consolePrintCommand || "console.log";
this.deps = [
doneFn,
errorFn,
'function $LOG(str) { ' + this._print('str') + '}',
]

if(args.batch) {
// Done comes from the parent context
this.deps = [
errorFn,
this.logFn
]
} else {
this.deps = [
doneFn,
errorFn,
this.logFn
]
}
if(!this.command) throw "--consoleCommand option required for console runner";


Runner.apply(this, arguments);
}
ConsoleRunner.prototype = Object.create(Runner.prototype);
ConsoleRunner.prototype._print = function(str) {
return this.printCommand + '(' + str + ');\n';
}
Object.defineProperty(ConsoleRunner.prototype, 'logFn', {
get: memoize(function() {
return 'function $LOG(str) { ' + this._print('str') + '}';
})
});

Object.defineProperty(ConsoleRunner.prototype, 'runNextFn', {
get: memoize(function() {
if(!this._createEnv) throw "Don't know how to create an environment";
if(!this._runBatched) throw "Don't know how to run a batched tests";

var runNextFn = function runNext() {
var test = tests.shift();
var env = $1;
env.$DONE = $DONE;

try {
$LOG('test262/test-start')
$2;
} catch(e) {
$DONE(e);
}
}.toString();

return runNextFn.replace("$1", this._createEnv)
.replace("$2", this._runBatched)
})
});

ConsoleRunner.prototype.execute = function(test, cb) {
var runner = this;
Expand All @@ -58,3 +107,53 @@ 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' +
batchDoneFn + '\n' +
this.runNextFn + '\n';

script += 'var tests = ' + JSON.stringify(batch.map(function(test, i) {
return test.contents
})) + '\n';

script += 'runNext();'

fs.writeFileSync(scriptFile, script);

cp.exec(this.command + " " + scriptFile, function(err, stdout, stderr) {
var results = { log: [] };
var lines = stdout.split(/\r?\n/);
var index = 0;

lines.forEach(function(line) {
switch(line) {
case 'test262/test-start':
break;
case 'test262/test-end':
var test = batch[index++];
runner.validateResult(test, results);
results = { log: [] };

break;
default:
results.log.push(line);
}
})

//fs.unlink(scriptFile);
batchDone();
});
}



function memoize(getter) {
var val = null;

return function() {
if(val) return val;
return val = getter.apply(this);
}
}
60 changes: 2 additions & 58 deletions lib/runners/jsshell.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,64 +12,8 @@ function JSShellRunner(args) {
args.consolePrintCommand = args.consolePrintCommand || "print";

ConsoleRunner.apply(this, arguments);

if(args.batch) {
this.batchTestStart =
'var env = newGlobal();\n' +
'try {\n';

this.batchTestEnd =
'} catch(e) {\n' +
'if(e.hasOwnProperty("name")) ' +
this._print('"test262/error " + e.name + " " + e.message') +
'else ' + this._print('"test262/error " + e') +
'}\n';
}

}

JSShellRunner.prototype = Object.create(ConsoleRunner.prototype);

JSShellRunner.prototype.executeBatch = function(batch, batchDone) {
var runner = this;
var baseFile = '__tmp' + counter++ + '_';
var script = '';

// write test files to disk
batch.forEach(function(test, i) {
script += this._print('"test262/test-start"')
+ this.batchTestStart
+ 'env.evaluate(' + JSON.stringify(test.contents) + ');\n'
+ this.batchTestEnd
+ this._print('"test262/test-end"');
}, this);

var scriptFile = baseFile + 'main.js';

fs.writeFileSync(scriptFile, script);

cp.exec(this.command + " " + scriptFile, function(err, stdout, stderr) {
var results = { log: [] };
var lines = stdout.split(/\r?\n/);
var index = 0;

lines.forEach(function(line) {
switch(line) {
case 'test262/test-start':
break;
case 'test262/test-end':
var test = batch[index++];
runner.validateResult(test, results);
results = { log: [] };

break;
default:
results.log.push(line);
}
})

fs.unlink(scriptFile);
batchDone();
});
}

JSShellRunner.prototype._createEnv = 'newGlobal()';
JSShellRunner.prototype._runBatched = 'env.evaluate(test);'

0 comments on commit 35d9d0d

Please sign in to comment.