| 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 | 
|---|