blob: 1fec766dd1599c989ce2077dcc9546e81748418b [file] [log] [blame]
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001// 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// Based on Mozilla Object.assign() tests
6
7function checkDataProperty(object, propertyKey, value, writable, enumerable, configurable) {
8 var desc = Object.getOwnPropertyDescriptor(object, propertyKey);
9 assertFalse(desc === undefined);
10 assertTrue('value' in desc);
11 assertEquals(desc.value, value);
12 assertEquals(desc.writable, writable);
13 assertEquals(desc.enumerable, enumerable);
14 assertEquals(desc.configurable, configurable);
15}
16
17// 19.1.2.1 Object.assign ( target, ...sources )
18assertEquals(Object.assign.length, 2);
19
20// Basic functionality works with multiple sources
21(function basicMultipleSources() {
22 var a = {};
23 var b = { bProp: 1 };
24 var c = { cProp: 2 };
25 Object.assign(a, b, c);
26 assertEquals(a, {
27 bProp: 1,
28 cProp: 2
29 });
30})();
31
32// Basic functionality works with symbols
33(function basicSymbols() {
34 var a = {};
35 var b = { bProp: 1 };
36 var aSymbol = Symbol("aSymbol");
37 b[aSymbol] = 2;
38 Object.assign(a, b);
39 assertEquals(1, a.bProp);
40 assertEquals(2, a[aSymbol]);
41})();
42
43// Dies if target is null or undefined
44assertThrows(function() { return Object.assign(null, null); }, TypeError);
45assertThrows(function() { return Object.assign(null, {}); }, TypeError);
46assertThrows(function() { return Object.assign(undefined); }, TypeError);
47assertThrows(function() { return Object.assign(); }, TypeError);
48
49// Calls ToObject for target
50assertTrue(Object.assign(true, {}) instanceof Boolean);
51assertTrue(Object.assign(1, {}) instanceof Number);
52assertTrue(Object.assign("string", {}) instanceof String);
53var o = {};
54assertSame(Object.assign(o, {}), o);
55
56// Only [[Enumerable]] properties are assigned to target
57(function onlyEnumerablePropertiesAssigned() {
58 var source = Object.defineProperties({}, {
59 a: {value: 1, enumerable: true},
60 b: {value: 2, enumerable: false},
61 });
62 var target = Object.assign({}, source);
63 assertTrue("a" in target);
64 assertFalse("b" in target);
65})();
66
67// Properties are retrieved through Get()
68// Properties are assigned through Put()
69(function testPropertiesAssignedThroughPut() {
70 var setterCalled = false;
71 Object.assign({set a(v) { setterCalled = v }}, {a: true});
72 assertTrue(setterCalled);
73})();
74
75// Properties are retrieved through Get()
76// Properties are assigned through Put(): Existing property attributes are not altered
77(function propertiesAssignedExistingNotAltered() {
78 var source = {a: 1, b: 2, c: 3};
79 var target = {a: 0, b: 0, c: 0};
80 Object.defineProperty(target, "a", {enumerable: false});
81 Object.defineProperty(target, "b", {configurable: false});
82 Object.defineProperty(target, "c", {enumerable: false, configurable: false});
83 Object.assign(target, source);
84 checkDataProperty(target, "a", 1, true, false, true);
85 checkDataProperty(target, "b", 2, true, true, false);
86 checkDataProperty(target, "c", 3, true, false, false);
87})();
88
89// Properties are retrieved through Get()
90// Properties are assigned through Put(): Throws TypeError if non-writable
91(function propertiesAssignedTypeErrorNonWritable() {
92 var source = {a: 1};
93 var target = {a: 0};
94 Object.defineProperty(target, "a", {writable: false});
95 assertThrows(function() { return Object.assign(target, source); }, TypeError);
96 checkDataProperty(target, "a", 0, false, true, true);
97})();
98
99// Properties are retrieved through Get()
100// Put() creates standard properties; Property attributes from source are
101// ignored
102(function createsStandardProperties() {
103 var source = {a: 1, b: 2, c: 3, get d() { return 4 }};
104 Object.defineProperty(source, "b", {writable: false});
105 Object.defineProperty(source, "c", {configurable: false});
106 var target = Object.assign({}, source);
107 checkDataProperty(target, "a", 1, true, true, true);
108 checkDataProperty(target, "b", 2, true, true, true);
109 checkDataProperty(target, "c", 3, true, true, true);
110 checkDataProperty(target, "d", 4, true, true, true);
111})();
112
113// Properties created during traversal are not copied
114(function propertiesCreatedDuringTraversalNotCopied() {
115 var source = {get a() { this.b = 2 }};
116 var target = Object.assign({}, source);
117 assertTrue("a" in target);
118 assertFalse("b" in target);
119})();
120
121// String and Symbol valued properties are copied
122(function testStringAndSymbolPropertiesCopied() {
123 var keyA = "str-prop";
124 var source = {"str-prop": 1};
125 var target = Object.assign({}, source);
126 checkDataProperty(target, keyA, 1, true, true, true);
127})();
128
129(function testExceptionsStopFirstException() {
130 var ErrorA = function ErrorA() {};
131 var ErrorB = function ErrorB() {};
132 var log = "";
133 var source = { b: 1, a: 1 };
134 var target = {
135 set a(v) { log += "a"; throw new ErrorA },
136 set b(v) { log += "b"; throw new ErrorB },
137 };
138 assertThrows(function() { return Object.assign(target, source); }, ErrorB);
139 assertEquals(log, "b");
140})();
Ben Murdoch097c5b22016-05-18 11:27:45 +0100141
142(function add_to_source() {
143 var target = {set k1(v) { source.k3 = 100; }};
144 var source = {k1:10};
145 Object.defineProperty(source, "k2",
146 {value: 20, enumerable: false, configurable: true});
147 Object.assign(target, source);
148 assertEquals(undefined, target.k2);
149 assertEquals(undefined, target.k3);
150})();
151
152(function reconfigure_enumerable_source() {
153 var target = {set k1(v) {
154 Object.defineProperty(source, "k2", {value: 20, enumerable: true});
155 }};
156 var source = {k1:10};
157 Object.defineProperty(source, "k2",
158 {value: 20, enumerable: false, configurable: true});
159 Object.assign(target, source);
160 assertEquals(20, target.k2);
161})();
162
163(function propagate_assign_failure() {
164 var target = {set k1(v) { throw "fail" }};
165 var source = {k1:10};
166 assertThrows(()=>Object.assign(target, source));
167})();
168
169(function propagate_read_failure() {
170 var target = {};
171 var source = {get k1() { throw "fail" }};
172 assertThrows(()=>Object.assign(target, source));
173})();