OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2009 the V8 project authors. All rights reserved. | |
2 // Redistribution and use in source and binary forms, with or without | |
3 // modification, are permitted provided that the following conditions are | |
4 // met: | |
5 // | |
6 // * Redistributions of source code must retain the above copyright | |
7 // notice, this list of conditions and the following disclaimer. | |
8 // * Redistributions in binary form must reproduce the above | |
9 // copyright notice, this list of conditions and the following | |
10 // disclaimer in the documentation and/or other materials provided | |
11 // with the distribution. | |
12 // * Neither the name of Google Inc. nor the names of its | |
13 // contributors may be used to endorse or promote products derived | |
14 // from this software without specific prior written permission. | |
15 // | |
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
27 | |
28 // Test ES5 sections 15.2.3.5 Object.create. | |
29 // We do not support nonconfigurable properties on objects so that is not | |
30 // tested. We do test getters, setters, writable, enumerable and value. | |
31 | |
32 // Check that no exceptions are thrown. | |
33 Object.create(null); | |
34 Object.create(null, undefined); | |
35 | |
36 var ctr = 0; | |
37 var ctr2 = 0; | |
38 var ctr3 = 0; | |
39 var ctr4 = 0; | |
40 var ctr5 = 0; | |
41 var ctr6 = 1000; | |
42 | |
43 var foo_proto = { foo: function() { ctr++; }}; | |
Christian Plesner Hansen
2009/12/08 20:44:40
lowerCamelCase.
| |
44 var fooValue = { foo: { writable: true, value: function() { ctr2++; }}}; | |
45 var fooGetter = { foo: { get: function() { return ctr3++; }}}; | |
46 var fooSetter = { foo: { set: function() { return ctr4++; }}}; | |
47 var fooAmbiguous = { foo: { get: function() { return ctr3++; }, | |
48 value: 3 }}; | |
49 | |
50 function valueGet() { ctr5++; return 3 }; | |
51 function getterGet() { ctr5++; return function() { return ctr6++; }; }; | |
52 | |
53 // Simple object with prototype, no properties added. | |
54 Object.create(foo_proto).foo(); | |
55 assertEquals(1, ctr); | |
56 | |
57 // Simple object with object with prototype, no properties added. | |
58 Object.create(Object.create(foo_proto)).foo(); | |
59 assertEquals(2, ctr); | |
60 | |
61 // Add a property foo that returns a function. | |
62 var v = Object.create(foo_proto, fooValue); | |
63 v.foo(); | |
64 assertEquals(2, ctr); | |
65 assertEquals(1, ctr2); | |
66 | |
67 // Ensure the property is writable. | |
68 v.foo = 42; | |
69 assertEquals(42, v.foo); | |
70 assertEquals(2, ctr); | |
71 assertEquals(1, ctr2); | |
72 | |
73 // Ensure by default properties are not writable. | |
74 v = Object.create(null, { foo: {value: 103}}); | |
75 assertEquals(103, v.foo); | |
76 v.foo = 42; | |
77 assertEquals(103, v.foo); | |
78 | |
79 // Add a getter foo that returns a counter value. | |
80 assertEquals(0, Object.create(foo_proto, fooGetter).foo); | |
81 assertEquals(2, ctr); | |
82 assertEquals(1, ctr2); | |
83 assertEquals(1, ctr3); | |
84 | |
85 // Add a setter foo that runs a function. | |
86 assertEquals(1, Object.create(foo_proto, fooSetter).foo = 1); | |
87 assertEquals(2, ctr); | |
88 assertEquals(1, ctr2); | |
89 assertEquals(1, ctr3); | |
90 assertEquals(1, ctr4); | |
91 | |
92 // Make sure that trying to add both a value and a getter | |
93 // will result in an exception. | |
94 try { | |
95 Object.create(foo_proto, fooAmbiguous); | |
96 assertTrue(false); | |
97 } catch (e) { | |
98 assertTrue(/Invalid property/.test(e)); | |
99 } | |
100 assertEquals(2, ctr); | |
101 assertEquals(1, ctr2); | |
102 assertEquals(1, ctr3); | |
103 assertEquals(1, ctr4); | |
104 | |
105 var ctr7 = 0; | |
106 | |
107 var metaProps = { | |
108 enumerable: { get: function() { | |
109 assertEquals(0, ctr7++); | |
110 return true; | |
111 }}, | |
112 configurable: { get: function() { | |
113 assertEquals(1, ctr7++); | |
114 return true; | |
115 }}, | |
116 value: { get: function() { | |
117 assertEquals(2, ctr7++); | |
118 return 4; | |
119 }}, | |
120 writable: { get: function() { | |
121 assertEquals(3, ctr7++); | |
122 return true; | |
123 }}, | |
124 get: { get: function() { | |
125 assertEquals(4, ctr7++); | |
126 return function() { }; | |
127 }}, | |
128 set: { get: function() { | |
129 assertEquals(5, ctr7++); | |
130 return function() { }; | |
131 }} | |
132 }; | |
133 | |
134 | |
135 // Instead of a plain props object, let's use getters to return its properties. | |
136 var magicValueProps = { foo: Object.create(null, { value: { get: valueGet }})}; | |
137 var magicGetterProps = { foo: Object.create(null, { get: { get: getterGet }})}; | |
138 var magicAmbiguousProps = { foo: Object.create(null, metaProps) }; | |
139 | |
140 assertEquals(3, Object.create(null, magicValueProps).foo); | |
141 assertEquals(1, ctr5); | |
142 | |
143 assertEquals(1000, Object.create(null, magicGetterProps).foo); | |
144 assertEquals(2, ctr5); | |
145 | |
146 // See if we do the steps in ToPropertyDescriptor in the right order. | |
147 // We shouldn't throw the exception for an ambiguous properties object | |
148 // before we got all the values out. | |
149 try { | |
150 Object.create(null, magicAmbiguousProps); | |
151 assertTrue(false); | |
152 } catch (e) { | |
153 assertTrue(/Invalid property/.test(e)); | |
154 assertEquals(6, ctr7); | |
155 } | |
156 | |
157 var magicWritableProps = { | |
158 foo: Object.create(null, { value: { value: 4 }, | |
159 writable: { get: function() { | |
160 ctr6++; | |
161 return false; | |
162 }}})}; | |
163 | |
164 var fooNotWritable = Object.create(null, magicWritableProps) | |
165 assertEquals(1002, ctr6); | |
166 assertEquals(4, fooNotWritable.foo); | |
167 fooNotWritable.foo = 5; | |
168 assertEquals(4, fooNotWritable.foo); | |
169 | |
170 | |
171 // Test enumerable flag. | |
172 | |
173 var fooNotEnumerable = | |
174 Object.create({fizz: 14}, {foo: {value: 3, enumerable: false}, | |
175 bar: {value: 4, enumerable: true}, | |
176 baz: {value: 5}}); | |
177 var sum = 0; | |
178 for (x in fooNotEnumerable) { | |
179 assertTrue(x === 'bar' || x === 'fizz'); | |
180 sum += fooNotEnumerable[x]; | |
181 } | |
182 assertEquals(18, sum); | |
183 | |
184 | |
185 try { | |
186 Object.create(null, {foo: { get: 0 }}); | |
187 assertTrue(false); | |
188 } catch (e) { | |
189 assertTrue(/Getter must be a function/.test(e)); | |
190 } | |
191 | |
192 try { | |
193 Object.create(null, {foo: { set: 0 }}); | |
194 assertTrue(false); | |
195 } catch (e) { | |
196 assertTrue(/Setter must be a function/.test(e)); | |
197 } | |
198 | |
199 try { | |
200 Object.create(null, {foo: { set: 0, get: 0 }}); | |
201 assertTrue(false); | |
202 } catch (e) { | |
203 assertTrue(/Getter must be a function/.test(e)); | |
204 } | |
205 | |
206 | |
207 // Ensure that only enumerable own properties on the descriptor are used. | |
208 var tricky = Object.create( | |
209 { foo: { value: 1, enumerable: true }}, | |
210 { bar: { value: { value: 2, enumerable: true }, enumerable: false }, | |
211 baz: { value: { value: 4, enumerable: false }, enumerable: true }, | |
212 fizz: { value: { value: 8, enumerable: false }, enumerable: false }, | |
213 buzz: { value: { value: 16, enumerable: true }, enumerable: true }}); | |
214 | |
215 assertEquals(1, tricky.foo.value); | |
216 assertEquals(2, tricky.bar.value); | |
217 assertEquals(4, tricky.baz.value); | |
218 assertEquals(8, tricky.fizz.value); | |
219 assertEquals(16, tricky.buzz.value); | |
220 | |
221 var sonOfTricky = Object.create(null, tricky); | |
222 | |
223 assertFalse("foo" in sonOfTricky); | |
224 assertFalse("bar" in sonOfTricky); | |
225 assertTrue("baz" in sonOfTricky); | |
226 assertFalse("fizz" in sonOfTricky); | |
227 assertTrue("buzz" in sonOfTricky); | |
228 | |
229 var sum = 0; | |
230 for (x in sonOfTricky) { | |
231 assertTrue(x === 'buzz'); | |
232 sum += sonOfTricky[x]; | |
233 } | |
234 assertEquals(16, sum); | |
OLD | NEW |