function-definition-evaluate.js (11303B)
1 // |reftest| skip-if(!xulRuntime.shell) -- needs evaluate() 2 /* 3 * Any copyright is dedicated to the Public Domain. 4 * http://creativecommons.org/licenses/publicdomain/ 5 */ 6 7 //----------------------------------------------------------------------------- 8 var BUGNUMBER = 577325; 9 var summary = 'Implement the ES5 algorithm for processing function statements'; 10 11 print(BUGNUMBER + ": " + summary); 12 13 /************** 14 * BEGIN TEST * 15 **************/ 16 17 var outer, desc; 18 19 /////////////////////////////////////////////////// 20 // Function definitions over accessor properties // 21 /////////////////////////////////////////////////// 22 23 var getCalled, setCalled; 24 25 // configurable properties get blown away 26 27 getCalled = false, setCalled = false; 28 Object.defineProperty(this, "acc1", 29 { 30 get: function() { getCalled = true; throw "FAIL get 1"; }, 31 set: function(v) { setCalled = true; throw "FAIL set 1 " + v; }, 32 configurable: true, 33 enumerable: false 34 }); 35 36 // does not throw 37 outer = undefined; 38 evaluate("function acc1() { throw 'FAIL redefined 1'; } outer = acc1;"); 39 assertEq(getCalled, false); 40 assertEq(setCalled, false); 41 assertEq(typeof acc1, "function"); 42 assertEq(acc1, outer); 43 desc = Object.getOwnPropertyDescriptor(this, "acc1"); 44 assertEq(desc.value, acc1); 45 assertEq(desc.writable, true); 46 assertEq(desc.enumerable, true); 47 assertEq(desc.configurable, false); 48 49 50 getCalled = false, setCalled = false; 51 Object.defineProperty(this, "acc2", 52 { 53 get: function() { getCalled = true; throw "FAIL get 2"; }, 54 set: function(v) { setCalled = true; throw "FAIL set 2 " + v; }, 55 configurable: true, 56 enumerable: true 57 }); 58 59 // does not throw 60 outer = undefined; 61 evaluate("function acc2() { throw 'FAIL redefined 2'; } outer = acc2;"); 62 assertEq(getCalled, false); 63 assertEq(setCalled, false); 64 assertEq(typeof acc2, "function"); 65 assertEq(acc2, outer); 66 desc = Object.getOwnPropertyDescriptor(this, "acc2"); 67 assertEq(desc.value, acc2); 68 assertEq(desc.writable, true); 69 assertEq(desc.enumerable, true); 70 assertEq(desc.configurable, false); 71 72 73 // non-configurable properties produce a TypeError 74 75 getCalled = false, setCalled = false; 76 Object.defineProperty(this, "acc3", 77 { 78 get: function() { getCalled = true; throw "FAIL get 3"; }, 79 set: function(v) { setCalled = true; throw "FAIL set 3 " + v; }, 80 configurable: false, 81 enumerable: true 82 }); 83 84 outer = undefined; 85 try 86 { 87 evaluate("function acc3() { throw 'FAIL redefined 3'; }; outer = acc3"); 88 throw new Error("should have thrown trying to redefine global function " + 89 "over a non-configurable, enumerable accessor"); 90 } 91 catch (e) 92 { 93 assertEq(e instanceof TypeError, true, 94 "global function definition, when that function would overwrite " + 95 "a non-configurable, enumerable accessor, must throw a TypeError " + 96 "per ES5+errata: " + e); 97 desc = Object.getOwnPropertyDescriptor(this, "acc3"); 98 assertEq(typeof desc.get, "function"); 99 assertEq(typeof desc.set, "function"); 100 assertEq(desc.enumerable, true); 101 assertEq(desc.configurable, false); 102 assertEq(outer, undefined); 103 assertEq(getCalled, false); 104 assertEq(setCalled, false); 105 } 106 107 108 getCalled = false, setCalled = false; 109 Object.defineProperty(this, "acc4", 110 { 111 get: function() { getCalled = true; throw "FAIL get 4"; }, 112 set: function(v) { setCalled = true; throw "FAIL set 4 " + v; }, 113 configurable: false, 114 enumerable: false 115 }); 116 117 outer = undefined; 118 try 119 { 120 evaluate("function acc4() { throw 'FAIL redefined 4'; }; outer = acc4"); 121 throw new Error("should have thrown trying to redefine global function " + 122 "over a non-configurable, non-enumerable accessor"); 123 } 124 catch (e) 125 { 126 assertEq(e instanceof TypeError, true, 127 "global function definition, when that function would overwrite " + 128 "a non-configurable, non-enumerable accessor, must throw a " + 129 "TypeError per ES5+errata: " + e); 130 desc = Object.getOwnPropertyDescriptor(this, "acc4"); 131 assertEq(typeof desc.get, "function"); 132 assertEq(typeof desc.set, "function"); 133 assertEq(desc.enumerable, false); 134 assertEq(desc.configurable, false); 135 assertEq(outer, undefined); 136 assertEq(getCalled, false); 137 assertEq(setCalled, false); 138 } 139 140 141 /////////////////////////////////////////////// 142 // Function definitions over data properties // 143 /////////////////////////////////////////////// 144 145 146 // configurable properties, regardless of other attributes, get blown away 147 148 Object.defineProperty(this, "data1", 149 { 150 configurable: true, 151 enumerable: true, 152 writable: true, 153 value: "data1" 154 }); 155 156 outer = undefined; 157 evaluate("function data1() { return 'data1 function'; } outer = data1;"); 158 assertEq(typeof data1, "function"); 159 assertEq(data1, outer); 160 desc = Object.getOwnPropertyDescriptor(this, "data1"); 161 assertEq(desc.configurable, false); 162 assertEq(desc.enumerable, true); 163 assertEq(desc.writable, true); 164 assertEq(desc.value, data1); 165 166 167 Object.defineProperty(this, "data2", 168 { 169 configurable: true, 170 enumerable: true, 171 writable: false, 172 value: "data2" 173 }); 174 175 outer = undefined; 176 evaluate("function data2() { return 'data2 function'; } outer = data2;"); 177 assertEq(typeof data2, "function"); 178 assertEq(data2, outer); 179 desc = Object.getOwnPropertyDescriptor(this, "data2"); 180 assertEq(desc.configurable, false); 181 assertEq(desc.enumerable, true); 182 assertEq(desc.writable, true); 183 assertEq(desc.value, data2); 184 185 186 Object.defineProperty(this, "data3", 187 { 188 configurable: true, 189 enumerable: false, 190 writable: true, 191 value: "data3" 192 }); 193 194 outer = undefined; 195 evaluate("function data3() { return 'data3 function'; } outer = data3;"); 196 assertEq(typeof data3, "function"); 197 assertEq(data3, outer); 198 desc = Object.getOwnPropertyDescriptor(this, "data3"); 199 assertEq(desc.configurable, false); 200 assertEq(desc.enumerable, true); 201 assertEq(desc.writable, true); 202 assertEq(desc.value, data3); 203 204 205 Object.defineProperty(this, "data4", 206 { 207 configurable: true, 208 enumerable: false, 209 writable: false, 210 value: "data4" 211 }); 212 213 outer = undefined; 214 evaluate("function data4() { return 'data4 function'; } outer = data4;"); 215 assertEq(typeof data4, "function"); 216 assertEq(data4, outer); 217 desc = Object.getOwnPropertyDescriptor(this, "data4"); 218 assertEq(desc.value, data4); 219 assertEq(desc.writable, true); 220 assertEq(desc.enumerable, true); 221 assertEq(desc.configurable, false); 222 223 224 // non-configurable data properties are trickier 225 226 Object.defineProperty(this, "data5", 227 { 228 configurable: false, 229 enumerable: true, 230 writable: true, 231 value: "data5" 232 }); 233 234 outer = undefined; 235 evaluate("function data5() { return 'data5 function'; } outer = data5;"); 236 assertEq(typeof data5, "function"); 237 assertEq(data5, outer); 238 desc = Object.getOwnPropertyDescriptor(this, "data5"); 239 assertEq(desc.configurable, false); 240 assertEq(desc.enumerable, true); 241 assertEq(desc.writable, true); 242 assertEq(desc.value, data5); 243 244 245 Object.defineProperty(this, "data6", 246 { 247 configurable: false, 248 enumerable: true, 249 writable: false, 250 value: "data6" 251 }); 252 253 outer = undefined; 254 try 255 { 256 evaluate("function data6() { return 'data6 function'; } outer = data6;"); 257 throw new Error("should have thrown trying to redefine global function " + 258 "over a non-configurable, enumerable, non-writable accessor"); 259 } 260 catch (e) 261 { 262 assertEq(e instanceof TypeError, true, 263 "global function definition, when that function would overwrite " + 264 "a non-configurable, enumerable, non-writable data property, must " + 265 "throw a TypeError per ES5+errata: " + e); 266 assertEq(data6, "data6"); 267 assertEq(outer, undefined); 268 desc = Object.getOwnPropertyDescriptor(this, "data6"); 269 assertEq(desc.configurable, false); 270 assertEq(desc.enumerable, true); 271 assertEq(desc.writable, false); 272 assertEq(desc.value, "data6"); 273 } 274 275 276 Object.defineProperty(this, "data7", 277 { 278 configurable: false, 279 enumerable: false, 280 writable: true, 281 value: "data7" 282 }); 283 284 outer = undefined; 285 try 286 { 287 evaluate("function data7() { return 'data7 function'; } outer = data7;"); 288 throw new Error("should have thrown trying to redefine global function " + 289 "over a non-configurable, non-enumerable, writable data" + 290 "property"); 291 } 292 catch (e) 293 { 294 assertEq(e instanceof TypeError, true, 295 "global function definition, when that function would overwrite " + 296 "a non-configurable, non-enumerable, writable data property, must " + 297 "throw a TypeError per ES5+errata: " + e); 298 assertEq(data7, "data7"); 299 assertEq(outer, undefined); 300 desc = Object.getOwnPropertyDescriptor(this, "data7"); 301 assertEq(desc.configurable, false); 302 assertEq(desc.enumerable, false); 303 assertEq(desc.writable, true); 304 assertEq(desc.value, "data7"); 305 } 306 307 308 Object.defineProperty(this, "data8", 309 { 310 configurable: false, 311 enumerable: false, 312 writable: false, 313 value: "data8" 314 }); 315 316 outer = undefined; 317 try 318 { 319 evaluate("function data8() { return 'data8 function'; } outer = data8;"); 320 throw new Error("should have thrown trying to redefine global function " + 321 "over a non-configurable, non-enumerable, non-writable data" + 322 "property"); 323 } 324 catch (e) 325 { 326 assertEq(e instanceof TypeError, true, 327 "global function definition, when that function would overwrite " + 328 "a non-configurable, non-enumerable, non-writable data property, " + 329 "must throw a TypeError per ES5+errata: " + e); 330 assertEq(data8, "data8"); 331 assertEq(outer, undefined); 332 desc = Object.getOwnPropertyDescriptor(this, "data8"); 333 assertEq(desc.configurable, false); 334 assertEq(desc.enumerable, false); 335 assertEq(desc.writable, false); 336 assertEq(desc.value, "data8"); 337 } 338 339 /******************************************************************************/ 340 341 if (typeof reportCompare === "function") 342 reportCompare(true, true); 343 344 print("All tests passed!");