Initial set for Object Spread feature (#890)

This commit is contained in:
Caio Lima 2017-03-13 14:21:26 +00:00 committed by Leo Balter
parent 471bde9162
commit 16e66ece0c
27 changed files with 816 additions and 0 deletions

View File

@ -0,0 +1,23 @@
// Copyright (C) 2017 Caio Lima. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
desc: Object Spread operator results in error when there is an getter that throws an exception
template: Error
esid: pending
info: |
Pending Runtime Semantics: PropertyDefinitionEvaluation
PropertyDefinition:...AssignmentExpression
1. Let exprValue be the result of evaluating AssignmentExpression.
2. Let fromValue be GetValue(exprValue).
3. ReturnIfAbrupt(fromValue).
4. Let excludedNames be a new empty List.
5. Return CopyDataProperties(object, fromValue, excludedNames).
---*/
//- error
Test262Error
//- args
{a: 1, ...{ get foo() { throw new Test262Error(); } }}

View File

@ -0,0 +1,23 @@
// Copyright (C) 2017 Caio Lima. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
desc: Object Spread operator results in error when using an unresolvable reference
template: error
esid: pending
info: |
Pending Runtime Semantics: PropertyDefinitionEvaluation
PropertyDefinition:...AssignmentExpression
1. Let exprValue be the result of evaluating AssignmentExpression.
2. Let fromValue be GetValue(exprValue).
3. ReturnIfAbrupt(fromValue).
4. Let excludedNames be a new empty List.
5. Return CopyDataProperties(object, fromValue, excludedNames).
---*/
//- error
ReferenceError
//- args
{a: 0, ...unresolvableReference}

View File

@ -0,0 +1,39 @@
// Copyright (C) 2017 Caio Lima. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
desc: Object Spread operator following other arguments
template: default
esid: pending
includes: [propertyHelper.js]
info: |
Pending Runtime Semantics: PropertyDefinitionEvaluation
PropertyDefinition:...AssignmentExpression
1. Let exprValue be the result of evaluating AssignmentExpression.
2. Let fromValue be GetValue(exprValue).
3. ReturnIfAbrupt(fromValue).
4. Let excludedNames be a new empty List.
5. Return CopyDataProperties(object, fromValue, excludedNames).
---*/
//- args
{a: 1, b: 2, ...{c: 3, d: 4}}
//- params
obj
//- body
assert.sameValue(obj.a, 1);
assert.sameValue(obj.b, 2);
assert.sameValue(obj.c, 3);
assert.sameValue(obj.d, 4);
assert.sameValue(Object.keys(obj).length, 4);
verifyEnumerable(obj, "c");
verifyWritable(obj, "c");
verifyConfigurable(obj, "c");
verifyEnumerable(obj, "d");
verifyWritable(obj, "d");
verifyConfigurable(obj, "d");

View File

@ -0,0 +1,27 @@
// Copyright (C) 2017 Caio Lima. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
desc: Object Spread operator following other arguments with empty object
template: default
esid: pending
info: |
Pending Runtime Semantics: PropertyDefinitionEvaluation
PropertyDefinition:...AssignmentExpression
1. Let exprValue be the result of evaluating AssignmentExpression.
2. Let fromValue be GetValue(exprValue).
3. ReturnIfAbrupt(fromValue).
4. Let excludedNames be a new empty List.
5. Return CopyDataProperties(object, fromValue, excludedNames).
---*/
//- args
{a: 1, b: 2, ...{}}
//- params
obj
//- body
assert.sameValue(obj.a, 1);
assert.sameValue(obj.b, 2);
assert.sameValue(Object.keys(obj).length, 2);

View File

@ -0,0 +1,49 @@
// Copyright (C) 2017 Caio Lima. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
desc: Object Spread operator following other properties
template: default
esid: pending
includes: [propertyHelper.js]
info: |
Pending Runtime Semantics: PropertyDefinitionEvaluation
PropertyDefinition:...AssignmentExpression
1. Let exprValue be the result of evaluating AssignmentExpression.
2. Let fromValue be GetValue(exprValue).
3. ReturnIfAbrupt(fromValue).
4. Let excludedNames be a new empty List.
5. Return CopyDataProperties(object, fromValue, excludedNames).
---*/
//- setup
let o = {c: 3, d: 4};
//- args
{a: 1, b: 2, ...o}
//- params
obj
//- body
assert.sameValue(obj.a, 1);
assert.sameValue(obj.b, 2);
assert.sameValue(obj.c, 3);
assert.sameValue(obj.d, 4);
assert.sameValue(Object.keys(obj).length, 4);
verifyEnumerable(obj, "a");
verifyWritable(obj, "a");
verifyConfigurable(obj, "a");
verifyEnumerable(obj, "b");
verifyWritable(obj, "b");
verifyConfigurable(obj, "b");
verifyEnumerable(obj, "c");
verifyWritable(obj, "c");
verifyConfigurable(obj, "c");
verifyEnumerable(obj, "d");
verifyWritable(obj, "d");
verifyConfigurable(obj, "d");

View File

@ -0,0 +1,30 @@
// Copyright (C) 2017 Caio Lima. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
desc: Object Spread operator following other arguments with null, undefined and empty object
template: default
esid: pending
includes: [compareArray.js]
info: |
Pending Runtime Semantics: PropertyDefinitionEvaluation
PropertyDefinition:...AssignmentExpression
1. Let exprValue be the result of evaluating AssignmentExpression.
2. Let fromValue be GetValue(exprValue).
3. ReturnIfAbrupt(fromValue).
4. Let excludedNames be a new empty List.
5. Return CopyDataProperties(object, fromValue, excludedNames).
---*/
//- args
{a: 1, ...null, b: 2, ...undefined, c: 3, ...{}, ...{...{}}, d: 4}
//- params
obj
//- body
assert.sameValue(obj.a, 1);
assert.sameValue(obj.b, 2);
assert.sameValue(obj.c, 3);
assert.sameValue(obj.d, 4);
assert(compareArray(Object.keys(obj), ["a", "b", "c", "d"]));

View File

@ -0,0 +1,27 @@
// Copyright (C) 2017 Caio Lima. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
desc: Object Spread operator following other arguments with null value
template: default
esid: pending
info: |
Pending Runtime Semantics: PropertyDefinitionEvaluation
PropertyDefinition:...AssignmentExpression
1. Let exprValue be the result of evaluating AssignmentExpression.
2. Let fromValue be GetValue(exprValue).
3. ReturnIfAbrupt(fromValue).
4. Let excludedNames be a new empty List.
5. Return CopyDataProperties(object, fromValue, excludedNames).
---*/
//- args
{a: 1, b: 2, ...null}
//- params
obj
//- body
assert.sameValue(obj.a, 1);
assert.sameValue(obj.b, 2);
assert.sameValue(Object.keys(obj).length, 2);

View File

@ -0,0 +1,27 @@
// Copyright (C) 2017 Caio Lima. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
desc: Object Spread operator following other arguments with undefined
template: default
esid: pending
info: |
Pending Runtime Semantics: PropertyDefinitionEvaluation
PropertyDefinition:...AssignmentExpression
1. Let exprValue be the result of evaluating AssignmentExpression.
2. Let fromValue be GetValue(exprValue).
3. ReturnIfAbrupt(fromValue).
4. Let excludedNames be a new empty List.
5. Return CopyDataProperties(object, fromValue, excludedNames).
---*/
//- args
{a: 1, b: 2, ...undefined}
//- params
obj
//- body
assert.sameValue(obj.a, 1);
assert.sameValue(obj.b, 2);
assert.sameValue(Object.keys(obj).length, 2);

View File

@ -0,0 +1,41 @@
// Copyright (C) 2017 Caio Lima. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
desc: Spread operation with getter results in data property descriptor
template: default
esid: pending
includes: [propertyHelper.js]
info: |
Pending Runtime Semantics: PropertyDefinitionEvaluation
PropertyDefinition:...AssignmentExpression
1. Let exprValue be the result of evaluating AssignmentExpression.
2. Let fromValue be GetValue(exprValue).
3. ReturnIfAbrupt(fromValue).
4. Let excludedNames be a new empty List.
5. Return CopyDataProperties(object, fromValue, excludedNames).
---*/
//- setup
let o = {
get a() {
return 42;
}
};
//- args
{...o, c: 4, d: 5}
//- params
obj
//- body
assert.sameValue(Object.getOwnPropertyDescriptor(obj, "a").value, 42);
assert.sameValue(obj.c, 4);
assert.sameValue(obj.d, 5);
assert.sameValue(Object.keys(obj).length, 3);
verifyEnumerable(obj, "a");
verifyWritable(obj, "a");
verifyConfigurable(obj, "a");

View File

@ -0,0 +1,22 @@
// Copyright (C) 2017 Caio Lima. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
desc: Getter in object literal is not evaluated
template: default
esid: pending
---*/
//- setup
let o = {a: 2, b: 3};
let executedGetter = false;
//- args
{...o, get c() { executedGetter = true; }}
//- params
obj
//- body
assert.sameValue(obj.a, 2);
assert.sameValue(obj.b, 3);
assert.sameValue(executedGetter, false)
assert.sameValue(Object.keys(obj).length, 3);

View File

@ -0,0 +1,36 @@
// Copyright (C) 2017 Caio Lima. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
desc: Getter manipulates outter object before it's spread operation
template: default
esid: pending
info: |
Pending Runtime Semantics: PropertyDefinitionEvaluation
PropertyDefinition:...AssignmentExpression
1. Let exprValue be the result of evaluating AssignmentExpression.
2. Let fromValue be GetValue(exprValue).
3. ReturnIfAbrupt(fromValue).
4. Let excludedNames be a new empty List.
5. Return CopyDataProperties(object, fromValue, excludedNames).
---*/
//- setup
var o = { a: 0, b: 1 };
var cthulhu = { get x() {
delete o.a;
o.b = 42;
o.c = "ni";
}};
//- args
{...cthulhu, ...o}
//- params
obj
//- body
assert.sameValue(obj.hasOwnProperty("a"), false);
assert.sameValue(obj.b, 42);
assert.sameValue(obj.c, "ni");
assert(obj.hasOwnProperty("x"));
assert.sameValue(Object.keys(obj).length, 3);

View File

@ -0,0 +1,36 @@
// Copyright (C) 2017 Caio Lima. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
desc: Multiple Object Spread usage calls getter multiple times
template: default
esid: pending
info: |
Pending Runtime Semantics: PropertyDefinitionEvaluation
PropertyDefinition:...AssignmentExpression
1. Let exprValue be the result of evaluating AssignmentExpression.
2. Let fromValue be GetValue(exprValue).
3. ReturnIfAbrupt(fromValue).
4. Let excludedNames be a new empty List.
5. Return CopyDataProperties(object, fromValue, excludedNames).
---*/
//- setup
let getterCallCount = 0;
let o = {
get a() {
return ++getterCallCount;
}
};
//- args
{...o, c: 4, d: 5, a: 42, ...o}
//- params
obj
//- body
assert.sameValue(obj.a, 2);
assert.sameValue(obj.c, 4);
assert.sameValue(obj.d, 5);
assert.sameValue(Object.keys(obj).length, 3);

View File

@ -0,0 +1,34 @@
// Copyright (C) 2017 Caio Lima. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
desc: Multiple Object Spread operation
template: default
esid: pending
info: |
Pending Runtime Semantics: PropertyDefinitionEvaluation
PropertyDefinition:...AssignmentExpression
1. Let exprValue be the result of evaluating AssignmentExpression.
2. Let fromValue be GetValue(exprValue).
3. ReturnIfAbrupt(fromValue).
4. Let excludedNames be a new empty List.
5. Return CopyDataProperties(object, fromValue, excludedNames).
---*/
//- setup
let o = {a: 2, b: 3};
let o2 = {c: 4, d: 5};
//- args
{...o, ...o2}
//- params
obj
//- body
assert.sameValue(obj.a, 2);
assert.sameValue(obj.b, 3);
assert.sameValue(obj.c, 4);
assert.sameValue(obj.d, 5);
assert.sameValue(Object.keys(obj).length, 4);

25
src/spread/obj-null.case Normal file
View File

@ -0,0 +1,25 @@
// Copyright (C) 2017 Caio Lima. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
desc: Null Object Spread is ignored
template: default
esid: pending
info: |
Pending Runtime Semantics: PropertyDefinitionEvaluation
PropertyDefinition:...AssignmentExpression
1. Let exprValue be the result of evaluating AssignmentExpression.
2. Let fromValue be GetValue(exprValue).
3. ReturnIfAbrupt(fromValue).
4. Let excludedNames be a new empty List.
5. Return CopyDataProperties(object, fromValue, excludedNames).
---*/
//- args
{...null}
//- params
obj
//- body
assert.sameValue(Object.keys(obj).length, 0);

View File

@ -0,0 +1,30 @@
// Copyright (C) 2017 Caio Lima. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
desc: Object Spread overriding immutable properties
template: default
esid: pending
includes: [propertyHelper.js]
---*/
//- setup
let o = {b: 2};
Object.defineProperty(o, "a", {value: 1, enumerable: true, writable: false, configurable: true});
//- args
{...o, a: 3}
//- params
obj
//- body
assert.sameValue(obj.a, 3)
assert.sameValue(obj.b, 2);
verifyEnumerable(obj, "a");
verifyWritable(obj, "a");
verifyConfigurable(obj, "a");
verifyEnumerable(obj, "b");
verifyWritable(obj, "b");
verifyConfigurable(obj, "b");

View File

@ -0,0 +1,32 @@
// Copyright (C) 2017 Caio Lima. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
desc: Object Spread properties overrides previous definitions
template: default
esid: pending
info: |
Pending Runtime Semantics: PropertyDefinitionEvaluation
PropertyDefinition:...AssignmentExpression
1. Let exprValue be the result of evaluating AssignmentExpression.
2. Let fromValue be GetValue(exprValue).
3. ReturnIfAbrupt(fromValue).
4. Let excludedNames be a new empty List.
5. Return CopyDataProperties(object, fromValue, excludedNames).
---*/
//- setup
let o = {a: 2, b: 3};
//- args
{a: 1, b: 7, ...o}
//- params
obj
//- body
assert.sameValue(obj.a, 2);
assert.sameValue(obj.b, 3);
assert.sameValue(Object.keys(obj).length, 2);
assert.sameValue(o.a, 2);
assert.sameValue(o.b, 3);

View File

@ -0,0 +1,19 @@
// Copyright (C) 2017 Caio Lima. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
desc: Setter are not executed when redefined in Object Spread
template: default
esid: pending
---*/
//- setup
let executedSetter = false;
//- args
{set c(v) { executedSetter = true; }, ...{c: 1}}
//- params
obj
//- body
assert.sameValue(obj.c, 1);
assert.sameValue(executedSetter, false);
assert.sameValue(Object.keys(obj).length, 1);

View File

@ -0,0 +1,20 @@
// Copyright (C) 2017 Caio Lima. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
desc: Object Spread doesn't copy non-enumerable properties
template: default
esid: pending
---*/
//- setup
let o = {};
Object.defineProperty(o, "b", {value: 3, enumerable: false});
//- args
{...o}
//- params
obj
//- body
assert.sameValue(obj.hasOwnProperty("b"), false)
assert.sameValue(Object.keys(obj).length, 0);

View File

@ -0,0 +1,33 @@
// Copyright (C) 2017 Caio Lima. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
desc: Spread operation follows [[OwnPropertyKeys]] order
template: default
esid: pending
includes: [compareArray.js]
info: |
Pending Runtime Semantics: PropertyDefinitionEvaluation
PropertyDefinition:...AssignmentExpression
1. Let exprValue be the result of evaluating AssignmentExpression.
2. Let fromValue be GetValue(exprValue).
3. ReturnIfAbrupt(fromValue).
4. Let excludedNames be a new empty List.
5. Return CopyDataProperties(object, fromValue, excludedNames).
---*/
//- setup
var calls = [];
var o = { get z() { calls.push('z') }, get a() { calls.push('a') } };
Object.defineProperty(o, 1, { get: () => { calls.push(1) }, enumerable: true });
Object.defineProperty(o, Symbol('foo'), { get: () => { calls.push("Symbol(foo)") }, enumerable: true });
//- args
{...o}
//- params
obj
//- body
assert(compareArray(calls, [1, 'z', 'a', "Symbol(foo)"]));
assert.sameValue(Object.keys(obj).length, 3);

View File

@ -0,0 +1,34 @@
// Copyright (C) 2017 Caio Lima. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
desc: Spread operation where source object contains Symbol properties
template: default
esid: pending
info: |
Pending Runtime Semantics: PropertyDefinitionEvaluation
PropertyDefinition:...AssignmentExpression
1. Let exprValue be the result of evaluating AssignmentExpression.
2. Let fromValue be GetValue(exprValue).
3. ReturnIfAbrupt(fromValue).
4. Let excludedNames be a new empty List.
5. Return CopyDataProperties(object, fromValue, excludedNames).
---*/
//- setup
let symbol = Symbol('foo');
let o = {};
o[symbol] = 1;
//- args
{...o, c: 4, d: 5}
//- params
obj
//- body
assert.sameValue(obj[symbol], 1);
assert.sameValue(obj.c, 4);
assert.sameValue(obj.d, 5);
assert.sameValue(Object.keys(obj).length, 2);

View File

@ -0,0 +1,25 @@
// Copyright (C) 2017 Caio Lima. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
desc: Undefined Object Spread is ignored
template: default
esid: pending
info: |
Pending Runtime Semantics: PropertyDefinitionEvaluation
PropertyDefinition:...AssignmentExpression
1. Let exprValue be the result of evaluating AssignmentExpression.
2. Let fromValue be GetValue(exprValue).
3. ReturnIfAbrupt(fromValue).
4. Let excludedNames be a new empty List.
5. Return CopyDataProperties(object, fromValue, excludedNames).
---*/
//- args
{...undefined}
//- params
obj
//- body
assert.sameValue(Object.keys(obj).length, 0);

View File

@ -0,0 +1,38 @@
// Copyright (C) 2017 Caio Lima. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
desc: Object Spread properties being overriden
template: default
esid: pending
info: |
Pending Runtime Semantics: PropertyDefinitionEvaluation
PropertyDefinition:...AssignmentExpression
1. Let exprValue be the result of evaluating AssignmentExpression.
2. Let fromValue be GetValue(exprValue).
3. ReturnIfAbrupt(fromValue).
4. Let excludedNames be a new empty List.
5. Return CopyDataProperties(object, fromValue, excludedNames).
---*/
//- setup
let o = {a: 2, b: 3, c: 4, e: undefined, f: null, g: false};
//- args
{...o, a: 1, b: 7, d: 5, h: -0, i: Symbol("foo"), j: o}
//- params
obj
//- body
assert.sameValue(obj.a, 1);
assert.sameValue(obj.b, 7);
assert.sameValue(obj.c, 4);
assert.sameValue(obj.d, 5);
assert(obj.hasOwnProperty("e"));
assert.sameValue(obj.f, null);
assert.sameValue(obj.g, false);
assert.sameValue(obj.h, -0);
assert.sameValue(obj.i.toString(), "Symbol(foo)");
assert(Object.is(obj.j, o));
assert.sameValue(Object.keys(obj).length, 10);

View File

@ -0,0 +1,23 @@
// Copyright (C) 2017 Caio Lima. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
desc: Object Spread operator results in error when there is an getter that throws an exception
template: error
esid: pending
info: |
Pending Runtime Semantics: PropertyDefinitionEvaluation
PropertyDefinition:...AssignmentExpression
1. Let exprValue be the result of evaluating AssignmentExpression.
2. Let fromValue be GetValue(exprValue).
3. ReturnIfAbrupt(fromValue).
4. Let excludedNames be a new empty List.
5. Return CopyDataProperties(object, fromValue, excludedNames).
---*/
//- error
Test262Error
//- args
{...{ get foo() { throw new Test262Error(); } }}

View File

@ -0,0 +1,23 @@
// Copyright (C) 2017 Caio Lima. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
desc: Object Spread operator results in error when using an unresolvable reference
template: error
esid: pending
info: |
Pending Runtime Semantics: PropertyDefinitionEvaluation
PropertyDefinition:...AssignmentExpression
1. Let exprValue be the result of evaluating AssignmentExpression.
2. Let fromValue be GetValue(exprValue).
3. ReturnIfAbrupt(fromValue).
4. Let excludedNames be a new empty List.
5. Return CopyDataProperties(object, fromValue, excludedNames).
---*/
//- error
ReferenceError
//- args
{...unresolvableReference}

View File

@ -0,0 +1,36 @@
// Copyright (C) 2017 Caio Lima. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
desc: Object Spread operator without other arguments
template: default
esid: pending
includes: [propertyHelper.js]
info: |
Pending Runtime Semantics: PropertyDefinitionEvaluation
PropertyDefinition:...AssignmentExpression
1. Let exprValue be the result of evaluating AssignmentExpression.
2. Let fromValue be GetValue(exprValue).
3. ReturnIfAbrupt(fromValue).
4. Let excludedNames be a new empty List.
5. Return CopyDataProperties(object, fromValue, excludedNames).
---*/
//- args
{...{c: 3, d: 4}}
//- params
obj
//- body
assert.sameValue(obj.c, 3);
assert.sameValue(obj.d, 4);
assert.sameValue(Object.keys(obj).length, 2);
verifyEnumerable(obj, "c");
verifyWritable(obj, "c");
verifyConfigurable(obj, "c");
verifyEnumerable(obj, "d");
verifyWritable(obj, "d");
verifyConfigurable(obj, "d");

View File

@ -0,0 +1,25 @@
// Copyright (C) 2017 Caio Lima. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
desc: Object Spread operator on a single empty object
template: default
esid: pending
info: |
Pending Runtime Semantics: PropertyDefinitionEvaluation
PropertyDefinition:...AssignmentExpression
1. Let exprValue be the result of evaluating AssignmentExpression.
2. Let fromValue be GetValue(exprValue).
3. ReturnIfAbrupt(fromValue).
4. Let excludedNames be a new empty List.
5. Return CopyDataProperties(object, fromValue, excludedNames).
---*/
//- args
{...{}}
//- params
obj
//- body
assert.sameValue(Object.keys(obj).length, 0);

View File

@ -0,0 +1,39 @@
// Copyright (C) 2017 Caio Lima. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
desc: Object Spread operator without other arguments
template: default
esid: pending
includes: [propertyHelper.js]
info: |
Pending Runtime Semantics: PropertyDefinitionEvaluation
PropertyDefinition:...AssignmentExpression
1. Let exprValue be the result of evaluating AssignmentExpression.
2. Let fromValue be GetValue(exprValue).
3. ReturnIfAbrupt(fromValue).
4. Let excludedNames be a new empty List.
5. Return CopyDataProperties(object, fromValue, excludedNames).
---*/
//- setup
let o = {c: 3, d: 4};
//- args
{...o}
//- params
obj
//- body
assert.sameValue(obj.c, 3);
assert.sameValue(obj.d, 4);
assert.sameValue(Object.keys(obj).length, 2);
verifyEnumerable(obj, "c");
verifyWritable(obj, "c");
verifyConfigurable(obj, "c");
verifyEnumerable(obj, "d");
verifyWritable(obj, "d");
verifyConfigurable(obj, "d");