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// 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})(); 141