Source code

Revision control

Copy as Markdown

Other Tools

load(libdir + "asserts.js");
load(libdir + "iteration.js");
var k1 = {};
var v1 = 42;
var k2 = {};
var v2 = 42;
var k3 = {};
var v3 = 43;
var k4 = {};
var v4 = 44;
function test_patched() {
let orig = WeakMap.prototype.set;
// If adder is modified, constructor should call it.
var called = false;
WeakMap.prototype.set = function(k, v) {
assertEq(k, k1);
assertEq(v, v1);
orig.call(this, k2, v2);
called = true;
};
var arr = [[k1, v1]];
var m = new WeakMap(arr);
assertEq(called, true);
assertEq(m.has(k1), false);
assertEq(m.has(k2), true);
assertEq(m.get(k1), undefined);
assertEq(m.get(k2), v2);
WeakMap.prototype.set = orig;
}
function test_proxy1() {
let orig = WeakMap.prototype.set;
// If adder is modified, constructor should call it.
var called = false;
WeakMap.prototype.set = new Proxy(function(k, v) {
assertEq(k, k1);
assertEq(v, v1);
orig.call(this, k2, v2);
called = true;
}, {});
var arr = [[k1, v1]];
var m = new WeakMap(arr);
assertEq(called, true);
assertEq(m.has(k1), false);
assertEq(m.has(k2), true);
assertEq(m.get(k1), undefined);
assertEq(m.get(k2), v2);
WeakMap.prototype.set = orig;
}
function test_proxy2() {
let orig = WeakMap.prototype.set;
// If adder is modified, constructor should call it.
var called = false;
WeakMap.prototype.set = new Proxy(function() {
}, {
apply: function(target, that, args) {
var [k, v] = args;
assertEq(k, k1);
assertEq(v, v1);
orig.call(that, k2, v2);
called = true;
}
});
var arr = [[k1, v1]];
var m = new WeakMap(arr);
assertEq(called, true);
assertEq(m.has(k1), false);
assertEq(m.has(k2), true);
assertEq(m.get(k1), undefined);
assertEq(m.get(k2), v2);
WeakMap.prototype.set = orig;
}
function test_change1() {
let orig = WeakMap.prototype.set;
// Change to adder in GetIterator(..) call should be ignored.
var called = false;
var modified = false;
var arr = [[k1, v1]];
var proxy_arr = new Proxy(arr, {
get: function(target, name) {
if (name == Symbol.iterator) {
modified = true;
WeakMap.prototype.set = function() {
called = true;
};
}
return target[name];
}
});
var m = new WeakMap(proxy_arr);
assertEq(modified, true);
assertEq(called, false);
assertEq(m.has(k1), true);
assertEq(m.has(k2), false);
assertEq(m.get(k1), v1);
assertEq(m.get(k2), undefined);
WeakMap.prototype.set = orig;
}
function test_change2() {
let orig = WeakMap.prototype.set;
// Change to adder in adder(...) call should be ignored.
var called = false;
var count = 0;
WeakMap.prototype.set = function(k, v) {
if (count == 0) {
assertEq(k, k1);
assertEq(v, v1);
orig.call(this, k3, v3);
WeakMap.prototype.set = function() {
called = true;
};
count = 1;
} else {
assertEq(k, k2);
assertEq(v, v2);
orig.call(this, k4, v4);
count = 2;
}
};
var arr = [[k1, v1], [k2, v2]];
var m = new WeakMap(arr);
assertEq(called, false);
assertEq(count, 2);
assertEq(m.has(k1), false);
assertEq(m.has(k2), false);
assertEq(m.has(k3), true);
assertEq(m.has(k4), true);
assertEq(m.get(k1), undefined);
assertEq(m.get(k2), undefined);
assertEq(m.get(k3), v3);
assertEq(m.get(k4), v4);
WeakMap.prototype.set = orig;
}
function test_error() {
let orig = WeakMap.prototype.set;
var arr = [[k1, v1]];
// WeakMap should throw TypeError if adder is not callable.
WeakMap.prototype.set = null;
assertThrowsInstanceOf(() => new WeakMap(arr), TypeError);
WeakMap.prototype.set = {};
assertThrowsInstanceOf(() => new WeakMap(arr), TypeError);
// WeakMap should propagate error thrown by adder.
WeakMap.prototype.set = function() {
throw SyntaxError();
};
assertThrowsInstanceOf(() => new WeakMap(arr), SyntaxError);
WeakMap.prototype.set = orig;
}
function test() {
test_patched();
test_proxy1();
test_proxy2();
test_change1();
test_change2();
test_error();
}
test();