| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 /** | 5 /** |
| 6 * A simple mocking/spy library. | 6 * A simple mocking/spy library. |
| 7 * | 7 * |
| 8 * To create a mock objects for some class T, create a new class using: | 8 * To create a mock objects for some class T, create a new class using: |
| 9 * | 9 * |
| 10 * class MockT extends Mock implements T {}; | 10 * class MockT extends Mock implements T {}; |
| 11 * | 11 * |
| 12 * Then specify the [Behavior] of the Mock for different methods using | 12 * Then specify the [Behavior] of the Mock for different methods using |
| 13 * [when] (to select the method and parameters) and then the [Action]s | 13 * [when] (to select the method and parameters) and then the [Action]s |
| 14 * for the [Behavior] by calling [thenReturn], [alwaysReturn], [thenThrow], | 14 * for the [Behavior] by calling [thenReturn], [alwaysReturn], [thenThrow], |
| 15 * [alwaysThrow], [thenCall] or [alwaysCall]. | 15 * [alwaysThrow], [thenCall] or [alwaysCall]. |
| 16 * | 16 * |
| 17 * [thenReturn], [thenThrow] and [thenCall] are one-shot so you would | 17 * [thenReturn], [thenThrow] and [thenCall] are one-shot so you would |
| 18 * typically call these more than once to specify a sequence of actions; | 18 * typically call these more than once to specify a sequence of actions; |
| 19 * this can be done with chained calls, e.g.: | 19 * this can be done with chained calls, e.g.: |
| 20 * | 20 * |
| 21 * m.when(callsTo('foo')). | 21 * m.when(callsTo('foo')). |
| 22 * thenReturn(0).thenReturn(1).thenReturn(2); | 22 * thenReturn(0).thenReturn(1).thenReturn(2); |
| 23 * | 23 * |
| 24 * [thenCall] and [alwaysCall] allow you to proxy mocked methods, chaining | 24 * [thenCall] and [alwaysCall] allow you to proxy mocked methods, chaining |
| 25 * to some other implementation. This provides a way to implement 'spies'. | 25 * to some other implementation. This provides a way to implement 'spies'. |
| 26 * | 26 * |
| 27 * For getters and setters, use "get foo" and "set foo"-style arguments |
| 28 * to [callsTo]. |
| 29 * |
| 27 * You can disable logging for a particular [Behavior] easily: | 30 * You can disable logging for a particular [Behavior] easily: |
| 28 * | 31 * |
| 29 * m.when(callsTo('bar')).logging = false; | 32 * m.when(callsTo('bar')).logging = false; |
| 30 * | 33 * |
| 31 * You can then use the mock object. Once you are done, to verify the | 34 * You can then use the mock object. Once you are done, to verify the |
| 32 * behavior, use [getLogs] to extract a relevant subset of method call | 35 * behavior, use [getLogs] to extract a relevant subset of method call |
| 33 * logs and apply [Matchers] to these through calling [verify]. | 36 * logs and apply [Matchers] to these through calling [verify]. |
| 34 * | 37 * |
| 35 * A Mock can be given a name when constructed. In this case instead of | 38 * A Mock can be given a name when constructed. In this case instead of |
| 36 * keeping its own log, it uses a shared log. This can be useful to get an | 39 * keeping its own log, it uses a shared log. This can be useful to get an |
| (...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 262 } | 265 } |
| 263 } | 266 } |
| 264 return true; | 267 return true; |
| 265 } | 268 } |
| 266 } | 269 } |
| 267 | 270 |
| 268 /** | 271 /** |
| 269 * Returns a [CallMatcher] for the specified signature. [method] can be | 272 * Returns a [CallMatcher] for the specified signature. [method] can be |
| 270 * null to match anything, or a literal [String], a predicate [Function], | 273 * null to match anything, or a literal [String], a predicate [Function], |
| 271 * or a [Matcher]. The various arguments can be scalar values or [Matcher]s. | 274 * or a [Matcher]. The various arguments can be scalar values or [Matcher]s. |
| 275 * To match getters and setters, use "get " and "set " prefixes on the names. |
| 276 * For example, for a property "foo", you could use "get foo" and "set foo" |
| 277 * as literal string arguments to callsTo to match the getter and setter |
| 278 * of "foo". |
| 272 */ | 279 */ |
| 273 CallMatcher callsTo([method, | 280 CallMatcher callsTo([method, |
| 274 arg0 = _noArg, | 281 arg0 = _noArg, |
| 275 arg1 = _noArg, | 282 arg1 = _noArg, |
| 276 arg2 = _noArg, | 283 arg2 = _noArg, |
| 277 arg3 = _noArg, | 284 arg3 = _noArg, |
| 278 arg4 = _noArg, | 285 arg4 = _noArg, |
| 279 arg5 = _noArg, | 286 arg5 = _noArg, |
| 280 arg6 = _noArg, | 287 arg6 = _noArg, |
| 281 arg7 = _noArg, | 288 arg7 = _noArg, |
| (...skipping 997 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1279 * of [Behavior]s, and find the first match that still has return | 1286 * of [Behavior]s, and find the first match that still has return |
| 1280 * values available, and then do the action specified by that | 1287 * values available, and then do the action specified by that |
| 1281 * return value. If we find no [Behavior] to apply an exception is | 1288 * return value. If we find no [Behavior] to apply an exception is |
| 1282 * thrown. | 1289 * thrown. |
| 1283 */ | 1290 */ |
| 1284 noSuchMethod(InvocationMirror invocation) { | 1291 noSuchMethod(InvocationMirror invocation) { |
| 1285 var method = invocation.memberName; | 1292 var method = invocation.memberName; |
| 1286 var args = invocation.positionalArguments; | 1293 var args = invocation.positionalArguments; |
| 1287 if (invocation.isGetter) { | 1294 if (invocation.isGetter) { |
| 1288 method = 'get $method'; | 1295 method = 'get $method'; |
| 1289 } else if (method.startsWith('get:')) { | 1296 } else if (invocation.isSetter) { |
| 1290 // TODO(gram): Remove this when VM handles the isGetter version above. | 1297 method = 'set $method'; |
| 1291 method = 'get ${method.substring(4)}'; | 1298 // Remove the trailing '='. |
| 1299 if (method[method.length-1] == '=') { |
| 1300 method = method.substring(0, method.length - 1); |
| 1301 } |
| 1292 } | 1302 } |
| 1293 bool matchedMethodName = false; | 1303 bool matchedMethodName = false; |
| 1294 MatchState matchState = new MatchState(); | 1304 MatchState matchState = new MatchState(); |
| 1295 for (String k in _behaviors.keys) { | 1305 for (String k in _behaviors.keys) { |
| 1296 Behavior b = _behaviors[k]; | 1306 Behavior b = _behaviors[k]; |
| 1297 if (b.matcher.nameFilter.matches(method, matchState)) { | 1307 if (b.matcher.nameFilter.matches(method, matchState)) { |
| 1298 matchedMethodName = true; | 1308 matchedMethodName = true; |
| 1299 } | 1309 } |
| 1300 if (b.matches(method, args)) { | 1310 if (b.matches(method, args)) { |
| 1301 List actions = b.actions; | 1311 List actions = b.actions; |
| (...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1465 } | 1475 } |
| 1466 } | 1476 } |
| 1467 } | 1477 } |
| 1468 | 1478 |
| 1469 /** Clear both logs and behavior. */ | 1479 /** Clear both logs and behavior. */ |
| 1470 void reset() { | 1480 void reset() { |
| 1471 resetBehavior(); | 1481 resetBehavior(); |
| 1472 clearLogs(); | 1482 clearLogs(); |
| 1473 } | 1483 } |
| 1474 } | 1484 } |
| OLD | NEW |