getOwnPropertyDescriptor.js revision dcc8cf2e65d1aa555cce12431a16547e66b469ee
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