| Index: pkg/expect/lib/expect.dart
|
| diff --git a/pkg/expect/lib/expect.dart b/pkg/expect/lib/expect.dart
|
| index 616920b0b8f98466ed7ec63e9dda4b449a1af2c3..4ee2832d383bb10203d22ad7edcd9c98648aa0b5 100644
|
| --- a/pkg/expect/lib/expect.dart
|
| +++ b/pkg/expect/lib/expect.dart
|
| @@ -81,7 +81,7 @@ class Expect {
|
| var truncExpected = _truncateString(expected, start, end, 20);
|
| var truncActual = _truncateString(actual, start, end, 20);
|
| return "at index $start: Expected <$truncExpected>, "
|
| - "Found: <$truncActual>";
|
| + "Found: <$truncActual>";
|
| }
|
| }
|
| return null;
|
| @@ -146,7 +146,7 @@ class Expect {
|
| if (_identical(expected, actual)) return;
|
| String msg = _getMessage(reason);
|
| _fail("Expect.identical(expected: <$expected>, actual: <$actual>$msg) "
|
| - "fails.");
|
| + "fails.");
|
| }
|
|
|
| // Unconditional failure.
|
| @@ -159,10 +159,8 @@ class Expect {
|
| * given tolerance. If no tolerance is given, tolerance is assumed to be the
|
| * value 4 significant digits smaller than the value given for expected.
|
| */
|
| - static void approxEquals(num expected,
|
| - num actual,
|
| - [num tolerance = null,
|
| - String reason = null]) {
|
| + static void approxEquals(num expected, num actual,
|
| + [num tolerance = null, String reason = null]) {
|
| if (tolerance == null) {
|
| tolerance = (expected / 1e4).abs();
|
| }
|
| @@ -171,14 +169,14 @@ class Expect {
|
|
|
| String msg = _getMessage(reason);
|
| _fail('Expect.approxEquals(expected:<$expected>, actual:<$actual>, '
|
| - 'tolerance:<$tolerance>$msg) fails');
|
| + 'tolerance:<$tolerance>$msg) fails');
|
| }
|
|
|
| static void notEquals(unexpected, actual, [String reason = null]) {
|
| if (unexpected != actual) return;
|
| String msg = _getMessage(reason);
|
| _fail("Expect.notEquals(unexpected: <$unexpected>, actual:<$actual>$msg) "
|
| - "fails.");
|
| + "fails.");
|
| }
|
|
|
| /**
|
| @@ -193,16 +191,16 @@ class Expect {
|
| for (int i = 0; i < n; i++) {
|
| if (expected[i] != actual[i]) {
|
| _fail('Expect.listEquals(at index $i, '
|
| - 'expected: <${expected[i]}>, actual: <${actual[i]}>$msg) fails');
|
| + 'expected: <${expected[i]}>, actual: <${actual[i]}>$msg) fails');
|
| }
|
| }
|
| // We check on length at the end in order to provide better error
|
| // messages when an unexpected item is inserted in a list.
|
| if (expected.length != actual.length) {
|
| _fail('Expect.listEquals(list length, '
|
| - 'expected: <${expected.length}>, actual: <${actual.length}>$msg) '
|
| - 'fails: Next element <'
|
| - '${expected.length > n ? expected[n] : actual[n]}>');
|
| + 'expected: <${expected.length}>, actual: <${actual.length}>$msg) '
|
| + 'fails: Next element <'
|
| + '${expected.length > n ? expected[n] : actual[n]}>');
|
| }
|
| }
|
|
|
| @@ -235,9 +233,8 @@ class Expect {
|
| * Specialized equality test for strings. When the strings don't match,
|
| * this method shows where the mismatch starts and ends.
|
| */
|
| - static void stringEquals(String expected,
|
| - String actual,
|
| - [String reason = null]) {
|
| + static void stringEquals(String expected, String actual,
|
| + [String reason = null]) {
|
| if (expected == actual) return;
|
|
|
| String msg = _getMessage(reason);
|
| @@ -262,10 +259,11 @@ class Expect {
|
| }
|
|
|
| // Scan from the right until we find the mismatch.
|
| - int eRem = eLen - left; // Remaining length ignoring left match.
|
| + int eRem = eLen - left; // Remaining length ignoring left match.
|
| int aRem = aLen - left;
|
| while (true) {
|
| - if (right == eRem || right == aRem ||
|
| + if (right == eRem ||
|
| + right == aRem ||
|
| expected[eLen - right - 1] != actual[aLen - right - 1]) {
|
| break;
|
| }
|
| @@ -293,12 +291,14 @@ class Expect {
|
|
|
| // If snippets are long, elide the middle.
|
| if (eSnippet.length > 43) {
|
| - eSnippet = eSnippet.substring(0, 20) + "..." +
|
| - eSnippet.substring(eSnippet.length - 20);
|
| + eSnippet = eSnippet.substring(0, 20) +
|
| + "..." +
|
| + eSnippet.substring(eSnippet.length - 20);
|
| }
|
| if (aSnippet.length > 43) {
|
| - aSnippet = aSnippet.substring(0, 20) + "..." +
|
| - aSnippet.substring(aSnippet.length - 20);
|
| + aSnippet = aSnippet.substring(0, 20) +
|
| + "..." +
|
| + aSnippet.substring(aSnippet.length - 20);
|
| }
|
| // Add "..." before and after, unless the snippets reach the end.
|
| String leftLead = "...";
|
| @@ -307,8 +307,8 @@ class Expect {
|
| if (right <= 10) rightTail = "";
|
|
|
| String diff = '\nDiff ($left..${eLen - right}/${aLen - right}):\n'
|
| - '$leftLead$leftSnippet[ $eSnippet ]$rightSnippet$rightTail\n'
|
| - '$leftLead$leftSnippet[ $aSnippet ]$rightSnippet$rightTail';
|
| + '$leftLead$leftSnippet[ $eSnippet ]$rightSnippet$rightTail\n'
|
| + '$leftLead$leftSnippet[ $aSnippet ]$rightSnippet$rightTail';
|
| _fail("$defaultMessage$diff");
|
| }
|
|
|
| @@ -316,9 +316,8 @@ class Expect {
|
| * Checks that every element of [expected] is also in [actual], and that
|
| * every element of [actual] is also in [expected].
|
| */
|
| - static void setEquals(Iterable expected,
|
| - Iterable actual,
|
| - [String reason = null]) {
|
| + static void setEquals(Iterable expected, Iterable actual,
|
| + [String reason = null]) {
|
| final missingSet = new Set.from(expected);
|
| missingSet.removeAll(actual);
|
| final extraSet = new Set.from(actual);
|
| @@ -349,6 +348,58 @@ class Expect {
|
| }
|
|
|
| /**
|
| + * Checks that [expected] is equivalent to [actual].
|
| + *
|
| + * If the objects are iterables or maps, recurses into them.
|
| + */
|
| + static void deepEquals(Object expected, Object actual) {
|
| + // Early exit check for equality.
|
| + if (expected == actual) return;
|
| +
|
| + if (expected is String && actual is String) {
|
| + stringEquals(expected, actual);
|
| + } else if (expected is Iterable && actual is Iterable) {
|
| + var expectedLength = expected.length;
|
| + var actualLength = actual.length;
|
| +
|
| + var length =
|
| + expectedLength < actualLength ? expectedLength : actualLength;
|
| + for (var i = 0; i < length; i++) {
|
| + deepEquals(expected.elementAt(i), actual.elementAt(i));
|
| + }
|
| +
|
| + // We check on length at the end in order to provide better error
|
| + // messages when an unexpected item is inserted in a list.
|
| + if (expectedLength != actualLength) {
|
| + var nextElement =
|
| + (expectedLength > length ? expected : actual).elementAt(length);
|
| + _fail('Expect.deepEquals(list length, '
|
| + 'expected: <$expectedLength>, actual: <$actualLength>) '
|
| + 'fails: Next element <$nextElement>');
|
| + }
|
| + } else if (expected is Map && actual is Map) {
|
| + // Make sure all of the values are present in both and match.
|
| + for (final key in expected.keys) {
|
| + if (!actual.containsKey(key)) {
|
| + _fail('Expect.deepEquals(missing expected key: <$key>) fails');
|
| + }
|
| +
|
| + Expect.deepEquals(expected[key], actual[key]);
|
| + }
|
| +
|
| + // Make sure the actual map doesn't have any extra keys.
|
| + for (final key in actual.keys) {
|
| + if (!expected.containsKey(key)) {
|
| + _fail('Expect.deepEquals(unexpected key: <$key>) fails');
|
| + }
|
| + }
|
| + } else {
|
| + _fail("Expect.deepEquals(expected: <$expected>, actual: <$actual>) "
|
| + "fails.");
|
| + }
|
| + }
|
| +
|
| + /**
|
| * Calls the function [f] and verifies that it throws an exception.
|
| * The optional [check] function can provide additional validation
|
| * that the correct exception is being thrown. For example, to check
|
| @@ -357,8 +408,7 @@ class Expect {
|
| * Expect.throws(myThrowingFunction, (e) => e is MyException);
|
| */
|
| static void throws(void f(),
|
| - [bool check(exception) = null,
|
| - String reason = null]) {
|
| + [_CheckExceptionFn check = null, String reason = null]) {
|
| String msg = reason == null ? "" : "($reason)";
|
| if (f is! _Nullary) {
|
| // Only throws from executing the funtion body should count as throwing.
|
| @@ -378,8 +428,8 @@ class Expect {
|
| _fail('Expect.throws$msg fails: Did not throw');
|
| }
|
|
|
| - static String _getMessage(String reason)
|
| - => (reason == null) ? "" : ", '$reason'";
|
| + static String _getMessage(String reason) =>
|
| + (reason == null) ? "" : ", '$reason'";
|
|
|
| static void _fail(String message) {
|
| throw new ExpectException(message);
|
| @@ -388,7 +438,8 @@ class Expect {
|
|
|
| bool _identical(a, b) => identical(a, b);
|
|
|
| -typedef _Nullary(); // Expect.throws argument must be this type.
|
| +typedef bool _CheckExceptionFn(exception);
|
| +typedef _Nullary(); // Expect.throws argument must be this type.
|
|
|
| class ExpectException implements Exception {
|
| ExpectException(this.message);
|
|
|