Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / v8 / test / mjsunit / es6 / symbols.js
1 // Copyright 2013 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 // Flags: --expose-gc --allow-natives-syntax --harmony-tostring
29
30 var symbols = []
31
32
33 // Returns true if the string is a valid
34 // serialization of Symbols added to the 'symbols'
35 // array. Adjust if you extend 'symbols' with other
36 // values.
37 function isValidSymbolString(s) {
38   return ["Symbol(66)", "Symbol()"].indexOf(s) >= 0;
39 }
40
41
42 // Test different forms of constructor calls.
43 function TestNew() {
44   function indirectSymbol() { return Symbol() }
45   function indirect() { return indirectSymbol() }
46   for (var i = 0; i < 2; ++i) {
47     for (var j = 0; j < 5; ++j) {
48       symbols.push(Symbol())
49       symbols.push(Symbol(undefined))
50       symbols.push(Symbol("66"))
51       symbols.push(Symbol(66))
52       symbols.push(Symbol().valueOf())
53       symbols.push(indirect())
54     }
55     %OptimizeFunctionOnNextCall(indirect)
56     indirect()  // Call once before GC throws away type feedback.
57     gc()        // Promote existing symbols and then allocate some more.
58   }
59   assertThrows(function () { Symbol(Symbol()) }, TypeError)
60   assertThrows(function () { new Symbol(66) }, TypeError)
61 }
62 TestNew()
63
64
65 function TestType() {
66   for (var i in symbols) {
67     assertEquals("symbol", typeof symbols[i])
68     assertTrue(typeof symbols[i] === "symbol")
69     assertFalse(%SymbolIsPrivate(symbols[i]))
70     assertEquals(null, %_ClassOf(symbols[i]))
71     assertEquals("Symbol", %_ClassOf(Object(symbols[i])))
72   }
73 }
74 TestType()
75
76
77 function TestPrototype() {
78   assertSame(Object.prototype, Symbol.prototype.__proto__)
79   assertSame(Symbol.prototype, Symbol().__proto__)
80   assertSame(Symbol.prototype, Object(Symbol()).__proto__)
81   for (var i in symbols) {
82     assertSame(Symbol.prototype, symbols[i].__proto__)
83   }
84 }
85 TestPrototype()
86
87
88 function TestConstructor() {
89   assertSame(Function.prototype, Symbol.__proto__)
90   assertFalse(Object === Symbol.prototype.constructor)
91   assertFalse(Symbol === Object.prototype.constructor)
92   assertSame(Symbol, Symbol.prototype.constructor)
93   assertSame(Symbol, Symbol().__proto__.constructor)
94   assertSame(Symbol, Object(Symbol()).__proto__.constructor)
95   for (var i in symbols) {
96     assertSame(Symbol, symbols[i].__proto__.constructor)
97   }
98 }
99 TestConstructor()
100
101
102 function TestValueOf() {
103   for (var i in symbols) {
104     assertTrue(symbols[i] === Object(symbols[i]).valueOf())
105     assertTrue(symbols[i] === symbols[i].valueOf())
106     assertTrue(Symbol.prototype.valueOf.call(Object(symbols[i])) === symbols[i])
107     assertTrue(Symbol.prototype.valueOf.call(symbols[i]) === symbols[i])
108   }
109 }
110 TestValueOf()
111
112
113 function TestToString() {
114   for (var i in symbols) {
115     assertThrows(function() { new String(symbols[i]) }, TypeError)
116     assertEquals(symbols[i].toString(), String(symbols[i]))
117     assertThrows(function() { symbols[i] + "" }, TypeError)
118     assertThrows(function() { String(Object(symbols[i])) }, TypeError)
119     assertTrue(isValidSymbolString(symbols[i].toString()))
120     assertTrue(isValidSymbolString(Object(symbols[i]).toString()))
121     assertTrue(
122       isValidSymbolString(Symbol.prototype.toString.call(symbols[i])))
123     assertEquals(
124       "[object Symbol]", Object.prototype.toString.call(symbols[i]))
125   }
126 }
127 TestToString()
128
129
130 function TestToBoolean() {
131   for (var i in symbols) {
132     assertTrue(Boolean(Object(symbols[i])))
133     assertFalse(!Object(symbols[i]))
134     assertTrue(Boolean(symbols[i]).valueOf())
135     assertFalse(!symbols[i])
136     assertTrue(!!symbols[i])
137     assertTrue(symbols[i] && true)
138     assertFalse(!symbols[i] && false)
139     assertTrue(!symbols[i] || true)
140     assertEquals(1, symbols[i] ? 1 : 2)
141     assertEquals(2, !symbols[i] ? 1 : 2)
142     if (!symbols[i]) assertUnreachable();
143     if (symbols[i]) {} else assertUnreachable();
144   }
145 }
146 TestToBoolean()
147
148
149 function TestToNumber() {
150   for (var i in symbols) {
151     assertThrows(function() { Number(Object(symbols[i])) }, TypeError)
152     assertThrows(function() { +Object(symbols[i]) }, TypeError)
153     assertThrows(function() { Number(symbols[i]) }, TypeError)
154     assertThrows(function() { symbols[i] + 0 }, TypeError)
155   }
156 }
157 TestToNumber()
158
159
160 function TestEquality() {
161   // Every symbol should equal itself, and non-strictly equal its wrapper.
162   for (var i in symbols) {
163     assertSame(symbols[i], symbols[i])
164     assertEquals(symbols[i], symbols[i])
165     assertTrue(Object.is(symbols[i], symbols[i]))
166     assertTrue(symbols[i] === symbols[i])
167     assertTrue(symbols[i] == symbols[i])
168     assertFalse(symbols[i] === Object(symbols[i]))
169     assertFalse(Object(symbols[i]) === symbols[i])
170     assertFalse(symbols[i] == Object(symbols[i]))
171     assertFalse(Object(symbols[i]) == symbols[i])
172     assertTrue(symbols[i] === symbols[i].valueOf())
173     assertTrue(symbols[i].valueOf() === symbols[i])
174     assertTrue(symbols[i] == symbols[i].valueOf())
175     assertTrue(symbols[i].valueOf() == symbols[i])
176     assertFalse(Object(symbols[i]) === Object(symbols[i]))
177     assertEquals(Object(symbols[i]).valueOf(), Object(symbols[i]).valueOf())
178   }
179
180   // All symbols should be distinct.
181   for (var i = 0; i < symbols.length; ++i) {
182     for (var j = i + 1; j < symbols.length; ++j) {
183       assertFalse(Object.is(symbols[i], symbols[j]))
184       assertFalse(symbols[i] === symbols[j])
185       assertFalse(symbols[i] == symbols[j])
186     }
187   }
188
189   // Symbols should not be equal to any other value (and the test terminates).
190   var values = [347, 1.275, NaN, "string", null, undefined, {}, function() {}]
191   for (var i in symbols) {
192     for (var j in values) {
193       assertFalse(symbols[i] === values[j])
194       assertFalse(values[j] === symbols[i])
195       assertFalse(symbols[i] == values[j])
196       assertFalse(values[j] == symbols[i])
197     }
198   }
199 }
200 TestEquality()
201
202
203 function TestGet() {
204   for (var i in symbols) {
205     assertTrue(isValidSymbolString(symbols[i].toString()))
206     assertEquals(symbols[i], symbols[i].valueOf())
207     assertEquals(undefined, symbols[i].a)
208     assertEquals(undefined, symbols[i]["a" + "b"])
209     assertEquals(undefined, symbols[i]["" + "1"])
210     assertEquals(undefined, symbols[i][62])
211   }
212 }
213 TestGet()
214
215
216 function TestSet() {
217   for (var i in symbols) {
218     symbols[i].toString = 0
219     assertTrue(isValidSymbolString(symbols[i].toString()))
220     symbols[i].valueOf = 0
221     assertEquals(symbols[i], symbols[i].valueOf())
222     symbols[i].a = 0
223     assertEquals(undefined, symbols[i].a)
224     symbols[i]["a" + "b"] = 0
225     assertEquals(undefined, symbols[i]["a" + "b"])
226     symbols[i][62] = 0
227     assertEquals(undefined, symbols[i][62])
228   }
229 }
230 TestSet()
231
232
233 // Test Symbol wrapping/boxing over non-builtins.
234 Symbol.prototype.getThisProto = function () {
235   return Object.getPrototypeOf(this);
236 }
237 function TestCall() {
238   for (var i in symbols) {
239     assertTrue(symbols[i].getThisProto() === Symbol.prototype)
240   }
241 }
242 TestCall()
243
244
245 function TestCollections() {
246   var set = new Set
247   var map = new Map
248   var weakmap = new WeakMap
249   for (var i in symbols) {
250     set.add(symbols[i])
251     map.set(symbols[i], i)
252     weakmap.set(symbols[i], i)
253   }
254   assertEquals(symbols.length, set.size)
255   assertEquals(symbols.length, map.size)
256   for (var i in symbols) {
257     assertTrue(set.has(symbols[i]))
258     assertTrue(map.has(symbols[i]))
259     assertTrue(weakmap.has(symbols[i]))
260     assertEquals(i, map.get(symbols[i]))
261     assertEquals(i, weakmap.get(symbols[i]))
262   }
263   for (var i in symbols) {
264     assertTrue(set.delete(symbols[i]))
265     assertTrue(map.delete(symbols[i]))
266     assertTrue(weakmap.delete(symbols[i]))
267   }
268   assertEquals(0, set.size)
269   assertEquals(0, map.size)
270 }
271 TestCollections()
272
273
274
275 function TestKeySet(obj) {
276   assertTrue(%HasFastProperties(obj))
277   // Set the even symbols via assignment.
278   for (var i = 0; i < symbols.length; i += 2) {
279     obj[symbols[i]] = i
280     // Object should remain in fast mode until too many properties were added.
281     assertTrue(%HasFastProperties(obj) || i >= 30)
282   }
283 }
284
285
286 function TestKeyDefine(obj) {
287   // Set the odd symbols via defineProperty (as non-enumerable).
288   for (var i = 1; i < symbols.length; i += 2) {
289     Object.defineProperty(obj, symbols[i], {value: i, configurable: true})
290   }
291 }
292
293
294 function TestKeyGet(obj) {
295   var obj2 = Object.create(obj)
296   for (var i in symbols) {
297     assertEquals(i|0, obj[symbols[i]])
298     assertEquals(i|0, obj2[symbols[i]])
299   }
300 }
301
302
303 function TestKeyHas(obj) {
304   for (var i in symbols) {
305     assertTrue(symbols[i] in obj)
306     assertTrue(Object.hasOwnProperty.call(obj, symbols[i]))
307   }
308 }
309
310
311 function TestKeyEnum(obj) {
312   for (var name in obj) {
313     assertEquals("string", typeof name)
314   }
315 }
316
317
318 function TestKeyNames(obj) {
319   assertEquals(0, Object.keys(obj).length)
320
321   var names = Object.getOwnPropertyNames(obj)
322   for (var i in names) {
323     assertEquals("string", typeof names[i])
324   }
325 }
326
327
328 function TestGetOwnPropertySymbols(obj) {
329   var syms = Object.getOwnPropertySymbols(obj)
330   assertEquals(syms.length, symbols.length)
331   for (var i in syms) {
332     assertEquals("symbol", typeof syms[i])
333   }
334 }
335
336
337 function TestKeyDescriptor(obj) {
338   for (var i in symbols) {
339     var desc = Object.getOwnPropertyDescriptor(obj, symbols[i])
340     assertEquals(i|0, desc.value)
341     assertTrue(desc.configurable)
342     assertEquals(i % 2 == 0, desc.writable)
343     assertEquals(i % 2 == 0, desc.enumerable)
344     assertEquals(i % 2 == 0,
345         Object.prototype.propertyIsEnumerable.call(obj, symbols[i]))
346   }
347 }
348
349
350 function TestKeyDelete(obj) {
351   for (var i in symbols) {
352     delete obj[symbols[i]]
353   }
354   for (var i in symbols) {
355     assertEquals(undefined, Object.getOwnPropertyDescriptor(obj, symbols[i]))
356   }
357 }
358
359
360 var objs = [{}, [], Object.create(null), Object(1), new Map, function(){}]
361
362 for (var i in objs) {
363   var obj = objs[i]
364   TestKeySet(obj)
365   TestKeyDefine(obj)
366   TestKeyGet(obj)
367   TestKeyHas(obj)
368   TestKeyEnum(obj)
369   TestKeyNames(obj)
370   TestGetOwnPropertySymbols(obj)
371   TestKeyDescriptor(obj)
372   TestKeyDelete(obj)
373 }
374
375
376 function TestDefineProperties() {
377   var properties = {}
378   for (var i in symbols) {
379     Object.defineProperty(
380         properties, symbols[i], {value: {value: i}, enumerable: i % 2 === 0})
381   }
382   var o = Object.defineProperties({}, properties)
383   for (var i in symbols) {
384     assertEquals(i % 2 === 0, symbols[i] in o)
385   }
386 }
387 TestDefineProperties()
388
389
390 function TestCreate() {
391   var properties = {}
392   for (var i in symbols) {
393     Object.defineProperty(
394       properties, symbols[i], {value: {value: i}, enumerable: i % 2 === 0})
395   }
396   var o = Object.create(Object.prototype, properties)
397   for (var i in symbols) {
398     assertEquals(i % 2 === 0, symbols[i] in o)
399   }
400 }
401 TestCreate()
402
403
404 function TestCachedKeyAfterScavenge() {
405   gc();
406   // Keyed property lookup are cached.  Hereby we assume that the keys are
407   // tenured, so that we only have to clear the cache between mark compacts,
408   // but not between scavenges.  This must also apply for symbol keys.
409   var key = Symbol("key");
410   var a = {};
411   a[key] = "abc";
412
413   for (var i = 0; i < 100000; i++) {
414     a[key] += "a";  // Allocations cause a scavenge.
415   }
416 }
417 TestCachedKeyAfterScavenge();
418
419
420 function TestGetOwnPropertySymbolsWithProto() {
421   // We need to be have fast properties to have insertion order for property
422   // keys. The current limit is currently 30 properties.
423   var syms = symbols.slice(0, 30);
424   var proto = {}
425   var object = Object.create(proto)
426   for (var i = 0; i < syms.length; i++) {
427     // Even on object, odd on proto.
428     if (i % 2) {
429       proto[syms[i]] = i
430     } else {
431       object[syms[i]] = i
432     }
433   }
434
435   assertTrue(%HasFastProperties(object));
436
437   var objectOwnSymbols = Object.getOwnPropertySymbols(object)
438   assertEquals(objectOwnSymbols.length, syms.length / 2)
439
440   for (var i = 0; i < objectOwnSymbols.length; i++) {
441     assertEquals(objectOwnSymbols[i], syms[i * 2])
442   }
443 }
444 TestGetOwnPropertySymbolsWithProto()
445
446
447 function TestWellKnown() {
448   var symbols = [
449     // TODO(rossberg): reactivate once implemented.
450     // "hasInstance", "isConcatSpreadable", "isRegExp",
451     "iterator", /* "toStringTag", */ "unscopables"
452   ]
453
454   for (var i in symbols) {
455     var name = symbols[i]
456     var desc = Object.getOwnPropertyDescriptor(Symbol, name)
457     assertSame("symbol", typeof desc.value)
458     assertSame("Symbol(Symbol." + name + ")", desc.value.toString())
459     assertFalse(desc.writable)
460     assertFalse(desc.configurable)
461     assertFalse(desc.enumerable)
462
463     assertFalse(Symbol.for("Symbol." + name) === desc.value)
464     assertTrue(Symbol.keyFor(desc.value) === undefined)
465   }
466 }
467 TestWellKnown()
468
469
470 function TestRegistry() {
471   var symbol1 = Symbol.for("x1")
472   var symbol2 = Symbol.for("x2")
473   assertFalse(symbol1 === symbol2)
474
475   assertSame(symbol1, Symbol.for("x1"))
476   assertSame(symbol2, Symbol.for("x2"))
477   assertSame("x1", Symbol.keyFor(symbol1))
478   assertSame("x2", Symbol.keyFor(symbol2))
479
480   assertSame(Symbol.for("1"), Symbol.for(1))
481   assertThrows(function() { Symbol.keyFor("bla") }, TypeError)
482   assertThrows(function() { Symbol.keyFor({}) }, TypeError)
483
484   var realm = Realm.create()
485   assertFalse(Symbol === Realm.eval(realm, "Symbol"))
486   assertFalse(Symbol.for === Realm.eval(realm, "Symbol.for"))
487   assertFalse(Symbol.keyFor === Realm.eval(realm, "Symbol.keyFor"))
488   assertSame(Symbol.create, Realm.eval(realm, "Symbol.create"))
489   assertSame(Symbol.iterator, Realm.eval(realm, "Symbol.iterator"))
490
491   assertSame(symbol1, Realm.eval(realm, "Symbol.for")("x1"))
492   assertSame(symbol1, Realm.eval(realm, "Symbol.for('x1')"))
493   assertSame("x1", Realm.eval(realm, "Symbol.keyFor")(symbol1))
494   Realm.shared = symbol1
495   assertSame("x1", Realm.eval(realm, "Symbol.keyFor(Realm.shared)"))
496
497   var symbol3 = Realm.eval(realm, "Symbol.for('x3')")
498   assertFalse(symbol1 === symbol3)
499   assertFalse(symbol2 === symbol3)
500   assertSame(symbol3, Symbol.for("x3"))
501   assertSame("x3", Symbol.keyFor(symbol3))
502 }
503 TestRegistry()
504
505
506 function TestGetOwnPropertySymbolsOnPrimitives() {
507   assertEquals(Object.getOwnPropertySymbols(true), []);
508   assertEquals(Object.getOwnPropertySymbols(5000), []);
509   assertEquals(Object.getOwnPropertySymbols("OK"), []);
510 }
511 TestGetOwnPropertySymbolsOnPrimitives();