Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / v8 / test / mjsunit / object-freeze.js
1 // Copyright 2010 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 // Tests the Object.freeze and Object.isFrozen methods - ES 15.2.3.9 and
29 // ES 15.2.3.12
30
31 // Flags: --allow-natives-syntax
32
33 // Test that we throw an error if an object is not passed as argument.
34 var non_objects = new Array(undefined, null, 1, -1, 0, 42.43);
35 for (var key in non_objects) {
36   var exception = false;
37   try {
38     Object.freeze(non_objects[key]);
39   } catch(e) {
40     exception = true;
41     assertTrue(/Object.freeze called on non-object/.test(e));
42   }
43   assertTrue(exception);
44 }
45
46 for (var key in non_objects) {
47   exception = false;
48   try {
49     Object.isFrozen(non_objects[key]);
50   } catch(e) {
51     exception = true;
52     assertTrue(/Object.isFrozen called on non-object/.test(e));
53   }
54   assertTrue(exception);
55 }
56
57 // Test normal data properties.
58 var obj = { x: 42, z: 'foobar' };
59 var desc = Object.getOwnPropertyDescriptor(obj, 'x');
60 assertTrue(desc.writable);
61 assertTrue(desc.configurable);
62 assertEquals(42, desc.value);
63
64 desc = Object.getOwnPropertyDescriptor(obj, 'z');
65 assertTrue(desc.writable);
66 assertTrue(desc.configurable);
67 assertEquals('foobar', desc.value);
68
69 assertTrue(Object.isExtensible(obj));
70 assertFalse(Object.isFrozen(obj));
71
72 Object.freeze(obj);
73
74 // Make sure we are no longer extensible.
75 assertFalse(Object.isExtensible(obj));
76 assertTrue(Object.isFrozen(obj));
77
78 obj.foo = 42;
79 assertEquals(obj.foo, undefined);
80
81 desc = Object.getOwnPropertyDescriptor(obj, 'x');
82 assertFalse(desc.writable);
83 assertFalse(desc.configurable);
84 assertEquals(42, desc.value);
85
86 desc = Object.getOwnPropertyDescriptor(obj, 'z');
87 assertFalse(desc.writable);
88 assertFalse(desc.configurable);
89 assertEquals("foobar", desc.value);
90
91 // Make sure that even if we try overwrite a value that is not writable, it is
92 // not changed.
93 obj.x = "tete";
94 assertEquals(42, obj.x);
95 obj.x = { get: function() {return 43}, set: function() {} };
96 assertEquals(42, obj.x);
97
98 // Test on accessors.
99 var obj2 = {};
100 function get() { return 43; };
101 function set() {};
102 Object.defineProperty(obj2, 'x', { get: get, set: set, configurable: true });
103
104 desc = Object.getOwnPropertyDescriptor(obj2, 'x');
105 assertTrue(desc.configurable);
106 assertEquals(undefined, desc.value);
107 assertEquals(set, desc.set);
108 assertEquals(get, desc.get);
109
110 assertTrue(Object.isExtensible(obj2));
111 assertFalse(Object.isFrozen(obj2));
112 Object.freeze(obj2);
113 assertTrue(Object.isFrozen(obj2));
114 assertFalse(Object.isExtensible(obj2));
115
116 desc = Object.getOwnPropertyDescriptor(obj2, 'x');
117 assertFalse(desc.configurable);
118 assertEquals(undefined, desc.value);
119 assertEquals(set, desc.set);
120 assertEquals(get, desc.get);
121
122 obj2.foo = 42;
123 assertEquals(obj2.foo, undefined);
124
125
126 // Test freeze on arrays.
127 var arr = new Array(42,43);
128
129 desc = Object.getOwnPropertyDescriptor(arr, '0');
130 assertTrue(desc.configurable);
131 assertTrue(desc.writable);
132 assertEquals(42, desc.value);
133
134 desc = Object.getOwnPropertyDescriptor(arr, '1');
135 assertTrue(desc.configurable);
136 assertTrue(desc.writable);
137 assertEquals(43, desc.value);
138
139 assertTrue(Object.isExtensible(arr));
140 assertFalse(Object.isFrozen(arr));
141 Object.freeze(arr);
142 assertTrue(Object.isFrozen(arr));
143 assertFalse(Object.isExtensible(arr));
144
145 desc = Object.getOwnPropertyDescriptor(arr, '0');
146 assertFalse(desc.configurable);
147 assertFalse(desc.writable);
148 assertEquals(42, desc.value);
149
150 desc = Object.getOwnPropertyDescriptor(arr, '1');
151 assertFalse(desc.configurable);
152 assertFalse(desc.writable);
153 assertEquals(43, desc.value);
154
155 arr[0] = 'foo';
156
157 assertEquals(arr[0], 42);
158
159
160 // Test that isFrozen return the correct value even if configurable has been set
161 // to false on all properties manually and the extensible flag has also been set
162 // to false manually.
163 var obj3 = { x: 42, y: 'foo' };
164
165 assertFalse(Object.isFrozen(obj3));
166
167 Object.defineProperty(obj3, 'x', {configurable: false, writable: false});
168 Object.defineProperty(obj3, 'y', {configurable: false, writable: false});
169 Object.preventExtensions(obj3);
170
171 assertTrue(Object.isFrozen(obj3));
172
173
174 // Make sure that an object that has only non-configurable, but one
175 // writable property, is not classified as frozen.
176 var obj4 = {};
177 Object.defineProperty(obj4, 'x', {configurable: false, writable: true});
178 Object.defineProperty(obj4, 'y', {configurable: false, writable: false});
179 Object.preventExtensions(obj4);
180
181 assertFalse(Object.isFrozen(obj4));
182
183 // Make sure that an object that has only non-writable, but one
184 // configurable property, is not classified as frozen.
185 var obj5 = {};
186 Object.defineProperty(obj5, 'x', {configurable: true, writable: false});
187 Object.defineProperty(obj5, 'y', {configurable: false, writable: false});
188 Object.preventExtensions(obj5);
189
190 assertFalse(Object.isFrozen(obj5));
191
192 // Make sure that Object.freeze returns the frozen object.
193 var obj6 = {}
194 assertTrue(obj6 === Object.freeze(obj6))
195
196 // Test that the enumerable attribute is unperturbed by freezing.
197 obj = { x: 42, y: 'foo' };
198 Object.defineProperty(obj, 'y', {enumerable: false});
199 Object.freeze(obj);
200 assertTrue(Object.isFrozen(obj));
201 desc = Object.getOwnPropertyDescriptor(obj, 'x');
202 assertTrue(desc.enumerable);
203 desc = Object.getOwnPropertyDescriptor(obj, 'y');
204 assertFalse(desc.enumerable);
205
206 // Fast properties should remain fast
207 obj = { x: 42, y: 'foo' };
208 assertTrue(%HasFastProperties(obj));
209 Object.freeze(obj);
210 assertTrue(Object.isFrozen(obj));
211 assertTrue(%HasFastProperties(obj));
212
213 // Frozen objects should share maps where possible
214 obj = { prop1: 1, prop2: 2 };
215 obj2 = { prop1: 3, prop2: 4 };
216 assertTrue(%HaveSameMap(obj, obj2));
217 Object.freeze(obj);
218 Object.freeze(obj2);
219 assertTrue(Object.isFrozen(obj));
220 assertTrue(Object.isFrozen(obj2));
221 assertTrue(%HaveSameMap(obj, obj2));
222
223 // Frozen objects should share maps even when they have elements
224 obj = { prop1: 1, prop2: 2, 75: 'foo' };
225 obj2 = { prop1: 3, prop2: 4, 150: 'bar' };
226 assertTrue(%HaveSameMap(obj, obj2));
227 Object.freeze(obj);
228 Object.freeze(obj2);
229 assertTrue(Object.isFrozen(obj));
230 assertTrue(Object.isFrozen(obj2));
231 assertTrue(%HaveSameMap(obj, obj2));
232
233 // Setting elements after freezing should not be allowed
234 obj = { prop: 'thing' };
235 Object.freeze(obj);
236 assertTrue(Object.isFrozen(obj));
237 obj[0] = 'hello';
238 assertFalse(obj.hasOwnProperty(0));
239
240 // Freezing an object in dictionary mode should work
241 // Also testing that getter/setter properties work after freezing
242 obj = { };
243 for (var i = 0; i < 100; ++i) {
244   obj['x' + i] = i;
245 }
246 var accessorDidRun = false;
247 Object.defineProperty(obj, 'accessor', {
248   get: function() { return 42 },
249   set: function() { accessorDidRun = true },
250   configurable: true,
251   enumerable: true
252 });
253
254 assertFalse(%HasFastProperties(obj));
255 Object.freeze(obj);
256 assertFalse(%HasFastProperties(obj));
257 assertTrue(Object.isFrozen(obj));
258 assertFalse(Object.isExtensible(obj));
259 for (var i = 0; i < 100; ++i) {
260   desc = Object.getOwnPropertyDescriptor(obj, 'x' + i);
261   assertFalse(desc.writable);
262   assertFalse(desc.configurable);
263 }
264 assertEquals(42, obj.accessor);
265 assertFalse(accessorDidRun);
266 obj.accessor = 'ignored value';
267 assertTrue(accessorDidRun);
268
269 // Freezing arguments should work
270 var func = function(arg) {
271   Object.freeze(arguments);
272   assertTrue(Object.isFrozen(arguments));
273 };
274 func('hello', 'world');
275 func('goodbye', 'world');
276
277 // Freezing sparse arrays
278 var sparseArr = [0, 1];
279 sparseArr[10000] = 10000;
280 Object.freeze(sparseArr);
281 assertTrue(Object.isFrozen(sparseArr));
282
283 // Accessors on fast object should behavior properly after freezing
284 obj = {};
285 Object.defineProperty(obj, 'accessor', {
286   get: function() { return 42 },
287   set: function() { accessorDidRun = true },
288   configurable: true,
289   enumerable: true
290 });
291 assertTrue(%HasFastProperties(obj));
292 Object.freeze(obj);
293 assertTrue(Object.isFrozen(obj));
294 assertTrue(%HasFastProperties(obj));
295 assertEquals(42, obj.accessor);
296 accessorDidRun = false;
297 obj.accessor = 'ignored value';
298 assertTrue(accessorDidRun);
299
300 // Test for regression in mixed accessor/data property objects.
301 // The strict function is one such object.
302 assertTrue(Object.isFrozen(Object.freeze(function(){"use strict";})));
303
304 // Also test a simpler case
305 obj = {};
306 Object.defineProperty(obj, 'accessor', {
307   get: function() { return 42 },
308   set: function() { accessorDidRun = true },
309   configurable: true,
310   enumerable: true
311 });
312 obj.data = 'foo';
313 assertTrue(%HasFastProperties(obj));
314 Object.freeze(obj);
315 assertTrue(%HasFastProperties(obj));
316 assertTrue(Object.isFrozen(obj));
317
318 // Test array built-in functions with freeze.
319 obj = [1,2,3];
320 Object.freeze(obj);
321 // if frozen implies sealed, then the tests in object-seal.js are mostly
322 // sufficient.
323 assertTrue(Object.isSealed(obj));
324
325 // Verify that the length can't be written by builtins.
326 assertThrows(function() { obj.push(); }, TypeError);
327 assertThrows(function() { obj.unshift(); }, TypeError);
328 assertThrows(function() { obj.splice(0,0); }, TypeError);
329 assertTrue(Object.isFrozen(obj));
330
331 // Verify that an item can't be changed with splice.
332 assertThrows(function() { obj.splice(0,1,1); }, TypeError);
333 assertTrue(Object.isFrozen(obj));
334
335 // Verify that unshift() with no arguments will fail if it reifies from
336 // the prototype into the object.
337 obj = [1,,3];
338 obj.__proto__[1] = 1;
339 assertEquals(1, obj[1]);
340 Object.freeze(obj);
341 assertThrows(function() { obj.unshift(); }, TypeError);