OLD | NEW |
(Empty) | |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. |
| 2 // Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. |
| 3 // |
| 4 // Redistribution and use in source and binary forms, with or without |
| 5 // modification, are permitted provided that the following conditions |
| 6 // are met: |
| 7 // 1. Redistributions of source code must retain the above copyright |
| 8 // notice, this list of conditions and the following disclaimer. |
| 9 // 2. Redistributions in binary form must reproduce the above copyright |
| 10 // notice, this list of conditions and the following disclaimer in the |
| 11 // documentation and/or other materials provided with the distribution. |
| 12 // |
| 13 // THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND AN
Y |
| 14 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
| 15 // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
| 16 // DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR AN
Y |
| 17 // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
| 18 // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
| 19 // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND O
N |
| 20 // ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 21 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
| 22 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 23 |
| 24 description("Test to ensure correct behaviour of Object.defineProperty"); |
| 25 |
| 26 shouldBe("JSON.stringify(Object.getOwnPropertyDescriptor(Object.defineProperty({
}, 'foo', {value:1}), 'foo'))", |
| 27 "JSON.stringify({value: 1, writable: false, enumerable: false, configur
able: false})"); |
| 28 shouldBe("JSON.stringify(Object.getOwnPropertyDescriptor(Object.defineProperty({
}, 'foo', {}), 'foo'))", |
| 29 "JSON.stringify({writable: false, enumerable: false, configurable: fals
e})"); |
| 30 shouldBe("JSON.stringify(Object.getOwnPropertyDescriptor(Object.defineProperty({
}, 'foo', {get:undefined}), 'foo'))", |
| 31 "JSON.stringify({enumerable: false, configurable: false})"); |
| 32 shouldBe("JSON.stringify(Object.getOwnPropertyDescriptor(Object.defineProperty({
}, 'foo', {value:1, writable: false}), 'foo'))", |
| 33 "JSON.stringify({value: 1, writable: false, enumerable: false, configur
able: false})"); |
| 34 shouldBe("JSON.stringify(Object.getOwnPropertyDescriptor(Object.defineProperty({
}, 'foo', {value:1, writable: true}), 'foo'))", |
| 35 "JSON.stringify({value: 1, writable: true, enumerable: false, configura
ble: false})"); |
| 36 shouldBe("JSON.stringify(Object.getOwnPropertyDescriptor(Object.defineProperty({
}, 'foo', {value:1, enumerable: false}), 'foo'))", |
| 37 "JSON.stringify({value: 1, writable: false, enumerable: false, configur
able: false})"); |
| 38 shouldBe("JSON.stringify(Object.getOwnPropertyDescriptor(Object.defineProperty({
}, 'foo', {value:1, enumerable: true}), 'foo'))", |
| 39 "JSON.stringify({value: 1, writable: false, enumerable: true, configura
ble: false})"); |
| 40 shouldBe("JSON.stringify(Object.getOwnPropertyDescriptor(Object.defineProperty({
}, 'foo', {value:1, configurable: false}), 'foo'))", |
| 41 "JSON.stringify({value: 1, writable: false, enumerable: false, configur
able: false})"); |
| 42 shouldBe("JSON.stringify(Object.getOwnPropertyDescriptor(Object.defineProperty({
}, 'foo', {value:1, configurable: true}), 'foo'))", |
| 43 "JSON.stringify({value: 1, writable: false, enumerable: false, configur
able: true})"); |
| 44 shouldBe("JSON.stringify(Object.getOwnPropertyDescriptor(Object.defineProperty([
1,2,3], 'foo', {value:1, configurable: true}), 'foo'))", |
| 45 "JSON.stringify({value: 1, writable: false, enumerable: false, configur
able: true})"); |
| 46 shouldBe("Object.getOwnPropertyDescriptor(Object.defineProperty([1,2,3], '1', {v
alue:'foo', configurable: true}), '1').value", "'foo'"); |
| 47 shouldBe("a=[1,2,3], Object.defineProperty(a, '1', {value:'foo', configurable: t
rue}), a[1]", "'foo'"); |
| 48 shouldBe("Object.getOwnPropertyDescriptor(Object.defineProperty([1,2,3], '1', {g
et:getter, configurable: true}), '1').get", "getter"); |
| 49 shouldThrow("Object.defineProperty([1,2,3], '1', {get:getter, configurable: true
})[1]", "'called getter'"); |
| 50 |
| 51 shouldThrow("Object.defineProperty()"); |
| 52 shouldThrow("Object.defineProperty(null)"); |
| 53 shouldThrow("Object.defineProperty('foo')"); |
| 54 shouldThrow("Object.defineProperty({})"); |
| 55 shouldThrow("Object.defineProperty({}, 'foo')"); |
| 56 shouldThrow("Object.defineProperty({}, 'foo', {get:undefined, value:true}).foo")
; |
| 57 shouldBeTrue("Object.defineProperty({get foo() { return true; } }, 'foo', {confi
gurable:false}).foo"); |
| 58 |
| 59 function createUnconfigurableProperty(o, prop, writable, enumerable) { |
| 60 writable = writable || false; |
| 61 enumerable = enumerable || false; |
| 62 return Object.defineProperty(o, prop, {value:1, configurable:false, writable
: writable, enumerable: enumerable}); |
| 63 } |
| 64 shouldThrow("Object.defineProperty(createUnconfigurableProperty({}, 'foo'), 'foo
', {configurable: true})"); |
| 65 shouldThrow("Object.defineProperty(createUnconfigurableProperty({}, 'foo'), 'foo
', {writable: true})"); |
| 66 shouldThrow("Object.defineProperty(createUnconfigurableProperty({}, 'foo'), 'foo
', {enumerable: true})"); |
| 67 shouldThrow("Object.defineProperty(createUnconfigurableProperty({}, 'foo', false
, true), 'foo', {enumerable: false}), 'foo'"); |
| 68 |
| 69 shouldBe("JSON.stringify(Object.getOwnPropertyDescriptor(Object.defineProperty(c
reateUnconfigurableProperty({}, 'foo', true), 'foo', {writable: false}), 'foo'))
", |
| 70 "JSON.stringify({value: 1, writable: false, enumerable: false, configur
able: false})"); |
| 71 |
| 72 shouldThrow("Object.defineProperty({}, 'foo', {value:1, get: function(){}})"); |
| 73 shouldThrow("Object.defineProperty({}, 'foo', {value:1, set: function(){}})"); |
| 74 shouldThrow("Object.defineProperty({}, 'foo', {writable:true, get: function(){}}
)"); |
| 75 shouldThrow("Object.defineProperty({}, 'foo', {writable:true, set: function(){}}
)"); |
| 76 shouldThrow("Object.defineProperty({}, 'foo', {get: null})"); |
| 77 shouldThrow("Object.defineProperty({}, 'foo', {set: null})"); |
| 78 function getter(){ throw "called getter"; } |
| 79 function getter1(){ throw "called getter1"; } |
| 80 function setter(){ throw "called setter"; } |
| 81 function setter1(){ throw "called setter1"; } |
| 82 shouldThrow("Object.defineProperty({}, 'foo', {set: setter}).foo='test'", "'call
ed setter'"); |
| 83 shouldThrow("Object.defineProperty(Object.defineProperty({}, 'foo', {set: setter
}), 'foo', {set: setter1})"); |
| 84 shouldThrow("Object.defineProperty(Object.defineProperty({}, 'foo', {set: setter
}), 'foo', {get: getter1})"); |
| 85 shouldThrow("Object.defineProperty(Object.defineProperty({}, 'foo', {set: setter
}), 'foo', {value: 1})"); |
| 86 shouldThrow("Object.defineProperty(Object.defineProperty({}, 'foo', {set: setter
, configurable: true}), 'foo', {set: setter1}).foo='test'", "'called setter1'"); |
| 87 shouldThrow("Object.defineProperty(Object.defineProperty({}, 'foo', {set: setter
, configurable: true}), 'foo', {get: getter1}).foo", "'called getter1'"); |
| 88 shouldBeTrue("Object.defineProperty(Object.defineProperty({}, 'foo', {set: sette
r, configurable: true}), 'foo', {value: true}).foo"); |
| 89 shouldBeTrue("'foo' in Object.defineProperty(Object.defineProperty({}, 'foo', {s
et: setter, configurable: true}), 'foo', {writable: true})"); |
| 90 shouldBeUndefined("Object.defineProperty(Object.defineProperty({}, 'foo', {set:
setter, configurable: true}), 'foo', {writable: true}).foo"); |
| 91 shouldThrow("Object.defineProperty({}, 'foo', {get: getter}).foo", "'called gett
er'"); |
| 92 shouldThrow("Object.defineProperty(Object.defineProperty({}, 'foo', {get: getter
}), 'foo', {get: getter1})"); |
| 93 shouldThrow("Object.defineProperty(Object.defineProperty({}, 'foo', {get: getter
}), 'foo', {set: setter1})"); |
| 94 shouldThrow("Object.defineProperty(Object.defineProperty({}, 'foo', {get: getter
, configurable: true}), 'foo', {get: getter1}).foo", "'called getter1'"); |
| 95 shouldThrow("Object.defineProperty(Object.defineProperty({}, 'foo', {get: getter
, configurable: true}), 'foo', {set: setter1}).foo='test'", "'called setter1'"); |
| 96 shouldBeTrue("Object.defineProperty(Object.defineProperty({}, 'foo', {get: gette
r, configurable: true}), 'foo', {value: true}).foo"); |
| 97 shouldBeUndefined("Object.defineProperty(Object.defineProperty({}, 'foo', {get:
getter, configurable: true}), 'foo', {writable: true}).foo"); |
| 98 shouldBeTrue("'foo' in Object.defineProperty(Object.defineProperty({}, 'foo', {g
et: getter, configurable: true}), 'foo', {writable: true})"); |
| 99 |
| 100 shouldThrow("Object.defineProperty(Object.defineProperty({}, 'foo', {value: 1}),
'foo', {set: setter1})"); |
| 101 shouldThrow("Object.defineProperty(Object.defineProperty({}, 'foo', {value: 1, c
onfigurable: true}), 'foo', {set: setter1}).foo='test'", "'called setter1'"); |
| 102 shouldThrow("Object.defineProperty(Object.defineProperty({}, 'foo', {value: 1}),
'foo', {get: getter1})"); |
| 103 shouldThrow("Object.defineProperty(Object.defineProperty({}, 'foo', {value: 1}),
'foo', {set: setter1})"); |
| 104 shouldThrow("Object.defineProperty(Object.defineProperty({}, 'foo', {value: 1, c
onfigurable: true}), 'foo', {get: getter1}).foo", "'called getter1'"); |
| 105 shouldThrow("Object.defineProperty(Object.defineProperty({}, 'foo', {value: 1, c
onfigurable: true}), 'foo', {set: setter1}).foo='test'", "'called setter1'"); |
| 106 |
| 107 // Should be able to redefine an non-writable property, if it is configurable. |
| 108 shouldBe("Object.defineProperty(Object.defineProperty({}, 'foo', {value: 1, conf
igurable: true, writable: false}), 'foo', {value: 2, configurable: true, writabl
e: true}).foo", "2"); |
| 109 shouldBe("Object.defineProperty(Object.defineProperty({}, 'foo', {value: 1, conf
igurable: true, writable: false}), 'foo', {value: 2, configurable: true, writabl
e: false}).foo", "2"); |
| 110 |
| 111 // Should be able to redefine an non-writable, non-configurable property, with t
he same value and attributes. |
| 112 shouldBe("Object.defineProperty(Object.defineProperty({}, 'foo', {value: 1, conf
igurable: false, writable: false}), 'foo', {value: 1, configurable: false, writa
ble: false}).foo", "1"); |
| 113 |
| 114 // Should be able to redefine a configurable accessor, with the same or with dif
ferent attributes. |
| 115 // Check the accessor function changed. |
| 116 shouldBe("Object.defineProperty(Object.defineProperty({}, 'foo', {get: function(
) { return 1; }, configurable: true, enumerable: true}), 'foo', {get: function()
{ return 2; }, configurable: true, enumerable: false}).foo", "2"); |
| 117 shouldBe("Object.defineProperty(Object.defineProperty({}, 'foo', {get: function(
) { return 1; }, configurable: true, enumerable: false}), 'foo', {get: function(
) { return 2; }, configurable: true, enumerable: false}).foo", "2"); |
| 118 // Check the attributes changed. |
| 119 shouldBeFalse("var result = false; var o = Object.defineProperty(Object.definePr
operty({}, 'foo', {get: function() { return 1; }, configurable: true, enumerable
: true}), 'foo', {get: function() { return 2; }, configurable: true, enumerable:
false}); for (x in o) result = true; result"); |
| 120 shouldBeTrue("var result = false; var o = Object.defineProperty(Object.definePro
perty({}, 'foo', {get: function() { return 1; }, configurable: true, enumerable:
false}), 'foo', {get: function() { return 2; }, configurable: true, enumerable:
true}); for (x in o) result = true; result"); |
| 121 |
| 122 // Should be able to define an non-configurable accessor. |
| 123 shouldBeUndefined("var o = Object.defineProperty({}, 'foo', {get: function() { r
eturn 1; }, configurable: true}); delete o.foo; o.foo"); |
| 124 shouldBe("var o = Object.defineProperty({}, 'foo', {get: function() { return 1;
}, configurable: false}); delete o.foo; o.foo", '1'); |
| 125 shouldBe("Object.defineProperty(Object.defineProperty({}, 'foo', {get: function(
) { return 1; }, configurable: true}), 'foo', {value:2}).foo", "2"); |
| 126 shouldThrow("Object.defineProperty(Object.defineProperty({}, 'foo', {get: functi
on() { return 1; }, configurable: false}), 'foo', {value:2}).foo"); |
| 127 |
| 128 // Defining a data descriptor over an accessor should result in a read only prop
erty. |
| 129 shouldBe("var o = Object.defineProperty(Object.defineProperty({}, 'foo', {get: f
unction() { return 1; }, configurable: true}), 'foo', {value:2}); o.foo = 3; o.f
oo", "2"); |
| 130 |
| 131 // Trying to redefine a non-configurable property as configurable should throw. |
| 132 shouldThrow("Object.defineProperty(Object.defineProperty({}, 'foo', {value: 1}),
'foo', {value:2, configurable: true})"); |
| 133 shouldThrow("Object.defineProperty(Object.defineProperty([], 'foo', {value: 1}),
'foo', {value:2, configurable: true})"); |
| 134 |
| 135 // Test an object with a getter setter. |
| 136 // Either accessor may be omitted or replaced with undefined, or both may be rep
laced with undefined. |
| 137 shouldBe("var o = Object.defineProperty({}, 'foo', {get:function(){return 42;},
set:function(x){this.result = x;}}); o.foo", '42') |
| 138 shouldBe("var o = Object.defineProperty({}, 'foo', {get:function(){return 42;},
set:function(x){this.result = x;}}); o.foo = 42; o.result;", '42'); |
| 139 shouldBe("var o = Object.defineProperty({}, 'foo', {get:undefined, set:function(
x){this.result = x;}}); o.foo", 'undefined') |
| 140 shouldBe("var o = Object.defineProperty({}, 'foo', {get:undefined, set:function(
x){this.result = x;}}); o.foo = 42; o.result;", '42'); |
| 141 shouldBe("var o = Object.defineProperty({}, 'foo', {set:function(x){this.result
= x;}}); o.foo", 'undefined') |
| 142 shouldBe("var o = Object.defineProperty({}, 'foo', {set:function(x){this.result
= x;}}); o.foo = 42; o.result;", '42'); |
| 143 shouldBe("var o = Object.defineProperty({}, 'foo', {get:function(){return 42;},
set:undefined}); o.foo", '42') |
| 144 shouldBe("var o = Object.defineProperty({}, 'foo', {get:function(){return 42;},
set:undefined}); o.foo = 42; o.result;", 'undefined'); |
| 145 shouldBe("var o = Object.defineProperty({}, 'foo', {get:function(){return 42;}})
; o.foo", '42') |
| 146 shouldBe("var o = Object.defineProperty({}, 'foo', {get:function(){return 42;}})
; o.foo = 42; o.result;", 'undefined'); |
| 147 shouldBe("var o = Object.defineProperty({}, 'foo', {get:undefined, set:undefined
}); o.foo", 'undefined') |
| 148 shouldBe("var o = Object.defineProperty({}, 'foo', {get:undefined, set:undefined
}); o.foo = 42; o.result;", 'undefined'); |
| 149 // Test replacing or removing either the getter or setter individually. |
| 150 shouldBe("var o = Object.defineProperty(Object.defineProperty({foo:1}, 'foo', {g
et:function(){return 42;}, set:function(x){this.result = x;}}), 'foo', {get:func
tion(){return 13;}}); o.foo", '13') |
| 151 shouldBe("var o = Object.defineProperty(Object.defineProperty({foo:1}, 'foo', {g
et:function(){return 42;}, set:function(x){this.result = x;}}), 'foo', {get:func
tion(){return 13;}}); o.foo = 42; o.result;", '42') |
| 152 shouldBe("var o = Object.defineProperty(Object.defineProperty({foo:1}, 'foo', {g
et:function(){return 42;}, set:function(x){this.result = x;}}), 'foo', {get:unde
fined}); o.foo", 'undefined') |
| 153 shouldBe("var o = Object.defineProperty(Object.defineProperty({foo:1}, 'foo', {g
et:function(){return 42;}, set:function(x){this.result = x;}}), 'foo', {get:unde
fined}); o.foo = 42; o.result;", '42') |
| 154 shouldBe("var o = Object.defineProperty(Object.defineProperty({foo:1}, 'foo', {g
et:function(){return 42;}, set:function(x){this.result = x;}}), 'foo', {set:func
tion(){this.result = 13;}}); o.foo", '42') |
| 155 shouldBe("var o = Object.defineProperty(Object.defineProperty({foo:1}, 'foo', {g
et:function(){return 42;}, set:function(x){this.result = x;}}), 'foo', {set:func
tion(){this.result = 13;}}); o.foo = 42; o.result;", '13') |
| 156 shouldBe("var o = Object.defineProperty(Object.defineProperty({foo:1}, 'foo', {g
et:function(){return 42;}, set:function(x){this.result = x;}}), 'foo', {set:unde
fined}); o.foo", '42') |
| 157 shouldBe("var o = Object.defineProperty(Object.defineProperty({foo:1}, 'foo', {g
et:function(){return 42;}, set:function(x){this.result = x;}}), 'foo', {set:unde
fined}); o.foo = 42; o.result;", 'undefined') |
| 158 |
| 159 // Repeat of the above, in strict mode. |
| 160 // Either accessor may be omitted or replaced with undefined, or both may be rep
laced with undefined. |
| 161 shouldBe("'use strict'; var o = Object.defineProperty({}, 'foo', {get:function()
{return 42;}, set:function(x){this.result = x;}}); o.foo", '42') |
| 162 shouldBe("'use strict'; var o = Object.defineProperty({}, 'foo', {get:function()
{return 42;}, set:function(x){this.result = x;}}); o.foo = 42; o.result;", '42')
; |
| 163 shouldBe("'use strict'; var o = Object.defineProperty({}, 'foo', {get:undefined,
set:function(x){this.result = x;}}); o.foo", 'undefined') |
| 164 shouldBe("'use strict'; var o = Object.defineProperty({}, 'foo', {get:undefined,
set:function(x){this.result = x;}}); o.foo = 42; o.result;", '42'); |
| 165 shouldBe("'use strict'; var o = Object.defineProperty({}, 'foo', {set:function(x
){this.result = x;}}); o.foo", 'undefined') |
| 166 shouldBe("'use strict'; var o = Object.defineProperty({}, 'foo', {set:function(x
){this.result = x;}}); o.foo = 42; o.result;", '42'); |
| 167 shouldBe("'use strict'; var o = Object.defineProperty({}, 'foo', {get:function()
{return 42;}, set:undefined}); o.foo", '42') |
| 168 shouldThrow("'use strict'; var o = Object.defineProperty({}, 'foo', {get:functio
n(){return 42;}, set:undefined}); o.foo = 42; o.result;"); |
| 169 shouldBe("'use strict'; var o = Object.defineProperty({}, 'foo', {get:function()
{return 42;}}); o.foo", '42') |
| 170 shouldThrow("'use strict'; var o = Object.defineProperty({}, 'foo', {get:functio
n(){return 42;}}); o.foo = 42; o.result;"); |
| 171 shouldBe("'use strict'; var o = Object.defineProperty({}, 'foo', {get:undefined,
set:undefined}); o.foo", 'undefined') |
| 172 shouldThrow("'use strict'; var o = Object.defineProperty({}, 'foo', {get:undefin
ed, set:undefined}); o.foo = 42; o.result;"); |
| 173 // Test replacing or removing either the getter or setter individually. |
| 174 shouldBe("'use strict'; var o = Object.defineProperty(Object.defineProperty({foo
:1}, 'foo', {get:function(){return 42;}, set:function(x){this.result = x;}}), 'f
oo', {get:function(){return 13;}}); o.foo", '13') |
| 175 shouldBe("'use strict'; var o = Object.defineProperty(Object.defineProperty({foo
:1}, 'foo', {get:function(){return 42;}, set:function(x){this.result = x;}}), 'f
oo', {get:function(){return 13;}}); o.foo = 42; o.result;", '42') |
| 176 shouldBe("'use strict'; var o = Object.defineProperty(Object.defineProperty({foo
:1}, 'foo', {get:function(){return 42;}, set:function(x){this.result = x;}}), 'f
oo', {get:undefined}); o.foo", 'undefined') |
| 177 shouldBe("'use strict'; var o = Object.defineProperty(Object.defineProperty({foo
:1}, 'foo', {get:function(){return 42;}, set:function(x){this.result = x;}}), 'f
oo', {get:undefined}); o.foo = 42; o.result;", '42') |
| 178 shouldBe("'use strict'; var o = Object.defineProperty(Object.defineProperty({foo
:1}, 'foo', {get:function(){return 42;}, set:function(x){this.result = x;}}), 'f
oo', {set:function(){this.result = 13;}}); o.foo", '42') |
| 179 shouldBe("'use strict'; var o = Object.defineProperty(Object.defineProperty({foo
:1}, 'foo', {get:function(){return 42;}, set:function(x){this.result = x;}}), 'f
oo', {set:function(){this.result = 13;}}); o.foo = 42; o.result;", '13') |
| 180 shouldBe("'use strict'; var o = Object.defineProperty(Object.defineProperty({foo
:1}, 'foo', {get:function(){return 42;}, set:function(x){this.result = x;}}), 'f
oo', {set:undefined}); o.foo", '42') |
| 181 shouldThrow("'use strict'; var o = Object.defineProperty(Object.defineProperty({
foo:1}, 'foo', {get:function(){return 42;}, set:function(x){this.result = x;}}),
'foo', {set:undefined}); o.foo = 42; o.result;") |
| 182 |
| 183 Object.defineProperty(Object.prototype, 0, {get:function(){ return false; }, con
figurable:true}) |
| 184 shouldBeTrue("0 in Object.prototype"); |
| 185 shouldBeTrue("'0' in Object.prototype"); |
| 186 delete Object.prototype[0]; |
| 187 |
| 188 Object.defineProperty(Object.prototype, 'readOnly', {value:true, configurable:tr
ue, writable:false}) |
| 189 shouldBeTrue("var o = {}; o.readOnly = false; o.readOnly"); |
| 190 shouldThrow("'use strict'; var o = {}; o.readOnly = false; o.readOnly"); |
| 191 delete Object.prototype.readOnly; |
| 192 |
| 193 // Check the writable attribute is set correctly when redefining an accessor as
a data descriptor. |
| 194 shouldBeFalse("Object.getOwnPropertyDescriptor(Object.defineProperty(Object.defi
neProperty({}, 'foo', {get: function() { return false; }, configurable: true}),
'foo', {value:false}), 'foo').writable"); |
| 195 shouldBeFalse("Object.getOwnPropertyDescriptor(Object.defineProperty(Object.defi
neProperty({}, 'foo', {get: function() { return false; }, configurable: true}),
'foo', {value:false, writable: false}), 'foo').writable"); |
| 196 shouldBeTrue("Object.getOwnPropertyDescriptor(Object.defineProperty(Object.defin
eProperty({}, 'foo', {get: function() { return false; }, configurable: true}), '
foo', {value:false, writable: true}), 'foo').writable"); |
| 197 |
| 198 // If array length is read-only, [[Put]] should fail. |
| 199 shouldBeFalse("var a = Object.defineProperty([], 'length', {writable: false}); a
[0] = 42; 0 in a;"); |
| 200 shouldThrow("'use strict'; var a = Object.defineProperty([], 'length', {writable
: false}); a[0] = 42; 0 in a;"); |
| 201 |
| 202 // If array property is read-only, [[Put]] should fail. |
| 203 shouldBe("var a = Object.defineProperty([42], '0', {writable: false}); a[0] = fa
lse; a[0];", '42'); |
| 204 shouldThrow("'use strict'; var a = Object.defineProperty([42], '0', {writable: f
alse}); a[0] = false; a[0];"); |
| 205 |
| 206 // If array property is an undefined setter, [[Put]] should fail. |
| 207 shouldBeUndefined("var a = Object.defineProperty([], '0', {set: undefined}); a[0
] = 42; a[0];"); |
| 208 shouldThrow("'use strict'; var a = Object.defineProperty([], '0', {set: undefine
d}); a[0] = 42; a[0];"); |
| 209 |
| 210 function testObject() |
| 211 { |
| 212 // Test case from https://bugs.webkit.org/show_bug.cgi?id=38636 |
| 213 Object.defineProperty(anObj, 'slot1', {value: 'foo', enumerable: true}); |
| 214 Object.defineProperty(anObj, 'slot2', {value: 'bar', writable: true}); |
| 215 Object.defineProperty(anObj, 'slot3', {value: 'baz', enumerable: false}); |
| 216 Object.defineProperty(anObj, 'slot4', {value: 'goo', configurable: false}); |
| 217 shouldBe("anObj.slot1", '"foo"'); |
| 218 shouldBe("anObj.slot2", '"bar"'); |
| 219 anObj.slot2 = 'bad value'; |
| 220 shouldBeTrue("anObj.propertyIsEnumerable('slot1')"); |
| 221 shouldBeFalse("anObj.propertyIsEnumerable('slot2')"); |
| 222 delete anObj.slot4; |
| 223 shouldBe("anObj.slot4", '"goo"'); |
| 224 |
| 225 // Test case from https://bugs.webkit.org/show_bug.cgi?id=48911 |
| 226 Object.defineProperty(Object.getPrototypeOf(anObj), 'slot5', {get: function(
) { return this._Slot5; }, set: function(v) { this._Slot5 = v; }, configurable:
false}); |
| 227 anObj.slot5 = 123; |
| 228 shouldBe("anObj.slot5", '123'); |
| 229 shouldBe("anObj._Slot5", '123'); |
| 230 shouldBeUndefined("Object.getOwnPropertyDescriptor(anObj, 'slot5')"); |
| 231 Object.defineProperty(anObj, 'slot5', { value: 456 }); |
| 232 shouldBe("anObj.slot5", '456'); |
| 233 shouldBe("anObj._Slot5", '123'); |
| 234 shouldBe("Object.getOwnPropertyDescriptor(anObj, 'slot5').value", '456'); |
| 235 } |
| 236 var anObj = {}; |
| 237 testObject(); |
| 238 var anObj = this; |
| 239 testObject(); |
OLD | NEW |