From 39cd09f7a8bb20f2e5c5db22cb12ed56d1aa4d21 Mon Sep 17 00:00:00 2001
From: Mike Pennisi <mike@mikepennisi.com>
Date: Wed, 10 Jun 2015 17:53:27 -0400
Subject: [PATCH] Extend coverage for Object.assign

---
 .../Object/assign/OnlyOneArgument.js          |  1 +
 test/built-ins/Object/assign/assign-length.js | 17 ++++++++-
 .../Object/assign/invoked-as-ctor.js          | 16 +++++++++
 test/built-ins/Object/assign/name.js          | 31 ++++++++++++++++
 .../Object/assign/source-get-attr-error.js    | 25 +++++++++++++
 .../Object/assign/source-non-enum.js          | 25 +++++++++++++
 .../assign/source-own-prop-desc-missing.js    | 35 +++++++++++++++++++
 .../Object/assign/source-own-prop-error.js    | 24 +++++++++++++
 .../assign/source-own-prop-keys-error.js      | 26 ++++++++++++++
 .../Object/assign/target-set-not-writable.js  | 25 +++++++++++++
 .../Object/assign/target-set-user-error.js    | 27 ++++++++++++++
 11 files changed, 251 insertions(+), 1 deletion(-)
 create mode 100644 test/built-ins/Object/assign/invoked-as-ctor.js
 create mode 100644 test/built-ins/Object/assign/name.js
 create mode 100644 test/built-ins/Object/assign/source-get-attr-error.js
 create mode 100644 test/built-ins/Object/assign/source-non-enum.js
 create mode 100644 test/built-ins/Object/assign/source-own-prop-desc-missing.js
 create mode 100644 test/built-ins/Object/assign/source-own-prop-error.js
 create mode 100644 test/built-ins/Object/assign/source-own-prop-keys-error.js
 create mode 100644 test/built-ins/Object/assign/target-set-not-writable.js
 create mode 100644 test/built-ins/Object/assign/target-set-user-error.js

diff --git a/test/built-ins/Object/assign/OnlyOneArgument.js b/test/built-ins/Object/assign/OnlyOneArgument.js
index 9131e1146a..1c5f90faec 100644
--- a/test/built-ins/Object/assign/OnlyOneArgument.js
+++ b/test/built-ins/Object/assign/OnlyOneArgument.js
@@ -10,4 +10,5 @@ es6id:  19.1.2.1.3
 var target = "a";
 var result = Object.assign(target);
 
+assert.sameValue(typeof result, "object");
 assert.sameValue(result.valueOf(), "a", "The value should be 'a'.");
diff --git a/test/built-ins/Object/assign/assign-length.js b/test/built-ins/Object/assign/assign-length.js
index b49b0a7149..2509132255 100644
--- a/test/built-ins/Object/assign/assign-length.js
+++ b/test/built-ins/Object/assign/assign-length.js
@@ -4,6 +4,21 @@
 /*---
 description: The length property of the assign method should be 2
 es6id:  19.1.2.1
+info: >
+    The length property of the assign method is 2.
+
+    ES6 Section 17:
+
+    Unless otherwise specified, the length property of a built-in Function
+    object has the attributes { [[Writable]]: false, [[Enumerable]]: false,
+    [[Configurable]]: true }.
+includes: [propertyHelper.js]
 ---*/
 
