1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/js/src/tests/ecma_5/Object/defineProperty-setup.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,1106 @@ 1.4 +// |reftest| skip -- not a test. 1.5 +// Any copyright is dedicated to the Public Domain. 1.6 +// http://creativecommons.org/licenses/publicdomain/ 1.7 + 1.8 +assertEq("defineProperty" in Object, true); 1.9 +assertEq(Object.defineProperty.length, 3); 1.10 + 1.11 +/* 1.12 + * Disable an assertion that is pathologically slow given the exhaustiveness of 1.13 + * these tests. 1.14 + */ 1.15 +if (typeof enableStackWalkingAssertion === "function") 1.16 + enableStackWalkingAssertion(false); 1.17 + 1.18 +if (!Object.prototype.toSource) 1.19 +{ 1.20 + Object.defineProperty(Object.prototype, "toSource", 1.21 + { 1.22 + value: function toSource() 1.23 + { 1.24 + if (this instanceof RegExp) 1.25 + { 1.26 + var v = "new RegExp(" + uneval(this.source); 1.27 + var f = (this.multiline ? "m" : "") + 1.28 + (this.global ? "g" : "") + 1.29 + (this.ignoreCase ? "i" : ""); 1.30 + return v + (f ? ", '" + f + "'" : "") + ")"; 1.31 + } 1.32 + return JSON.stringify(this); 1.33 + }, 1.34 + enumerable: false, 1.35 + configurable: true, 1.36 + writable: true 1.37 + }); 1.38 +} 1.39 +if (!("uneval" in this)) 1.40 +{ 1.41 + Object.defineProperty(this, "uneval", 1.42 + { 1.43 + value: function uneval(v) 1.44 + { 1.45 + if (v === null) 1.46 + return "null"; 1.47 + if (typeof v === "object") 1.48 + return v.toSource(); 1.49 + if (typeof v === "string") 1.50 + { 1.51 + v = JSON.stringify({v:v}); 1.52 + return v.substring(5, v.length - 1); 1.53 + } 1.54 + return "" + v; 1.55 + }, 1.56 + enumerable: false, 1.57 + configurable: true, 1.58 + writable: true 1.59 + }); 1.60 +} 1.61 + 1.62 +// reimplemented for the benefit of engines which don't have this helper 1.63 +function assertEq(v1, v2, m) 1.64 +{ 1.65 + if (!SameValue(v1, v2)) 1.66 + { 1.67 + throw "assertion failed: " + 1.68 + "got " + uneval(v1) + ", expected " + uneval(v2) + 1.69 + (m ? ": " + m : ""); 1.70 + } 1.71 +} 1.72 + 1.73 +function SameValue(v1, v2) 1.74 +{ 1.75 + if (v1 === 0 && v2 === 0) 1.76 + return 1 / v1 === 1 / v2; 1.77 + if (v1 !== v1 && v2 !== v2) 1.78 + return true; 1.79 + return v1 === v2; 1.80 +} 1.81 + 1.82 +function PropertyDescriptor(pd) 1.83 +{ 1.84 + if (pd) 1.85 + this.update(pd); 1.86 +} 1.87 +PropertyDescriptor.prototype.update = function update(pd) 1.88 +{ 1.89 + if ("get" in pd) 1.90 + this.get = pd.get; 1.91 + if ("set" in pd) 1.92 + this.set = pd.set; 1.93 + if ("configurable" in pd) 1.94 + this.configurable = pd.configurable; 1.95 + if ("writable" in pd) 1.96 + this.writable = pd.writable; 1.97 + if ("enumerable" in pd) 1.98 + this.enumerable = pd.enumerable; 1.99 + if ("value" in pd) 1.100 + this.value = pd.value; 1.101 +}; 1.102 +PropertyDescriptor.prototype.convertToDataDescriptor = function convertToDataDescriptor() 1.103 +{ 1.104 + delete this.get; 1.105 + delete this.set; 1.106 + this.writable = false; 1.107 + this.value = undefined; 1.108 +}; 1.109 +PropertyDescriptor.prototype.convertToAccessorDescriptor = function convertToAccessorDescriptor() 1.110 +{ 1.111 + delete this.writable; 1.112 + delete this.value; 1.113 + this.get = undefined; 1.114 + this.set = undefined; 1.115 +}; 1.116 + 1.117 +function compareDescriptors(d1, d2) 1.118 +{ 1.119 + if (d1 === undefined) 1.120 + { 1.121 + assertEq(d2, undefined, "non-descriptors"); 1.122 + return; 1.123 + } 1.124 + if (d2 === undefined) 1.125 + { 1.126 + assertEq(true, false, "descriptor-equality mismatch: " + uneval(d1) + ", " + uneval(d2)); 1.127 + return; 1.128 + } 1.129 + 1.130 + var props = ["value", "get", "set", "enumerable", "configurable", "writable"]; 1.131 + for (var i = 0, sz = props.length; i < sz; i++) 1.132 + { 1.133 + var p = props[i]; 1.134 + assertEq(p in d1, p in d2, p + " different in d1/d2"); 1.135 + if (p in d1) 1.136 + assertEq(d1[p], d2[p], p); 1.137 + } 1.138 +} 1.139 + 1.140 +function examine(desc, field, allowDefault) 1.141 +{ 1.142 + if (field in desc) 1.143 + return desc[field]; 1.144 + assertEq(allowDefault, true, "reimplementation error"); 1.145 + switch (field) 1.146 + { 1.147 + case "value": 1.148 + case "get": 1.149 + case "set": 1.150 + return undefined; 1.151 + case "writable": 1.152 + case "enumerable": 1.153 + case "configurable": 1.154 + return false; 1.155 + default: 1.156 + assertEq(true, false, "bad field name: " + field); 1.157 + } 1.158 +} 1.159 + 1.160 +function IsAccessorDescriptor(desc) 1.161 +{ 1.162 + if (!desc) 1.163 + return false; 1.164 + if (!("get" in desc) && !("set" in desc)) 1.165 + return false; 1.166 + return true; 1.167 +} 1.168 + 1.169 +function IsDataDescriptor(desc) 1.170 +{ 1.171 + if (!desc) 1.172 + return false; 1.173 + if (!("value" in desc) && !("writable" in desc)) 1.174 + return false; 1.175 + return true; 1.176 +} 1.177 + 1.178 +function IsGenericDescriptor(desc) 1.179 +{ 1.180 + if (!desc) 1.181 + return false; 1.182 + if (!IsAccessorDescriptor(desc) && !IsDataDescriptor(desc)) 1.183 + return true; 1.184 + return false; 1.185 +} 1.186 + 1.187 + 1.188 + 1.189 +function CustomObject() 1.190 +{ 1.191 + this.properties = {}; 1.192 + this.extensible = true; 1.193 +} 1.194 +CustomObject.prototype = 1.195 +{ 1.196 + _reject: function _reject(throwing, msg) 1.197 + { 1.198 + if (throwing) 1.199 + throw new TypeError(msg + "; rejected!"); 1.200 + return false; 1.201 + }, 1.202 + defineOwnProperty: function defineOwnProperty(propname, desc, throwing) 1.203 + { 1.204 + assertEq(typeof propname, "string", "non-string propname"); 1.205 + 1.206 + // Step 1. 1.207 + var current = this.properties[propname]; 1.208 + 1.209 + // Step 2. 1.210 + var extensible = this.extensible; 1.211 + 1.212 + // Step 3. 1.213 + if (current === undefined && !extensible) 1.214 + return this._reject(throwing, "object not extensible"); 1.215 + 1.216 + // Step 4. 1.217 + if (current === undefined && extensible) 1.218 + { 1.219 + var p; 1.220 + // Step 4(a). 1.221 + if (IsGenericDescriptor(desc) || IsDataDescriptor(desc)) 1.222 + { 1.223 + p = new PropertyDescriptor(); 1.224 + p.value = examine(desc, "value", true); 1.225 + p.writable = examine(desc, "writable", true); 1.226 + p.enumerable = examine(desc, "enumerable", true); 1.227 + p.configurable = examine(desc, "configurable", true); 1.228 + } 1.229 + // Step 4(b). 1.230 + else 1.231 + { 1.232 + p = new PropertyDescriptor(); 1.233 + p.get = examine(desc, "get", true); 1.234 + p.set = examine(desc, "set", true); 1.235 + p.enumerable = examine(desc, "enumerable", true); 1.236 + p.configurable = examine(desc, "configurable", true); 1.237 + } 1.238 + 1.239 + this.properties[propname] = p; 1.240 + 1.241 + // Step 4(c). 1.242 + return true; 1.243 + } 1.244 + 1.245 + // Step 5. 1.246 + if (!("value" in desc) && !("get" in desc) && !("set" in desc) && 1.247 + !("writable" in desc) && !("enumerable" in desc) && 1.248 + !("configurable" in desc)) 1.249 + { 1.250 + return; 1.251 + } 1.252 + 1.253 + // Step 6. 1.254 + do 1.255 + { 1.256 + if ("value" in desc) 1.257 + { 1.258 + if (!("value" in current) || !SameValue(desc.value, current.value)) 1.259 + break; 1.260 + } 1.261 + if ("get" in desc) 1.262 + { 1.263 + if (!("get" in current) || !SameValue(desc.get, current.get)) 1.264 + break; 1.265 + } 1.266 + if ("set" in desc) 1.267 + { 1.268 + if (!("set" in current) || !SameValue(desc.set, current.set)) 1.269 + break; 1.270 + } 1.271 + if ("writable" in desc) 1.272 + { 1.273 + if (!("writable" in current) || 1.274 + !SameValue(desc.writable, current.writable)) 1.275 + { 1.276 + break; 1.277 + } 1.278 + } 1.279 + if ("enumerable" in desc) 1.280 + { 1.281 + if (!("enumerable" in current) || 1.282 + !SameValue(desc.enumerable, current.enumerable)) 1.283 + { 1.284 + break; 1.285 + } 1.286 + } 1.287 + if ("configurable" in desc) 1.288 + { 1.289 + if (!("configurable" in current) || 1.290 + !SameValue(desc.configurable, current.configurable)) 1.291 + { 1.292 + break; 1.293 + } 1.294 + } 1.295 + 1.296 + // all fields in desc also in current, with the same values 1.297 + return true; 1.298 + } 1.299 + while (false); 1.300 + 1.301 + // Step 7. 1.302 + if (!examine(current, "configurable")) 1.303 + { 1.304 + if ("configurable" in desc && examine(desc, "configurable")) 1.305 + return this._reject(throwing, "can't make configurable again"); 1.306 + if ("enumerable" in desc && 1.307 + examine(current, "enumerable") !== examine(desc, "enumerable")) 1.308 + { 1.309 + return this._reject(throwing, "can't change enumerability"); 1.310 + } 1.311 + } 1.312 + 1.313 + // Step 8. 1.314 + if (IsGenericDescriptor(desc)) 1.315 + { 1.316 + // do nothing 1.317 + } 1.318 + // Step 9. 1.319 + else if (IsDataDescriptor(current) !== IsDataDescriptor(desc)) 1.320 + { 1.321 + // Step 9(a). 1.322 + if (!examine(current, "configurable")) 1.323 + return this._reject(throwing, "can't change unconfigurable descriptor's type"); 1.324 + // Step 9(b). 1.325 + if (IsDataDescriptor(current)) 1.326 + current.convertToAccessorDescriptor(); 1.327 + // Step 9(c). 1.328 + else 1.329 + current.convertToDataDescriptor(); 1.330 + } 1.331 + // Step 10. 1.332 + else if (IsDataDescriptor(current) && IsDataDescriptor(desc)) 1.333 + { 1.334 + // Step 10(a) 1.335 + if (!examine(current, "configurable")) 1.336 + { 1.337 + // Step 10(a).i. 1.338 + if (!examine(current, "writable") && 1.339 + "writable" in desc && examine(desc, "writable")) 1.340 + { 1.341 + return this._reject(throwing, "can't make data property writable again"); 1.342 + } 1.343 + // Step 10(a).ii. 1.344 + if (!examine(current, "writable")) 1.345 + { 1.346 + if ("value" in desc && 1.347 + !SameValue(examine(desc, "value"), examine(current, "value"))) 1.348 + { 1.349 + return this._reject(throwing, "can't change value if not writable"); 1.350 + } 1.351 + } 1.352 + } 1.353 + // Step 10(b). 1.354 + else 1.355 + { 1.356 + assertEq(examine(current, "configurable"), true, 1.357 + "spec bug step 10(b)"); 1.358 + } 1.359 + } 1.360 + // Step 11. 1.361 + else 1.362 + { 1.363 + assertEq(IsAccessorDescriptor(current) && IsAccessorDescriptor(desc), 1.364 + true, 1.365 + "spec bug"); 1.366 + 1.367 + // Step 11(a). 1.368 + if (!examine(current, "configurable")) 1.369 + { 1.370 + // Step 11(a).i. 1.371 + if ("set" in desc && 1.372 + !SameValue(examine(desc, "set"), examine(current, "set"))) 1.373 + { 1.374 + return this._reject(throwing, "can't change setter if not configurable"); 1.375 + } 1.376 + // Step 11(a).ii. 1.377 + if ("get" in desc && 1.378 + !SameValue(examine(desc, "get"), examine(current, "get"))) 1.379 + { 1.380 + return this._reject(throwing, "can't change getter if not configurable"); 1.381 + } 1.382 + } 1.383 + } 1.384 + 1.385 + // Step 12. 1.386 + current.update(desc); 1.387 + 1.388 + // Step 13. 1.389 + return true; 1.390 + } 1.391 +}; 1.392 + 1.393 +function IsCallable(v) 1.394 +{ 1.395 + return typeof v === "undefined" || typeof v === "function"; 1.396 +} 1.397 + 1.398 +var NativeTest = 1.399 + { 1.400 + newObject: function newObject() 1.401 + { 1.402 + return {}; 1.403 + }, 1.404 + defineProperty: function defineProperty(obj, propname, propdesc) 1.405 + { 1.406 + Object.defineProperty(obj, propname, propdesc); 1.407 + }, 1.408 + getDescriptor: function getDescriptor(obj, propname) 1.409 + { 1.410 + return Object.getOwnPropertyDescriptor(obj, propname); 1.411 + } 1.412 + }; 1.413 + 1.414 +var ReimplTest = 1.415 + { 1.416 + newObject: function newObject() 1.417 + { 1.418 + return new CustomObject(); 1.419 + }, 1.420 + defineProperty: function defineProperty(obj, propname, propdesc) 1.421 + { 1.422 + assertEq(obj instanceof CustomObject, true, "obj not instanceof CustomObject"); 1.423 + if ("get" in propdesc || "set" in propdesc) 1.424 + { 1.425 + if ("value" in propdesc || "writable" in propdesc) 1.426 + throw new TypeError("get/set and value/writable"); 1.427 + if (!IsCallable(propdesc.get)) 1.428 + throw new TypeError("get defined, uncallable"); 1.429 + if (!IsCallable(propdesc.set)) 1.430 + throw new TypeError("set defined, uncallable"); 1.431 + } 1.432 + return obj.defineOwnProperty(propname, propdesc, true); 1.433 + }, 1.434 + getDescriptor: function getDescriptor(obj, propname) 1.435 + { 1.436 + if (!(propname in obj.properties)) 1.437 + return undefined; 1.438 + 1.439 + return new PropertyDescriptor(obj.properties[propname]); 1.440 + } 1.441 + }; 1.442 + 1.443 +var JSVAL_INT_MAX = Math.pow(2, 30) - 1; 1.444 +var JSVAL_INT_MIN = -Math.pow(2, 30); 1.445 + 1.446 + 1.447 +function isValidDescriptor(propdesc) 1.448 +{ 1.449 + if ("get" in propdesc || "set" in propdesc) 1.450 + { 1.451 + if ("value" in propdesc || "writable" in propdesc) 1.452 + return false; 1.453 + 1.454 + // We permit null here simply because this test's author believes the 1.455 + // implementation may sometime be susceptible to making mistakes in this 1.456 + // regard and would prefer to be cautious. 1.457 + if (propdesc.get !== null && propdesc.get !== undefined && !IsCallable(propdesc.get)) 1.458 + return false; 1.459 + if (propdesc.set !== null && propdesc.set !== undefined && !IsCallable(propdesc.set)) 1.460 + return false; 1.461 + } 1.462 + 1.463 + return true; 1.464 +} 1.465 + 1.466 + 1.467 +var OMIT = {}; 1.468 +var VALUES = 1.469 + [-Infinity, JSVAL_INT_MIN, -0, +0, 1.5, JSVAL_INT_MAX, Infinity, 1.470 + NaN, "foo", "bar", null, undefined, true, false, {}, /a/, OMIT]; 1.471 +var GETS = 1.472 + [undefined, function get1() { return 1; }, function get2() { return 2; }, 1.473 + null, 5, OMIT]; 1.474 +var SETS = 1.475 + [undefined, function set1() { return 1; }, function set2() { return 2; }, 1.476 + null, 5, OMIT]; 1.477 +var ENUMERABLES = [true, false, OMIT]; 1.478 +var CONFIGURABLES = [true, false, OMIT]; 1.479 +var WRITABLES = [true, false, OMIT]; 1.480 + 1.481 +function mapTestDescriptors(filter) 1.482 +{ 1.483 + var descs = []; 1.484 + var desc = {}; 1.485 + 1.486 + function put(field, value) 1.487 + { 1.488 + if (value !== OMIT) 1.489 + desc[field] = value; 1.490 + } 1.491 + 1.492 + VALUES.forEach(function(value) 1.493 + { 1.494 + GETS.forEach(function(get) 1.495 + { 1.496 + SETS.forEach(function(set) 1.497 + { 1.498 + ENUMERABLES.forEach(function(enumerable) 1.499 + { 1.500 + CONFIGURABLES.forEach(function(configurable) 1.501 + { 1.502 + WRITABLES.forEach(function(writable) 1.503 + { 1.504 + desc = {}; 1.505 + put("value", value); 1.506 + put("get", get); 1.507 + put("set", set); 1.508 + put("enumerable", enumerable); 1.509 + put("configurable", configurable); 1.510 + put("writable", writable); 1.511 + if (filter(desc)) 1.512 + descs.push(desc); 1.513 + }); 1.514 + }); 1.515 + }); 1.516 + }); 1.517 + }); 1.518 + }); 1.519 + 1.520 + return descs; 1.521 +} 1.522 + 1.523 +var ALL_DESCRIPTORS = mapTestDescriptors(function(d) { return true; }); 1.524 +var VALID_DESCRIPTORS = mapTestDescriptors(isValidDescriptor); 1.525 + 1.526 +var SKIP_FULL_FUNCTION_LENGTH_TESTS = true; 1.527 + 1.528 +function TestRunner() 1.529 +{ 1.530 + this._logLines = []; 1.531 +} 1.532 +TestRunner.prototype = 1.533 + { 1.534 + // MAIN METHODS 1.535 + 1.536 + runFunctionLengthTests: function runFunctionLengthTests() 1.537 + { 1.538 + var self = this; 1.539 + function functionLengthTests() 1.540 + { 1.541 + if (SKIP_FULL_FUNCTION_LENGTH_TESTS) 1.542 + { 1.543 + print("Skipping full tests for redefining Function.length for now " + 1.544 + "because we don't support redefinition of properties with " + 1.545 + "native getter or setter..."); 1.546 + self._simpleFunctionLengthTests(); 1.547 + } 1.548 + else 1.549 + { 1.550 + self._simpleFunctionLengthTests(); 1.551 + self._fullFunctionLengthTests(function() { }, 0); 1.552 + self._fullFunctionLengthTests(function(one) { }, 1); 1.553 + self._fullFunctionLengthTests(function(one, two) { }, 2); 1.554 + } 1.555 + } 1.556 + 1.557 + this._runTestSet(functionLengthTests, "Function length tests completed!"); 1.558 + }, 1.559 + 1.560 + runNotPresentTests: function runNotPresentTests() 1.561 + { 1.562 + var self = this; 1.563 + function notPresentTests() 1.564 + { 1.565 + print("Running not-present tests now..."); 1.566 + 1.567 + for (var i = 0, sz = ALL_DESCRIPTORS.length; i < sz; i++) 1.568 + self._runSingleNotPresentTest(ALL_DESCRIPTORS[i]); 1.569 + }; 1.570 + 1.571 + this._runTestSet(notPresentTests, "Not-present length tests completed!"); 1.572 + }, 1.573 + 1.574 + runPropertyPresentTestsFraction: 1.575 + function runPropertyPresentTestsFraction(part, parts) 1.576 + { 1.577 + var self = this; 1.578 + function propertyPresentTests() 1.579 + { 1.580 + print("Running already-present tests now..."); 1.581 + 1.582 + var total = VALID_DESCRIPTORS.length; 1.583 + var start = Math.floor((part - 1) / parts * total); 1.584 + var end = Math.floor(part / parts * total); 1.585 + 1.586 + for (var i = start; i < end; i++) 1.587 + { 1.588 + var old = VALID_DESCRIPTORS[i]; 1.589 + print("Starting test with old descriptor " + old.toSource() + "..."); 1.590 + 1.591 + for (var j = 0, sz2 = VALID_DESCRIPTORS.length; j < sz2; j++) 1.592 + self._runSinglePropertyPresentTest(old, VALID_DESCRIPTORS[j], []); 1.593 + } 1.594 + } 1.595 + 1.596 + this._runTestSet(propertyPresentTests, 1.597 + "Property-present fraction " + part + " of " + parts + 1.598 + " completed!"); 1.599 + }, 1.600 + 1.601 + runNonTerminalPropertyPresentTestsFraction: 1.602 + function runNonTerminalPropertyPresentTestsFraction(part, parts) 1.603 + { 1.604 + var self = this; 1.605 + 1.606 + /* 1.607 + * A plain old property to define on the object before redefining the 1.608 + * originally-added property, to test redefinition of a property that's 1.609 + * not also lastProperty. NB: we could loop over every possible 1.610 + * descriptor here if we wanted, even try adding more than one, but we'd 1.611 + * hit cubic complexity and worse, and SpiderMonkey only distinguishes by 1.612 + * the mere presence of the middle property, not its precise details. 1.613 + */ 1.614 + var middleDefines = 1.615 + [{ 1.616 + property: "middle", 1.617 + descriptor: 1.618 + { value: 17, writable: true, configurable: true, enumerable: true } 1.619 + }]; 1.620 + 1.621 + function nonTerminalPropertyPresentTests() 1.622 + { 1.623 + print("Running non-terminal already-present tests now..."); 1.624 + 1.625 + var total = VALID_DESCRIPTORS.length; 1.626 + var start = Math.floor((part - 1) / parts * total); 1.627 + var end = Math.floor(part / parts * total); 1.628 + 1.629 + for (var i = start; i < end; i++) 1.630 + { 1.631 + var old = VALID_DESCRIPTORS[i]; 1.632 + print("Starting test with old descriptor " + old.toSource() + "..."); 1.633 + 1.634 + for (var j = 0, sz2 = VALID_DESCRIPTORS.length; j < sz2; j++) 1.635 + { 1.636 + self._runSinglePropertyPresentTest(old, VALID_DESCRIPTORS[j], 1.637 + middleDefines); 1.638 + } 1.639 + } 1.640 + } 1.641 + 1.642 + this._runTestSet(nonTerminalPropertyPresentTests, 1.643 + "Non-terminal property-present fraction " + 1.644 + part + " of " + parts + " completed!"); 1.645 + }, 1.646 + 1.647 + runDictionaryPropertyPresentTestsFraction: 1.648 + function runDictionaryPropertyPresentTestsFraction(part, parts) 1.649 + { 1.650 + var self = this; 1.651 + 1.652 + /* 1.653 + * Add and readd properties such that the scope for the object is in 1.654 + * dictionary mode. 1.655 + */ 1.656 + var middleDefines = 1.657 + [ 1.658 + { 1.659 + property: "mid1", 1.660 + descriptor: 1.661 + { value: 17, writable: true, configurable: true, enumerable: true } 1.662 + }, 1.663 + { 1.664 + property: "mid2", 1.665 + descriptor: 1.666 + { value: 17, writable: true, configurable: true, enumerable: true } 1.667 + }, 1.668 + { 1.669 + property: "mid1", 1.670 + descriptor: 1.671 + { get: function g() { }, set: function s(v){}, configurable: false, 1.672 + enumerable: true } 1.673 + }, 1.674 + ]; 1.675 + 1.676 + function dictionaryPropertyPresentTests() 1.677 + { 1.678 + print("Running dictionary already-present tests now..."); 1.679 + 1.680 + var total = VALID_DESCRIPTORS.length; 1.681 + var start = Math.floor((part - 1) / parts * total); 1.682 + var end = Math.floor(part / parts * total); 1.683 + 1.684 + for (var i = start; i < end; i++) 1.685 + { 1.686 + var old = VALID_DESCRIPTORS[i]; 1.687 + print("Starting test with old descriptor " + old.toSource() + "..."); 1.688 + 1.689 + for (var j = 0, sz2 = VALID_DESCRIPTORS.length; j < sz2; j++) 1.690 + { 1.691 + self._runSinglePropertyPresentTest(old, VALID_DESCRIPTORS[j], 1.692 + middleDefines); 1.693 + } 1.694 + } 1.695 + } 1.696 + 1.697 + this._runTestSet(dictionaryPropertyPresentTests, 1.698 + "Dictionary property-present fraction " + 1.699 + part + " of " + parts + " completed!"); 1.700 + }, 1.701 + 1.702 + 1.703 + // HELPERS 1.704 + 1.705 + runPropertyPresentTests: function runPropertyPresentTests() 1.706 + { 1.707 + print("Running already-present tests now..."); 1.708 + 1.709 + for (var i = 0, sz = VALID_DESCRIPTORS.length; i < sz; i++) 1.710 + { 1.711 + var old = VALID_DESCRIPTORS[i]; 1.712 + print("Starting test with old descriptor " + old.toSource() + "..."); 1.713 + 1.714 + for (var j = 0, sz2 = VALID_DESCRIPTORS.length; j < sz2; j++) 1.715 + this._runSinglePropertyPresentTest(old, VALID_DESCRIPTORS[j], []); 1.716 + } 1.717 + }, 1.718 + _runTestSet: function _runTestSet(fun, completeMessage) 1.719 + { 1.720 + try 1.721 + { 1.722 + fun(); 1.723 + 1.724 + print(completeMessage); 1.725 + } 1.726 + catch (e) 1.727 + { 1.728 + print("ERROR, EXITING (line " + (e.lineNumber || -1) + "): " + e); 1.729 + throw e; 1.730 + } 1.731 + finally 1.732 + { 1.733 + this._reportAllErrors(); 1.734 + } 1.735 + }, 1.736 + _reportAllErrors: function _reportAllErrors() 1.737 + { 1.738 + var errorCount = this._logLines.length; 1.739 + print("Full accumulated number of errors: " + errorCount); 1.740 + if (errorCount > 0) 1.741 + throw errorCount + " errors detected, FAIL"; 1.742 + }, 1.743 + _simpleFunctionLengthTests: function _simpleFunctionLengthTests(fun) 1.744 + { 1.745 + print("Running simple Function.length tests now.."); 1.746 + 1.747 + function expectThrowTypeError(o, p, desc) 1.748 + { 1.749 + var err = "<none>", passed = false; 1.750 + try 1.751 + { 1.752 + Object.defineProperty(o, p, desc); 1.753 + } 1.754 + catch (e) 1.755 + { 1.756 + err = e; 1.757 + passed = e instanceof TypeError; 1.758 + } 1.759 + assertEq(passed, true, fun + " didn't throw TypeError when called: " + err); 1.760 + } 1.761 + 1.762 + expectThrowTypeError(function a() { }, "length", { value: 1 }); 1.763 + expectThrowTypeError(function a() { }, "length", { enumerable: true }); 1.764 + expectThrowTypeError(function a() { }, "length", { configurable: true }); 1.765 + expectThrowTypeError(function a() { }, "length", { writable: true }); 1.766 + }, 1.767 + _fullFunctionLengthTests: function _fullFunctionLengthTests(fun) 1.768 + { 1.769 + var len = fun.length; 1.770 + print("Running Function.length (" + len + ") tests now..."); 1.771 + 1.772 + var desc; 1.773 + var gen = new DescriptorState(); 1.774 + while ((desc = gen.nextDescriptor())) 1.775 + this._runSingleFunctionLengthTest(fun, len, desc); 1.776 + }, 1.777 + _log: function _log(v) 1.778 + { 1.779 + var m = "" + v; 1.780 + print(m); 1.781 + this._logLines.push(m); 1.782 + }, 1.783 + _runSingleNotPresentTest: function _runSingleNotPresentTest(desc) 1.784 + { 1.785 + var nativeObj = NativeTest.newObject(); 1.786 + var reimplObj = ReimplTest.newObject(); 1.787 + 1.788 + try 1.789 + { 1.790 + NativeTest.defineProperty(nativeObj, "foo", desc); 1.791 + } 1.792 + catch (e) 1.793 + { 1.794 + try 1.795 + { 1.796 + ReimplTest.defineProperty(reimplObj, "foo", desc); 1.797 + } 1.798 + catch (e2) 1.799 + { 1.800 + if (e.constructor !== e2.constructor) 1.801 + { 1.802 + this._log("Difference when comparing native/reimplementation " + 1.803 + "behavior for new descriptor " + desc.toSource() + 1.804 + ", native threw " + e + ", reimpl threw " + e2); 1.805 + } 1.806 + return; 1.807 + } 1.808 + this._log("Difference when comparing native/reimplementation " + 1.809 + "behavior for new descriptor " + desc.toSource() + 1.810 + ", error " + e); 1.811 + return; 1.812 + } 1.813 + 1.814 + try 1.815 + { 1.816 + ReimplTest.defineProperty(reimplObj, "foo", desc); 1.817 + } 1.818 + catch (e) 1.819 + { 1.820 + this._log("Reimpl threw defining new descriptor " + desc.toSource() + 1.821 + ", error: " + e); 1.822 + return; 1.823 + } 1.824 + 1.825 + var nativeDesc = NativeTest.getDescriptor(nativeObj, "foo"); 1.826 + var reimplDesc = ReimplTest.getDescriptor(reimplObj, "foo"); 1.827 + try 1.828 + { 1.829 + compareDescriptors(nativeDesc, reimplDesc); 1.830 + } 1.831 + catch (e) 1.832 + { 1.833 + this._log("Difference comparing returned descriptors for new " + 1.834 + "property defined with descriptor " + desc.toSource() + 1.835 + "; error: " + e); 1.836 + return; 1.837 + } 1.838 + }, 1.839 + _runSinglePropertyPresentTest: 1.840 + function _runSinglePropertyPresentTest(old, add, middleDefines) 1.841 + { 1.842 + var nativeObj = NativeTest.newObject(); 1.843 + var reimplObj = ReimplTest.newObject(); 1.844 + 1.845 + try 1.846 + { 1.847 + NativeTest.defineProperty(nativeObj, "foo", old); 1.848 + } 1.849 + catch (e) 1.850 + { 1.851 + if (!SameValue(NativeTest.getDescriptor(nativeObj, "foo"), undefined)) 1.852 + { 1.853 + this._log("defining bad property descriptor: " + old.toSource()); 1.854 + return; 1.855 + } 1.856 + 1.857 + try 1.858 + { 1.859 + ReimplTest.defineProperty(reimplObj, "foo", old); 1.860 + } 1.861 + catch (e2) 1.862 + { 1.863 + if (!SameValue(ReimplTest.getDescriptor(reimplObj, "foo"), 1.864 + undefined)) 1.865 + { 1.866 + this._log("defining bad property descriptor: " + old.toSource() + 1.867 + "; reimplObj: " + uneval(reimplObj)); 1.868 + } 1.869 + 1.870 + if (e.constructor !== e2.constructor) 1.871 + { 1.872 + this._log("Different errors defining bad property descriptor: " + 1.873 + old.toSource() + "; native threw " + e + ", reimpl " + 1.874 + "threw " + e2); 1.875 + } 1.876 + 1.877 + return; 1.878 + } 1.879 + 1.880 + this._log("Difference defining a property with descriptor " + 1.881 + old.toSource() + ", error " + e); 1.882 + return; 1.883 + } 1.884 + 1.885 + try 1.886 + { 1.887 + ReimplTest.defineProperty(reimplObj, "foo", old); 1.888 + } 1.889 + catch (e) 1.890 + { 1.891 + this._log("Difference when comparing native/reimplementation " + 1.892 + "behavior when adding descriptor " + add.toSource() + 1.893 + ", error: " + e); 1.894 + return; 1.895 + } 1.896 + 1.897 + // Now add (or even readd) however many properties were specified between 1.898 + // the original property to add and the new one, to test redefining 1.899 + // non-last-properties and properties in scopes in dictionary mode. 1.900 + for (var i = 0, sz = middleDefines.length; i < sz; i++) 1.901 + { 1.902 + var middle = middleDefines[i]; 1.903 + var prop = middle.property; 1.904 + var desc = middle.descriptor; 1.905 + 1.906 + try 1.907 + { 1.908 + NativeTest.defineProperty(nativeObj, prop, desc); 1.909 + ReimplTest.defineProperty(reimplObj, prop, desc); 1.910 + } 1.911 + catch (e) 1.912 + { 1.913 + this._log("failure defining middle descriptor: " + desc.toSource() + 1.914 + ", error " + e); 1.915 + return; 1.916 + } 1.917 + 1.918 + // Sanity check 1.919 + var nativeDesc = NativeTest.getDescriptor(nativeObj, prop); 1.920 + var reimplDesc = ReimplTest.getDescriptor(reimplObj, prop); 1.921 + 1.922 + compareDescriptors(nativeDesc, reimplDesc); 1.923 + compareDescriptors(nativeDesc, desc); 1.924 + } 1.925 + 1.926 + try 1.927 + { 1.928 + NativeTest.defineProperty(nativeObj, "foo", add); 1.929 + } 1.930 + catch (e) 1.931 + { 1.932 + try 1.933 + { 1.934 + ReimplTest.defineProperty(reimplObj, "foo", add); 1.935 + } 1.936 + catch (e2) 1.937 + { 1.938 + if (e.constructor !== e2.constructor) 1.939 + { 1.940 + this._log("Difference when comparing native/reimplementation " + 1.941 + "behavior for descriptor " + add.toSource() + 1.942 + " overwriting descriptor " + old.toSource() + "; " + 1.943 + "native threw " + e + ", reimpl threw " + e2); 1.944 + } 1.945 + return; 1.946 + } 1.947 + this._log("Difference when comparing native/reimplementation " + 1.948 + "behavior for added descriptor " + add.toSource() + ", " + 1.949 + "initial was " + old.toSource() + "; error: " + e); 1.950 + return; 1.951 + } 1.952 + 1.953 + try 1.954 + { 1.955 + ReimplTest.defineProperty(reimplObj, "foo", add); 1.956 + } 1.957 + catch (e) 1.958 + { 1.959 + this._log("Difference when comparing native/reimplementation " + 1.960 + "behavior for readded descriptor " + add.toSource() + ", " + 1.961 + "initial was " + old.toSource() + "; native readd didn't " + 1.962 + "throw, reimpl add did, error: " + e); 1.963 + return; 1.964 + } 1.965 + 1.966 + var nativeDesc = NativeTest.getDescriptor(nativeObj, "foo"); 1.967 + var reimplDesc = ReimplTest.getDescriptor(reimplObj, "foo"); 1.968 + try 1.969 + { 1.970 + compareDescriptors(nativeDesc, reimplDesc); 1.971 + } 1.972 + catch (e) 1.973 + { 1.974 + this._log("Difference comparing returned descriptors for readded " + 1.975 + "property defined with descriptor " + add.toSource() + "; " + 1.976 + "initial was " + old.toSource() + "; error: " + e); 1.977 + return; 1.978 + } 1.979 + }, 1.980 + _runSingleFunctionLengthTest: function _runSingleFunctionLengthTest(fun, len, desc) 1.981 + { 1.982 + var nativeObj = fun; 1.983 + var reimplObj = ReimplTest.newObject(); 1.984 + ReimplTest.defineProperty(reimplObj, "length", 1.985 + { 1.986 + value: len, 1.987 + enumerable: false, 1.988 + configurable: false, 1.989 + writable: false 1.990 + }); 1.991 + 1.992 + try 1.993 + { 1.994 + NativeTest.defineProperty(nativeObj, "length", desc); 1.995 + } 1.996 + catch (e) 1.997 + { 1.998 + try 1.999 + { 1.1000 + ReimplTest.defineProperty(reimplObj, "length", desc); 1.1001 + } 1.1002 + catch (e2) 1.1003 + { 1.1004 + if (e.constructor !== e2.constructor) 1.1005 + { 1.1006 + this._log("Difference when comparing native/reimplementation " + 1.1007 + "behavior defining fun.length with " + desc.toSource() + 1.1008 + "; native threw " + e + ", reimpl threw " + e2); 1.1009 + } 1.1010 + return; 1.1011 + } 1.1012 + this._log("Difference when comparing Function.length native/reimpl " + 1.1013 + "behavior for descriptor " + desc.toSource() + 1.1014 + ", native impl threw error " + e); 1.1015 + return; 1.1016 + } 1.1017 + 1.1018 + try 1.1019 + { 1.1020 + ReimplTest.defineProperty(reimplObj, "length", desc); 1.1021 + } 1.1022 + catch (e) 1.1023 + { 1.1024 + this._log("Difference defining new Function.length descriptor: impl " + 1.1025 + "succeeded, reimpl threw for descriptor " + 1.1026 + desc.toSource() + ", error: " + e); 1.1027 + return; 1.1028 + } 1.1029 + 1.1030 + var nativeDesc = NativeTest.getDescriptor(nativeObj, "length"); 1.1031 + var reimplDesc = ReimplTest.getDescriptor(reimplObj, "length"); 1.1032 + try 1.1033 + { 1.1034 + compareDescriptors(nativeDesc, reimplDesc); 1.1035 + } 1.1036 + catch (e) 1.1037 + { 1.1038 + this._log("Difference comparing returned descriptors for " + 1.1039 + "Function.length with descriptor " + desc.toSource() + 1.1040 + "; error: " + e); 1.1041 + return; 1.1042 + } 1.1043 + } 1.1044 + }; 1.1045 + 1.1046 +function runDictionaryPropertyPresentTestsFraction(PART, PARTS) 1.1047 +{ 1.1048 + var testfile = 1.1049 + '15.2.3.6-dictionary-redefinition-' + PART + '-of-' + PARTS + '.js'; 1.1050 + var BUGNUMBER = 560566; 1.1051 + var summary = 1.1052 + 'ES5 Object.defineProperty(O, P, Attributes): dictionary redefinition ' + 1.1053 + PART + ' of ' + PARTS; 1.1054 + 1.1055 + print(BUGNUMBER + ": " + summary); 1.1056 + 1.1057 + try 1.1058 + { 1.1059 + new TestRunner().runDictionaryPropertyPresentTestsFraction(PART, PARTS); 1.1060 + } 1.1061 + catch (e) 1.1062 + { 1.1063 + throw "Error thrown during testing: " + e + 1.1064 + " at line " + e.lineNumber + "\n" + 1.1065 + (e.stack 1.1066 + ? "Stack: " + e.stack.split("\n").slice(2).join("\n") + "\n" 1.1067 + : ""); 1.1068 + } 1.1069 + 1.1070 + if (typeof reportCompare === "function") 1.1071 + reportCompare(true, true); 1.1072 + 1.1073 + print("Tests complete!"); 1.1074 +} 1.1075 + 1.1076 +function runNonTerminalPropertyPresentTestsFraction(PART, PARTS) 1.1077 +{ 1.1078 + var BUGNUMBER = 560566; 1.1079 + var summary = 1.1080 + 'ES5 Object.defineProperty(O, P, Attributes): middle redefinition ' + 1.1081 + PART + ' of ' + PARTS; 1.1082 + 1.1083 + print(BUGNUMBER + ": " + summary); 1.1084 + 1.1085 + 1.1086 + /************** 1.1087 + * BEGIN TEST * 1.1088 + **************/ 1.1089 + 1.1090 + try 1.1091 + { 1.1092 + new TestRunner().runNonTerminalPropertyPresentTestsFraction(PART, PARTS); 1.1093 + } 1.1094 + catch (e) 1.1095 + { 1.1096 + throw "Error thrown during testing: " + e + 1.1097 + " at line " + e.lineNumber + "\n" + 1.1098 + (e.stack 1.1099 + ? "Stack: " + e.stack.split("\n").slice(2).join("\n") + "\n" 1.1100 + : ""); 1.1101 + } 1.1102 + 1.1103 + /******************************************************************************/ 1.1104 + 1.1105 + if (typeof reportCompare === "function") 1.1106 + reportCompare(true, true); 1.1107 + 1.1108 + print("Tests complete!"); 1.1109 +}