Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(69)

Side by Side Diff: lib/unittest/mock.dart

Issue 10832058: Improved the way we generate mismatch descriptions. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « lib/unittest/matcher.dart ('k') | lib/unittest/numeric_matchers.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 */
11 String _mockingErrorFormatter(actual, Matcher matcher, String signature) { 11 String _mockingErrorFormatter(actual, Matcher matcher, String signature,
12 MatchState matchState, bool verbose) {
12 var description = new StringDescription(); 13 var description = new StringDescription();
13 description.add('Expected ${signature} ').addDescriptionOf(matcher). 14 description.add('Expected ${signature} ').addDescriptionOf(matcher).
14 add('\n but: '); 15 add('\n but: ');
15 matcher.describeMismatch(actual, description).add('.'); 16 matcher.describeMismatch(actual, description, matchState, verbose).add('.');
16 return description.toString(); 17 return description.toString();
17 } 18 }
18 19
19 /** 20 /**
20 * The failure handler for the [expect()] calls that occur in [verify()] 21 * The failure handler for the [expect()] calls that occur in [verify()]
21 * methods in the mock objects. This calls the real failure handler used 22 * methods in the mock objects. This calls the real failure handler used
22 * by the unit test library after formatting the error message with 23 * by the unit test library after formatting the error message with
23 * the custom formatter. 24 * the custom formatter.
24 */ 25 */
25 class _MockFailureHandler implements FailureHandler { 26 class _MockFailureHandler implements FailureHandler {
26 FailureHandler proxy; 27 FailureHandler proxy;
27 _MockFailureHandler(this.proxy); 28 _MockFailureHandler(this.proxy);
28 void fail(String reason) { 29 void fail(String reason) {
29 proxy.fail(reason); 30 proxy.fail(reason);
30 } 31 }
31 void failMatch(actual, Matcher matcher, String reason) { 32 void failMatch(actual, Matcher matcher, String reason,
32 proxy.fail(_mockingErrorFormatter(actual, matcher, reason)); 33 MatchState matchState, bool verbose) {
34 proxy.fail(_mockingErrorFormatter(actual, matcher, reason,
35 matchState, verbose));
33 } 36 }
34 } 37 }
35 38
36 _MockFailureHandler _mockFailureHandler = null; 39 _MockFailureHandler _mockFailureHandler = null;
37 40
38 /** 41 /**
39 * [_noArg] is a sentinel value representing no argument. 42 * [_noArg] is a sentinel value representing no argument.
40 */ 43 */
41 final _noArg = const _Sentinel(); 44 final _noArg = const _Sentinel();
42 45
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
150 } 153 }
151 d.add(')'); 154 d.add(')');
152 return d.toString(); 155 return d.toString();
153 } 156 }
154 157
155 /** 158 /**
156 * Given a [method] name and list of [arguments], return true 159 * Given a [method] name and list of [arguments], return true
157 * if it matches this [CallMatcher. 160 * if it matches this [CallMatcher.
158 */ 161 */
159 bool matches(String method, List arguments) { 162 bool matches(String method, List arguments) {
160 if (!nameFilter.matches(method)) { 163 var matchState = new MatchState();
164 if (!nameFilter.matches(method, matchState)) {
161 return false; 165 return false;
162 } 166 }
163 if (arguments.length < argMatchers.length) { 167 if (arguments.length < argMatchers.length) {
164 throw new Exception("Less arguments than matchers for $method."); 168 throw new Exception("Less arguments than matchers for $method.");
165 } 169 }
166 for (var i = 0; i < argMatchers.length; i++) { 170 for (var i = 0; i < argMatchers.length; i++) {
167 if (!argMatchers[i].matches(arguments[i])) { 171 if (!argMatchers[i].matches(arguments[i], matchState)) {
168 return false; 172 return false;
169 } 173 }
170 } 174 }
171 return true; 175 return true;
172 } 176 }
173 } 177 }
174 178
175 /** 179 /**
176 * Returns a [CallMatcher] for the specified signature. [method] can be 180 * Returns a [CallMatcher] for the specified signature. [method] can be
177 * null to match anything, or a literal [String], a predicate [Function], 181 * null to match anything, or a literal [String], a predicate [Function],
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
302 d.add('${time.hour}:${_pad2(time.minute)}:' 306 d.add('${time.hour}:${_pad2(time.minute)}:'
303 '${_pad2(time.second)}.${time.millisecond}> '); 307 '${_pad2(time.second)}.${time.millisecond}> ');
304 } else { 308 } else {
305 // Show relative time. 309 // Show relative time.
306 int delta = time.millisecondsSinceEpoch - baseTime.millisecondsSinceEpoch; 310 int delta = time.millisecondsSinceEpoch - baseTime.millisecondsSinceEpoch;
307 int secs = delta ~/ 1000; 311 int secs = delta ~/ 1000;
308 int msecs = delta % 1000; 312 int msecs = delta % 1000;
309 d.add('$secs.$msecs> '); 313 d.add('$secs.$msecs> ');
310 } 314 }
311 d.add('${_qualifiedName(mockName, methodName)}('); 315 d.add('${_qualifiedName(mockName, methodName)}(');
312 for (var i = 0; i < args.length; i++) { 316 if (args != null) {
313 if (i != 0) d.add(', '); 317 for (var i = 0; i < args.length; i++) {
314 d.addDescriptionOf(args[i]); 318 if (i != 0) d.add(', ');
319 d.addDescriptionOf(args[i]);
320 }
315 } 321 }
316 d.add(') ${action == Action.THROW ? "threw" : "returned"} '); 322 d.add(') ${action == Action.THROW ? "threw" : "returned"} ');
317 d.addDescriptionOf(value); 323 d.addDescriptionOf(value);
318 return d.toString(); 324 return d.toString();
319 } 325 }
320 } 326 }
321 327
322 /** Utility function for optionally qualified method names */ 328 /** Utility function for optionally qualified method names */
323 String _qualifiedName(owner, String method) { 329 String _qualifiedName(owner, String method) {
324 if (owner == null || owner === anything) { 330 if (owner == null || owner === anything) {
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
385 Matcher actionMatcher, 391 Matcher actionMatcher,
386 bool destructive = false]) { 392 bool destructive = false]) {
387 if (mockNameFilter == null) { 393 if (mockNameFilter == null) {
388 mockNameFilter = anything; 394 mockNameFilter = anything;
389 } else { 395 } else {
390 mockNameFilter = wrapMatcher(mockNameFilter); 396 mockNameFilter = wrapMatcher(mockNameFilter);
391 } 397 }
392 Function entryFilter = _makePredicate(logFilter); 398 Function entryFilter = _makePredicate(logFilter);
393 String filterName = _qualifiedName(mockNameFilter, logFilter.toString()); 399 String filterName = _qualifiedName(mockNameFilter, logFilter.toString());
394 LogEntryList rtn = new LogEntryList(filterName); 400 LogEntryList rtn = new LogEntryList(filterName);
401 MatchState matchState = new MatchState();
395 for (var i = 0; i < logs.length; i++) { 402 for (var i = 0; i < logs.length; i++) {
396 LogEntry entry = logs[i]; 403 LogEntry entry = logs[i];
397 if (mockNameFilter.matches(entry.mockName) && entryFilter(entry)) { 404 if (mockNameFilter.matches(entry.mockName, matchState) &&
398 if (actionMatcher == null || actionMatcher.matches(entry)) { 405 entryFilter(entry)) {
406 if (actionMatcher == null ||
407 actionMatcher.matches(entry, matchState)) {
399 rtn.add(entry); 408 rtn.add(entry);
400 if (destructive) { 409 if (destructive) {
401 logs.removeRange(i--, 1); 410 logs.removeRange(i--, 1);
402 } 411 }
403 } 412 }
404 } 413 }
405 } 414 }
406 return rtn; 415 return rtn;
407 } 416 }
408 417
(...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after
687 // we get our first key match). 696 // we get our first key match).
688 List scratch = null; 697 List scratch = null;
689 int remainingCount = 0; 698 int remainingCount = 0;
690 if (isPreceding) { 699 if (isPreceding) {
691 scratch = new List(); 700 scratch = new List();
692 remainingCount = logs.length; 701 remainingCount = logs.length;
693 } 702 }
694 703
695 var keyIterator = keys.logs.iterator(); 704 var keyIterator = keys.logs.iterator();
696 LogEntry keyEntry = keyIterator.next(); 705 LogEntry keyEntry = keyIterator.next();
706 MatchState matchState = new MatchState();
697 707
698 for (LogEntry logEntry in logs) { 708 for (LogEntry logEntry in logs) {
699 // If we have a log entry match, copy the saved matches from the 709 // If we have a log entry match, copy the saved matches from the
700 // scratch buffer into the return list, as well as the matching entry, 710 // scratch buffer into the return list, as well as the matching entry,
701 // if appropriate, and reset the scratch buffer. Continue processing 711 // if appropriate, and reset the scratch buffer. Continue processing
702 // from the next key entry. 712 // from the next key entry.
703 if (keyEntry == logEntry) { 713 if (keyEntry == logEntry) {
704 if (scratch != null) { 714 if (scratch != null) {
705 int numToCopy = scratch.length; 715 int numToCopy = scratch.length;
706 if (distance > 0 && distance < numToCopy) { 716 if (distance > 0 && distance < numToCopy) {
707 numToCopy = distance; 717 numToCopy = distance;
708 } 718 }
709 for (var i = scratch.length - numToCopy; i < scratch.length; i++) { 719 for (var i = scratch.length - numToCopy; i < scratch.length; i++) {
710 rtn.logs.add(scratch[i]); 720 rtn.logs.add(scratch[i]);
711 } 721 }
712 scratch.clear(); 722 scratch.clear();
713 } else { 723 } else {
714 remainingCount = distance > 0 ? distance : logs.length; 724 remainingCount = distance > 0 ? distance : logs.length;
715 } 725 }
716 if (includeKeys) { 726 if (includeKeys) {
717 rtn.logs.add(keyEntry); 727 rtn.logs.add(keyEntry);
718 } 728 }
719 if (keyIterator.hasNext()) { 729 if (keyIterator.hasNext()) {
720 keyEntry = keyIterator.next(); 730 keyEntry = keyIterator.next();
721 } else if (isPreceding) { // We're done. 731 } else if (isPreceding) { // We're done.
722 break; 732 break;
723 } 733 }
724 } else if (remainingCount > 0 && 734 } else if (remainingCount > 0 &&
725 mockNameFilter.matches(logEntry.mockName) && 735 mockNameFilter.matches(logEntry.mockName, matchState) &&
726 logFilter(logEntry)) { 736 logFilter(logEntry)) {
727 if (scratch != null) { 737 if (scratch != null) {
728 scratch.add(logEntry); 738 scratch.add(logEntry);
729 } else { 739 } else {
730 rtn.logs.add(logEntry); 740 rtn.logs.add(logEntry);
731 --remainingCount; 741 --remainingCount;
732 } 742 }
733 } 743 }
734 } 744 }
735 return rtn; 745 return rtn;
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
791 801
792 /** 802 /**
793 * [_TimesMatcher]s are used to make assertions about the number of 803 * [_TimesMatcher]s are used to make assertions about the number of
794 * times a method was called. 804 * times a method was called.
795 */ 805 */
796 class _TimesMatcher extends BaseMatcher { 806 class _TimesMatcher extends BaseMatcher {
797 final int min, max; 807 final int min, max;
798 808
799 const _TimesMatcher(this.min, [this.max = -1]); 809 const _TimesMatcher(this.min, [this.max = -1]);
800 810
801 bool matches(logList) => logList.length >= min && 811 bool matches(logList, MatchState matchState) => logList.length >= min &&
802 (max < 0 || logList.length <= max); 812 (max < 0 || logList.length <= max);
803 813
804 Description describe(Description description) { 814 Description describe(Description description) {
805 description.add(' to be called '); 815 description.add('to be called ');
806 if (max < 0) { 816 if (max < 0) {
807 description.add('at least $min'); 817 description.add('at least $min');
808 } else if (max == min) { 818 } else if (max == min) {
809 description.add('$max'); 819 description.add('$max');
810 } else if (min == 0) { 820 } else if (min == 0) {
811 description.add('at most $max'); 821 description.add('at most $max');
812 } else { 822 } else {
813 description.add('between $min and $max'); 823 description.add('between $min and $max');
814 } 824 }
815 return description.add(' times'); 825 return description.add(' times');
816 } 826 }
817 827
818 Description describeMismatch(logList, Description mismatchDescription) => 828 Description describeMismatch(logList, Description mismatchDescription,
829 MatchState matchState, bool verbose) =>
819 mismatchDescription.add('was called ${logList.length} times'); 830 mismatchDescription.add('was called ${logList.length} times');
820 } 831 }
821 832
822 /** [happenedExactly] matches an exact number of calls. */ 833 /** [happenedExactly] matches an exact number of calls. */
823 Matcher happenedExactly(count) { 834 Matcher happenedExactly(count) {
824 return new _TimesMatcher(count, count); 835 return new _TimesMatcher(count, count);
825 } 836 }
826 837
827 /** [happenedAtLeast] matches a minimum number of calls. */ 838 /** [happenedAtLeast] matches a minimum number of calls. */
828 Matcher happenedAtLeast(count) { 839 Matcher happenedAtLeast(count) {
(...skipping 20 matching lines...) Expand all
849 /** 860 /**
850 * [_ResultMatcher]s are used to make assertions about the results 861 * [_ResultMatcher]s are used to make assertions about the results
851 * of method calls. These can be used as optional parameters to [getLogs]. 862 * of method calls. These can be used as optional parameters to [getLogs].
852 */ 863 */
853 class _ResultMatcher extends BaseMatcher { 864 class _ResultMatcher extends BaseMatcher {
854 final Action action; 865 final Action action;
855 final Matcher value; 866 final Matcher value;
856 867
857 const _ResultMatcher(this.action, this.value); 868 const _ResultMatcher(this.action, this.value);
858 869
859 bool matches(item) { 870 bool matches(item, MatchState matchState) {
860 if (item is! LogEntry) { 871 if (item is! LogEntry) {
861 return false; 872 return false;
862 } 873 }
863 // normalize the action; _PROXY is like _RETURN. 874 // normalize the action; _PROXY is like _RETURN.
864 Action eaction = item.action; 875 Action eaction = item.action;
865 if (eaction == Action.PROXY) { 876 if (eaction == Action.PROXY) {
866 eaction = Action.RETURN; 877 eaction = Action.RETURN;
867 } 878 }
868 return (eaction == action && value.matches(item.value)); 879 return (eaction == action && value.matches(item.value, matchState));
869 } 880 }
870 881
871 Description describe(Description description) { 882 Description describe(Description description) {
872 description.add(' to '); 883 description.add(' to ');
873 if (action == Action.RETURN || action == Action.PROXY) 884 if (action == Action.RETURN || action == Action.PROXY)
874 description.add('return '); 885 description.add('return ');
875 else 886 else
876 description.add('throw '); 887 description.add('throw ');
877 return description.addDescriptionOf(value); 888 return description.addDescriptionOf(value);
878 } 889 }
879 890
880 Description describeMismatch(item, Description mismatchDescription) { 891 Description describeMismatch(item, Description mismatchDescription,
892 MatchState matchState, bool verbose) {
881 if (item.action == Action.RETURN || item.action == Action.PROXY) { 893 if (item.action == Action.RETURN || item.action == Action.PROXY) {
882 mismatchDescription.add('returned '); 894 mismatchDescription.add('returned ');
883 } else { 895 } else {
884 mismatchDescription.add('threw '); 896 mismatchDescription.add('threw ');
885 } 897 }
886 mismatchDescription.add(item.value); 898 mismatchDescription.add(item.value);
887 return mismatchDescription; 899 return mismatchDescription;
888 } 900 }
889 } 901 }
890 902
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
928 * We could make this class use _ResultMatcher but it doesn't buy that 940 * We could make this class use _ResultMatcher but it doesn't buy that
929 * match and adds some perf hit, so there is some duplication here. 941 * match and adds some perf hit, so there is some duplication here.
930 */ 942 */
931 class _ResultSetMatcher extends BaseMatcher { 943 class _ResultSetMatcher extends BaseMatcher {
932 final Action action; 944 final Action action;
933 final Matcher value; 945 final Matcher value;
934 final _Frequency frequency; // ALL, SOME, or NONE. 946 final _Frequency frequency; // ALL, SOME, or NONE.
935 947
936 const _ResultSetMatcher(this.action, this.value, this.frequency); 948 const _ResultSetMatcher(this.action, this.value, this.frequency);
937 949
938 bool matches(logList) { 950 bool matches(logList, MatchState matchState) {
939 for (LogEntry entry in logList) { 951 for (LogEntry entry in logList) {
940 // normalize the action; PROXY is like RETURN. 952 // normalize the action; PROXY is like RETURN.
941 Action eaction = entry.action; 953 Action eaction = entry.action;
942 if (eaction == Action.PROXY) { 954 if (eaction == Action.PROXY) {
943 eaction = Action.RETURN; 955 eaction = Action.RETURN;
944 } 956 }
945 if (eaction == action && value.matches(entry.value)) { 957 if (eaction == action && value.matches(entry.value, matchState)) {
946 if (frequency == _Frequency.NONE) { 958 if (frequency == _Frequency.NONE) {
959 matchState.state = {
960 'state' : matchState.state,
961 'entry' : entry
962 };
947 return false; 963 return false;
948 } else if (frequency == _Frequency.SOME) { 964 } else if (frequency == _Frequency.SOME) {
949 return true; 965 return true;
950 } 966 }
951 } else { 967 } else {
952 // Mismatch. 968 // Mismatch.
953 if (frequency == _Frequency.ALL) { // We need just one mismatch to fail. 969 if (frequency == _Frequency.ALL) { // We need just one mismatch to fail.
970 matchState.state = {
971 'state' : matchState.state,
972 'entry' : entry
973 };
954 return false; 974 return false;
955 } 975 }
956 } 976 }
957 } 977 }
958 // If we get here, then if count is _ALL we got all matches and 978 // If we get here, then if count is _ALL we got all matches and
959 // this is success; otherwise we got all mismatched which is 979 // this is success; otherwise we got all mismatched which is
960 // success for count == _NONE and failure for count == _SOME. 980 // success for count == _NONE and failure for count == _SOME.
961 return (frequency != _Frequency.SOME); 981 return (frequency != _Frequency.SOME);
962 } 982 }
963 983
964 Description describe(Description description) { 984 Description describe(Description description) {
965 description.add(' to '); 985 description.add(' to ');
966 description.add(frequency == _Frequency.ALL ? 'alway ' : 986 description.add(frequency == _Frequency.ALL ? 'alway ' :
967 (frequency == _Frequency.NONE ? 'never ' : 'sometimes ')); 987 (frequency == _Frequency.NONE ? 'never ' : 'sometimes '));
968 if (action == Action.RETURN || action == Action.PROXY) 988 if (action == Action.RETURN || action == Action.PROXY)
969 description.add('return '); 989 description.add('return ');
970 else 990 else
971 description.add('throw '); 991 description.add('throw ');
972 return description.addDescriptionOf(value); 992 return description.addDescriptionOf(value);
973 } 993 }
974 994
975 Description describeMismatch(logList, Description mismatchDescription) { 995 Description describeMismatch(logList, Description mismatchDescription,
996 MatchState matchState, bool verbose) {
976 if (frequency != _Frequency.SOME) { 997 if (frequency != _Frequency.SOME) {
977 for (LogEntry entry in logList) { 998 LogEntry entry = matchState.state['entry'];
978 if (entry.action != action || !value.matches(entry.value)) { 999 if (entry.action == Action.RETURN || entry.action == Action.PROXY) {
979 if (entry.action == Action.RETURN || entry.action == Action.PROXY) 1000 mismatchDescription.add('returned ');
980 mismatchDescription.add('returned '); 1001 } else {
981 else 1002 mismatchDescription.add('threw ');
982 mismatchDescription.add('threw ');
983 mismatchDescription.add(entry.value);
984 mismatchDescription.add(' at least once');
985 break;
986 }
987 } 1003 }
1004 mismatchDescription.add(entry.value);
1005 mismatchDescription.add(' that ');
1006 value.describeMismatch(entry.value, mismatchDescription,
1007 matchState.state['state'], verbose);
1008 mismatchDescription.add(' at least once');
988 } else { 1009 } else {
989 mismatchDescription.add('never did'); 1010 mismatchDescription.add('never did');
990 } 1011 }
991 return mismatchDescription; 1012 return mismatchDescription;
992 } 1013 }
993 } 1014 }
994 1015
995 /** 1016 /**
996 *[alwaysReturned] asserts that all matching calls to a method returned 1017 *[alwaysReturned] asserts that all matching calls to a method returned
997 * a value that matched [value]. 1018 * a value that matched [value].
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after
1191 * of [Behavior]s, and find the first match that still has return 1212 * of [Behavior]s, and find the first match that still has return
1192 * values available, and then do the action specified by that 1213 * values available, and then do the action specified by that
1193 * return value. If we find no [Behavior] to apply an exception is 1214 * return value. If we find no [Behavior] to apply an exception is
1194 * thrown. 1215 * thrown.
1195 */ 1216 */
1196 noSuchMethod(String method, List args) { 1217 noSuchMethod(String method, List args) {
1197 if (method.startsWith('get:')) { 1218 if (method.startsWith('get:')) {
1198 method = 'get ${method.substring(4)}'; 1219 method = 'get ${method.substring(4)}';
1199 } 1220 }
1200 bool matchedMethodName = false; 1221 bool matchedMethodName = false;
1222 MatchState matchState = new MatchState();
1201 for (String k in _behaviors.getKeys()) { 1223 for (String k in _behaviors.getKeys()) {
1202 Behavior b = _behaviors[k]; 1224 Behavior b = _behaviors[k];
1203 if (b.matcher.nameFilter.matches(method)) { 1225 if (b.matcher.nameFilter.matches(method, matchState)) {
1204 matchedMethodName = true; 1226 matchedMethodName = true;
1205 } 1227 }
1206 if (b.matches(method, args)) { 1228 if (b.matches(method, args)) {
1207 List actions = b.actions; 1229 List actions = b.actions;
1208 if (actions == null || actions.length == 0) { 1230 if (actions == null || actions.length == 0) {
1209 continue; // No return values left in this Behavior. 1231 continue; // No return values left in this Behavior.
1210 } 1232 }
1211 // Get the first response. 1233 // Get the first response.
1212 Responder response = actions[0]; 1234 Responder response = actions[0];
1213 // If it is exhausted, remove it from the list. 1235 // If it is exhausted, remove it from the list.
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
1348 arg3 = _noArg, 1370 arg3 = _noArg,
1349 arg4 = _noArg, 1371 arg4 = _noArg,
1350 arg5 = _noArg, 1372 arg5 = _noArg,
1351 arg6 = _noArg, 1373 arg6 = _noArg,
1352 arg7 = _noArg, 1374 arg7 = _noArg,
1353 arg8 = _noArg, 1375 arg8 = _noArg,
1354 arg9 = _noArg]) => 1376 arg9 = _noArg]) =>
1355 getLogs(callsTo(method, arg0, arg1, arg2, arg3, arg4, 1377 getLogs(callsTo(method, arg0, arg1, arg2, arg3, arg4,
1356 arg5, arg6, arg7, arg8, arg9)); 1378 arg5, arg6, arg7, arg8, arg9));
1357 } 1379 }
OLDNEW
« no previous file with comments | « lib/unittest/matcher.dart ('k') | lib/unittest/numeric_matchers.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698