WeakSet-constructor-add.js (3521B)
1 load(libdir + "asserts.js"); 2 load(libdir + "iteration.js"); 3 4 var k1 = {}; 5 var k2 = {}; 6 var k3 = {}; 7 var k4 = {}; 8 9 function test_patched() { 10 let orig = WeakSet.prototype.add; 11 12 // If adder is modified, constructor should call it. 13 var called = false; 14 15 WeakSet.prototype.add = function(k, v) { 16 assertEq(k, k1); 17 orig.call(this, k2); 18 called = true; 19 }; 20 21 var arr = [k1]; 22 23 var m = new WeakSet(arr); 24 25 assertEq(called, true); 26 assertEq(m.has(k1), false); 27 assertEq(m.has(k2), true); 28 29 WeakSet.prototype.add = orig; 30 } 31 32 function test_proxy1() { 33 let orig = WeakSet.prototype.add; 34 35 // If adder is modified, constructor should call it. 36 var called = false; 37 38 WeakSet.prototype.add = new Proxy(function(k, v) { 39 assertEq(k, k1); 40 orig.call(this, k2); 41 called = true; 42 }, {}); 43 44 var arr = [k1]; 45 46 var m = new WeakSet(arr); 47 48 assertEq(called, true); 49 assertEq(m.has(k1), false); 50 assertEq(m.has(k2), true); 51 52 WeakSet.prototype.add = orig; 53 } 54 55 function test_proxy2() { 56 let orig = WeakSet.prototype.add; 57 58 // If adder is modified, constructor should call it. 59 var called = false; 60 61 WeakSet.prototype.add = new Proxy(function() { 62 }, { 63 apply: function(target, that, args) { 64 var [k, v] = args; 65 assertEq(k, k1); 66 orig.call(that, k2); 67 called = true; 68 } 69 }); 70 71 var arr = [k1]; 72 73 var m = new WeakSet(arr); 74 75 assertEq(called, true); 76 assertEq(m.has(k1), false); 77 assertEq(m.has(k2), true); 78 79 WeakSet.prototype.add = orig; 80 } 81 82 function test_change1() { 83 let orig = WeakSet.prototype.add; 84 85 // Change to adder in GetIterator(..) call should be ignored. 86 var called = false; 87 var modified = false; 88 89 var arr = [k1]; 90 91 var proxy_arr = new Proxy(arr, { 92 get: function(target, name) { 93 if (name == Symbol.iterator) { 94 modified = true; 95 WeakSet.prototype.add = function() { 96 called = true; 97 }; 98 } 99 return target[name]; 100 } 101 }); 102 103 var m = new WeakSet(proxy_arr); 104 105 assertEq(modified, true); 106 assertEq(called, false); 107 assertEq(m.has(k1), true); 108 assertEq(m.has(k2), false); 109 110 WeakSet.prototype.add = orig; 111 } 112 113 function test_change2() { 114 let orig = WeakSet.prototype.add; 115 116 // Change to adder in adder(...) call should be ignored. 117 var called = false; 118 var count = 0; 119 120 WeakSet.prototype.add = function(k, v) { 121 if (count == 0) { 122 assertEq(k, k1); 123 orig.call(this, k3); 124 WeakSet.prototype.add = function() { 125 called = true; 126 }; 127 count = 1; 128 } else { 129 assertEq(k, k2); 130 orig.call(this, k4); 131 count = 2; 132 } 133 }; 134 135 var arr = [k1, k2]; 136 137 var m = new WeakSet(arr); 138 139 assertEq(called, false); 140 assertEq(count, 2); 141 assertEq(m.has(k1), false); 142 assertEq(m.has(k2), false); 143 assertEq(m.has(k3), true); 144 assertEq(m.has(k4), true); 145 146 WeakSet.prototype.add = orig; 147 } 148 149 function test_error() { 150 let orig = WeakSet.prototype.add; 151 152 var arr = [k1]; 153 154 // WeakSet should throw TypeError if adder is not callable. 155 WeakSet.prototype.add = null; 156 assertThrowsInstanceOf(() => new WeakSet(arr), TypeError); 157 WeakSet.prototype.add = {}; 158 assertThrowsInstanceOf(() => new WeakSet(arr), TypeError); 159 160 // WeakSet should propagate error thrown by adder. 161 WeakSet.prototype.add = function() { 162 throw SyntaxError(); 163 }; 164 assertThrowsInstanceOf(() => new WeakSet(arr), SyntaxError); 165 166 WeakSet.prototype.add = orig; 167 } 168 169 function test() { 170 test_patched(); 171 test_proxy1(); 172 test_proxy2(); 173 test_change1(); 174 test_change2(); 175 test_error(); 176 } 177 178 test();