diff options
Diffstat (limited to 'js/src/jit-test/tests/collections/Set-constructor-add.js')
-rw-r--r-- | js/src/jit-test/tests/collections/Set-constructor-add.js | 183 |
1 files changed, 183 insertions, 0 deletions
diff --git a/js/src/jit-test/tests/collections/Set-constructor-add.js b/js/src/jit-test/tests/collections/Set-constructor-add.js new file mode 100644 index 0000000000..8604c1386a --- /dev/null +++ b/js/src/jit-test/tests/collections/Set-constructor-add.js @@ -0,0 +1,183 @@ +load(libdir + "asserts.js"); +load(libdir + "iteration.js"); + +var k1 = {}; +var k2 = {}; +var k3 = {}; +var k4 = {}; + +function test_patched() { + let orig = Set.prototype.add; + + // If adder is modified, constructor should call it. + var called = false; + + Set.prototype.add = function(k, v) { + assertEq(k, k1); + orig.call(this, k2); + called = true; + }; + + var arr = [k1]; + + var m = new Set(arr); + + assertEq(called, true); + assertEq(m.size, 1); + assertEq(m.has(k1), false); + assertEq(m.has(k2), true); + + Set.prototype.add = orig; +} + +function test_proxy1() { + let orig = Set.prototype.add; + + // If adder is modified, constructor should call it. + var called = false; + + Set.prototype.add = new Proxy(function(k, v) { + assertEq(k, k1); + orig.call(this, k2); + called = true; + }, {}); + + var arr = [k1]; + + var m = new Set(arr); + + assertEq(called, true); + assertEq(m.size, 1); + assertEq(m.has(k1), false); + assertEq(m.has(k2), true); + + Set.prototype.add = orig; +} + +function test_proxy2() { + let orig = Set.prototype.add; + + // If adder is modified, constructor should call it. + var called = false; + + Set.prototype.add = new Proxy(function() { + }, { + apply: function(target, that, args) { + var [k, v] = args; + assertEq(k, k1); + orig.call(that, k2); + called = true; + } + }); + + var arr = [k1]; + + var m = new Set(arr); + + assertEq(called, true); + assertEq(m.size, 1); + assertEq(m.has(k1), false); + assertEq(m.has(k2), true); + + Set.prototype.add = orig; +} + +function test_change1() { + let orig = Set.prototype.add; + + // Change to adder in GetIterator(..) call should be ignored. + var called = false; + var modified = false; + + var arr = [k1]; + + var proxy_arr = new Proxy(arr, { + get: function(target, name) { + if (name == Symbol.iterator) { + modified = true; + Set.prototype.add = function() { + called = true; + }; + } + return target[name]; + } + }); + + var m = new Set(proxy_arr); + + assertEq(modified, true); + assertEq(called, false); + assertEq(m.size, 1); + assertEq(m.has(k1), true); + assertEq(m.has(k2), false); + + Set.prototype.add = orig; +} + +function test_change2() { + let orig = Set.prototype.add; + + // Change to adder in adder(...) call should be ignored. + var called = false; + var count = 0; + + Set.prototype.add = function(k, v) { + if (count == 0) { + assertEq(k, k1); + orig.call(this, k3); + Set.prototype.add = function() { + called = true; + }; + count = 1; + } else { + assertEq(k, k2); + orig.call(this, k4); + count = 2; + } + }; + + var arr = [k1, k2]; + + var m = new Set(arr); + + assertEq(called, false); + assertEq(count, 2); + assertEq(m.size, 2); + assertEq(m.has(k1), false); + assertEq(m.has(k2), false); + assertEq(m.has(k3), true); + assertEq(m.has(k4), true); + + Set.prototype.add = orig; +} + +function test_error() { + let orig = Set.prototype.add; + + var arr = [k1]; + + // Set should throw TypeError if adder is not callable. + Set.prototype.add = null; + assertThrowsInstanceOf(() => new Set(arr), TypeError); + Set.prototype.add = {}; + assertThrowsInstanceOf(() => new Set(arr), TypeError); + + // Set should propagate error thrown by adder. + Set.prototype.add = function() { + throw SyntaxError(); + }; + assertThrowsInstanceOf(() => new Set(arr), SyntaxError); + + Set.prototype.add = orig; +} + +function test() { + test_patched(); + test_proxy1(); + test_proxy2(); + test_change1(); + test_change2(); + test_error(); +} + +test(); |