|  | 
| 2 | 2 | // This code is governed by the license found in the LICENSE file. | 
| 3 | 3 | 
 | 
| 4 | 4 | /*--- | 
|  | 5 | +esid: sec-object.assign | 
| 5 | 6 | description: > | 
| 6 |  | -  Test the first argument(target) of Object.Assign(target,...sources), | 
| 7 |  | -  being an Array. | 
|  | 7 | +  Object.assign with an Array Exotic Object target employs the corresponding | 
|  | 8 | +  internal methods. | 
|  | 9 | +info: | | 
|  | 10 | +  Object.assign ( _target_, ..._sources_ ) | 
|  | 11 | +  3.a.iii.2.b. Perform ? Set(_to_, _nextKey_, _propValue_, *true*). | 
|  | 12 | +
 | 
|  | 13 | +  Set ( _O_, _P_, _V_, _Throw_ ) | 
|  | 14 | +  1. Let _success_ be ? _O_.[[Set]](_P_, _V_, _O_). | 
|  | 15 | +
 | 
|  | 16 | +  OrdinarySet ( _O_, _P_, _V_, _Receiver_ ) | 
|  | 17 | +  1. Let _ownDesc_ be ? _O_.[[GetOwnProperty]](_P_). | 
|  | 18 | +  2. Return ? OrdinarySetWithOwnDescriptor(_O_, _P_, _V_, _Receiver_, _ownDesc_). | 
|  | 19 | +
 | 
|  | 20 | +  OrdinarySetWithOwnDescriptor ( _O_, _P_, _V_, _Receiver_, _ownDesc_ ) | 
|  | 21 | +  1. If _ownDesc_ is *undefined*, then | 
|  | 22 | +     a. Let _parent_ be ? O.[[GetPrototypeOf]](). | 
|  | 23 | +     b. If _parent_ is not *null*, then | 
|  | 24 | +        i. Return ? _parent_.[[Set]](_P_, _V_, _Receiver_). | 
|  | 25 | +     c. Else, | 
|  | 26 | +        i. Set _ownDesc_ to the PropertyDescriptor { [[Value]]: *undefined*, [[Writable]]: *true*, [[Enumerable]]: *true*, [[Configurable]]: *true* }. | 
|  | 27 | +  2. If IsDataDescriptor(_ownDesc_) is *true*, then | 
|  | 28 | +     ... | 
|  | 29 | +     c. Let _existingDescriptor_ be ? _Receiver_.[[GetOwnProperty]](_P_). | 
|  | 30 | +     d. If _existingDescriptor_ is not *undefined*, then | 
|  | 31 | +        ... | 
|  | 32 | +        iii. Let _valueDesc_ be the PropertyDescriptor { [[Value]]: _V_ }. | 
|  | 33 | +        iv. Return ? _Receiver_.[[DefineOwnProperty]](_P_, _valueDesc_). | 
|  | 34 | +     e. Else, | 
|  | 35 | +        i. Assert: _Receiver_ does not currently have a property _P_. | 
|  | 36 | +        ii. Return ? CreateDataProperty(_Receiver_, _P_, _V_). | 
|  | 37 | +
 | 
|  | 38 | +  CreateDataProperty ( _O_, _P_, _V_ ) | 
|  | 39 | +  1. Let _newDesc_ be the PropertyDescriptor { [[Value]]: _V_, [[Writable]]: *true*, [[Enumerable]]: *true*, [[Configurable]]: *true* }. | 
|  | 40 | +  2. Return ? _O_.[[DefineOwnProperty]](_P_, _newDesc_). | 
|  | 41 | +
 | 
|  | 42 | +  Array exotic object [[DefineOwnProperty]] ( _P_, _Desc_ ) | 
|  | 43 | +  1. If _P_ is *"length"*, then | 
|  | 44 | +     a. Return ? ArraySetLength(_A_, _Desc_). | 
|  | 45 | +  2. Else if _P_ is an array index, then | 
|  | 46 | +     ... | 
|  | 47 | +     k. If _index_ ≥ _length_, then | 
|  | 48 | +        i. Set _lengthDesc_.[[Value]] to _index_ + *1*𝔽. | 
|  | 49 | +        ii. Set _succeeded_ to ! OrdinaryDefineOwnProperty(_A_, *"length"*, _lengthDesc_). | 
|  | 50 | +  3. Return ? OrdinaryDefineOwnProperty(_A_, _P_, _Desc_). | 
|  | 51 | +
 | 
|  | 52 | +  The Object Type | 
|  | 53 | +  An **integer index** is a property name _n_ such that CanonicalNumericIndexString(_n_) returns an | 
|  | 54 | +  integral Number in the inclusive interval from *+0*𝔽 to 𝔽(2**53 - 1). An **array index** is an | 
|  | 55 | +  integer index _n_ such that CanonicalNumericIndexString(_n_) returns an integral Number in the | 
|  | 56 | +  inclusive interval from *+0*𝔽 to 𝔽(2**32 - 2). | 
| 8 | 57 | ---*/ | 
| 9 | 58 | 
 | 
