Index: packages/matcher/lib/src/core_matchers.dart |
diff --git a/packages/matcher/lib/src/core_matchers.dart b/packages/matcher/lib/src/core_matchers.dart |
index 1b001f973c04ede36dbe77a360e5b02a1bf22e03..94f9d7d4f3eaf09a47637da01b9bac92b24a2d30 100644 |
--- a/packages/matcher/lib/src/core_matchers.dart |
+++ b/packages/matcher/lib/src/core_matchers.dart |
@@ -2,7 +2,7 @@ |
// for details. All rights reserved. Use of this source code is governed by a |
// BSD-style license that can be found in the LICENSE file. |
-library matcher.core_matchers; |
+import 'package:stack_trace/stack_trace.dart'; |
import 'description.dart'; |
import 'interfaces.dart'; |
@@ -123,7 +123,7 @@ class _DeepMatcher extends Matcher { |
var expectedIterator = expected.iterator; |
var actualIterator = actual.iterator; |
- for (var index = 0; ; index++) { |
+ for (var index = 0;; index++) { |
// Advance in lockstep. |
var expectedNext = expectedIterator.moveNext(); |
var actualNext = actualIterator.moveNext(); |
@@ -263,7 +263,7 @@ class _DeepMatcher extends Matcher { |
Description describeMismatch( |
item, Description mismatchDescription, Map matchState, bool verbose) { |
- var reason = matchState['reason']; |
+ var reason = matchState['reason'] ?? ''; |
// If we didn't get a good reason, that would normally be a |
// simple 'is <value>' message. We only add that if the mismatch |
// description is non empty (so we are supplementing the mismatch |
@@ -310,11 +310,11 @@ class _StringEqualsMatcher extends Matcher { |
} |
if (start == minLength) { |
if (escapedValue.length < escapedItem.length) { |
- buff.write(' Both strings start the same, but the given value also' |
+ buff.write(' Both strings start the same, but the actual value also' |
' has the following trailing characters: '); |
_writeTrailing(buff, escapedItem, escapedValue.length); |
} else { |
- buff.write(' Both strings start the same, but the given value is' |
+ buff.write(' Both strings start the same, but the actual value is' |
' missing the following trailing characters: '); |
_writeTrailing(buff, escapedValue, escapedItem.length); |
} |
@@ -363,7 +363,7 @@ class _IsAnything extends Matcher { |
} |
/// Returns a matcher that matches if an object is an instance |
-/// of [type] (or a subtype). |
+/// of [T] (or a subtype). |
/// |
/// As types are not first class objects in Dart we can only |
/// approximate this test by using a generic wrapper class. |
@@ -530,8 +530,8 @@ class _Contains extends Matcher { |
Description describeMismatch( |
item, Description mismatchDescription, Map matchState, bool verbose) { |
if (item is String || item is Iterable || item is Map) { |
- return super.describeMismatch( |
- item, mismatchDescription, matchState, verbose); |
+ return super |
+ .describeMismatch(item, mismatchDescription, matchState, verbose); |
} else { |
return mismatchDescription.add('is not a string, map or iterable'); |
} |
@@ -616,9 +616,23 @@ class CustomMatcher extends Matcher { |
featureValueOf(actual) => actual; |
bool matches(item, Map matchState) { |
- var f = featureValueOf(item); |
- if (_matcher.matches(f, matchState)) return true; |
- addStateInfo(matchState, {'feature': f}); |
+ try { |
+ var f = featureValueOf(item); |
+ if (_matcher.matches(f, matchState)) return true; |
+ addStateInfo(matchState, {'custom.feature': f}); |
+ } catch (exception, stack) { |
+ addStateInfo(matchState, { |
+ 'custom.exception': exception.toString(), |
+ 'custom.stack': new Chain.forTrace(stack) |
+ .foldFrames( |
+ (frame) => |
+ frame.package == 'test' || |
+ frame.package == 'stream_channel' || |
+ frame.package == 'matcher', |
+ terse: true) |
+ .toString() |
+ }); |
+ } |
return false; |
} |
@@ -627,14 +641,25 @@ class CustomMatcher extends Matcher { |
Description describeMismatch( |
item, Description mismatchDescription, Map matchState, bool verbose) { |
+ if (matchState['custom.exception'] != null) { |
+ mismatchDescription |
+ .add('threw ') |
+ .addDescriptionOf(matchState['custom.exception']) |
+ .add('\n') |
+ .add(matchState['custom.stack'].toString()); |
+ return mismatchDescription; |
+ } |
+ |
mismatchDescription |
.add('has ') |
.add(_featureName) |
.add(' with value ') |
- .addDescriptionOf(matchState['feature']); |
+ .addDescriptionOf(matchState['custom.feature']); |
var innerDescription = new StringDescription(); |
- _matcher.describeMismatch( |
- matchState['feature'], innerDescription, matchState['state'], verbose); |
+ |
+ _matcher.describeMismatch(matchState['custom.feature'], innerDescription, |
+ matchState['state'], verbose); |
+ |
if (innerDescription.length > 0) { |
mismatchDescription.add(' which ').add(innerDescription.toString()); |
} |