1// Copyright 2014 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5
6function ID(x) {
7  return x;
8}
9
10
11
12(function TestBasicsString() {
13  var object = {
14    a: 'A',
15    ['b']: 'B',
16    c: 'C',
17    [ID('d')]: 'D',
18  };
19  assertEquals('A', object.a);
20  assertEquals('B', object.b);
21  assertEquals('C', object.c);
22  assertEquals('D', object.d);
23  assertArrayEquals(['a', 'b', 'c', 'd'], Object.keys(object));
24})();
25
26
27(function TestBasicsNumber() {
28  var object = {
29    a: 'A',
30    [1]: 'B',
31    c: 'C',
32    [ID(2)]: 'D',
33  };
34  assertEquals('A', object.a);
35  assertEquals('B', object[1]);
36  assertEquals('C', object.c);
37  assertEquals('D', object[2]);
38  // Array indexes first.
39  assertArrayEquals(['1', '2', 'a', 'c'], Object.keys(object));
40})();
41
42
43(function TestBasicsSymbol() {
44  var sym1 = Symbol();
45  var sym2 = Symbol();
46  var object = {
47    a: 'A',
48    [sym1]: 'B',
49    c: 'C',
50    [ID(sym2)]: 'D',
51  };
52  assertEquals('A', object.a);
53  assertEquals('B', object[sym1]);
54  assertEquals('C', object.c);
55  assertEquals('D', object[sym2]);
56  assertArrayEquals(['a', 'c'], Object.keys(object));
57  assertArrayEquals([sym1, sym2], Object.getOwnPropertySymbols(object));
58})();
59
60
61(function TestToNameSideEffects() {
62  var counter = 0;
63  var key1 = {
64    toString: function() {
65      assertEquals(0, counter++);
66      return 'b';
67    }
68  };
69  var key2 = {
70    toString: function() {
71      assertEquals(1, counter++);
72      return 'd';
73    }
74  };
75  var object = {
76    a: 'A',
77    [key1]: 'B',
78    c: 'C',
79    [key2]: 'D',
80  };
81  assertEquals(2, counter);
82  assertEquals('A', object.a);
83  assertEquals('B', object.b);
84  assertEquals('C', object.c);
85  assertEquals('D', object.d);
86  assertArrayEquals(['a', 'b', 'c', 'd'], Object.keys(object));
87})();
88
89
90(function TestToNameSideEffectsNumbers() {
91  var counter = 0;
92  var key1 = {
93    valueOf: function() {
94      assertEquals(0, counter++);
95      return 1;
96    },
97    toString: null
98  };
99  var key2 = {
100    valueOf: function() {
101      assertEquals(1, counter++);
102      return 2;
103    },
104    toString: null
105  };
106
107  var object = {
108    a: 'A',
109    [key1]: 'B',
110    c: 'C',
111    [key2]: 'D',
112  };
113  assertEquals(2, counter);
114  assertEquals('A', object.a);
115  assertEquals('B', object[1]);
116  assertEquals('C', object.c);
117  assertEquals('D', object[2]);
118  // Array indexes first.
119  assertArrayEquals(['1', '2', 'a', 'c'], Object.keys(object));
120})();
121
122
123(function TestDoubleName() {
124  var object = {
125    [1.2]: 'A',
126    [1e55]: 'B',
127    [0.000001]: 'C',
128    [-0]: 'D',
129    // TODO(arv): https://code.google.com/p/v8/issues/detail?id=3815
130    // [Infinity]: 'E',
131    // [-Infinity]: 'F',
132    [NaN]: 'G',
133  };
134  assertEquals('A', object['1.2']);
135  assertEquals('B', object['1e+55']);
136  assertEquals('C', object['0.000001']);
137  assertEquals('D', object[0]);
138  // TODO(arv): https://code.google.com/p/v8/issues/detail?id=3815
139  // assertEquals('E', object[Infinity]);
140  // assertEquals('F', object[-Infinity]);
141  assertEquals('G', object[NaN]);
142})();
143
144
145(function TestGetter() {
146  var object = {
147    get ['a']() {
148      return 'A';
149    }
150  };
151  assertEquals('A', object.a);
152
153  object = {
154    get b() {
155      assertUnreachable();
156    },
157    get ['b']() {
158      return 'B';
159    }
160  };
161  assertEquals('B', object.b);
162
163  object = {
164    get c() {
165      assertUnreachable();
166    },
167    get ['c']() {
168      assertUnreachable();
169    },
170    get ['c']() {
171      return 'C';
172    }
173  };
174  assertEquals('C', object.c);
175
176  object = {
177    get ['d']() {
178      assertUnreachable();
179    },
180    get d() {
181      return 'D';
182    }
183  };
184  assertEquals('D', object.d);
185})();
186
187
188(function TestSetter() {
189  var calls = 0;
190  var object = {
191    set ['a'](_) {
192      calls++;
193    }
194  };
195  object.a = 'A';
196  assertEquals(1, calls);
197
198  calls = 0;
199  object = {
200    set b(_) {
201      assertUnreachable();
202    },
203    set ['b'](_) {
204      calls++;
205    }
206  };
207  object.b = 'B';
208  assertEquals(1, calls);
209
210  calls = 0;
211  object = {
212    set c(_) {
213      assertUnreachable()
214    },
215    set ['c'](_) {
216      assertUnreachable()
217    },
218    set ['c'](_) {
219      calls++
220    }
221  };
222  object.c = 'C';
223  assertEquals(1, calls);
224
225  calls = 0;
226  object = {
227    set ['d'](_) {
228      assertUnreachable()
229    },
230    set d(_) {
231      calls++
232    }
233  };
234  object.d = 'D';
235  assertEquals(1, calls);
236})();
237
238
239(function TestDuplicateKeys() {
240  'use strict';
241  // ES5 does not allow duplicate keys.
242  // ES6 does but we haven't changed our code yet.
243
244  var object = {
245    a: 1,
246    ['a']: 2,
247  };
248  assertEquals(2, object.a);
249})();
250
251
252(function TestProto() {
253  var proto = {};
254  var object = {
255    __proto__: proto
256  };
257  assertEquals(proto, Object.getPrototypeOf(object));
258
259  object = {
260    '__proto__': proto
261  };
262  assertEquals(proto, Object.getPrototypeOf(object));
263
264  object = {
265    ['__proto__']: proto
266  };
267  assertEquals(Object.prototype, Object.getPrototypeOf(object));
268  assertEquals(proto, object.__proto__);
269  assertTrue(object.hasOwnProperty('__proto__'));
270
271  object = {
272    [ID('x')]: 'X',
273    __proto__: proto
274  };
275  assertEquals('X', object.x);
276  assertEquals(proto, Object.getPrototypeOf(object));
277})();
278
279
280(function TestExceptionInName() {
281  function MyError() {};
282  function throwMyError() {
283    throw new MyError();
284  }
285  assertThrows(function() {
286    var o = {
287      [throwMyError()]: 42
288    };
289  }, MyError);
290  assertThrows(function() {
291    var o = {
292      get [throwMyError()]() { return 42; }
293    };
294  }, MyError);
295  assertThrows(function() {
296    var o = {
297      set [throwMyError()](_) { }
298    };
299  }, MyError);
300})();
301
302
303(function TestNestedLiterals() {
304  var array = [
305    42,
306    { a: 'A',
307      ['b']: 'B',
308      c: 'C',
309      [ID('d')]: 'D',
310    },
311    43,
312  ];
313  assertEquals(42, array[0]);
314  assertEquals(43, array[2]);
315  assertEquals('A', array[1].a);
316  assertEquals('B', array[1].b);
317  assertEquals('C', array[1].c);
318  assertEquals('D', array[1].d);
319  var object = {
320    outer: 42,
321    inner: {
322      a: 'A',
323      ['b']: 'B',
324      c: 'C',
325      [ID('d')]: 'D',
326    },
327    outer2: 43,
328  };
329  assertEquals(42, object.outer);
330  assertEquals(43, object.outer2);
331  assertEquals('A', object.inner.a);
332  assertEquals('B', object.inner.b);
333  assertEquals('C', object.inner.c);
334  assertEquals('D', object.inner.d);
335  var object = {
336    outer: 42,
337    array: [
338      43,
339      { a: 'A',
340        ['b']: 'B',
341        c: 'C',
342        [ID('d')]: 'D',
343      },
344      44,
345    ],
346    outer2: 45
347  };
348  assertEquals(42, object.outer);
349  assertEquals(45, object.outer2);
350  assertEquals(43, object.array[0]);
351  assertEquals(44, object.array[2]);
352  assertEquals('A', object.array[1].a);
353  assertEquals('B', object.array[1].b);
354  assertEquals('C', object.array[1].c);
355  assertEquals('D', object.array[1].d);
356})();
357