| 10 |  | -var target = [7,5,3] | 
| 11 |  | -var result = Object.assign(target, [1, 2, 4]); | 
|  | 59 | +var target = [7, 8, 9]; | 
|  | 60 | +var result = Object.assign(target, [1]); | 
|  | 61 | +assert.sameValue(result, target); | 
|  | 62 | +assert.compareArray(result, [1, 8, 9], | 
|  | 63 | +  "elements must be assigned from an array source onto an array target"); | 
|  | 64 | + | 
|  | 65 | +var sparseArraySource = []; | 
|  | 66 | +sparseArraySource[2] = 3; | 
|  | 67 | +result = Object.assign(target, sparseArraySource); | 
|  | 68 | +assert.sameValue(result, target); | 
|  | 69 | +assert.compareArray(result, [1, 8, 3], "holes in a sparse array source must not be copied"); | 
|  | 70 | + | 
|  | 71 | +var shortObjectSource = { 1: 2, length: 2 }; | 
|  | 72 | +shortObjectSource["-0"] = -1; | 
|  | 73 | +shortObjectSource["1.5"] = -2; | 
|  | 74 | +shortObjectSource["4294967295"] = -3; // 2**32 - 1 | 
|  | 75 | +result = Object.assign(target, shortObjectSource); | 
|  | 76 | +assert.sameValue(result, target); | 
|  | 77 | +assert.compareArray(result, [1, 2], | 
|  | 78 | +  "array index properties must be copied from a non-array source"); | 
|  | 79 | +assert.sameValue(result["-0"], -1, | 
|  | 80 | +  "a property with name -0 must be assigned onto an array target"); | 
|  | 81 | +assert.sameValue(result["1.5"], -2, | 
|  | 82 | +  "a property with name 1.5 must be assigned onto an array target"); | 
|  | 83 | +assert.sameValue(result["4294967295"], -3, | 
|  | 84 | +  "a property with name 4294967295 (2**32 - 1) must be assigned onto an array target"); | 
|  | 85 | + | 
|  | 86 | +result = Object.assign(target, { length: 1 }); | 
|  | 87 | +assert.sameValue(result, target); | 
|  | 88 | +assert.compareArray(result, [1], "assigning a short length must shrink an array target"); | 
|  | 89 | + | 
|  | 90 | +result = Object.assign(target, { 2: 0 }); | 
|  | 91 | +assert.sameValue(result, target); | 
|  | 92 | +assert.compareArray(result, [1, undefined, 0], | 
|  | 93 | +  "assigning a high array index must grow an array target"); | 
| 12 | 94 | 
 | 
| 13 |  | -assert.sameValue(result[0], 1, "The value should be {0: 1}."); | 
| 14 |  | -assert.sameValue(result[1], 2, "The value should be {1: 2}."); | 
| 15 |  | -assert.sameValue(result[2], 4, "The value should be {2: 4}."); | 
|  | 95 | +if (typeof Proxy !== 'undefined') { | 
|  | 96 | +  var accordionSource = new Proxy({ length: 0, 1: 9 }, { | 
|  | 97 | +    ownKeys: function() { | 
|  | 98 | +      return ["length", "1"]; | 
|  | 99 | +    } | 
|  | 100 | +  }); | 
|  | 101 | +  result = Object.assign(target, accordionSource); | 
|  | 102 | +  assert.sameValue(result, target); | 
|  | 103 | +  assert.compareArray(result, [undefined, 9], | 
|  | 104 | +    "assigning a short length before a high array index must shrink and then grow an array target"); | 
|  | 105 | +} | 
0 commit comments