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