| OLD | NEW |
| 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 library test.frontend.expect_async; | 5 library test.frontend.expect_async; |
| 6 | 6 |
| 7 import 'dart:async'; |
| 8 |
| 7 import '../backend/invoker.dart'; | 9 import '../backend/invoker.dart'; |
| 8 import '../backend/state.dart'; | 10 import '../backend/state.dart'; |
| 9 import 'expect.dart'; | 11 import 'expect.dart'; |
| 10 | 12 |
| 11 /// An object used to detect unpassed arguments. | 13 /// An object used to detect unpassed arguments. |
| 12 const _PLACEHOLDER = const Object(); | 14 const _PLACEHOLDER = const Object(); |
| 13 | 15 |
| 14 // Functions used to check how many arguments a callback takes. | 16 // Functions used to check how many arguments a callback takes. |
| 15 typedef _Func0(); | 17 typedef _Func0(); |
| 16 typedef _Func1(a); | 18 typedef _Func1(a); |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 59 | 61 |
| 60 /// An optional description of why the function is expected to be called. | 62 /// An optional description of why the function is expected to be called. |
| 61 /// | 63 /// |
| 62 /// If not passed, this will be an empty string. | 64 /// If not passed, this will be an empty string. |
| 63 final String _reason; | 65 final String _reason; |
| 64 | 66 |
| 65 /// The number of times the function has been called. | 67 /// The number of times the function has been called. |
| 66 int _actualCalls = 0; | 68 int _actualCalls = 0; |
| 67 | 69 |
| 68 /// The test invoker in which this function was wrapped. | 70 /// The test invoker in which this function was wrapped. |
| 69 final Invoker _invoker; | 71 Invoker get _invoker => _zone[#test.invoker]; |
| 72 |
| 73 /// The zone in which this function was wrapped. |
| 74 final Zone _zone; |
| 70 | 75 |
| 71 /// Whether this function has been called the requisite number of times. | 76 /// Whether this function has been called the requisite number of times. |
| 72 bool _complete; | 77 bool _complete; |
| 73 | 78 |
| 74 /// Wraps [callback] in a function that asserts that it's called at least | 79 /// Wraps [callback] in a function that asserts that it's called at least |
| 75 /// [minExpected] times and no more than [maxExpected] times. | 80 /// [minExpected] times and no more than [maxExpected] times. |
| 76 /// | 81 /// |
| 77 /// If passed, [id] is used as a descriptive name fo the function and [reason] | 82 /// If passed, [id] is used as a descriptive name fo the function and [reason] |
| 78 /// as a reason it's expected to be called. If [isDone] is passed, the test | 83 /// as a reason it's expected to be called. If [isDone] is passed, the test |
| 79 /// won't be allowed to complete until it returns `true`. | 84 /// won't be allowed to complete until it returns `true`. |
| 80 _ExpectedFunction(Function callback, int minExpected, int maxExpected, | 85 _ExpectedFunction(Function callback, int minExpected, int maxExpected, |
| 81 {String id, String reason, bool isDone()}) | 86 {String id, String reason, bool isDone()}) |
| 82 : this._callback = callback, | 87 : this._callback = callback, |
| 83 _minExpectedCalls = minExpected, | 88 _minExpectedCalls = minExpected, |
| 84 _maxExpectedCalls = (maxExpected == 0 && minExpected > 0) | 89 _maxExpectedCalls = (maxExpected == 0 && minExpected > 0) |
| 85 ? minExpected | 90 ? minExpected |
| 86 : maxExpected, | 91 : maxExpected, |
| 87 this._isDone = isDone, | 92 this._isDone = isDone, |
| 88 this._reason = reason == null ? '' : '\n$reason', | 93 this._reason = reason == null ? '' : '\n$reason', |
| 89 this._invoker = Invoker.current, | 94 this._zone = Zone.current, |
| 90 this._id = _makeCallbackId(id, callback) { | 95 this._id = _makeCallbackId(id, callback) { |
| 91 if (_invoker == null) { | 96 if (_invoker == null) { |
| 92 throw new StateError("[expectAsync] was called outside of a test."); | 97 throw new StateError("[expectAsync] was called outside of a test."); |
| 93 } else if (maxExpected > 0 && minExpected > maxExpected) { | 98 } else if (maxExpected > 0 && minExpected > maxExpected) { |
| 94 throw new ArgumentError("max ($maxExpected) may not be less than count " | 99 throw new ArgumentError("max ($maxExpected) may not be less than count " |
| 95 "($minExpected)."); | 100 "($minExpected)."); |
| 96 } | 101 } |
| 97 | 102 |
| 98 if (isDone != null || minExpected > 0) { | 103 if (isDone != null || minExpected > 0) { |
| 99 _invoker.addOutstandingCallback(); | 104 _invoker.addOutstandingCallback(); |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 171 _invoker.liveTest.state.result == Result.success) { | 176 _invoker.liveTest.state.result == Result.success) { |
| 172 throw 'Callback ${_id}called ($_actualCalls) after test case ' | 177 throw 'Callback ${_id}called ($_actualCalls) after test case ' |
| 173 '${_invoker.liveTest.test.name} had already completed.$_reason'; | 178 '${_invoker.liveTest.test.name} had already completed.$_reason'; |
| 174 } else if (_maxExpectedCalls >= 0 && _actualCalls > _maxExpectedCalls) { | 179 } else if (_maxExpectedCalls >= 0 && _actualCalls > _maxExpectedCalls) { |
| 175 throw new TestFailure('Callback ${_id}called more times than expected ' | 180 throw new TestFailure('Callback ${_id}called more times than expected ' |
| 176 '($_maxExpectedCalls).$_reason'); | 181 '($_maxExpectedCalls).$_reason'); |
| 177 } | 182 } |
| 178 | 183 |
| 179 return Function.apply(_callback, args.toList()); | 184 return Function.apply(_callback, args.toList()); |
| 180 } catch (error, stackTrace) { | 185 } catch (error, stackTrace) { |
| 181 _invoker.handleError(error, stackTrace); | 186 _zone.handleUncaughtError(error, stackTrace); |
| 182 return null; | 187 return null; |
| 183 } finally { | 188 } finally { |
| 184 _afterRun(); | 189 _afterRun(); |
| 185 } | 190 } |
| 186 } | 191 } |
| 187 | 192 |
| 188 /// After each time the function is run, check to see if it's complete. | 193 /// After each time the function is run, check to see if it's complete. |
| 189 void _afterRun() { | 194 void _afterRun() { |
| 190 if (_complete) return; | 195 if (_complete) return; |
| 191 if (_minExpectedCalls > 0 && _actualCalls < _minExpectedCalls) return; | 196 if (_minExpectedCalls > 0 && _actualCalls < _minExpectedCalls) return; |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 225 /// true will the callback be considered complete. [callback] may take up to six | 230 /// true will the callback be considered complete. [callback] may take up to six |
| 226 /// optional or required positional arguments; named arguments are not | 231 /// optional or required positional arguments; named arguments are not |
| 227 /// supported. | 232 /// supported. |
| 228 /// | 233 /// |
| 229 /// Both [id] and [reason] are optional and provide extra information about the | 234 /// Both [id] and [reason] are optional and provide extra information about the |
| 230 /// callback when debugging. [id] should be the name of the callback, while | 235 /// callback when debugging. [id] should be the name of the callback, while |
| 231 /// [reason] should be the reason the callback is expected to be called. | 236 /// [reason] should be the reason the callback is expected to be called. |
| 232 Function expectAsyncUntil(Function callback, bool isDone(), | 237 Function expectAsyncUntil(Function callback, bool isDone(), |
| 233 {String id, String reason}) => new _ExpectedFunction(callback, 0, -1, | 238 {String id, String reason}) => new _ExpectedFunction(callback, 0, -1, |
| 234 id: id, reason: reason, isDone: isDone).func; | 239 id: id, reason: reason, isDone: isDone).func; |
| OLD | NEW |