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

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

Issue 10694146: Added ability to disable logging in mocks, to avoid the memory overhead if you don't need behavior … (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 5 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/expect.dart ('k') | lib/unittest/unittest.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 var description = new StringDescription(); 12 var description = new StringDescription();
13 description.add('Expected ${signature} ').addDescriptionOf(matcher). 13 description.add('Expected ${signature} ').addDescriptionOf(matcher).
14 add('\n but: '); 14 add('\n but: ');
15 matcher.describeMismatch(actual, description); 15 matcher.describeMismatch(actual, description).add('.');
16 return description.toString(); 16 return description.toString();
17 } 17 }
18 18
19 /** 19 /**
20 * The failure handler for the [expect()] calls that occur in [verify()] 20 * The failure handler for the [expect()] calls that occur in [verify()]
21 * methods in the mock objects. This calls the real failure handler used 21 * methods in the mock objects. This calls the real failure handler used
22 * by the unit test library after formatting the error message with 22 * by the unit test library after formatting the error message with
23 * the custom formatter. 23 * the custom formatter.
24 */ 24 */
25 class _MockFailureHandler implements FailureHandler { 25 class _MockFailureHandler implements FailureHandler {
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
149 149
150 /** 150 /**
151 * Given a [method] name and list of [arguments], return true 151 * Given a [method] name and list of [arguments], return true
152 * if it matches this [CallMatcher. 152 * if it matches this [CallMatcher.
153 */ 153 */
154 bool matches(String method, List arguments) { 154 bool matches(String method, List arguments) {
155 if (!nameFilter.matches(method)) { 155 if (!nameFilter.matches(method)) {
156 return false; 156 return false;
157 } 157 }
158 if (arguments.length < argMatchers.length) { 158 if (arguments.length < argMatchers.length) {
159 throw new Exception("Less arguments than matchers for $method"); 159 throw new Exception("Less arguments than matchers for $method.");
160 } 160 }
161 for (var i = 0; i < argMatchers.length; i++) { 161 for (var i = 0; i < argMatchers.length; i++) {
162 if (!argMatchers[i].matches(arguments[i])) { 162 if (!argMatchers[i].matches(arguments[i])) {
163 return false; 163 return false;
164 } 164 }
165 } 165 }
166 return true; 166 return true;
167 } 167 }
168 } 168 }
169 169
(...skipping 558 matching lines...) Expand 10 before | Expand all | Expand 10 after
728 /** The mock name. Needed if the log is shared; optional otherwise. */ 728 /** The mock name. Needed if the log is shared; optional otherwise. */
729 final String name; 729 final String name;
730 730
731 /** The set of [behavior]s supported. */ 731 /** The set of [behavior]s supported. */
732 Map<String,Behavior> behaviors; 732 Map<String,Behavior> behaviors;
733 733
734 /** The [log] of calls made. Only used if [name] is null. */ 734 /** The [log] of calls made. Only used if [name] is null. */
735 LogEntryList log; 735 LogEntryList log;
736 736
737 /** How to handle unknown method calls - swallow or throw. */ 737 /** How to handle unknown method calls - swallow or throw. */
738 final bool throwIfNoBehavior = false; 738 final bool throwIfNoBehavior;
739
740 /** Whether to create an audit log or not. */
741 final bool logging;
739 742
740 /** 743 /**
741 * Default constructor. Unknown method calls are allowed and logged, 744 * Default constructor. Unknown method calls are allowed and logged,
742 * the mock has no name, and has its own log. 745 * the mock has no name, and has its own log.
743 */ 746 */
744 Mock() : throwIfNoBehavior = false, name = null { 747 Mock() : throwIfNoBehavior = false, logging = true, name = null {
745 log = new LogEntryList(); 748 log = new LogEntryList();
746 behaviors = new Map<String,Behavior>(); 749 behaviors = new Map<String,Behavior>();
747 } 750 }
748 751
749 /** 752 /**
750 * This constructor makes a mock that has a [name] and possibly uses 753 * This constructor makes a mock that has a [name] and possibly uses
751 * a shared [log]. If [throwIfNoBehavior] is true, any calls to methods 754 * a shared [log]. If [throwIfNoBehavior] is true, any calls to methods
752 * that have no defined behaviors will throw an exception; otherwise they 755 * that have no defined behaviors will throw an exception; otherwise they
753 * will be allowed and logged (but will not do anything). 756 * will be allowed and logged (but will not do anything). If [logging]
757 * is false, no logging will be done (whether or not a [log] is supplied).
754 */ 758 */
755 Mock.custom([this.name, 759 Mock.custom([this.name,
756 this.log, 760 this.log,
757 this.throwIfNoBehavior = false]) { 761 this.throwIfNoBehavior = false,
758 if (log == null) { 762 this.logging = true]) {
763 if (!logging) {
764 log = null;
765 } else if (log == null) {
759 log = new LogEntryList(); 766 log = new LogEntryList();
760 } 767 }
761 behaviors = new Map<String,Behavior>(); 768 behaviors = new Map<String,Behavior>();
762 } 769 }
763 770
764 /** 771 /**
765 * [when] is used to create a new or extend an existing [Behavior]. 772 * [when] is used to create a new or extend an existing [Behavior].
766 * A [CallMatcher] [filter] must be supplied, and the [Behavior]s for 773 * A [CallMatcher] [filter] must be supplied, and the [Behavior]s for
767 * that signature are returned (being created first if needed). 774 * that signature are returned (being created first if needed).
768 * 775 *
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
809 // Note that for endlessly repeating values, we started the count at 816 // Note that for endlessly repeating values, we started the count at
810 // 0, so we get a potentially useful value here, which is the 817 // 0, so we get a potentially useful value here, which is the
811 // (negation of) the number of times we returned the value. 818 // (negation of) the number of times we returned the value.
812 if (--response.count == 0) { 819 if (--response.count == 0) {
813 actions.removeRange(0, 1); 820 actions.removeRange(0, 1);
814 } 821 }
815 // Do the response. 822 // Do the response.
816 _Action action = response.action; 823 _Action action = response.action;
817 var value = response.value; 824 var value = response.value;
818 if (action == _Action.RETURN) { 825 if (action == _Action.RETURN) {
819 log.add(new LogEntry(name, method, args, action, value)); 826 if (log != null) {
Siggi Cherem (dart-lang) 2012/07/11 22:46:04 why not continbue using the flag? ('if (logging)'
gram 2012/07/11 23:24:07 You're right - I originally didn't mean to make th
827 log.add(new LogEntry(name, method, args, action, value));
828 }
820 return value; 829 return value;
821 } else if (action == _Action.THROW) { 830 } else if (action == _Action.THROW) {
822 log.add(new LogEntry(name, method, args, action, value)); 831 if (log != null) {
832 log.add(new LogEntry(name, method, args, action, value));
833 }
823 throw value; 834 throw value;
824 } else if (action == _Action.PROXY) { 835 } else if (action == _Action.PROXY) {
825 var rtn; 836 var rtn;
826 switch (args.length) { 837 switch (args.length) {
827 case 0: 838 case 0:
828 rtn = value(); 839 rtn = value();
829 break; 840 break;
830 case 1: 841 case 1:
831 rtn = value(args[0]); 842 rtn = value(args[0]);
832 break; 843 break;
(...skipping 24 matching lines...) Expand all
857 case 9: 868 case 9:
858 rtn = value(args[0], args[1], args[2], args[3], 869 rtn = value(args[0], args[1], args[2], args[3],
859 args[4], args[5], args[6], args[7], args[8]); 870 args[4], args[5], args[6], args[7], args[8]);
860 break; 871 break;
861 case 9: 872 case 9:
862 rtn = value(args[0], args[1], args[2], args[3], 873 rtn = value(args[0], args[1], args[2], args[3],
863 args[4], args[5], args[6], args[7], args[8], args[9]); 874 args[4], args[5], args[6], args[7], args[8], args[9]);
864 break; 875 break;
865 default: 876 default:
866 throw new Exception( 877 throw new Exception(
867 "Cannot proxy calls with more than 10 parameters"); 878 "Cannot proxy calls with more than 10 parameters.");
868 } 879 }
869 log.add(new LogEntry(name, method, args, action, rtn)); 880 if (log != null) {
881 log.add(new LogEntry(name, method, args, action, rtn));
882 }
870 return rtn; 883 return rtn;
871 } 884 }
872 } 885 }
873 } 886 }
874 if (matchedMethodName) { 887 if (matchedMethodName) {
875 // User did specify behavior for this method, but all the 888 // User did specify behavior for this method, but all the
876 // actions are exhausted. This is considered an error. 889 // actions are exhausted. This is considered an error.
877 throw new Exception('No more actions for method ' 890 throw new Exception('No more actions for method '
878 '${_qualifiedName(name, method)}'); 891 '${_qualifiedName(name, method)}.');
879 } else if (throwIfNoBehavior) { 892 } else if (throwIfNoBehavior) {
880 throw new Exception('No behavior specified for method ' 893 throw new Exception('No behavior specified for method '
881 '${_qualifiedName(name, method)}'); 894 '${_qualifiedName(name, method)}.');
882 } 895 }
883 // User hasn't specified behavior for this method; we don't throw 896 // Otherwise user hasn't specified behavior for this method; we don't throw
884 // so we can underspecify. 897 // so we can underspecify.
885 log.add(new LogEntry(name, method, args, _Action.IGNORE)); 898 if (log != null) {
899 log.add(new LogEntry(name, method, args, _Action.IGNORE));
900 }
886 } 901 }
887 902
888 /** [verifyZeroInteractions] returns true if no calls were made */ 903 /** [verifyZeroInteractions] returns true if no calls were made */
889 bool verifyZeroInteractions() => log.logs.length == 0; 904 bool verifyZeroInteractions() {
905 if (log == null) {
906 throw new Exception("Can't verify behavior when logging is disabled.");
907 }
908 return log.logs.length == 0;
909 }
890 910
891 /** 911 /**
892 * [getLogs] extracts all calls from the call log that match the 912 * [getLogs] extracts all calls from the call log that match the
893 * [logFilter] [CallMatcher], and returns the matching list of 913 * [logFilter] [CallMatcher], and returns the matching list of
894 * [LogEntry]s. If [destructive] is false (the default) the matching 914 * [LogEntry]s. If [destructive] is false (the default) the matching
895 * calls are left in the log, else they are removed. Removal allows 915 * calls are left in the log, else they are removed. Removal allows
896 * us to verify a set of interactions and then verify that there are 916 * us to verify a set of interactions and then verify that there are
897 * no other interactions left. [actionMatcher] can be used to further 917 * no other interactions left. [actionMatcher] can be used to further
898 * restrict the returned logs based on the action the mock performed. 918 * restrict the returned logs based on the action the mock performed.
899 * 919 *
900 * Typical usage: 920 * Typical usage:
901 * 921 *
902 * getLogs(callsTo(...)).verify(...); 922 * getLogs(callsTo(...)).verify(...);
903 */ 923 */
904 LogEntryList getLogs([CallMatcher logFilter, 924 LogEntryList getLogs([CallMatcher logFilter,
905 Matcher actionMatcher, 925 Matcher actionMatcher,
906 bool destructive = false]) { 926 bool destructive = false]) {
907 return log.getMatches(name, logFilter, actionMatcher, destructive); 927 if (log == null) {
928 throw new Exception("Can't retrieve logs when logging is disabled.");
929 } else {
930 return log.getMatches(name, logFilter, actionMatcher, destructive);
931 }
908 } 932 }
909 } 933 }
OLDNEW
« no previous file with comments | « lib/unittest/expect.dart ('k') | lib/unittest/unittest.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698