Skip to content
This repository has been archived by the owner on Jun 5, 2020. It is now read-only.

allowFocusMode option #26

Merged
merged 6 commits into from
Oct 6, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions lib/reporters/brief.js
Original file line number Diff line number Diff line change
Expand Up @@ -412,3 +412,5 @@ BriefReporter.prototype = module.exports = {
}
}
};

module.exports["suite:error"] = module.exports["uncaughtException"];
9 changes: 9 additions & 0 deletions lib/reporters/json-proxy.js
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,15 @@
});
},

"suite:error": function (error) {
this.emit("suite:error", {
name: error.name,
message: error.message,
stack: error.stack,
uuid: error.uuid
});
},

"test:success": function (test) {
this.emit("test:success", {
name: test.name,
Expand Down
3 changes: 2 additions & 1 deletion lib/reporters/specification.js
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ module.exports = {
return prefix + (prefix.length > 0 ? " " : "");
},

printStats: function (stats) {
"suite:end": function (stats) {
this.printUncaughtExceptions();
stats = stats || {};

Expand Down Expand Up @@ -244,3 +244,4 @@ module.exports = {
};

module.exports["test:error"] = module.exports["test:failure"];
module.exports["suite:error"] = module.exports["uncaughtException"];
1 change: 1 addition & 0 deletions lib/reporters/xml.js
Original file line number Diff line number Diff line change
Expand Up @@ -224,5 +224,6 @@
};

xmlReporter["test:timeout"] = xmlReporter["test:failure"];
xmlReporter["suite:error"] = xmlReporter["uncaughtException"];
return xmlReporter;
});
25 changes: 11 additions & 14 deletions lib/test-runner.js
Original file line number Diff line number Diff line change
Expand Up @@ -159,10 +159,6 @@
return unsatiesfied;
}

function isAssertionError(err) {
return err && err.name === "AssertionError";
}

function prepareResults(results, error) {
return _.extend({}, results, {
ok: (results.failures + results.errors + results.timeouts === 0) && !(error instanceof Error)
Expand Down Expand Up @@ -298,14 +294,6 @@
};
}

function rejected(deferred) {
if (!deferred) {
deferred = when.defer();
}
deferred.reject();
return deferred.promise;
}

function listenForUncaughtExceptions() {
var listener, listening = false;
onUncaught = function (l) {
Expand Down Expand Up @@ -434,6 +422,7 @@
this.configuration = opt.configuration;
this.clients = 1;
this.concurrent = false;
this.allowFocusMode = typeof(opt.allowFocusMode) === "undefined" || opt.allowFocusMode;

if (opt.random === false) {
this.randomize = function (coll) { return coll; };
Expand Down Expand Up @@ -488,16 +477,24 @@
if (ctxs.length == 0) {
runSuitePromise = when.reject(new Error("No contexts"));
}
if (this.focusMode && !this.allowFocusMode) {
runSuitePromise = when.reject(new Error("Focus mode is disabled"));
}
if (!runSuitePromise) {
runSuitePromise = this.runContexts(ctxs);
}

return runSuitePromise.always(_.bind(function (e) {
var res = prepareResults(this.results, e);
res.uuid = this.runtime && this.runtime.uuid;
if (e instanceof Error) {
// emit the error for display in the reporter
this.emit("suite:error", e);
}

this.emit("suite:end", res);

if (e instanceof Error) {
// @todo: this error should be displayed somewhere!
throw e; // rethrow to reject the promise
}
return res;
Expand All @@ -516,7 +513,7 @@
},

runContext: function (context, thisProto) {
if (!context) { return rejected(); }
if (!context) { return when.reject(new Error("Empty context")); }
var reqs = unsatiesfiedRequirements(context);
if (reqs.length > 0) {
return when(emitUnsupported(this, context, reqs));
Expand Down
16 changes: 16 additions & 0 deletions test/reporters/brief-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -759,6 +759,22 @@ helper.testCase("Brief reporter uncaught exceptions", {
}
});

helper.testCase("Brief reporter prints suite:error", {
setUp: function () {
reporterSetUp.call(this);
this.firefox.emit("suite:configuration", { tests: 2 });
},

"prints uncaught errors continuously": function () {
this.firefox.emit("context:start", { name: "Stuff" });

this.firefox.emit("suite:error", new Error("Test error"));

this.assertIO("Uncaught exception in Firefox 16.0 on Ubuntu 64-bit:");
this.assertIO("Error: Test error");
}
});

helper.testCase("Brief reporter messages", {
setUp: function () {
reporterSetUp.call(this);
Expand Down
19 changes: 19 additions & 0 deletions test/reporters/json-proxy-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,25 @@
stack: "Trouble@here",
uuid: "1"
});
},

"emits serializable error to suite:error": function () {
var listener = sinon.spy();
this.proxy.on("suite:error", listener);

var error = new Error("Oops");
error.uuid = "1";
this.runner.emit("suite:error", error);

assert(listener.calledOnce);

var actualSerializedError = listener.args[0][0];
assert.match(actualSerializedError, {
name: "Error",
message: "Oops",
uuid: "1"
});
assert.match(actualSerializedError.stack, "Error: Oops");
}
});

Expand Down
27 changes: 27 additions & 0 deletions test/reporters/specification-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,33 @@ helper.testCase("SpecificationReporterTestsRunning", {
});

assert.match(this.out.toString(), "Skipping Stuff, unsupported requirements:\n localStorage\n document\n");
},

"prints summary at the end": function () {
this.runner.emit("suite:end", {
contexts: 2,
tests: 2,
assertions: 2,
failures: 0,
errors: 0,
ok: true
});

assert.match(this.out.toString(), "2 test cases, 2 tests, 2 assertions, 0 failures, 0 errors, 0 timeouts");
},

"prints uncaught exceptions at the end": function () {
this.runner.emit("uncaughtException", new Error("Don't catch me now"));
this.runner.emit("suite:end");
assert.match(this.out.toString(), "Uncaught exception!");
assert.match(this.out.toString(), "Error: Don't catch me now");
},

"prints suite:error as uncaught exception": function () {
this.runner.emit("suite:error", new Error("No exclamations for exceptions - it's bad enough - don't shout"));
this.runner.emit("suite:end");
assert.match(this.out.toString(), "Uncaught exception!");
assert.match(this.out.toString(), "No exclamations for exceptions - it's bad enough - don't shout");
}
});

Expand Down
9 changes: 9 additions & 0 deletions test/reporters/xml-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -386,5 +386,14 @@ helper.testCase("XMLReporterTest", {
this.runner.emit("suite:end");

refute.match(this.outputStream.toString(), "time=\"0\"name=\"#1\"");
},

"includes failure element for suite:error": function () {
this.runner.emit("suite:error", new Error("Borked test suite"));
this.runner.emit("suite:end");

this.assertIO("<testsuite errors=\"1\" tests=\"1\" failures=\"0\" name=\"Uncaught exceptions\">");
this.assertIO("<testcase classname=\"Uncaught exception\" time=\"0\" name=\"#1\">");
this.assertIO('<failure type="Error" message="Borked test suite">');
}
});
62 changes: 60 additions & 2 deletions test/test-runner-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,16 @@

refute(runner.concurrent);
assert.equals(runner.clients, 1);
},

"allows focus mode by default": function () {
var runner = testRunner.create();
assert(runner.allowFocusMode);
},

"disallows focus mode via options": function () {
var runner = testRunner.create({ allowFocusMode: false });
refute(runner.allowFocusMode);
}
});

