Mozilla Home
Privacy
Cookies
Legal
Bugzilla
Browse
Advanced Search
New Bug
Reports
Documentation
Log In
Log In with GitHub
or
Remember me
Browse
Advanced Search
New Bug
Reports
Documentation
Attachment 8462804 Details for
Bug 937855
[patch]
assign_test_edited_plus_mult_test.patch
assign_test_edited_plus_mult_test.patch (text/plain), 15.23 KB, created by
Nathan Braswell [:nathan]
(
hide
)
Description:
assign_test_edited_plus_mult_test.patch
Filename:
MIME Type:
Creator:
Nathan Braswell [:nathan]
Size:
15.23 KB
patch
obsolete
># HG changeset patch ># User Nathan Braswell <miloignis@gmail.com> ># Date 1406319982 25200 ># Fri Jul 25 13:26:22 2014 -0700 ># Node ID f7e2377d20aa7d0a58af718da5a293c52a5a1742 ># Parent da29df1337cb2f7921826d4db49eebda7825fa31 >Bug 937855 - Implement ES6 Object.assign - Test Cases by Andre Bargull updated to use ownKeys, plus a simple additional test to make sure that using multiple sources works. > >diff --git a/js/src/tests/ecma_6/Object/assign.js b/js/src/tests/ecma_6/Object/assign.js >new file mode 100644 >--- /dev/null >+++ b/js/src/tests/ecma_6/Object/assign.js >@@ -0,0 +1,372 @@ >+/* This Source Code Form is subject to the terms of the Mozilla Public >+ * License, v. 2.0. If a copy of the MPL was not distributed with this >+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ >+ >+function ToObject(o) { >+ if (o == null) throw new TypeError(); >+ return Object(o); >+} >+ >+/* 19.1.2.1 Object.assign ( target, ...sources ) */ >+assertBuiltinFunction(Object.assign, "assign", 2); >+// Basic functionality works with multiple sources >+{ >+ var a = {}; >+ var b = { bProp : 7 }; >+ var c = { cProp : 8 }; >+ Object.assign(a, b, c); >+ assertSame(7, a.bProp); >+ assertSame(8, a.cProp); >+} >+ >+// Calls ToObject() for target and source >+{ >+ assertThrows(() => Object.assign(null, null), TypeError); >+ assertThrows(() => Object.assign(null, {}), TypeError); >+ assertThrows(() => Object.assign({}, null), TypeError); >+ assertInstanceOf(Boolean, Object.assign(true, {})); >+ assertInstanceOf(Number, Object.assign(1, {})); >+ assertInstanceOf(String, Object.assign("string", {})); >+ let o = {}; >+ assertSame(o, Object.assign(o, {})); >+} >+ >+// Invokes [[OwnPropertyKeys]] on ToObject(source) >+{ >+ assertThrows(() => Object.assign(null, new Proxy({}, { >+ getOwnPropertyNames: () => fail("ToObject(target) succeeded") >+ })), TypeError); >+ >+ let ownKeysCalled = false; >+ Object.assign({}, new Proxy({}, { >+ ownKeys: function() { >+ ownKeysCalled = true; >+ return []; >+ } >+ })); >+ var thing = new Proxy({}, { >+ ownKeys: function(target) { >+ ownKeysCalled = true; >+ return []; >+ } >+ }); >+ assertTrue(ownKeysCalled); >+} >+ >+// Ensure correct property traversal >+{ >+ let log = ""; >+ let source = new Proxy({a: 1, b: 2}, { >+ ownKeys: () => ["b", "c", "a"], >+ getOwnPropertyDescriptor: function(t, pk) { >+ log += "#" + pk; >+ return Object.getOwnPropertyDescriptor(t, pk); >+ }, >+ get: function(t, pk, r) { >+ log += "-" + pk; >+ return t[pk]; >+ }, >+ }); >+ Object.assign({}, source); >+ assertSame("#b-b#c#a-a", log); >+} >+ >+// Only [[Enumerable]] properties are assigned to target >+{ >+ let source = Object.defineProperties({}, { >+ a: {value: 1, enumerable: true}, >+ b: {value: 2, enumerable: false}, >+ }); >+ let target = Object.assign({}, source); >+ assertTrue("a" in target); >+ assertFalse("b" in target); >+} >+ >+ >+// Enumerability is decided on-time, not before main loop (1) >+{ >+ let getterCalled = false; >+ // FIXME: sourceTarget should not be necessary, Proxy bug in SpiderMonkey >+ let sourceTarget; >+ let source = new Proxy(sourceTarget = { >+ get a() { getterCalled = true }, >+ get b() { Object.defineProperty(sourceTarget /* this */, "a", {enumerable: false}) }, >+ }, { >+ ownKeys: () => ["b", "a"] >+ }); >+ Object.assign({}, source); >+ assertFalse(getterCalled); >+} >+ >+// Enumerability is decided on-time, not before main loop (2) >+{ >+ let getterCalled = false; >+ // FIXME: sourceTarget should not be necessary, Proxy bug in SpiderMonkey >+ let sourceTarget; >+ let source = new Proxy(sourceTarget = { >+ get a() { getterCalled = true }, >+ get b() { Object.defineProperty(sourceTarget /* this */, "a", {enumerable: true}) }, >+ }, { >+ ownKeys: () => ["b", "a"] >+ }); >+ Object.defineProperty(sourceTarget /* source */, "a", {enumerable: false}); >+ Object.assign({}, source); >+ assertTrue(getterCalled); >+} >+ >+// Properties are retrieved through Get() >+{ >+ let getterCalled = false; >+ Object.assign({}, {get a() { getterCalled = true }}); >+ assertTrue(getterCalled); >+} >+ >+// Properties are retrieved through Get() >+// Properties are assigned through Put() >+{ >+ let setterCalled = false; >+ Object.assign({set a(v) { setterCalled = v }}, {a: true}); >+ assertTrue(setterCalled); >+} >+ >+// Properties are retrieved through Get() >+// Properties are assigned through Put(): Existing property attributes are not altered >+{ >+ let source = {a: 1, b: 2, c: 3}; >+ let target = {a: 0, b: 0, c: 0}; >+ Object.defineProperty(target, "a", {enumerable: false}); >+ Object.defineProperty(target, "b", {configurable: false}); >+ Object.defineProperty(target, "c", {enumerable: false, configurable: false}); >+ Object.assign(target, source); >+ assertDataProperty(target, "a", {value: 1, writable: true, enumerable: false, configurable: true}); >+ assertDataProperty(target, "b", {value: 2, writable: true, enumerable: true, configurable: false}); >+ assertDataProperty(target, "c", {value: 3, writable: true, enumerable: false, configurable: false}); >+} >+ >+// Properties are retrieved through Get() >+// Properties are assigned through Put(): Throws TypeError if non-writable >+{ >+ let source = {a: 1}; >+ let target = {a: 0}; >+ Object.defineProperty(target, "a", {writable: false}); >+ assertThrows(() => Object.assign(target, source), TypeError); >+ assertDataProperty(target, "a", {value: 0, writable: false, enumerable: true, configurable: true}); >+} >+ >+// Properties are retrieved through Get() >+// Put() creates standard properties; Property attributes from source are ignored >+{ >+ let source = {a: 1, b: 2, c: 3, get d() { return 4 }}; >+ Object.defineProperty(source, "b", {writable: false}); >+ Object.defineProperty(source, "c", {configurable: false}); >+ let target = Object.assign({}, source); >+ assertDataProperty(target, "a", {value: 1, writable: true, enumerable: true, configurable: true}); >+ assertDataProperty(target, "b", {value: 2, writable: true, enumerable: true, configurable: true}); >+ assertDataProperty(target, "c", {value: 3, writable: true, enumerable: true, configurable: true}); >+ assertDataProperty(target, "d", {value: 4, writable: true, enumerable: true, configurable: true}); >+} >+ >+// Properties created during traversal are not copied >+{ >+ let source = {get a() { this.b = 2 }}; >+ let target = Object.assign({}, source); >+ assertTrue("a" in target); >+ assertFalse("b" in target); >+} >+ >+// Properties created during traversal are copied - Proxy edition >+// FIXME: requires [[OwnKeys]] to be an Iterable >+if (false) { >+ let hasB = false; >+ let source = new Proxy({ >+ get a() { hasB = "b" in this }, >+ }, { >+ getOwnPropertyNames: () => function*() { >+ yield "a"; >+ source.b = 2; >+ yield "b"; >+ }() >+ }); >+ let target = Object.assign({}, source); >+ assertTrue("a" in target); >+ assertTrue("b" in target); >+ assertFalse(hasB); >+} >+ >+// Properties deleted during traversal are not copied >+{ >+ let source = new Proxy({ >+ get a() { delete this.b }, >+ b: 2, >+ }, { >+ getOwnPropertyNames: () => ["a", "b"] >+ }); >+ let target = Object.assign({}, source); >+ assertTrue("a" in target); >+ assertFalse("b" in target); >+} >+ >+// Properties first deleted and then recreated during traversal are copied (1) >+{ >+ let source = new Proxy({ >+ get a() { delete this.c }, >+ get b() { this.c = 4 }, >+ c: 3, >+ }, { >+ getOwnPropertyNames: () => ["a", "b", "c"] >+ }); >+ let target = Object.assign({}, source); >+ assertTrue("a" in target); >+ assertTrue("b" in target); >+ assertTrue("c" in target); >+ assertDataProperty(target, "c", {value: 4, writable: true, enumerable: true, configurable: true}); >+} >+ >+// Properties first deleted and then recreated during traversal are copied (2) >+{ >+ let source = new Proxy({ >+ get a() { delete this.c }, >+ get b() { this.c = 4 }, >+ c: 3, >+ }, { >+ ownKeys: () => ["a", "c", "b"] >+ }); >+ let target = Object.assign({}, source); >+ assertTrue("a" in target); >+ assertTrue("b" in target); >+ assertFalse("c" in target); >+} >+ >+// String and Symbol valued properties are copied >+{ >+ let keyA = "str-prop"; >+ let source = {"str-prop": 1}; >+ let target = Object.assign({}, source); >+ assertDataProperty(target, keyA, {value: 1, writable: true, enumerable: true, configurable: true}); >+} >+ >+// Intermediate exceptions do not stop property traversal, first exception is reported (1) >+{ >+ let ErrorA = function ErrorA() {}; >+ let ErrorB = function ErrorB() {}; >+ let log = ""; >+ let source = new Proxy({}, { >+ getOwnPropertyDescriptor: function(t, pk) { >+ log += pk; >+ throw new (pk === "a" ? ErrorA : ErrorB); >+ }, >+ ownKeys: () => ["b", "a"] >+ }); >+ assertThrows(() => Object.assign({}, source), ErrorB); >+ assertSame("ba", log); >+} >+ >+// Properties are retrieved through Get() >+// Intermediate exceptions do not stop property traversal, first exception is reported (2) >+{ >+ let ErrorA = function ErrorA() {}; >+ let ErrorB = function ErrorB() {}; >+ let log = ""; >+ let source = new Proxy({ >+ get a() { log += "a"; throw new ErrorA }, >+ get b() { log += "b"; throw new ErrorB }, >+ }, { >+ ownKeys: () => ["b", "a"] >+ }); >+ assertThrows(() => Object.assign({}, source), ErrorB); >+ assertSame("ba", log); >+} >+ >+// Intermediate exceptions do not stop property traversal, first exception is reported (3) >+{ >+ let ErrorA = function ErrorA() {}; >+ let ErrorB = function ErrorB() {}; >+ let log = ""; >+ let source = new Proxy({a: 1, b: 2}, { >+ ownKeys: () => ["b", "a"] >+ }); >+ let target = { >+ set a(v) { log += "a"; throw new ErrorA }, >+ set b(v) { log += "b"; throw new ErrorB }, >+ }; >+ assertThrows(() => Object.assign(target, source), ErrorB); >+ assertSame("ba", log); >+} >+ >+// Intermediate exceptions do not stop property traversal, first exception is reported (4) >+{ >+ let ErrorGetOwnProperty = function ErrorGetOwnProperty() {}; >+ let ErrorGet = function ErrorGet() {}; >+ let ErrorSet = function ErrorSet() {}; >+ let source = new Proxy({ >+ get a() { throw new ErrorGet } >+ }, { >+ getOwnPropertyDescriptor: function(t, pk) { >+ throw new ErrorGetOwnProperty; >+ } >+ }); >+ let target = { >+ set a(v) { throw new ErrorSet } >+ }; >+ assertThrows(() => Object.assign({}, source), ErrorGetOwnProperty); >+} >+ >+// Exceptions in Iterator directly stop property traversal (1) >+// FIXME: requires [[OwnKeys]] to be an Iterable >+if (false) { >+ let ErrorNext = function ErrorNext() {}; >+ let getterCalled = false; >+ let source = new Proxy({ >+ get a() { getterCalled = true } >+ }, { >+ getOwnPropertyNames: () => ({next: function() { throw new ErrorNext }}) >+ }); >+ assertThrows(() => Object.assign({}, source), ErrorNext); >+ assertFalse(getterCalled); >+} >+ >+// Exceptions in Iterator directly stop property traversal (2) >+// FIXME: requires [[OwnKeys]] to be an Iterable >+if (false) { >+ let ErrorDone = function ErrorDone() {}; >+ let ErrorValue = function ErrorValue() {}; >+ let getterCalled = false; >+ let source = new Proxy({ >+ get a() { getterCalled = true } >+ }, { >+ getOwnPropertyNames: () => ({ >+ next: function() { >+ return { >+ get done() { throw new ErrorDone }, >+ get value() { throw new ErrorValue }, >+ }; >+ } >+ }) >+ }); >+ assertThrows(() => Object.assign({}, source), ErrorDone); >+ assertFalse(getterCalled); >+} >+ >+// Exceptions in Iterator directly stop property traversal (3) >+// FIXME: requires [[OwnKeys]] to be an Iterable >+if (false) { >+ let ErrorValue = function ErrorValue() {}; >+ let getterCalled = false; >+ let source = new Proxy({ >+ get a() { getterCalled = true } >+ }, { >+ getOwnPropertyNames: () => ({ >+ next: function() { >+ return { >+ get done() { return false }, >+ get value() { throw new ErrorValue }, >+ }; >+ } >+ }) >+ }); >+ assertThrows(() => Object.assign({}, source), ErrorValue); >+ assertFalse(getterCalled); >+} >+ >+if (typeof reportCompare == "function") >+ reportCompare(true, true); >diff --git a/js/src/tests/ecma_6/Object/shell.js b/js/src/tests/ecma_6/Object/shell.js >--- a/js/src/tests/ecma_6/Object/shell.js >+++ b/js/src/tests/ecma_6/Object/shell.js >@@ -0,0 +1,85 @@ >+/* This Source Code Form is subject to the terms of the Mozilla Public >+ * License, v. 2.0. If a copy of the MPL was not distributed with this >+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ >+ >+if (typeof version != 'undefined') >+{ >+ version(185); >+} >+ >+var assertThrows = assertThrowsInstanceOf; >+ >+function fail(message) { >+ throw new Error(message); >+} >+ >+function IsCallable(o) { >+ return typeof o === "function"; >+} >+ >+function IsConstructor(o) { >+ try { >+ new (new Proxy(o, {construct: () => ({})})); >+ return true; >+ } catch(e) { >+ return false; >+ } >+} >+ >+function assertSame(expected, actual) { >+ return assertEq(actual, expected); >+} >+ >+function assertTrue(value) { >+ return assertSame(true, value); >+} >+ >+function assertFalse(value) { >+ return assertSame(false, value); >+} >+ >+function assertNotUndefined(value) { >+ return assertTrue(value !== undefined); >+} >+ >+function assertInstanceOf(constructor, value) { >+ return assertTrue(value instanceof constructor); >+} >+ >+function assertCallable(o) { >+ return assertTrue(IsCallable(o)); >+} >+ >+function assertNotConstructor(o) { >+ return assertFalse(IsConstructor(o)); >+} >+ >+function assertDataProperty(object, propertyKey, {value:value, writable:writable, enumerable:enumerable, configurable:configurable}) { >+ var desc = Object.getOwnPropertyDescriptor(object, propertyKey); >+ assertNotUndefined(desc); >+ assertTrue('value' in desc); >+ assertSame(value, desc.value); >+ assertSame(writable, desc.writable); >+ assertSame(enumerable, desc.enumerable); >+ assertSame(configurable, desc.configurable); >+} >+ >+function assertAccessorProperty(object, propertyKey, {get:get, set:set, enumerable:enumerable, configurable:configurable}) { >+ var desc = Object.getOwnPropertyDescriptor(object, propertyKey); >+ assertNotUndefined(desc); >+ assertFalse('value' in desc); >+ assertSame(get, desc.get); >+ assertSame(set, desc.set); >+ assertSame(enumerable, desc.enumerable); >+ assertSame(configurable, desc.configurable); >+} >+ >+function assertBuiltinFunction(fun, name, arity) { >+ assertSame("function", typeof fun); >+ assertCallable(fun); >+ // FIXME: Proxy should only have [[Construct]] if target has [[Construct]] (bug 929467) >+ // assertNotConstructor(fun); >+ assertSame(Function.prototype, Object.getPrototypeOf(fun)); >+ assertDataProperty(fun, "length", {value: arity, writable: false, enumerable: false, configurable: false}); >+ assertDataProperty(fun, "name", {value: name, writable: false, enumerable: false, configurable: false}); >+}
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
Flags:
Waldo
: review-
Actions:
View
|
Diff
|
Review
Attachments on
bug 937855
:
8341713
|
8341733
|
8343759
|
8455725
|
8456475
|
8462804
|
8462807
|
8468908
|
8470375