Commit 33fe4345 33fe4345f650024744d59cc0c7984211ece8cee4 by Nicolas Perriault

let abort() throw a real exception

1 parent e3b91c35
......@@ -173,10 +173,7 @@ var Casper = function Casper(options) {
this.initErrorHandler();
this.on('error', function(msg, backtrace) {
if (msg === '__termination__') {
return;
}
if (msg.indexOf('AssertionError') === 0) {
if (/^(Assertion|Termination|TimedOut)Error/.test(msg)) {
return;
}
var c = this.getColorizer();
......
......@@ -46,6 +46,15 @@ function AssertionError(msg, result) {
AssertionError.prototype = new Error();
exports.AssertionError = AssertionError;
function TerminationError(msg) {
"use strict";
Error.call(this);
this.message = msg;
this.name = 'TerminationError';
}
TerminationError.prototype = new Error();
exports.TerminationError = TerminationError;
function TimedOutError(msg) {
"use strict";
Error.call(this);
......@@ -76,17 +85,17 @@ exports.create = function create(casper, options) {
var Tester = function Tester(casper, options) {
"use strict";
/*jshint maxstatements:99*/
if (!utils.isCasperObject(casper)) {
throw new CasperError("Tester needs a Casper instance");
}
// self reference
var self = this;
// casper reference
this.casper = casper;
this.SKIP_MESSAGE = '__termination__';
// public properties
this.aborted = false;
this.executed = 0;
this.currentTestFile = null;
......@@ -160,11 +169,10 @@ var Tester = function Tester(casper, options) {
self.processError(error);
return self.done();
}
if (utils.isString(error) && error.indexOf('AssertionError') === 0) {
return;
}
if (error === self.SKIP_MESSAGE) {
return self.terminate('--fail-fast: aborted all remaining tests');
if (utils.isString(error)) {
if (/^(Assertion|Termination|TimedOut)Error/.test(error)) {
return;
}
}
var line = 0;
try {
......@@ -215,10 +223,7 @@ exports.Tester = Tester;
*/
Tester.prototype.abort = function abort(message) {
"use strict";
if (message) {
this.casper.warn('test suite aborted: ' + message);
}
throw this.SKIP_MESSAGE;
throw new TerminationError(message || 'test suite aborted');
};
/**
......@@ -1164,8 +1169,8 @@ Tester.prototype.processError = function processError(error) {
if (error instanceof AssertionError) {
return this.processAssertionError(error);
}
if (error === this.SKIP_MESSAGE) {
return this.terminate();
if (error instanceof TerminationError) {
return this.terminate(error.message);
}
return this.uncaughtError(error, this.currentTestFile, error.line);
};
......@@ -1181,8 +1186,9 @@ Tester.prototype.processPhantomError = function processPhantomError(msg, backtra
if (/^AssertionError/.test(msg)) {
this.casper.warn('looks you did not use begin() which is mandatory since 1.1');
}
if (msg === this.SKIP_MESSAGE) {
var message = 'test suite aborted';
var termination = /^TerminationError:?\s?(.*)/.exec(msg);
if (termination) {
var message = termination[1];
if (backtrace && backtrace[0]) {
message += ' at ' + backtrace[0].file + backtrace[0].line;
}
......
casper.test.begin('test abort()', 10, function(test) {
"use strict";
for (var i = 0; i < 10; i++) {
test.assert(true, 'test ' + (i + 1));
if (i === 4) {
test.abort('this is my abort message');
}
}
test.done();
});
casper.test.begin('should not being executed', 1, function(test) {
"use strict";
test.fail('damn.');
test.done();
});
......@@ -153,7 +153,7 @@ class CasperExecTest(unittest.TestCase):
@timeout(60)
def test_fail_fast(self):
folder_path = os.path.join(TEST_ROOT, 'fail-fast')
folder_path = os.path.join(TEST_ROOT, 'fail-fast', 'standard')
self.assertCommandOutputContains('test %s --fail-fast' % folder_path, [
'# test 1',
'# test 2',
......@@ -163,5 +163,15 @@ class CasperExecTest(unittest.TestCase):
'1 failed',
], failing=True)
@timeout(60)
def test_manual_abort(self):
folder_path = os.path.join(TEST_ROOT, 'fail-fast', 'manual-abort')
self.assertCommandOutputContains('test %s --fail-fast' % folder_path, [
'# test abort()',
'PASS test 1',
'PASS test 5',
'this is my abort message',
], failing=True)
if __name__ == '__main__':
unittest.main()
......