let abort() throw a real exception
Showing
4 changed files
with
48 additions
and
19 deletions
... | @@ -173,10 +173,7 @@ var Casper = function Casper(options) { | ... | @@ -173,10 +173,7 @@ var Casper = function Casper(options) { |
173 | this.initErrorHandler(); | 173 | this.initErrorHandler(); |
174 | 174 | ||
175 | this.on('error', function(msg, backtrace) { | 175 | this.on('error', function(msg, backtrace) { |
176 | if (msg === '__termination__') { | 176 | if (/^(Assertion|Termination|TimedOut)Error/.test(msg)) { |
177 | return; | ||
178 | } | ||
179 | if (msg.indexOf('AssertionError') === 0) { | ||
180 | return; | 177 | return; |
181 | } | 178 | } |
182 | var c = this.getColorizer(); | 179 | var c = this.getColorizer(); | ... | ... |
... | @@ -46,6 +46,15 @@ function AssertionError(msg, result) { | ... | @@ -46,6 +46,15 @@ function AssertionError(msg, result) { |
46 | AssertionError.prototype = new Error(); | 46 | AssertionError.prototype = new Error(); |
47 | exports.AssertionError = AssertionError; | 47 | exports.AssertionError = AssertionError; |
48 | 48 | ||
49 | function TerminationError(msg) { | ||
50 | "use strict"; | ||
51 | Error.call(this); | ||
52 | this.message = msg; | ||
53 | this.name = 'TerminationError'; | ||
54 | } | ||
55 | TerminationError.prototype = new Error(); | ||
56 | exports.TerminationError = TerminationError; | ||
57 | |||
49 | function TimedOutError(msg) { | 58 | function TimedOutError(msg) { |
50 | "use strict"; | 59 | "use strict"; |
51 | Error.call(this); | 60 | Error.call(this); |
... | @@ -76,17 +85,17 @@ exports.create = function create(casper, options) { | ... | @@ -76,17 +85,17 @@ exports.create = function create(casper, options) { |
76 | var Tester = function Tester(casper, options) { | 85 | var Tester = function Tester(casper, options) { |
77 | "use strict"; | 86 | "use strict"; |
78 | /*jshint maxstatements:99*/ | 87 | /*jshint maxstatements:99*/ |
79 | |||
80 | if (!utils.isCasperObject(casper)) { | 88 | if (!utils.isCasperObject(casper)) { |
81 | throw new CasperError("Tester needs a Casper instance"); | 89 | throw new CasperError("Tester needs a Casper instance"); |
82 | } | 90 | } |
83 | 91 | ||
92 | // self reference | ||
84 | var self = this; | 93 | var self = this; |
85 | 94 | ||
95 | // casper reference | ||
86 | this.casper = casper; | 96 | this.casper = casper; |
87 | 97 | ||
88 | this.SKIP_MESSAGE = '__termination__'; | 98 | // public properties |
89 | |||
90 | this.aborted = false; | 99 | this.aborted = false; |
91 | this.executed = 0; | 100 | this.executed = 0; |
92 | this.currentTestFile = null; | 101 | this.currentTestFile = null; |
... | @@ -160,11 +169,10 @@ var Tester = function Tester(casper, options) { | ... | @@ -160,11 +169,10 @@ var Tester = function Tester(casper, options) { |
160 | self.processError(error); | 169 | self.processError(error); |
161 | return self.done(); | 170 | return self.done(); |
162 | } | 171 | } |
163 | if (utils.isString(error) && error.indexOf('AssertionError') === 0) { | 172 | if (utils.isString(error)) { |
173 | if (/^(Assertion|Termination|TimedOut)Error/.test(error)) { | ||
164 | return; | 174 | return; |
165 | } | 175 | } |
166 | if (error === self.SKIP_MESSAGE) { | ||
167 | return self.terminate('--fail-fast: aborted all remaining tests'); | ||
168 | } | 176 | } |
169 | var line = 0; | 177 | var line = 0; |
170 | try { | 178 | try { |
... | @@ -215,10 +223,7 @@ exports.Tester = Tester; | ... | @@ -215,10 +223,7 @@ exports.Tester = Tester; |
215 | */ | 223 | */ |
216 | Tester.prototype.abort = function abort(message) { | 224 | Tester.prototype.abort = function abort(message) { |
217 | "use strict"; | 225 | "use strict"; |
218 | if (message) { | 226 | throw new TerminationError(message || 'test suite aborted'); |
219 | this.casper.warn('test suite aborted: ' + message); | ||
220 | } | ||
221 | throw this.SKIP_MESSAGE; | ||
222 | }; | 227 | }; |
223 | 228 | ||
224 | /** | 229 | /** |
... | @@ -1164,8 +1169,8 @@ Tester.prototype.processError = function processError(error) { | ... | @@ -1164,8 +1169,8 @@ Tester.prototype.processError = function processError(error) { |
1164 | if (error instanceof AssertionError) { | 1169 | if (error instanceof AssertionError) { |
1165 | return this.processAssertionError(error); | 1170 | return this.processAssertionError(error); |
1166 | } | 1171 | } |
1167 | if (error === this.SKIP_MESSAGE) { | 1172 | if (error instanceof TerminationError) { |
1168 | return this.terminate(); | 1173 | return this.terminate(error.message); |
1169 | } | 1174 | } |
1170 | return this.uncaughtError(error, this.currentTestFile, error.line); | 1175 | return this.uncaughtError(error, this.currentTestFile, error.line); |
1171 | }; | 1176 | }; |
... | @@ -1181,8 +1186,9 @@ Tester.prototype.processPhantomError = function processPhantomError(msg, backtra | ... | @@ -1181,8 +1186,9 @@ Tester.prototype.processPhantomError = function processPhantomError(msg, backtra |
1181 | if (/^AssertionError/.test(msg)) { | 1186 | if (/^AssertionError/.test(msg)) { |
1182 | this.casper.warn('looks you did not use begin() which is mandatory since 1.1'); | 1187 | this.casper.warn('looks you did not use begin() which is mandatory since 1.1'); |
1183 | } | 1188 | } |
1184 | if (msg === this.SKIP_MESSAGE) { | 1189 | var termination = /^TerminationError:?\s?(.*)/.exec(msg); |
1185 | var message = 'test suite aborted'; | 1190 | if (termination) { |
1191 | var message = termination[1]; | ||
1186 | if (backtrace && backtrace[0]) { | 1192 | if (backtrace && backtrace[0]) { |
1187 | message += ' at ' + backtrace[0].file + backtrace[0].line; | 1193 | message += ' at ' + backtrace[0].file + backtrace[0].line; |
1188 | } | 1194 | } | ... | ... |
1 | casper.test.begin('test abort()', 10, function(test) { | ||
2 | "use strict"; | ||
3 | for (var i = 0; i < 10; i++) { | ||
4 | test.assert(true, 'test ' + (i + 1)); | ||
5 | if (i === 4) { | ||
6 | test.abort('this is my abort message'); | ||
7 | } | ||
8 | } | ||
9 | test.done(); | ||
10 | }); | ||
11 | |||
12 | casper.test.begin('should not being executed', 1, function(test) { | ||
13 | "use strict"; | ||
14 | test.fail('damn.'); | ||
15 | test.done(); | ||
16 | }); |
... | @@ -153,7 +153,7 @@ class CasperExecTest(unittest.TestCase): | ... | @@ -153,7 +153,7 @@ class CasperExecTest(unittest.TestCase): |
153 | 153 | ||
154 | @timeout(60) | 154 | @timeout(60) |
155 | def test_fail_fast(self): | 155 | def test_fail_fast(self): |
156 | folder_path = os.path.join(TEST_ROOT, 'fail-fast') | 156 | folder_path = os.path.join(TEST_ROOT, 'fail-fast', 'standard') |
157 | self.assertCommandOutputContains('test %s --fail-fast' % folder_path, [ | 157 | self.assertCommandOutputContains('test %s --fail-fast' % folder_path, [ |
158 | '# test 1', | 158 | '# test 1', |
159 | '# test 2', | 159 | '# test 2', |
... | @@ -163,5 +163,15 @@ class CasperExecTest(unittest.TestCase): | ... | @@ -163,5 +163,15 @@ class CasperExecTest(unittest.TestCase): |
163 | '1 failed', | 163 | '1 failed', |
164 | ], failing=True) | 164 | ], failing=True) |
165 | 165 | ||
166 | @timeout(60) | ||
167 | def test_manual_abort(self): | ||
168 | folder_path = os.path.join(TEST_ROOT, 'fail-fast', 'manual-abort') | ||
169 | self.assertCommandOutputContains('test %s --fail-fast' % folder_path, [ | ||
170 | '# test abort()', | ||
171 | 'PASS test 1', | ||
172 | 'PASS test 5', | ||
173 | 'this is my abort message', | ||
174 | ], failing=True) | ||
175 | |||
166 | if __name__ == '__main__': | 176 | if __name__ == '__main__': |
167 | unittest.main() | 177 | unittest.main() | ... | ... |
-
Please register or sign in to post a comment