Expand Down Expand Up @@ -785,11 +795,19 @@
},

"rejects when no contexts provided": function (done) {
var onSuiteEnd = sinon.spy();
var onSuiteEnd = sinon.spy(),
onSuiteError = sinon.spy();

this.runner.on('suite:end', onSuiteEnd);
this.runner.runSuite([]).then(null, done(function () {
this.runner.on('suite:error', onSuiteError);
this.runner.runSuite([]).then(null, done(function (err) {
assert(onSuiteEnd.calledOnce, "Should still emit `suite:end`");
refute(onSuiteEnd.getCall(0).args[0].ok, "`suite:end` should emit with result.ok == false");

assert(onSuiteError.calledOnce, "Should have emitted `suite:error`");
assert.same(onSuiteError.getCall(0).args[0], err, "Should have emitted with the same error as rejection");
assert(err instanceof Error);
assert.equals(err.message, "No contexts");
}));
}
});
Expand Down Expand Up @@ -2838,6 +2856,46 @@
assert.isString(e.uuid);
}));
this.runner.runSuite([context]);
},

"fails when focus mode disabled": function (done) {
var onError = sinon.spy();

var runner = testRunner.create({ allowFocusMode: false });
runner.on("suite:error", onError);
var context = testCase("Test", {
"=>don't do it": function () {}
});

runner.runSuite([ context ]).then(function () {
assert.fail("runSuite promise should have been rejected");
}, function (err) {
assert(err instanceof Error);
assert.equals(err.message, "Focus mode is disabled");
assert(onError.calledOnce, "Should have emitted `suite:error`");
assert.same(onError.getCall(0).args[0], err, "`suite:error` should emit the same error as promise rejection");
done();
})
},

"runs when focus mode disabled, but no focus rocket used": function (done) {
var onError = sinon.spy();

var runner = testRunner.create({ allowFocusMode: false });
runner.on("suite:error", onError);

var unfocused = sinon.spy();
var context = testCase("Test", {
"do it": unfocused
});

runner.runSuite([ context ]).then(function () {
refute(onError.callCount, "Don't emit `suite:error` unnecessarily");
assert(unfocused.calledOnce);
done();
}, function () {
assert.fail("runSuite promise should have been rejected");
})
}
});

Expand Down