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 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
77 * A [CallMatcher] is a special matcher used to match method calls (i.e. | 77 * A [CallMatcher] is a special matcher used to match method calls (i.e. |
78 * a method name and set of arguments). It is not a [Matcher] like the | 78 * a method name and set of arguments). It is not a [Matcher] like the |
79 * unit test [Matcher], but instead represents a method name and a | 79 * unit test [Matcher], but instead represents a method name and a |
80 * collection of [Matcher]s, one per argument, that will be applied | 80 * collection of [Matcher]s, one per argument, that will be applied |
81 * to the parameters to decide if the method call is a match. | 81 * to the parameters to decide if the method call is a match. |
82 */ | 82 */ |
83 class CallMatcher { | 83 class CallMatcher { |
84 String name; | 84 String name; |
85 List<Matcher> argMatchers; | 85 List<Matcher> argMatchers; |
86 | 86 |
87 CallMatcher(this.name, [ | 87 CallMatcher([this.name, |
88 arg0 = _noArg, | 88 arg0 = _noArg, |
89 arg1 = _noArg, | 89 arg1 = _noArg, |
90 arg2 = _noArg, | 90 arg2 = _noArg, |
91 arg3 = _noArg, | 91 arg3 = _noArg, |
92 arg4 = _noArg, | 92 arg4 = _noArg, |
93 arg5 = _noArg, | 93 arg5 = _noArg, |
94 arg6 = _noArg, | 94 arg6 = _noArg, |
95 arg7 = _noArg, | 95 arg7 = _noArg, |
96 arg8 = _noArg, | 96 arg8 = _noArg, |
97 arg9 = _noArg]) { | 97 arg9 = _noArg]) { |
(...skipping 21 matching lines...) Expand all Loading... |
119 } | 119 } |
120 | 120 |
121 /** | 121 /** |
122 * We keep our behavior specifications in a Map, which is keyed | 122 * We keep our behavior specifications in a Map, which is keyed |
123 * by the [CallMatcher]. To make the keys unique and to get a | 123 * by the [CallMatcher]. To make the keys unique and to get a |
124 * descriptive value for the [CallMatcher] we have this override | 124 * descriptive value for the [CallMatcher] we have this override |
125 * of [toString()]. | 125 * of [toString()]. |
126 */ | 126 */ |
127 String toString() { | 127 String toString() { |
128 Description d = new StringDescription(); | 128 Description d = new StringDescription(); |
129 d.add(name).add('('); | 129 if (name != null) d.add(name); |
| 130 d.add('('); |
130 for (var i = 0; i < argMatchers.length; i++) { | 131 for (var i = 0; i < argMatchers.length; i++) { |
131 if (i > 0) d.add(', '); | 132 if (i > 0) d.add(', '); |
132 d.addDescriptionOf(argMatchers[i]); | 133 d.addDescriptionOf(argMatchers[i]); |
133 } | 134 } |
134 d.add(')'); | 135 d.add(')'); |
135 return d.toString(); | 136 return d.toString(); |
136 } | 137 } |
137 | 138 |
138 /** | 139 /** |
139 * Given a [method] name and list of [arguments], return true | 140 * Given a [method] name and list of [arguments], return true |
140 * if it matches this [CallMatcher. | 141 * if it matches this [CallMatcher. |
141 */ | 142 */ |
142 bool matches(String method, List arguments) { | 143 bool matches(String method, List arguments) { |
143 if (method != this.name) { | 144 if (this.name != null && method != this.name) { |
144 return false; | 145 return false; |
145 } | 146 } |
146 if (arguments.length < argMatchers.length) { | 147 if (arguments.length < argMatchers.length) { |
147 throw new Exception("Less arguments than matchers for $name"); | 148 throw new Exception("Less arguments than matchers for $name"); |
148 } | 149 } |
149 for (var i = 0; i < argMatchers.length; i++) { | 150 for (var i = 0; i < argMatchers.length; i++) { |
150 if (!argMatchers[i].matches(arguments[i])) { | 151 if (!argMatchers[i].matches(arguments[i])) { |
151 return false; | 152 return false; |
152 } | 153 } |
153 } | 154 } |
154 return true; | 155 return true; |
155 } | 156 } |
156 } | 157 } |
157 | 158 |
158 /** [callsTo] returns a CallMatcher for the specified signature. */ | 159 /** [callsTo] returns a CallMatcher for the specified signature. */ |
159 CallMatcher callsTo(String method, [ | 160 CallMatcher callsTo([String method, |
160 arg0 = _noArg, | 161 arg0 = _noArg, |
161 arg1 = _noArg, | 162 arg1 = _noArg, |
162 arg2 = _noArg, | 163 arg2 = _noArg, |
163 arg3 = _noArg, | 164 arg3 = _noArg, |
164 arg4 = _noArg, | 165 arg4 = _noArg, |
165 arg5 = _noArg, | 166 arg5 = _noArg, |
166 arg6 = _noArg, | 167 arg6 = _noArg, |
167 arg7 = _noArg, | 168 arg7 = _noArg, |
168 arg8 = _noArg, | 169 arg8 = _noArg, |
169 arg9 = _noArg]) { | 170 arg9 = _noArg]) { |
170 return new CallMatcher(method, arg0, arg1, arg2, arg3, arg4, | 171 return new CallMatcher(method, arg0, arg1, arg2, arg3, arg4, |
171 arg5, arg6, arg7, arg8, arg9); | 172 arg5, arg6, arg7, arg8, arg9); |
172 } | 173 } |
173 | 174 |
174 /** | 175 /** |
175 * A [Behavior] represents how a [Mock] will respond to one particular | 176 * A [Behavior] represents how a [Mock] will respond to one particular |
176 * type of method call. | 177 * type of method call. |
177 */ | 178 */ |
178 class Behavior { | 179 class Behavior { |
179 CallMatcher matcher; // The method call matcher. | 180 CallMatcher matcher; // The method call matcher. |
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
318 LogEntryList([this.filter]) { | 319 LogEntryList([this.filter]) { |
319 logs = new List<LogEntry>(); | 320 logs = new List<LogEntry>(); |
320 } | 321 } |
321 | 322 |
322 /** Add a [LogEntry] to the log. */ | 323 /** Add a [LogEntry] to the log. */ |
323 add(LogEntry entry) => logs.add(entry); | 324 add(LogEntry entry) => logs.add(entry); |
324 | 325 |
325 /** | 326 /** |
326 * Create a new [LogEntryList] consisting of [LogEntry]s from | 327 * Create a new [LogEntryList] consisting of [LogEntry]s from |
327 * this list that match the specified [mockName] and [logFilter]. | 328 * this list that match the specified [mockName] and [logFilter]. |
328 * If [mockName] is null, all entries will be checked. If [destructive] | 329 * If [mockName] is null, all entries will be checked. If [logFilter] |
| 330 * is null, all entries in the log will be returned. If [destructive] |
329 * is true, the log entries are removed from the original list. | 331 * is true, the log entries are removed from the original list. |
330 */ | 332 */ |
331 LogEntryList getMatches(String mockName, | 333 LogEntryList getMatches([String mockName, |
332 CallMatcher logFilter, | 334 CallMatcher logFilter, |
333 [Matcher actionMatcher, | 335 Matcher actionMatcher, |
334 bool destructive = false]) { | 336 bool destructive = false]) { |
| 337 if (logFilter == null) { |
| 338 logFilter = new CallMatcher(); |
| 339 } |
335 String filterName = _qualifiedName(mockName, logFilter.toString()); | 340 String filterName = _qualifiedName(mockName, logFilter.toString()); |
336 LogEntryList rtn = new LogEntryList(filterName); | 341 LogEntryList rtn = new LogEntryList(filterName); |
337 for (var i = 0; i < logs.length; i++) { | 342 for (var i = 0; i < logs.length; i++) { |
338 LogEntry entry = logs[i]; | 343 LogEntry entry = logs[i]; |
339 if (mockName != null && mockName != entry.mockName) { | 344 if (mockName != null && mockName != entry.mockName) { |
340 continue; | 345 continue; |
341 } | 346 } |
342 if (logFilter.matches(entry.methodName, entry.args)) { | 347 if (logFilter.matches(entry.methodName, entry.args)) { |
343 if (actionMatcher == null || actionMatcher.matches(entry)) { | 348 if (actionMatcher == null || actionMatcher.matches(entry)) { |
344 rtn.add(entry); | 349 rtn.add(entry); |
(...skipping 519 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
864 * [LogEntry]s. If [destructive] is false (the default) the matching | 869 * [LogEntry]s. If [destructive] is false (the default) the matching |
865 * calls are left in the log, else they are removed. Removal allows | 870 * calls are left in the log, else they are removed. Removal allows |
866 * us to verify a set of interactions and then verify that there are | 871 * us to verify a set of interactions and then verify that there are |
867 * no other interactions left. [actionMatcher] can be used to further | 872 * no other interactions left. [actionMatcher] can be used to further |
868 * restrict the returned logs based on the action the mock performed. | 873 * restrict the returned logs based on the action the mock performed. |
869 * | 874 * |
870 * Typical usage: | 875 * Typical usage: |
871 * | 876 * |
872 * getLogs(callsTo(...)).verify(...); | 877 * getLogs(callsTo(...)).verify(...); |
873 */ | 878 */ |
874 LogEntryList getLogs(CallMatcher logFilter, [Matcher actionMatcher, | 879 LogEntryList getLogs([CallMatcher logFilter, |
875 bool destructive = false]) { | 880 Matcher actionMatcher, |
| 881 bool destructive = false]) { |
876 return log.getMatches(name, logFilter, actionMatcher, destructive); | 882 return log.getMatches(name, logFilter, actionMatcher, destructive); |
877 } | 883 } |
878 } | 884 } |
OLD | NEW |