From 9a67b0c3447e825e15de2bff2b412af7c92c5dbf Mon Sep 17 00:00:00 2001 From: jmagaram Date: Mon, 20 Mar 2023 00:11:29 -0700 Subject: [PATCH 1/2] Object.assign documentation and tests --- src/Core__Object.res | 22 ++++++++++-- test/ObjectTests.mjs | 79 ++++++++++++++++++++++++++++++++++++++++++++ test/ObjectTests.res | 24 ++++++++++++++ test/TestSuite.mjs | 10 ++++-- test/TestSuite.res | 1 + 5 files changed, 131 insertions(+), 5 deletions(-) create mode 100644 test/ObjectTests.mjs create mode 100644 test/ObjectTests.res diff --git a/src/Core__Object.res b/src/Core__Object.res index e2e14c50..5b4a20b5 100644 --- a/src/Core__Object.res +++ b/src/Core__Object.res @@ -7,8 +7,26 @@ @val external createWithNull: (@as(json`null`) _, unit) => {..} = "Object.create" @val external createWithNullAndProperties: (@as(json`null`) _, {..}) => {..} = "Object.create" -@val external assign: ({..}, {..}) => {..} = "Object.assign" -@variadic @val external assignMany: ({..}, array<{..}>) => {..} = "Object.assign" +/** +`assign(target, source)` copies enumerable own properties from the source to the target, overwriting properties with the same name. It returns the modified target object. A deep clone is not created; properties are copied by reference. + +**Note:** ReScript provides [first-class support for immutable objects](https://rescript-lang.org/docs/manual/latest/object), including spreading one object into another. This is often more convenient than using `assign`. + +## Examples + +```rescript +Object.assign({"a": 1}, {"a": 2}) // {"a": 2} +Object.assign({"a": 1, "b": 2}, {"a": 0}) // {"a": 0, "b": 2} +Object.assign({"a": 1}, {"a": null}) // {"a": null} +``` +## Specifications +- [ECMAScript Language Specification](https://tc39.es/ecma262/multipage/fundamental-objects.html#sec-object.assign) +- [Object.assign on MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign) +*/ +@val +external assign: ({..}, {..}) => {..} = "Object.assign" +@variadic @val +external assignMany: ({..}, array<{..}>) => {..} = "Object.assign" @val external copy: (@as(json`{}`) _, {..}) => {..} = "Object.assign" @get_index external get: ({..}, string) => option<'a> = "" diff --git a/test/ObjectTests.mjs b/test/ObjectTests.mjs new file mode 100644 index 00000000..a9d8efa3 --- /dev/null +++ b/test/ObjectTests.mjs @@ -0,0 +1,79 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE + +import * as Test from "./Test.mjs"; +import * as Caml_obj from "rescript/lib/es6/caml_obj.js"; + +var eq = Caml_obj.equal; + +Test.run([ + [ + "ObjectTests.res", + 8, + 13, + 50 + ], + "assign copies from source to target" + ], Object.assign({ + a: 1, + b: 2 + }, { + b: 3, + c: 0 + }), eq, { + a: 1, + b: 3, + c: 0 + }); + +function assignOverwritesTarget(title, source) { + var sourceObj = { + a: source + }; + Test.run([ + [ + "ObjectTests.res", + 16, + 22, + 39 + ], + "assign " + title + "" + ], Object.assign({ + a: 1 + }, sourceObj), eq, sourceObj); + Test.run([ + [ + "ObjectTests.res", + 17, + 22, + 39 + ], + "assign " + title + "" + ], Object.assign({ + a: undefined + }, sourceObj), eq, sourceObj); + Test.run([ + [ + "ObjectTests.res", + 18, + 22, + 39 + ], + "assign " + title + "" + ], Object.assign({ + a: null + }, sourceObj), eq, sourceObj); +} + +assignOverwritesTarget("when source is undefined", undefined); + +assignOverwritesTarget("when source is null", null); + +assignOverwritesTarget("when source is a number", 1); + +assignOverwritesTarget("when source is a string", "abc"); + +export { + eq , + assignOverwritesTarget , +} +/* Not a pure module */ diff --git a/test/ObjectTests.res b/test/ObjectTests.res new file mode 100644 index 00000000..0b94a371 --- /dev/null +++ b/test/ObjectTests.res @@ -0,0 +1,24 @@ +open RescriptCore + +let eq = (a, b) => a == b + +// ====== assign ====== + +Test.run( + __POS_OF__("assign copies from source to target"), + Object.assign({"a": 1, "b": 2}, {"b": 3, "c": 0}), + eq, + {"a": 1, "b": 3, "c": 0}, +) + +let assignOverwritesTarget = (~title, ~source) => { + let sourceObj = {"a": source} + Test.run(__POS_OF__(`assign ${title}`), Object.assign({"a": 1}, sourceObj), eq, sourceObj) + Test.run(__POS_OF__(`assign ${title}`), Object.assign({"a": undefined}, sourceObj), eq, sourceObj) + Test.run(__POS_OF__(`assign ${title}`), Object.assign({"a": null}, sourceObj), eq, sourceObj) +} + +assignOverwritesTarget(~title="when source is undefined", ~source=undefined) +assignOverwritesTarget(~title="when source is null", ~source=null) +assignOverwritesTarget(~title="when source is a number", ~source=1) +assignOverwritesTarget(~title="when source is a string", ~source="abc") diff --git a/test/TestSuite.mjs b/test/TestSuite.mjs index c968bd8f..6f3c5c94 100644 --- a/test/TestSuite.mjs +++ b/test/TestSuite.mjs @@ -4,6 +4,7 @@ import * as IntTests from "./IntTests.mjs"; import * as TestTests from "./TestTests.mjs"; import * as ArrayTests from "./ArrayTests.mjs"; import * as ErrorTests from "./ErrorTests.mjs"; +import * as ObjectTests from "./ObjectTests.mjs"; import * as PromiseTest from "./PromiseTest.mjs"; var bign = TestTests.bign; @@ -26,10 +27,12 @@ var Concurrently = PromiseTest.Concurrently; var panicTest = ErrorTests.panicTest; -var eq = IntTests.eq; - var $$catch = IntTests.$$catch; +var eq = ObjectTests.eq; + +var assignOverwritesTarget = ObjectTests.assignOverwritesTarget; + export { bign , TestError , @@ -41,7 +44,8 @@ export { Catching , Concurrently , panicTest , - eq , $$catch , + eq , + assignOverwritesTarget , } /* IntTests Not a pure module */ diff --git a/test/TestSuite.res b/test/TestSuite.res index 6277bf57..ca2a63ca 100644 --- a/test/TestSuite.res +++ b/test/TestSuite.res @@ -3,3 +3,4 @@ include PromiseTest include ErrorTests include ArrayTests include IntTests +include ObjectTests From a251145caa31678c976796a0d60cacbe753d807a Mon Sep 17 00:00:00 2001 From: jmagaram Date: Tue, 21 Mar 2023 10:35:50 -0700 Subject: [PATCH 2/2] remove Specifications section. docs for assignMany but no examples. --- src/Core__Object.res | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/Core__Object.res b/src/Core__Object.res index 5b4a20b5..432927ea 100644 --- a/src/Core__Object.res +++ b/src/Core__Object.res @@ -12,6 +12,8 @@ **Note:** ReScript provides [first-class support for immutable objects](https://rescript-lang.org/docs/manual/latest/object), including spreading one object into another. This is often more convenient than using `assign`. +See [Object.assign on MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign) or [ECMAScript Language Specification](https://tc39.es/ecma262/multipage/fundamental-objects.html#sec-object.assign). + ## Examples ```rescript @@ -19,13 +21,18 @@ Object.assign({"a": 1}, {"a": 2}) // {"a": 2} Object.assign({"a": 1, "b": 2}, {"a": 0}) // {"a": 0, "b": 2} Object.assign({"a": 1}, {"a": null}) // {"a": null} ``` -## Specifications -- [ECMAScript Language Specification](https://tc39.es/ecma262/multipage/fundamental-objects.html#sec-object.assign) -- [Object.assign on MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign) */ @val external assign: ({..}, {..}) => {..} = "Object.assign" -@variadic @val +@variadic +@val +/** +`assignMany(target, sources)` copies enumerable own properties from each source to the target, overwriting properties with the same name. Later sources' properties overwrite earlier ones. It returns the modified target object. A deep clone is not created; properties are copied by reference. + +**Note:** ReScript provides [first-class support for immutable objects](https://rescript-lang.org/docs/manual/latest/object), including spreading one object into another. This is often more convenient than using `assign` or `assignMany`. + +See [Object.assign on MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign) or [ECMAScript Language Specification](https://tc39.es/ecma262/multipage/fundamental-objects.html#sec-object.assign). +*/ external assignMany: ({..}, array<{..}>) => {..} = "Object.assign" @val external copy: (@as(json`{}`) _, {..}) => {..} = "Object.assign"