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