1description("Test to ensure correct behaviour of Object.getOwnPropertyDescriptor"); 2 3function descriptorShouldBe(object, property, expected) { 4 var test = 'Object.getOwnPropertyDescriptor('+object+", "+property+')'; 5 if ("writable" in expected) { 6 // shouldBe(test+'.writable', '' + expected.writable); 7 shouldBe(test+'.value', '' + expected.value); 8 shouldBeFalse(test+".hasOwnProperty('get')"); 9 shouldBeFalse(test+".hasOwnProperty('set')"); 10 } else { 11 shouldBe(test+'.get', '' + expected.get); 12 shouldBe(test+'.set', '' + expected.set); 13 shouldBeFalse(test+".hasOwnProperty('value')"); 14 shouldBeFalse(test+".hasOwnProperty('writable')"); 15 } 16 shouldBe(test+'.enumerable', '' + expected.enumerable); 17 shouldBe(test+'.configurable', '' + expected.configurable); 18} 19 20shouldBeUndefined("Object.getOwnPropertyDescriptor({}, 'undefinedProperty')"); 21descriptorShouldBe("{definedProperty:'defined'}", "'definedProperty'", {writable: true, enumerable: true, configurable: true, value:'"defined"'}); 22descriptorShouldBe("Array.prototype", "'concat'", {writable: true, enumerable: false, configurable: true, value:"Array.prototype.concat"}); 23descriptorShouldBe("Date.prototype", "'toISOString'", {writable: true, enumerable: false, configurable: true, value: "Date.prototype.toISOString"}); 24descriptorShouldBe("String.prototype", "'concat'", {writable: true, enumerable: false, configurable: true, value:"String.prototype.concat"}); 25descriptorShouldBe("RegExp.prototype", "'exec'", {writable: true, enumerable: false, configurable: true, value:"RegExp.prototype.exec"}); 26descriptorShouldBe("document.__proto__.__proto__", "'createElement'", {writable: true, enumerable: true, configurable: false, value:"document.createElement"}); 27descriptorShouldBe("Number", "'NEGATIVE_INFINITY'", {writable: false, enumerable: false, configurable: false, value:"Number.NEGATIVE_INFINITY"}); 28descriptorShouldBe("RegExp", "'$_'", {writable: true, enumerable: false, configurable: true, value:"RegExp.$_"}); 29descriptorShouldBe("/a/g", "'global'", {writable: true, enumerable: false, configurable: false, value:true}); 30descriptorShouldBe("Node", "'DOCUMENT_POSITION_DISCONNECTED'", {writable: false, enumerable: true, configurable: false, value:"Node.DOCUMENT_POSITION_DISCONNECTED"}); 31descriptorShouldBe("Math", "'sin'", {writable: true, enumerable: false, configurable: true, value:"Math.sin"}); 32descriptorShouldBe("[1,2,3]", "0", {writable: true, enumerable: true, configurable: true, value:"1"}); 33descriptorShouldBe("[1,2,3]", "'length'", {writable: true, enumerable: false, configurable: false, value:"3"}); 34descriptorShouldBe("[1,2,3]", "'length'", {writable: true, enumerable: false, configurable: false, value:"3"}); 35descriptorShouldBe("/(a)*/g.exec('a')", "0", {writable: true, enumerable: true, configurable: true, value:"'a'"}); 36descriptorShouldBe("/(a)*/g.exec('a')", "'length'", {writable: true, enumerable: false, configurable: false, value:2}); 37descriptorShouldBe("function(){}", "'length'", {writable: false, enumerable: false, configurable: false, value:0}); 38descriptorShouldBe("Math.sin", "'length'", {writable: false, enumerable: false, configurable: false, value:1}); 39descriptorShouldBe("Math.sin", "'name'", {writable: false, enumerable: false, configurable: false, value:"'sin'"}); 40var global = this; 41descriptorShouldBe("global", "'global'", {writable: true, enumerable: true, configurable: false, value:"global"}); 42descriptorShouldBe("global", "'undefined'", {writable: false, enumerable: false, configurable: false, value:"undefined"}); 43descriptorShouldBe("global", "'NaN'", {writable: false, enumerable: false, configurable: false, value:"NaN"}); 44descriptorShouldBe("global", "'Infinity'", {writable: false, enumerable: false, configurable: false, value:"Infinity"}); 45descriptorShouldBe("global", "'window'", {writable: false, enumerable: true, configurable: false, value:"global"}); 46descriptorShouldBe("global", "'XMLHttpRequest'", {writable: true, enumerable: true, configurable: false, value:"XMLHttpRequest"}); 47descriptorShouldBe("global", "'length'", {writable: true, enumerable: true, configurable: false, value:"global.length"}); 48descriptorShouldBe("global", "0", {writable: true, enumerable: false, configurable: false, value:"global[0]"}); 49descriptorShouldBe("document.getElementsByTagName('div')", "'length'", {writable: false, enumerable: true, configurable: false, value:"1"}); 50descriptorShouldBe("document.getElementsByTagName('div')", "0", {writable: false, enumerable: true, configurable: false, value:"document.getElementsByTagName('div')[0]"}); 51descriptorShouldBe("document.getElementsByClassName('pass')", "0", {writable: false, enumerable: true, configurable: false, value:"document.getElementsByClassName('pass')[0]"}); 52descriptorShouldBe("document.getElementsByClassName('pass')", "'length'", {writable: false, enumerable: true, configurable: false, value:"document.getElementsByClassName('pass').length"}); 53var canvas = document.createElement("canvas"); 54var canvasPixelArray = canvas.getContext("2d").createImageData(10,10).data; 55descriptorShouldBe("canvasPixelArray", "'length'", {writable: false, enumerable: true, configurable: false, value:"canvasPixelArray.length"}); 56descriptorShouldBe("canvasPixelArray", "0", {writable: true, enumerable: true, configurable: false, value:"canvasPixelArray[0]"}); 57var select = document.createElement("select"); 58select.innerHTML = "<option>foo</option>"; 59descriptorShouldBe("select", "'length'", {writable: false, enumerable: true, configurable: false, value:"select.length"}); 60descriptorShouldBe("select", "0", {writable: true, enumerable: true, configurable: false, value:"select[0]"}); 61 62var objectWithGetter = {}; 63function getterFunc(){}; 64objectWithGetter.__defineGetter__("getter", getterFunc); 65descriptorShouldBe("objectWithGetter", "'getter'", {"get": "getterFunc", "set": undefined, enumerable: true, configurable: true}); 66var objectWithSetter = {}; 67function setterFunc(){}; 68objectWithSetter.__defineSetter__("setter", setterFunc); 69descriptorShouldBe("objectWithSetter", "'setter'", {"set": "setterFunc", "get": undefined, enumerable: true, configurable: true}); 70var objectWithAccessor = {}; 71objectWithAccessor.__defineSetter__("accessor", setterFunc); 72objectWithAccessor.__defineGetter__("accessor", getterFunc); 73descriptorShouldBe("objectWithAccessor", "'accessor'", {"set": "setterFunc", "get": "getterFunc", enumerable: true, configurable: true}); 74 75shouldThrow("Object.getOwnPropertyDescriptor(null)"); 76shouldThrow("Object.getOwnPropertyDescriptor(undefined)"); 77shouldThrow("Object.getOwnPropertyDescriptor(1)"); 78shouldThrow("Object.getOwnPropertyDescriptor('')"); 79shouldThrow("Object.getOwnPropertyDescriptor(true)"); 80shouldThrow("Object.getOwnPropertyDescriptor(false)"); 81 82debug("Checking property ordering"); 83var normalOrder = ["'value'", "'writable'", "'enumerable'", "'configurable'"]; 84var accessorOrder = ["'get'", "'set'", "'enumerable'", "'configurable'"]; 85var i = 0; 86for (var property in Object.getOwnPropertyDescriptor(Math, "sin")) 87 shouldBe('property', normalOrder[i++]); 88i = 0; 89for (var property in Object.getOwnPropertyDescriptor(objectWithGetter, "getter")) 90 shouldBe('property', accessorOrder[i++]); 91i = 0; 92for (var property in Object.getOwnPropertyDescriptor(objectWithSetter, "setter")) 93 shouldBe('property', accessorOrder[i++]); 94i = 0; 95for (var property in Object.getOwnPropertyDescriptor(objectWithAccessor, "accessor")) 96 shouldBe('property', accessorOrder[i++]); 97 98successfullyParsed = true; 99