blob: fe5c8ede5a2d5171ae8a6aa2f6838b5930ecedb1 [file] [log] [blame]
/**
* testharness-helpers contains userful extensions to testharness.js
* to allow them to be used across multiple tests.
*/
// Asserts that two objects |actual| and |expected| are weakly equal under the
// following definition:
//
// |a| and |b| are weakly equal if any of the following are true:
// 1. If |a| is not an 'object', and |a| === |b|.
// 2. If |a| is an 'object', and all of the following are true:
// 2.1 |a.p| is weakly equal to |b.p| for all enumerable properties |p| of
// |a|, including inherited properties.
// 2.2 |b.p| is weakly equal to |a.p| for all enumerable properties |p| of
// |b|, including inherited properties.
//
// This is a replacement for the the version of assert_object_equals() in
// testharness.js. The latter doesn't handle own properties correctly. I.e. if
// |a.p| is not an own property, it still requires that |b.p| be an own
// property.
//
// Note that |actual| must not contain cyclic references.
function assert_weak_equals(actual, expected, description) {
var object_stack = [];
function _is_equal(actual, expected, prefix) {
if (typeof actual !== 'object' || actual === null) {
assert_equals(actual, expected, prefix);
return;
}
assert_true(typeof expected === 'object', prefix);
assert_equals(object_stack.indexOf(actual), -1,
prefix + ' must not contain cyclic references.');
object_stack.push(actual);
let checked_set = new Set();
for(var property in expected) {
assert_true(property in actual, prefix);
_is_equal(actual[property], expected[property], prefix + '.' + property);
checked_set.add(actual[property]);
}
for(var property in actual) {
assert_true(property in expected, prefix);
if(!checked_set.has(actual[property])){
_is_equal(actual[property], expected[property], prefix + '.' + property);
}
}
object_stack.pop();
}
function _brand(object) {
return Object.prototype.toString.call(object).match(/^\[object (.*)\]$/)[1];
}
_is_equal(actual, expected,
(description ? description + ': ' : '') + _brand(expected));
};