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 |