Index: lib/unittest/mock.dart |
=================================================================== |
--- lib/unittest/mock.dart (revision 9570) |
+++ lib/unittest/mock.dart (working copy) |
@@ -12,7 +12,7 @@ |
var description = new StringDescription(); |
description.add('Expected ${signature} ').addDescriptionOf(matcher). |
add('\n but: '); |
- matcher.describeMismatch(actual, description); |
+ matcher.describeMismatch(actual, description).add('.'); |
return description.toString(); |
} |
@@ -156,7 +156,7 @@ |
return false; |
} |
if (arguments.length < argMatchers.length) { |
- throw new Exception("Less arguments than matchers for $method"); |
+ throw new Exception("Less arguments than matchers for $method."); |
} |
for (var i = 0; i < argMatchers.length; i++) { |
if (!argMatchers[i].matches(arguments[i])) { |
@@ -728,22 +728,33 @@ |
/** The mock name. Needed if the log is shared; optional otherwise. */ |
final String name; |
- /** The set of [behavior]s supported. */ |
- Map<String,Behavior> behaviors; |
+ /** The set of [Behavior]s supported. */ |
+ Map<String,Behavior> _behaviors; |
/** The [log] of calls made. Only used if [name] is null. */ |
LogEntryList log; |
/** How to handle unknown method calls - swallow or throw. */ |
- final bool throwIfNoBehavior = false; |
+ final bool _throwIfNoBehavior; |
+ /** Whether to create an audit log or not. */ |
+ bool _logging; |
+ |
+ bool get logging() => _logging; |
+ bool set logging(bool value) { |
+ if (value && log == null) { |
+ log = new LogEntryList(); |
+ } |
+ _logging = value; |
+ } |
+ |
/** |
* Default constructor. Unknown method calls are allowed and logged, |
* the mock has no name, and has its own log. |
*/ |
- Mock() : throwIfNoBehavior = false, name = null { |
- log = new LogEntryList(); |
- behaviors = new Map<String,Behavior>(); |
+ Mock() : _throwIfNoBehavior = false, log = null, name = null { |
+ logging = true; |
+ _behaviors = new Map<String,Behavior>(); |
} |
/** |
@@ -751,14 +762,15 @@ |
* a shared [log]. If [throwIfNoBehavior] is true, any calls to methods |
* that have no defined behaviors will throw an exception; otherwise they |
* will be allowed and logged (but will not do anything). |
+ * If [enableLogging] is false, no logging will be done initially (whether |
+ * or not a [log] is supplied), but [logging] can be set to true later. |
*/ |
Mock.custom([this.name, |
this.log, |
- this.throwIfNoBehavior = false]) { |
- if (log == null) { |
- log = new LogEntryList(); |
- } |
- behaviors = new Map<String,Behavior>(); |
+ throwIfNoBehavior = false, |
+ enableLogging = true]) : _throwIfNoBehavior = throwIfNoBehavior { |
+ logging = enableLogging; |
+ _behaviors = new Map<String,Behavior>(); |
} |
/** |
@@ -772,12 +784,12 @@ |
*/ |
Behavior when(CallMatcher logFilter) { |
String key = logFilter.toString(); |
- if (!behaviors.containsKey(key)) { |
+ if (!_behaviors.containsKey(key)) { |
Behavior b = new Behavior(logFilter); |
- behaviors[key] = b; |
+ _behaviors[key] = b; |
return b; |
} else { |
- return behaviors[key]; |
+ return _behaviors[key]; |
} |
} |
@@ -793,8 +805,8 @@ |
method = 'get ${method.substring(4)}'; |
} |
bool matchedMethodName = false; |
- for (String k in behaviors.getKeys()) { |
- Behavior b = behaviors[k]; |
+ for (String k in _behaviors.getKeys()) { |
+ Behavior b = _behaviors[k]; |
if (b.matcher.nameFilter.matches(method)) { |
matchedMethodName = true; |
} |
@@ -816,10 +828,14 @@ |
_Action action = response.action; |
var value = response.value; |
if (action == _Action.RETURN) { |
- log.add(new LogEntry(name, method, args, action, value)); |
+ if (_logging) { |
+ log.add(new LogEntry(name, method, args, action, value)); |
+ } |
return value; |
} else if (action == _Action.THROW) { |
- log.add(new LogEntry(name, method, args, action, value)); |
+ if (_logging) { |
+ log.add(new LogEntry(name, method, args, action, value)); |
+ } |
throw value; |
} else if (action == _Action.PROXY) { |
var rtn; |
@@ -864,9 +880,11 @@ |
break; |
default: |
throw new Exception( |
- "Cannot proxy calls with more than 10 parameters"); |
+ "Cannot proxy calls with more than 10 parameters."); |
} |
- log.add(new LogEntry(name, method, args, action, rtn)); |
+ if (_logging) { |
+ log.add(new LogEntry(name, method, args, action, rtn)); |
+ } |
return rtn; |
} |
} |
@@ -875,18 +893,28 @@ |
// User did specify behavior for this method, but all the |
// actions are exhausted. This is considered an error. |
throw new Exception('No more actions for method ' |
- '${_qualifiedName(name, method)}'); |
- } else if (throwIfNoBehavior) { |
+ '${_qualifiedName(name, method)}.'); |
+ } else if (_throwIfNoBehavior) { |
throw new Exception('No behavior specified for method ' |
- '${_qualifiedName(name, method)}'); |
+ '${_qualifiedName(name, method)}.'); |
} |
- // User hasn't specified behavior for this method; we don't throw |
+ // Otherwise user hasn't specified behavior for this method; we don't throw |
// so we can underspecify. |
- log.add(new LogEntry(name, method, args, _Action.IGNORE)); |
+ if (_logging) { |
+ log.add(new LogEntry(name, method, args, _Action.IGNORE)); |
+ } |
} |
/** [verifyZeroInteractions] returns true if no calls were made */ |
- bool verifyZeroInteractions() => log.logs.length == 0; |
+ bool verifyZeroInteractions() { |
+ if (log == null) { |
+ // This means we created the mock with logging off and have never turned |
+ // it on, so it doesn't make sense to verify behavior on such a mock. |
+ throw new |
+ Exception("Can't verify behavior when logging was never enabled."); |
+ } |
+ return log.logs.length == 0; |
+ } |
/** |
* [getLogs] extracts all calls from the call log that match the |
@@ -904,6 +932,13 @@ |
LogEntryList getLogs([CallMatcher logFilter, |
Matcher actionMatcher, |
bool destructive = false]) { |
- return log.getMatches(name, logFilter, actionMatcher, destructive); |
+ if (log == null) { |
+ // This means we created the mock with logging off and have never turned |
+ // it on, so it doesn't make sense to get logs from such a mock. |
+ throw new |
+ Exception("Can't retrieve logs when logging was never enabled."); |
+ } else { |
+ return log.getMatches(name, logFilter, actionMatcher, destructive); |
+ } |
} |
} |