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", "'undefined'", {writable: false, enumerable: false, configurable: false, value:"undefined"}); 43 descriptorShouldBe("global", "'NaN'", {writable: false, enumerable: false, configurable: false, value:"NaN"}); 44 descriptorShouldBe("global", "'Infinity'", {writable: false, enumerable: false, configurable: false, value:"Infinity"}); 45 descriptorShouldBe("global", "'window'", {writable: false, enumerable: true, configurable: false, value:"global"}); 46 descriptorShouldBe("global", "'XMLHttpRequest'", {writable: true, enumerable: true, configurable: false, value:"XMLHttpRequest"}); 47 descriptorShouldBe("global", "'length'", {writable: true, enumerable: true, configurable: false, value:"global.length"}); 48 descriptorShouldBe("global", "0", {writable: true, enumerable: false, configurable: false, value:"global[0]"}); 49 descriptorShouldBe("document.getElementsByTagName('div')", "'length'", {writable: false, enumerable: true, configurable: false, value:"1"}); 50 descriptorShouldBe("document.getElementsByTagName('div')", "0", {writable: false, enumerable: true, configurable: false, value:"document.getElementsByTagName('div')[0]"}); 51 descriptorShouldBe("document.getElementsByClassName('pass')", "0", {writable: false, enumerable: true, configurable: false, value:"document.getElementsByClassName('pass')[0]"}); 52 descriptorShouldBe("document.getElementsByClassName('pass')", "'length'", {writable: false, enumerable: true, configurable: false, value:"document.getElementsByClassName('pass').length"}); 53 var canvas = document.createElement("canvas"); 54 var canvasPixelArray = canvas.getContext("2d").createImageData(10,10).data; 55 descriptorShouldBe("canvasPixelArray", "'length'", {writable: false, enumerable: true, configurable: false, value:"canvasPixelArray.length"}); 56 descriptorShouldBe("canvasPixelArray", "0", {writable: true, enumerable: true, configurable: false, value:"canvasPixelArray[0]"}); 57 var select = document.createElement("select"); 58 select.innerHTML = "<option>foo</option>"; 59 descriptorShouldBe("select", "'length'", {writable: false, enumerable: true, configurable: false, value:"select.length"}); 60 descriptorShouldBe("select", "0", {writable: true, enumerable: true, configurable: false, value:"select[0]"}); 61 62 var objectWithGetter = {}; 63 function getterFunc(){}; 64 objectWithGetter.__defineGetter__("getter", getterFunc); 65 descriptorShouldBe("objectWithGetter", "'getter'", {"get": "getterFunc", "set": undefined, enumerable: true, configurable: true}); 66 var objectWithSetter = {}; 67 function setterFunc(){}; 68 objectWithSetter.__defineSetter__("setter", setterFunc); 69 descriptorShouldBe("objectWithSetter", "'setter'", {"set": "setterFunc", "get": undefined, enumerable: true, configurable: true}); 70 var objectWithAccessor = {}; 71 objectWithAccessor.__defineSetter__("accessor", setterFunc); 72 objectWithAccessor.__defineGetter__("accessor", getterFunc); 73 descriptorShouldBe("objectWithAccessor", "'accessor'", {"set": "setterFunc", "get": "getterFunc", enumerable: true, configurable: true}); 74 75 shouldThrow("Object.getOwnPropertyDescriptor(null)"); 76 shouldThrow("Object.getOwnPropertyDescriptor(undefined)"); 77 shouldThrow("Object.getOwnPropertyDescriptor(1)"); 78 shouldThrow("Object.getOwnPropertyDescriptor('')"); 79 shouldThrow("Object.getOwnPropertyDescriptor(true)"); 80 shouldThrow("Object.getOwnPropertyDescriptor(false)"); 81 82 debug("Checking property ordering"); 83 var normalOrder = ["'value'", "'writable'", "'enumerable'", "'configurable'"]; 84 var accessorOrder = ["'get'", "'set'", "'enumerable'", "'configurable'"]; 85 var i = 0; 86 for (var property in Object.getOwnPropertyDescriptor(Math, "sin")) 87 shouldBe('property', normalOrder[i++]); 88 i = 0; 89 for (var property in Object.getOwnPropertyDescriptor(objectWithGetter, "getter")) 90 shouldBe('property', accessorOrder[i++]); 91 i = 0; 92 for (var property in Object.getOwnPropertyDescriptor(objectWithSetter, "setter")) 93 shouldBe('property', accessorOrder[i++]); 94 i = 0; 95 for (var property in Object.getOwnPropertyDescriptor(objectWithAccessor, "accessor")) 96 shouldBe('property', accessorOrder[i++]); 97 98 successfullyParsed = true; 99