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 unittest.expected_function; | 5 library unittest.expected_function; |
6 | 6 |
7 import '../unittest.dart'; | 7 import '../unittest.dart'; |
8 | 8 |
9 import 'internal_test_case.dart'; | 9 import 'internal_test_case.dart'; |
10 | 10 |
(...skipping 12 matching lines...) Expand all Loading... |
23 typedef bool _IsDoneCallback(); | 23 typedef bool _IsDoneCallback(); |
24 | 24 |
25 /// A wrapper for a function that ensures that it's called the appropriate | 25 /// A wrapper for a function that ensures that it's called the appropriate |
26 /// number of times. | 26 /// number of times. |
27 /// | 27 /// |
28 /// The containing test won't be considered to have completed successfully until | 28 /// The containing test won't be considered to have completed successfully until |
29 /// this function has been called the appropriate number of times. | 29 /// this function has been called the appropriate number of times. |
30 /// | 30 /// |
31 /// The wrapper function is accessible via [func]. It supports up to six | 31 /// The wrapper function is accessible via [func]. It supports up to six |
32 /// optional and/or required positional arguments, but no named arguments. | 32 /// optional and/or required positional arguments, but no named arguments. |
33 class ExpectedFunction { | 33 class ExpectedFunction<T> { |
34 /// The wrapped callback. | 34 /// The wrapped callback. |
35 final Function _callback; | 35 final Function _callback; |
36 | 36 |
37 /// The minimum number of calls that are expected to be made to the function. | 37 /// The minimum number of calls that are expected to be made to the function. |
38 /// | 38 /// |
39 /// If fewer calls than this are made, the test will fail. | 39 /// If fewer calls than this are made, the test will fail. |
40 final int _minExpectedCalls; | 40 final int _minExpectedCalls; |
41 | 41 |
42 /// The maximum number of calls that are expected to be made to the function. | 42 /// The maximum number of calls that are expected to be made to the function. |
43 /// | 43 /// |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
118 | 118 |
119 start += prefix.length; | 119 start += prefix.length; |
120 var end = toString.indexOf("'", start); | 120 var end = toString.indexOf("'", start); |
121 if (end == -1) return ''; | 121 if (end == -1) return ''; |
122 return "${toString.substring(start, end)} "; | 122 return "${toString.substring(start, end)} "; |
123 } | 123 } |
124 | 124 |
125 /// Returns a function that has the same number of positional arguments as the | 125 /// Returns a function that has the same number of positional arguments as the |
126 /// wrapped function (up to a total of 6). | 126 /// wrapped function (up to a total of 6). |
127 Function get func { | 127 Function get func { |
128 if (_callback is _Func6) return _max6; | 128 if (_callback is _Func6) return max6; |
129 if (_callback is _Func5) return _max5; | 129 if (_callback is _Func5) return max5; |
130 if (_callback is _Func4) return _max4; | 130 if (_callback is _Func4) return max4; |
131 if (_callback is _Func3) return _max3; | 131 if (_callback is _Func3) return max3; |
132 if (_callback is _Func2) return _max2; | 132 if (_callback is _Func2) return max2; |
133 if (_callback is _Func1) return _max1; | 133 if (_callback is _Func1) return max1; |
134 if (_callback is _Func0) return _max0; | 134 if (_callback is _Func0) return max0; |
135 | 135 |
136 throw new ArgumentError( | 136 throw new ArgumentError( |
137 'The wrapped function has more than 6 required arguments'); | 137 'The wrapped function has more than 6 required arguments'); |
138 } | 138 } |
139 | 139 |
| 140 T max0() => max6(); |
| 141 |
140 // This indirection is critical. It ensures the returned function has an | 142 // This indirection is critical. It ensures the returned function has an |
141 // argument count of zero. | 143 // argument count of zero. |
142 _max0() => _max6(); | 144 T max1([Object a0 = _PLACEHOLDER]) => max6(a0); |
143 | 145 |
144 _max1([a0 = _PLACEHOLDER]) => _max6(a0); | 146 T max2([Object a0 = _PLACEHOLDER, Object a1 = _PLACEHOLDER]) => max6(a0, a1); |
145 | 147 |
146 _max2([a0 = _PLACEHOLDER, a1 = _PLACEHOLDER]) => _max6(a0, a1); | 148 T max3( |
| 149 [Object a0 = _PLACEHOLDER, |
| 150 Object a1 = _PLACEHOLDER, |
| 151 Object a2 = _PLACEHOLDER]) => |
| 152 max6(a0, a1, a2); |
147 | 153 |
148 _max3([a0 = _PLACEHOLDER, a1 = _PLACEHOLDER, a2 = _PLACEHOLDER]) => | 154 T max4( |
149 _max6(a0, a1, a2); | 155 [Object a0 = _PLACEHOLDER, |
| 156 Object a1 = _PLACEHOLDER, |
| 157 Object a2 = _PLACEHOLDER, |
| 158 Object a3 = _PLACEHOLDER]) => |
| 159 max6(a0, a1, a2, a3); |
150 | 160 |
151 _max4([a0 = _PLACEHOLDER, a1 = _PLACEHOLDER, a2 = _PLACEHOLDER, | 161 T max5( |
152 a3 = _PLACEHOLDER]) => _max6(a0, a1, a2, a3); | 162 [Object a0 = _PLACEHOLDER, |
| 163 Object a1 = _PLACEHOLDER, |
| 164 Object a2 = _PLACEHOLDER, |
| 165 Object a3 = _PLACEHOLDER, |
| 166 Object a4 = _PLACEHOLDER]) => |
| 167 max6(a0, a1, a2, a3, a4); |
153 | 168 |
154 _max5([a0 = _PLACEHOLDER, a1 = _PLACEHOLDER, a2 = _PLACEHOLDER, | 169 T max6( |
155 a3 = _PLACEHOLDER, a4 = _PLACEHOLDER]) => _max6(a0, a1, a2, a3, a4); | 170 [Object a0 = _PLACEHOLDER, |
156 | 171 Object a1 = _PLACEHOLDER, |
157 _max6([a0 = _PLACEHOLDER, a1 = _PLACEHOLDER, a2 = _PLACEHOLDER, | 172 Object a2 = _PLACEHOLDER, |
158 a3 = _PLACEHOLDER, a4 = _PLACEHOLDER, a5 = _PLACEHOLDER]) => | 173 Object a3 = _PLACEHOLDER, |
| 174 Object a4 = _PLACEHOLDER, |
| 175 Object a5 = _PLACEHOLDER]) => |
159 _run([a0, a1, a2, a3, a4, a5].where((a) => a != _PLACEHOLDER)); | 176 _run([a0, a1, a2, a3, a4, a5].where((a) => a != _PLACEHOLDER)); |
160 | 177 |
161 /// Runs the wrapped function with [args] and returns its return value. | 178 /// Runs the wrapped function with [args] and returns its return value. |
162 /// | 179 /// |
163 /// This will pass any errors on to [_testCase] and return `null`. | 180 /// This will pass any errors on to [_testCase] and return `null`. |
164 _run(Iterable args) { | 181 T _run(Iterable args) { |
165 try { | 182 try { |
166 _actualCalls++; | 183 _actualCalls++; |
167 if (_testCase.isComplete) { | 184 if (_testCase.isComplete) { |
168 // Don't run the callback if the test is done. We don't throw here as | 185 // Don't run the callback if the test is done. We don't throw here as |
169 // this is not the current test, but we do mark the old test as having | 186 // this is not the current test, but we do mark the old test as having |
170 // an error if it previously passed. | 187 // an error if it previously passed. |
171 if (_testCase.result == PASS) { | 188 if (_testCase.result == PASS) { |
172 _testCase.error( | 189 _testCase.error( |
173 'Callback ${_id}called ($_actualCalls) after test case ' | 190 'Callback ${_id}called ($_actualCalls) after test case ' |
174 '${_testCase.description} had already been marked as ' | 191 '${_testCase.description} had already been marked as ' |
175 '${_testCase.result}.$_reason'); | 192 '${_testCase.result}.$_reason'); |
176 } | 193 } |
177 return null; | 194 return null; |
178 } else if (_maxExpectedCalls >= 0 && _actualCalls > _maxExpectedCalls) { | 195 } else if (_maxExpectedCalls >= 0 && _actualCalls > _maxExpectedCalls) { |
179 throw new TestFailure('Callback ${_id}called more times than expected ' | 196 throw new TestFailure('Callback ${_id}called more times than expected ' |
180 '($_maxExpectedCalls).$_reason'); | 197 '($_maxExpectedCalls).$_reason'); |
181 } | 198 } |
182 | 199 |
183 return Function.apply(_callback, args.toList()); | 200 return Function.apply(_callback, args.toList()) as T; |
184 } catch (error, stackTrace) { | 201 } catch (error, stackTrace) { |
185 _testCase.registerException(error, stackTrace); | 202 _testCase.registerException(error, stackTrace); |
186 return null; | 203 return null; |
187 } finally { | 204 } finally { |
188 _afterRun(); | 205 _afterRun(); |
189 } | 206 } |
190 } | 207 } |
191 | 208 |
192 /// After each time the function is run, check to see if it's complete. | 209 /// After each time the function is run, check to see if it's complete. |
193 void _afterRun() { | 210 void _afterRun() { |
194 if (_complete) return; | 211 if (_complete) return; |
195 if (_minExpectedCalls > 0 && _actualCalls < _minExpectedCalls) return; | 212 if (_minExpectedCalls > 0 && _actualCalls < _minExpectedCalls) return; |
196 if (_isDone != null && !_isDone()) return; | 213 if (_isDone != null && !_isDone()) return; |
197 | 214 |
198 // Mark this callback as complete and remove it from the test case's | 215 // Mark this callback as complete and remove it from the test case's |
199 // oustanding callback count; if that hits zero the test is done. | 216 // oustanding callback count; if that hits zero the test is done. |
200 _complete = true; | 217 _complete = true; |
201 _testCase.markCallbackComplete(); | 218 _testCase.markCallbackComplete(); |
202 } | 219 } |
203 } | 220 } |
OLD | NEW |