in Utils/expect_common.dart [220:283]
static void deepEquals(var expected, var actual, [String reason = '']) {
Map planned = Map();
Map processed = Map();
void plan2check(var expected, var actual) {
if (expected == null) {
Expect.isNull(actual);
}
if ((expected is Map) || (expected is List)) {
var savedActual = planned[expected];
if (savedActual != null) {
// this pair is planned to investigate
Expect.equals(savedActual, actual);
} else if ((savedActual = processed[expected]) != null) {
// this pair is checked already
Expect.equals(savedActual, actual);
} else {
// this pair is not yet investigated
Expect.equals(expected.length, actual.length,
'Collection lengths are not equal: '
'expected length=${expected.length}, '
'actual length=${actual.length}');
planned[expected] = actual;
}
} else {
Expect.equals(expected, actual, reason);
}
}
void runPlanned(var expected, var actual) {
if (expected is Map) {
for (var key in expected.keys) {
// TODO check that key sets are equivalent.
// The following method does not work:
// Expect.isTrue(actual.keys.toSet().remove(key)");
plan2check(expected[key], actual[key]);
}
} else if (expected is List) {
for (int i = 0; i != expected.length; i++) {
plan2check(expected[i], actual[i]);
}
} else {
Expect.fail("only Lists and Maps expected in the plan");
}
// Move pair from planned to processed
planned.remove(expected);
processed[expected] = actual;
}
try {
plan2check(expected, actual);
for (;;) {
Iterable keys = planned.keys;
if (keys.isEmpty) {
return;
}
var key = keys.first;
runPlanned(key, planned[key]);
}
} catch (error) {
_fail('deepEquals($expected, $actual, $reason) fails\n [cause: $error]');
}
}