-assert.sameValue(Object.assign.length, 2, "The length property of the assign method should be 2.");
+assert.sameValue(
+  Object.assign.length, 2, "The length property of the assign method should be 2."
+);
+
+verifyNotEnumerable(Object.assign, 'length');
+verifyNotWritable(Object.assign, 'length');
+verifyConfigurable(Object.assign, 'length');
diff --git a/test/built-ins/Object/assign/invoked-as-ctor.js b/test/built-ins/Object/assign/invoked-as-ctor.js
new file mode 100644
index 0000000000..cc2d0801ab
--- /dev/null
+++ b/test/built-ins/Object/assign/invoked-as-ctor.js
@@ -0,0 +1,16 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+es6id: 19.1.2.1
+description: Invoked as a constructor
+info: >
+    ES6 Section 9.3:
+
+    Built-in function objects that are not identified as constructors do not
+    implement the [[Construct]] internal method unless otherwise specified in
+    the description of a particular function.
+---*/
+
+assert.throws(TypeError, function() {
+  new Object.assign({});
+});
diff --git a/test/built-ins/Object/assign/name.js b/test/built-ins/Object/assign/name.js
new file mode 100644
index 0000000000..8970a427fe
--- /dev/null
+++ b/test/built-ins/Object/assign/name.js
@@ -0,0 +1,31 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+es6id: 19.1.2.1
+description: '`name` property'
+info: >
+    ES6 Section 17:
+
+    Every built-in Function object, including constructors, that is not
+    identified as an anonymous function has a name property whose value is a
+    String. Unless otherwise specified, this value is the name that is given to
+    the function in this specification.
+
+    [...]
+
+    Unless otherwise specified, the name property of a built-in Function
+    object, if it exists, has the attributes { [[Writable]]: false,
+    [[Enumerable]]: false, [[Configurable]]: true }.
+includes: [propertyHelper.js]
+---*/
+
+assert.sameValue(
+  Object.assign.name,
+  'assign',
+  'The value of `Object.assign.name` is `"assign"`'
+);
+
+verifyNotEnumerable(Object.assign, 'name');
+verifyNotWritable(Object.assign, 'name');
+verifyConfigurable(Object.assign, 'name');
+
diff --git a/test/built-ins/Object/assign/source-get-attr-error.js b/test/built-ins/Object/assign/source-get-attr-error.js
new file mode 100644
index 0000000000..a18876bb7c
--- /dev/null
+++ b/test/built-ins/Object/assign/source-get-attr-error.js
@@ -0,0 +1,25 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+es6id: 19.1.2.1
+description: Errors thrown during retrieval of source object attributes
+info: >
+    [...]
+    5. For each element nextSource of sources, in ascending index order,
+    [...]
+    c. Repeat for each element nextKey of keys in List order,
+       [...]
+       iii. if desc is not undefined and desc.[[Enumerable]] is true, then
+            1. Let propValue be Get(from, nextKey).
+            2. ReturnIfAbrupt(propValue).
+---*/
+
+var source = {
+  get attr() {
+    throw new Test262Error();
+  }
+};
+
+assert.throws(Test262Error, function() {
+  Object.assign({}, source);
+});
diff --git a/test/built-ins/Object/assign/source-non-enum.js b/test/built-ins/Object/assign/source-non-enum.js
new file mode 100644
index 0000000000..7ce053be1f
--- /dev/null
+++ b/test/built-ins/Object/assign/source-non-enum.js
@@ -0,0 +1,25 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+es6id: 19.1.2.1
+description: Does not assign non-enumerable source properties
+info: >
+    [...]
+    5. For each element nextSource of sources, in ascending index order,
+       c. Repeat for each element nextKey of keys in List order,
+          i. Let desc be from.[[GetOwnProperty]](nextKey).
+          ii. ReturnIfAbrupt(desc).
+          iii. if desc is not undefined and desc.[[Enumerable]] is true, then
+---*/
+
+var target = {};
+var source = Object.defineProperty({}, 'attr', {
+  value: 1,
+  enumerable: false
+});
+var result;
+
+result = Object.assign(target, source);
+
+assert.sameValue(Object.hasOwnProperty.call(target, 'attr'), false);
+assert.sameValue(result, target);
diff --git a/test/built-ins/Object/assign/source-own-prop-desc-missing.js b/test/built-ins/Object/assign/source-own-prop-desc-missing.js
new file mode 100644
index 0000000000..1e51c46405
--- /dev/null
+++ b/test/built-ins/Object/assign/source-own-prop-desc-missing.js
@@ -0,0 +1,35 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+es6id: 19.1.2.1
+description: Invoked with a source which does not have a descriptor for an own property
+info: >
+    [...]
+    5. For each element nextSource of sources, in ascending index order,
+       [...]
+       c. Repeat for each element nextKey of keys in List order,
+          i. Let desc be from.[[GetOwnProperty]](nextKey).
+          ii. ReturnIfAbrupt(desc).
+          iii. if desc is not undefined and desc.[[Enumerable]] is true, then
+features: [Proxy]
+---*/
+
+var callCount = 0;
+var target = {};
+var result;
+var source = new Proxy({}, {
+  ownKeys: function() {
+    callCount += 1;
+    return ['missing'];
+  }
+});
+
+result = Object.assign(target, source);
+
+assert.sameValue(callCount, 1, 'Proxy trap was invoked exactly once');
+assert.sameValue(
+  Object.hasOwnProperty.call(target, 'missing'),
+  false,
+  'An own property was not created for a property without a property descriptor'
+);
+assert.sameValue(result, target);
diff --git a/test/built-ins/Object/assign/source-own-prop-error.js b/test/built-ins/Object/assign/source-own-prop-error.js
new file mode 100644
index 0000000000..ad4bef54f0
--- /dev/null
+++ b/test/built-ins/Object/assign/source-own-prop-error.js
@@ -0,0 +1,24 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+es6id: 19.1.2.1
+description: Invoked with a source whose own property descriptor cannot be retrieved
+info: >
+    [...]
+    5. For each element nextSource of sources, in ascending index order,
+       [...]
+       c. Repeat for each element nextKey of keys in List order,
+          i. Let desc be from.[[GetOwnProperty]](nextKey).
+          ii. ReturnIfAbrupt(desc).
+features: [Proxy]
+---*/
+
+var source = new Proxy({ attr: null }, {
+  getOwnPropertyDescriptor: function() {
+    throw new Test262Error();
+  }
+});
+
+assert.throws(Test262Error, function() {
+  Object.assign({}, source);
+});
diff --git a/test/built-ins/Object/assign/source-own-prop-keys-error.js b/test/built-ins/Object/assign/source-own-prop-keys-error.js
new file mode 100644
index 0000000000..88912fa5a2
--- /dev/null
+++ b/test/built-ins/Object/assign/source-own-prop-keys-error.js
@@ -0,0 +1,26 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+es6id: 19.1.2.1
+description: Invoked with a source whose own property keys cannot be retrieved
+info: >
+    [...]
+    5. For each element nextSource of sources, in ascending index order,
+       a. If nextSource is undefined or null, let keys be an empty List.
+       b. Else,
+          i. Let from be ToObject(nextSource).
+          ii. ReturnIfAbrupt(from).
+          iii. Let keys be from.[[OwnPropertyKeys]]().
+          iv. ReturnIfAbrupt(keys).
+features: [Proxy]
+---*/
+
+var source = new Proxy({}, {
+  ownKeys: function() {
+    throw new Test262Error();
+  }
+});
+
+assert.throws(Test262Error, function() {
+  Object.assign({}, source);
+});
diff --git a/test/built-ins/Object/assign/target-set-not-writable.js b/test/built-ins/Object/assign/target-set-not-writable.js
new file mode 100644
index 0000000000..91f1d04362
--- /dev/null
+++ b/test/built-ins/Object/assign/target-set-not-writable.js
@@ -0,0 +1,25 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+es6id: 19.1.2.1
+description: Errors thrown during definition of target object attributes
+info: >
+    [...]
+    5. For each element nextSource of sources, in ascending index order,
+    [...]
+    c. Repeat for each element nextKey of keys in List order,
+       [...]
+       iii. if desc is not undefined and desc.[[Enumerable]] is true, then
+            [...]
+            3. Let status be Set(to, nextKey, propValue, true).
+            4. ReturnIfAbrupt(status).
+---*/
+
+var target = {};
+Object.defineProperty(target, 'attr', {
+  writable: false
+});
+
+assert.throws(TypeError, function() {
+  Object.assign(target, { attr: 1 });
+});
diff --git a/test/built-ins/Object/assign/target-set-user-error.js b/test/built-ins/Object/assign/target-set-user-error.js
new file mode 100644
index 0000000000..1838ccc0ca
--- /dev/null
+++ b/test/built-ins/Object/assign/target-set-user-error.js
@@ -0,0 +1,27 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+es6id: 19.1.2.1
+description: Errors thrown during definition of target object attributes
+info: >
+    [...]
+    5. For each element nextSource of sources, in ascending index order,
+    [...]
+    c. Repeat for each element nextKey of keys in List order,
+       [...]
+       iii. if desc is not undefined and desc.[[Enumerable]] is true, then
+            [...]
+            3. Let status be Set(to, nextKey, propValue, true).
+            4. ReturnIfAbrupt(status).
+---*/
+
+var target = {};
+Object.defineProperty(target, 'attr', {
+  set: function(_) {
+    throw new Test262Error();
+  }
+});
+
+assert.throws(Test262Error, function() {
+  Object.assign(target, { attr: 1 });
+});
-- 
GitLab