| 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 * The error formatter for mocking is a bit different from the default one | 6 * The error formatter for mocking is a bit different from the default one |
| 7 * for unit testing; instead of the third argument being a 'reason' | 7 * for unit testing; instead of the third argument being a 'reason' |
| 8 * it is instead a [signature] describing the method signature filter | 8 * it is instead a [signature] describing the method signature filter |
| 9 * that was used to select the logs that were verified. | 9 * that was used to select the logs that were verified. |
| 10 */ | 10 */ |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 131 | 131 |
| 132 /** | 132 /** |
| 133 * We keep our behavior specifications in a Map, which is keyed | 133 * We keep our behavior specifications in a Map, which is keyed |
| 134 * by the [CallMatcher]. To make the keys unique and to get a | 134 * by the [CallMatcher]. To make the keys unique and to get a |
| 135 * descriptive value for the [CallMatcher] we have this override | 135 * descriptive value for the [CallMatcher] we have this override |
| 136 * of [toString()]. | 136 * of [toString()]. |
| 137 */ | 137 */ |
| 138 String toString() { | 138 String toString() { |
| 139 Description d = new StringDescription(); | 139 Description d = new StringDescription(); |
| 140 d.addDescriptionOf(nameFilter); | 140 d.addDescriptionOf(nameFilter); |
| 141 // If the nameFilter was a simple string - i.e. just a method name - |
| 142 // strip the quotes to make this more natural in appearance. |
| 143 if (d.toString()[0] == "'") { |
| 144 d.replace(d.toString().substring(1, d.toString().length - 1)); |
| 145 } |
| 141 d.add('('); | 146 d.add('('); |
| 142 for (var i = 0; i < argMatchers.length; i++) { | 147 for (var i = 0; i < argMatchers.length; i++) { |
| 143 if (i > 0) d.add(', '); | 148 if (i > 0) d.add(', '); |
| 144 d.addDescriptionOf(argMatchers[i]); | 149 d.addDescriptionOf(argMatchers[i]); |
| 145 } | 150 } |
| 146 d.add(')'); | 151 d.add(')'); |
| 147 return d.toString(); | 152 return d.toString(); |
| 148 } | 153 } |
| 149 | 154 |
| 150 /** | 155 /** |
| (...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 309 d.addDescriptionOf(args[i]); | 314 d.addDescriptionOf(args[i]); |
| 310 } | 315 } |
| 311 d.add(') ${action == _Action.THROW ? "threw" : "returned"} '); | 316 d.add(') ${action == _Action.THROW ? "threw" : "returned"} '); |
| 312 d.addDescriptionOf(value); | 317 d.addDescriptionOf(value); |
| 313 return d.toString(); | 318 return d.toString(); |
| 314 } | 319 } |
| 315 } | 320 } |
| 316 | 321 |
| 317 /** Utility function for optionally qualified method names */ | 322 /** Utility function for optionally qualified method names */ |
| 318 String _qualifiedName(owner, String method) { | 323 String _qualifiedName(owner, String method) { |
| 319 if (owner == null) { | 324 if (owner == null || owner === anything) { |
| 320 return method; | 325 return method; |
| 321 } else if (owner is Matcher) { | 326 } else if (owner is Matcher) { |
| 322 Description d = new StringDescription(); | 327 Description d = new StringDescription(); |
| 323 d.addDescriptionOf(owner); | 328 d.addDescriptionOf(owner); |
| 324 d.add('.'); | 329 d.add('.'); |
| 325 d.add(method); | 330 d.add(method); |
| 326 return d.toString(); | 331 return d.toString(); |
| 327 } else { | 332 } else { |
| 328 return '$owner.$method'; | 333 return '$owner.$method'; |
| 329 } | 334 } |
| (...skipping 11 matching lines...) Expand all Loading... |
| 341 logs = new List<LogEntry>(); | 346 logs = new List<LogEntry>(); |
| 342 } | 347 } |
| 343 | 348 |
| 344 /** Add a [LogEntry] to the log. */ | 349 /** Add a [LogEntry] to the log. */ |
| 345 add(LogEntry entry) => logs.add(entry); | 350 add(LogEntry entry) => logs.add(entry); |
| 346 | 351 |
| 347 /** | 352 /** |
| 348 * Create a new [LogEntryList] consisting of [LogEntry]s from | 353 * Create a new [LogEntryList] consisting of [LogEntry]s from |
| 349 * this list that match the specified [mockNameFilter] and [logFilter]. | 354 * this list that match the specified [mockNameFilter] and [logFilter]. |
| 350 * [mockNameFilter] can be null, a [String], a predicate [Function], | 355 * [mockNameFilter] can be null, a [String], a predicate [Function], |
| 351 * or a [Matcher]. If [mockNameFilter] is null, only Mocks with no name | 356 * or a [Matcher]. If [mockNameFilter] is null, this is the same as |
| 352 * will be checked. | 357 * [anything]. |
| 353 * If [logFilter] is null, all entries in the log will be returned. | 358 * If [logFilter] is null, all entries in the log will be returned. |
| 354 * If [destructive] is true, the log entries are removed from the | 359 * If [destructive] is true, the log entries are removed from the |
| 355 * original list. | 360 * original list. |
| 356 */ | 361 */ |
| 357 LogEntryList getMatches([mockNameFilter, | 362 LogEntryList getMatches([mockNameFilter, |
| 358 CallMatcher logFilter, | 363 CallMatcher logFilter, |
| 359 Matcher actionMatcher, | 364 Matcher actionMatcher, |
| 360 bool destructive = false]) { | 365 bool destructive = false]) { |
| 361 mockNameFilter = wrapMatcher(mockNameFilter); | 366 if (mockNameFilter == null) { |
| 367 mockNameFilter = anything; |
| 368 } else { |
| 369 mockNameFilter = wrapMatcher(mockNameFilter); |
| 370 } |
| 362 if (logFilter == null) { | 371 if (logFilter == null) { |
| 363 logFilter = new CallMatcher(); | 372 logFilter = new CallMatcher(); |
| 364 } | 373 } |
| 365 String filterName = _qualifiedName(mockNameFilter, logFilter.toString()); | 374 String filterName = _qualifiedName(mockNameFilter, logFilter.toString()); |
| 366 LogEntryList rtn = new LogEntryList(filterName); | 375 LogEntryList rtn = new LogEntryList(filterName); |
| 367 for (var i = 0; i < logs.length; i++) { | 376 for (var i = 0; i < logs.length; i++) { |
| 368 LogEntry entry = logs[i]; | 377 LogEntry entry = logs[i]; |
| 369 if (!mockNameFilter.matches(entry.mockName)) { | 378 if (!mockNameFilter.matches(entry.mockName)) { |
| 370 continue; | 379 continue; |
| 371 } | 380 } |
| (...skipping 390 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 762 * a shared [log]. If [throwIfNoBehavior] is true, any calls to methods | 771 * a shared [log]. If [throwIfNoBehavior] is true, any calls to methods |
| 763 * that have no defined behaviors will throw an exception; otherwise they | 772 * that have no defined behaviors will throw an exception; otherwise they |
| 764 * will be allowed and logged (but will not do anything). | 773 * will be allowed and logged (but will not do anything). |
| 765 * If [enableLogging] is false, no logging will be done initially (whether | 774 * If [enableLogging] is false, no logging will be done initially (whether |
| 766 * or not a [log] is supplied), but [logging] can be set to true later. | 775 * or not a [log] is supplied), but [logging] can be set to true later. |
| 767 */ | 776 */ |
| 768 Mock.custom([this.name, | 777 Mock.custom([this.name, |
| 769 this.log, | 778 this.log, |
| 770 throwIfNoBehavior = false, | 779 throwIfNoBehavior = false, |
| 771 enableLogging = true]) : _throwIfNoBehavior = throwIfNoBehavior { | 780 enableLogging = true]) : _throwIfNoBehavior = throwIfNoBehavior { |
| 781 if (log != null && name == null) { |
| 782 throw new Exception("Mocks with shared logs must have a name."); |
| 783 } |
| 772 logging = enableLogging; | 784 logging = enableLogging; |
| 773 _behaviors = new Map<String,Behavior>(); | 785 _behaviors = new Map<String,Behavior>(); |
| 774 } | 786 } |
| 775 | 787 |
| 776 /** | 788 /** |
| 777 * [when] is used to create a new or extend an existing [Behavior]. | 789 * [when] is used to create a new or extend an existing [Behavior]. |
| 778 * A [CallMatcher] [filter] must be supplied, and the [Behavior]s for | 790 * A [CallMatcher] [filter] must be supplied, and the [Behavior]s for |
| 779 * that signature are returned (being created first if needed). | 791 * that signature are returned (being created first if needed). |
| 780 * | 792 * |
| 781 * Typical use case: | 793 * Typical use case: |
| (...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 935 if (log == null) { | 947 if (log == null) { |
| 936 // This means we created the mock with logging off and have never turned | 948 // This means we created the mock with logging off and have never turned |
| 937 // it on, so it doesn't make sense to get logs from such a mock. | 949 // it on, so it doesn't make sense to get logs from such a mock. |
| 938 throw new | 950 throw new |
| 939 Exception("Can't retrieve logs when logging was never enabled."); | 951 Exception("Can't retrieve logs when logging was never enabled."); |
| 940 } else { | 952 } else { |
| 941 return log.getMatches(name, logFilter, actionMatcher, destructive); | 953 return log.getMatches(name, logFilter, actionMatcher, destructive); |
| 942 } | 954 } |
| 943 } | 955 } |
| 944 } | 956 } |
| OLD | NEW |