Index: pkg/expect/lib/expect.dart |
diff --git a/pkg/expect/lib/expect.dart b/pkg/expect/lib/expect.dart |
index 0f83041aacca35c3c5efa67086e40600dbc5dee7..716986281e33e719446bbab80c2fc52c0ce21a56 100644 |
--- a/pkg/expect/lib/expect.dart |
+++ b/pkg/expect/lib/expect.dart |
@@ -16,12 +16,67 @@ library expect; |
* test assertions. |
*/ |
class Expect { |
+ static String _truncateString(String string, int start, int end, int length) { |
floitsch
2013/05/30 12:13:48
make this a separate CL?
floitsch
2013/05/30 12:13:48
comment.
Lasse Reichstein Nielsen
2013/05/31 05:51:59
Done.
Lasse Reichstein Nielsen
2013/05/31 05:51:59
Rather not. It's just a tweak that happened as par
|
+ if (end - start > length) { |
+ end = start + length; |
+ } else if (end - start < length) { |
+ int overflow = length - (end - start); |
+ if (overflow > 10) overflow = 10; |
+ // Add context. |
+ start = start - ((overflow + 1) >> 1); |
floitsch
2013/05/30 12:13:48
~/ 2.
let the VM optimize this.
Lasse Reichstein Nielsen
2013/05/31 05:51:59
Done.
Lasse Reichstein Nielsen
2013/05/31 05:51:59
Done.
|
+ end = end + (overflow >> 1); |
+ if (start < 0) start = 0; |
+ if (end > string.length) end = string.length; |
+ } |
+ if (start == 0 && end == string.length) return string; |
+ StringBuffer buf = new StringBuffer(); |
+ if (start > 0) buf.write("..."); |
+ for (int i = start; i < end; i++) { |
+ int code = string.codeUnitAt(i); |
+ if (code < 0x20) { |
+ buf.write(r"\x"); |
+ buf.write("0123456789abcdef"[code >> 4]); |
floitsch
2013/05/30 12:13:48
~/ 16
Lasse Reichstein Nielsen
2013/05/31 05:51:59
Done.
|
+ buf.write("0123456789abcdef"[code & 0x0f]); |
floitsch
2013/05/30 12:13:48
% 16
Lasse Reichstein Nielsen
2013/05/31 05:51:59
Done.
|
+ } else { |
+ buf.writeCharCode(string.codeUnitAt(i)); |
+ } |
+ } |
+ if (end < string.length) buf.write("..."); |
+ return buf.toString(); |
+ } |
+ |
+ static String _stringDifference(String expected, String actual) { |
+ if (expected.length < 20 && actual.length < 20) return null; |
+ for (int i = 0; i < expected.length && i < actual.length; i++) { |
+ if (expected.codeUnitAt(i) != actual.codeUnitAt(i)) { |
+ int start = i; |
+ i++; |
+ while (i < expected.length && i < actual.length) { |
+ if (expected.codeUnitAt(i) == actual.codeUnitAt(i)) break; |
+ } |
+ int end = i; |
+ var truncExpected = _truncateString(expected, start, end, 20); |
+ var truncActual = _truncateString(actual, start, end, 20); |
+ return "at index $start: Expected <$truncExpected>, " |
+ "Found: <$truncActual>"; |
+ } |
+ } |
+ return null; |
+ } |
+ |
/** |
* Checks whether the expected and actual values are equal (using `==`). |
*/ |
static void equals(var expected, var actual, [String reason = null]) { |
if (expected == actual) return; |
String msg = _getMessage(reason); |
+ stringSpecialCase: |
+ if (expected is String && actual is String) { |
+ String stringDifference = _stringDifference(expected, actual); |
+ if (stringDifference != null) { |
+ _fail("Expect.equals($stringDifference$msg) fails."); |
+ } |
+ } |
_fail("Expect.equals(expected: <$expected>, actual: <$actual>$msg) fails."); |
} |