| OLD | NEW |
| (Empty) | |
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file |
| 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. |
| 4 |
| 5 library mock.call_matcher; |
| 6 |
| 7 import 'package:matcher/matcher.dart'; |
| 8 |
| 9 import 'util.dart'; |
| 10 |
| 11 /** |
| 12 * A [CallMatcher] is a special matcher used to match method calls (i.e. |
| 13 * a method name and set of arguments). It is not a [Matcher] like the |
| 14 * unit test [Matcher], but instead represents a method name and a |
| 15 * collection of [Matcher]s, one per argument, that will be applied |
| 16 * to the parameters to decide if the method call is a match. |
| 17 */ |
| 18 class CallMatcher { |
| 19 Matcher nameFilter; |
| 20 List<Matcher> argMatchers; |
| 21 |
| 22 /** |
| 23 * Constructor for [CallMatcher]. [name] can be null to |
| 24 * match anything, or a literal [String], a predicate [Function], |
| 25 * or a [Matcher]. The various arguments can be scalar values or |
| 26 * [Matcher]s. |
| 27 */ |
| 28 CallMatcher([name, |
| 29 arg0 = NO_ARG, |
| 30 arg1 = NO_ARG, |
| 31 arg2 = NO_ARG, |
| 32 arg3 = NO_ARG, |
| 33 arg4 = NO_ARG, |
| 34 arg5 = NO_ARG, |
| 35 arg6 = NO_ARG, |
| 36 arg7 = NO_ARG, |
| 37 arg8 = NO_ARG, |
| 38 arg9 = NO_ARG]) { |
| 39 if (name == null) { |
| 40 nameFilter = anything; |
| 41 } else { |
| 42 nameFilter = wrapMatcher(name); |
| 43 } |
| 44 argMatchers = new List<Matcher>(); |
| 45 if (identical(arg0, NO_ARG)) return; |
| 46 argMatchers.add(wrapMatcher(arg0)); |
| 47 if (identical(arg1, NO_ARG)) return; |
| 48 argMatchers.add(wrapMatcher(arg1)); |
| 49 if (identical(arg2, NO_ARG)) return; |
| 50 argMatchers.add(wrapMatcher(arg2)); |
| 51 if (identical(arg3, NO_ARG)) return; |
| 52 argMatchers.add(wrapMatcher(arg3)); |
| 53 if (identical(arg4, NO_ARG)) return; |
| 54 argMatchers.add(wrapMatcher(arg4)); |
| 55 if (identical(arg5, NO_ARG)) return; |
| 56 argMatchers.add(wrapMatcher(arg5)); |
| 57 if (identical(arg6, NO_ARG)) return; |
| 58 argMatchers.add(wrapMatcher(arg6)); |
| 59 if (identical(arg7, NO_ARG)) return; |
| 60 argMatchers.add(wrapMatcher(arg7)); |
| 61 if (identical(arg8, NO_ARG)) return; |
| 62 argMatchers.add(wrapMatcher(arg8)); |
| 63 if (identical(arg9, NO_ARG)) return; |
| 64 argMatchers.add(wrapMatcher(arg9)); |
| 65 } |
| 66 |
| 67 /** |
| 68 * We keep our behavior specifications in a Map, which is keyed |
| 69 * by the [CallMatcher]. To make the keys unique and to get a |
| 70 * descriptive value for the [CallMatcher] we have this override |
| 71 * of [toString()]. |
| 72 */ |
| 73 String toString() { |
| 74 Description d = new StringDescription(); |
| 75 d.addDescriptionOf(nameFilter); |
| 76 // If the nameFilter was a simple string - i.e. just a method name - |
| 77 // strip the quotes to make this more natural in appearance. |
| 78 if (d.toString()[0] == "'") { |
| 79 d.replace(d.toString().substring(1, d.toString().length - 1)); |
| 80 } |
| 81 d.add('('); |
| 82 for (var i = 0; i < argMatchers.length; i++) { |
| 83 if (i > 0) d.add(', '); |
| 84 d.addDescriptionOf(argMatchers[i]); |
| 85 } |
| 86 d.add(')'); |
| 87 return d.toString(); |
| 88 } |
| 89 |
| 90 /** |
| 91 * Given a [method] name and list of [arguments], return true |
| 92 * if it matches this [CallMatcher. |
| 93 */ |
| 94 bool matches(String method, List arguments) { |
| 95 var matchState = {}; |
| 96 if (!nameFilter.matches(method, matchState)) { |
| 97 return false; |
| 98 } |
| 99 var numArgs = (arguments == null) ? 0 : arguments.length; |
| 100 if (numArgs < argMatchers.length) { |
| 101 throw new Exception("Less arguments than matchers for $method."); |
| 102 } |
| 103 for (var i = 0; i < argMatchers.length; i++) { |
| 104 if (!argMatchers[i].matches(arguments[i], matchState)) { |
| 105 return false; |
| 106 } |
| 107 } |
| 108 return true; |
| 109 } |
| 110 } |
| 111 |
| 112 /** |
| 113 * Returns a [CallMatcher] for the specified signature. [method] can be |
| 114 * null to match anything, or a literal [String], a predicate [Function], |
| 115 * or a [Matcher]. The various arguments can be scalar values or [Matcher]s. |
| 116 * To match getters and setters, use "get " and "set " prefixes on the names. |
| 117 * For example, for a property "foo", you could use "get foo" and "set foo" |
| 118 * as literal string arguments to callsTo to match the getter and setter |
| 119 * of "foo". |
| 120 */ |
| 121 CallMatcher callsTo([method, |
| 122 arg0 = NO_ARG, |
| 123 arg1 = NO_ARG, |
| 124 arg2 = NO_ARG, |
| 125 arg3 = NO_ARG, |
| 126 arg4 = NO_ARG, |
| 127 arg5 = NO_ARG, |
| 128 arg6 = NO_ARG, |
| 129 arg7 = NO_ARG, |
| 130 arg8 = NO_ARG, |
| 131 arg9 = NO_ARG]) { |
| 132 return new CallMatcher(method, arg0, arg1, arg2, arg3, arg4, |
| 133 arg5, arg6, arg7, arg8, arg9); |
| 134 } |
| OLD | NEW |