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 * ## Installing ## | 8 * ## Installing ## |
9 * | 9 * |
10 * Use [pub][] to install this package. Add the following to your `pubspec.yaml` | 10 * Use [pub][] to install this package. Add the following to your `pubspec.yaml` |
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
181 | 181 |
182 /** Throw a supplied value. */ | 182 /** Throw a supplied value. */ |
183 static const THROW = const Action._('THROW'); | 183 static const THROW = const Action._('THROW'); |
184 | 184 |
185 /** Call a supplied function. */ | 185 /** Call a supplied function. */ |
186 static const PROXY = const Action._('PROXY'); | 186 static const PROXY = const Action._('PROXY'); |
187 | 187 |
188 const Action._(this.name); | 188 const Action._(this.name); |
189 | 189 |
190 final String name; | 190 final String name; |
| 191 |
| 192 String toString() => 'Action: $name'; |
191 } | 193 } |
192 | 194 |
193 /** | 195 /** |
194 * The behavior of a method call in the mock library is specified | 196 * The behavior of a method call in the mock library is specified |
195 * with [Responder]s. A [Responder] has a [value] to throw | 197 * with [Responder]s. A [Responder] has a [value] to throw |
196 * or return (depending on the type of [action]), | 198 * or return (depending on the type of [action]), |
197 * and can either be one-shot, multi-shot, or infinitely repeating, | 199 * and can either be one-shot, multi-shot, or infinitely repeating, |
198 * depending on the value of [count (1, greater than 1, or 0 respectively). | 200 * depending on the value of [count (1, greater than 1, or 0 respectively). |
199 */ | 201 */ |
200 class Responder { | 202 class Responder { |
201 var value; | 203 final Object value; |
202 Action action; | 204 final Action action; |
203 int count; | 205 int count; |
204 Responder(this.value, [this.count = 1, this.action = Action.RETURN]); | 206 Responder(this.value, [this.count = 1, this.action = Action.RETURN]); |
205 } | 207 } |
206 | 208 |
207 /** | 209 /** |
208 * A [CallMatcher] is a special matcher used to match method calls (i.e. | 210 * A [CallMatcher] is a special matcher used to match method calls (i.e. |
209 * a method name and set of arguments). It is not a [Matcher] like the | 211 * a method name and set of arguments). It is not a [Matcher] like the |
210 * unit test [Matcher], but instead represents a method name and a | 212 * unit test [Matcher], but instead represents a method name and a |
211 * collection of [Matcher]s, one per argument, that will be applied | 213 * collection of [Matcher]s, one per argument, that will be applied |
212 * to the parameters to decide if the method call is a match. | 214 * to the parameters to decide if the method call is a match. |
(...skipping 1030 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1243 /** The shared log used for named mocks. */ | 1245 /** The shared log used for named mocks. */ |
1244 LogEntryList sharedLog = null; | 1246 LogEntryList sharedLog = null; |
1245 | 1247 |
1246 /** The base class for all mocked objects. */ | 1248 /** The base class for all mocked objects. */ |
1247 @proxy | 1249 @proxy |
1248 class Mock { | 1250 class Mock { |
1249 /** The mock name. Needed if the log is shared; optional otherwise. */ | 1251 /** The mock name. Needed if the log is shared; optional otherwise. */ |
1250 final String name; | 1252 final String name; |
1251 | 1253 |
1252 /** The set of [Behavior]s supported. */ | 1254 /** The set of [Behavior]s supported. */ |
1253 LinkedHashMap<String,Behavior> _behaviors; | 1255 final LinkedHashMap<String,Behavior> _behaviors; |
1254 | |
1255 /** The [log] of calls made. Only used if [name] is null. */ | |
1256 LogEntryList log; | |
1257 | 1256 |
1258 /** How to handle unknown method calls - swallow or throw. */ | 1257 /** How to handle unknown method calls - swallow or throw. */ |
1259 final bool _throwIfNoBehavior; | 1258 final bool _throwIfNoBehavior; |
1260 | 1259 |
1261 /** For spys, the real object that we are spying on. */ | 1260 /** For spys, the real object that we are spying on. */ |
1262 Object _realObject; | 1261 final Object _realObject; |
| 1262 |
| 1263 /** The [log] of calls made. Only used if [name] is null. */ |
| 1264 LogEntryList log; |
1263 | 1265 |
1264 /** Whether to create an audit log or not. */ | 1266 /** Whether to create an audit log or not. */ |
1265 bool _logging; | 1267 bool _logging; |
1266 | 1268 |
1267 bool get logging => _logging; | 1269 bool get logging => _logging; |
1268 set logging(bool value) { | 1270 set logging(bool value) { |
1269 if (value && log == null) { | 1271 if (value && log == null) { |
1270 log = new LogEntryList(); | 1272 log = new LogEntryList(); |
1271 } | 1273 } |
1272 _logging = value; | 1274 _logging = value; |
1273 } | 1275 } |
1274 | 1276 |
1275 /** | 1277 /** |
1276 * Default constructor. Unknown method calls are allowed and logged, | 1278 * Default constructor. Unknown method calls are allowed and logged, |
1277 * the mock has no name, and has its own log. | 1279 * the mock has no name, and has its own log. |
1278 */ | 1280 */ |
1279 Mock() : _throwIfNoBehavior = false, log = null, name = null { | 1281 Mock() : |
| 1282 _throwIfNoBehavior = false, log = null, name = null, _realObject = null, |
| 1283 _behaviors = new LinkedHashMap<String,Behavior>() { |
1280 logging = true; | 1284 logging = true; |
1281 _behaviors = new LinkedHashMap<String,Behavior>(); | |
1282 } | 1285 } |
1283 | 1286 |
1284 /** | 1287 /** |
1285 * This constructor makes a mock that has a [name] and possibly uses | 1288 * This constructor makes a mock that has a [name] and possibly uses |
1286 * a shared [log]. If [throwIfNoBehavior] is true, any calls to methods | 1289 * a shared [log]. If [throwIfNoBehavior] is true, any calls to methods |
1287 * that have no defined behaviors will throw an exception; otherwise they | 1290 * that have no defined behaviors will throw an exception; otherwise they |
1288 * will be allowed and logged (but will not do anything). | 1291 * will be allowed and logged (but will not do anything). |
1289 * If [enableLogging] is false, no logging will be done initially (whether | 1292 * If [enableLogging] is false, no logging will be done initially (whether |
1290 * or not a [log] is supplied), but [logging] can be set to true later. | 1293 * or not a [log] is supplied), but [logging] can be set to true later. |
1291 */ | 1294 */ |
1292 Mock.custom({this.name, | 1295 Mock.custom({this.name, |
1293 this.log, | 1296 this.log, |
1294 throwIfNoBehavior: false, | 1297 throwIfNoBehavior: false, |
1295 enableLogging: true}) : _throwIfNoBehavior = throwIfNoBehavior { | 1298 enableLogging: true}) |
| 1299 : _throwIfNoBehavior = throwIfNoBehavior, _realObject = null, |
| 1300 _behaviors = new LinkedHashMap<String,Behavior>() { |
1296 if (log != null && name == null) { | 1301 if (log != null && name == null) { |
1297 throw new Exception("Mocks with shared logs must have a name."); | 1302 throw new Exception("Mocks with shared logs must have a name."); |
1298 } | 1303 } |
1299 logging = enableLogging; | 1304 logging = enableLogging; |
1300 _behaviors = new LinkedHashMap<String,Behavior>(); | |
1301 } | 1305 } |
1302 | 1306 |
1303 /** | 1307 /** |
1304 * This constructor creates a spy with no user-defined behavior. | 1308 * This constructor creates a spy with no user-defined behavior. |
1305 * This is simply a proxy for a real object that passes calls | 1309 * This is simply a proxy for a real object that passes calls |
1306 * through to that real object but captures an audit trail of | 1310 * through to that real object but captures an audit trail of |
1307 * calls made to the object that can be queried and validated | 1311 * calls made to the object that can be queried and validated |
1308 * later. | 1312 * later. |
1309 */ | 1313 */ |
1310 Mock.spy(this._realObject, {this.name, this.log}) | 1314 Mock.spy(this._realObject, {this.name, this.log}) |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1358 var result = mirror.delegate(invocation); | 1362 var result = mirror.delegate(invocation); |
1359 log.add(new LogEntry(name, method, args, Action.PROXY, result)); | 1363 log.add(new LogEntry(name, method, args, Action.PROXY, result)); |
1360 return result; | 1364 return result; |
1361 } catch (e) { | 1365 } catch (e) { |
1362 log.add(new LogEntry(name, method, args, Action.THROW, e)); | 1366 log.add(new LogEntry(name, method, args, Action.THROW, e)); |
1363 throw e; | 1367 throw e; |
1364 } | 1368 } |
1365 } | 1369 } |
1366 bool matchedMethodName = false; | 1370 bool matchedMethodName = false; |
1367 Map matchState = {}; | 1371 Map matchState = {}; |
| 1372 |
| 1373 print("hanging with behaviors"); |
| 1374 print(new Map.from(_behaviors)); |
1368 for (String k in _behaviors.keys) { | 1375 for (String k in _behaviors.keys) { |
1369 Behavior b = _behaviors[k]; | 1376 Behavior b = _behaviors[k]; |
1370 if (b.matcher.nameFilter.matches(method, matchState)) { | 1377 if (b.matcher.nameFilter.matches(method, matchState)) { |
1371 matchedMethodName = true; | 1378 matchedMethodName = true; |
1372 } | 1379 } |
1373 if (b.matches(method, args)) { | 1380 if (b.matches(method, args)) { |
1374 List actions = b.actions; | 1381 List actions = b.actions; |
1375 if (actions == null || actions.length == 0) { | 1382 if (actions == null || actions.length == 0) { |
1376 continue; // No return values left in this Behavior. | 1383 continue; // No return values left in this Behavior. |
1377 } | 1384 } |
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1539 } | 1546 } |
1540 } | 1547 } |
1541 } | 1548 } |
1542 | 1549 |
1543 /** Clear both logs and behavior. */ | 1550 /** Clear both logs and behavior. */ |
1544 void reset() { | 1551 void reset() { |
1545 resetBehavior(); | 1552 resetBehavior(); |
1546 clearLogs(); | 1553 clearLogs(); |
1547 } | 1554 } |
1548 } | 1555 } |
OLD | NEW |