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