diff --git a/src/Core__Object.res b/src/Core__Object.res index e2e14c50..a30a3acd 100644 --- a/src/Core__Object.res +++ b/src/Core__Object.res @@ -1,6 +1,33 @@ @obj external empty: unit => {..} = "" -@val external is: ('a, 'b) => bool = "Object.is" +/** +`is` determines if two objects are identical in all contexts. Objects, arrays, records, and other non-primitives are only identical if they reference the **exact** same object in memory. Primitives like ints, floats, and strings are identical if they have the same value. `+0` and `-0` are distinct. NaN is equal to itself. See [Object.is on MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is) + +In most scenarios use `==` or `===` or the custom `equals` function (if provided) for the type. + +## Examples + +```rescript +Object.is(25, 13) // false +Object.is("abc", "abc") // true +Object.is(undefined, undefined) // true +Object.is(undefined, null) // false +Object.is(-0.0, 0.0) // false +Object.is(list{1, 2}, list{1, 2}) // false + +Object.is([1, 2, 3], [1, 2, 3]) // false +[1, 2, 3] == [1, 2, 3] // true +[1, 2, 3] === [1, 2, 3] // false + +let fruit = {"name": "Apple" } +Object.is(fruit, fruit) // true +Object.is(fruit, {"name": "Apple" }) // false +fruit == {"name": "Apple" } // true +fruit === {"name": "Apple" } // false +``` +*/ +@val +external is: ('a, 'a) => bool = "Object.is" @val external create: {..} => {..} = "Object.create" @val external createWithProperties: ({..}, {..}) => {..} = "Object.create" diff --git a/test/ObjectTests.mjs b/test/ObjectTests.mjs new file mode 100644 index 00000000..d9145984 --- /dev/null +++ b/test/ObjectTests.mjs @@ -0,0 +1,407 @@ +// 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", + 9, + 20, + 30 + ], + "is: ints" + ], Object.is(25, 25), eq, true); + +Test.run([ + [ + "ObjectTests.res", + 11, + 20, + 33 + ], + "is: strings" + ], Object.is("abc", "abc"), eq, true); + +Test.run([ + [ + "ObjectTests.res", + 12, + 20, + 33 + ], + "is: strings" + ], Object.is("abc", "ABC"), eq, false); + +Test.run([ + [ + "ObjectTests.res", + 14, + 20, + 44 + ], + "is: null and undefined" + ], Object.is(null, undefined), eq, false); + +Test.run([ + [ + "ObjectTests.res", + 15, + 20, + 44 + ], + "is: null and undefined" + ], Object.is(undefined, undefined), eq, true); + +Test.run([ + [ + "ObjectTests.res", + 16, + 20, + 44 + ], + "is: null and undefined" + ], Object.is(null, null), eq, true); + +var nums = [ + 1, + 2, + 3 +]; + +Test.run([ + [ + "ObjectTests.res", + 21, + 20, + 32 + ], + "is: arrays" + ], Object.is([ + 1, + 2, + 3 + ], [ + 1, + 2, + 3 + ]), eq, false); + +Test.run([ + [ + "ObjectTests.res", + 22, + 20, + 32 + ], + "is: arrays" + ], Object.is(nums, nums), eq, true); + +Test.run([ + [ + "ObjectTests.res", + 23, + 20, + 32 + ], + "is: arrays" + ], Caml_obj.equal([ + 1, + 2, + 3 + ], [ + 1, + 2, + 3 + ]), eq, true); + +Test.run([ + [ + "ObjectTests.res", + 24, + 20, + 32 + ], + "is: arrays" + ], [ + 1, + 2, + 3 + ] === [ + 1, + 2, + 3 + ], eq, false); + +Test.run([ + [ + "ObjectTests.res", + 26, + 20, + 30 + ], + "is: list" + ], Object.is({ + hd: 1, + tl: { + hd: 2, + tl: { + hd: 3, + tl: /* [] */0 + } + } + }, { + hd: 1, + tl: { + hd: 2, + tl: { + hd: 3, + tl: /* [] */0 + } + } + }), eq, false); + +Test.run([ + [ + "ObjectTests.res", + 27, + 20, + 30 + ], + "is: list" + ], Caml_obj.equal({ + hd: 1, + tl: { + hd: 2, + tl: { + hd: 3, + tl: /* [] */0 + } + } + }, { + hd: 1, + tl: { + hd: 2, + tl: { + hd: 3, + tl: /* [] */0 + } + } + }), eq, true); + +Test.run([ + [ + "ObjectTests.res", + 28, + 20, + 30 + ], + "is: list" + ], ({ + hd: 1, + tl: { + hd: 2, + tl: { + hd: 3, + tl: /* [] */0 + } + } + }) === ({ + hd: 1, + tl: { + hd: 2, + tl: { + hd: 3, + tl: /* [] */0 + } + } + }), eq, false); + +var d = new Date(2000, 1); + +Test.run([ + [ + "ObjectTests.res", + 32, + 13, + 23 + ], + "is: date" + ], Object.is(new Date(2000, 1), new Date(2000, 1)), eq, false); + +Test.run([ + [ + "ObjectTests.res", + 37, + 20, + 30 + ], + "is: date" + ], Object.is(d, d), eq, true); + +var x = { + a: 1 +}; + +Test.run([ + [ + "ObjectTests.res", + 40, + 20, + 33 + ], + "is: objects" + ], Object.is(x, x), eq, true); + +Test.run([ + [ + "ObjectTests.res", + 41, + 20, + 33 + ], + "is: objects" + ], Object.is({ + a: 1 + }, { + a: 1 + }), eq, false); + +Test.run([ + [ + "ObjectTests.res", + 42, + 20, + 33 + ], + "is: objects" + ], Object.is({}, {}), eq, false); + +Test.run([ + [ + "ObjectTests.res", + 43, + 20, + 45 + ], + "is: === and == operator" + ], x === x, eq, true); + +Test.run([ + [ + "ObjectTests.res", + 44, + 20, + 45 + ], + "is: === and == operator" + ], Caml_obj.equal(x, x), eq, true); + +Test.run([ + [ + "ObjectTests.res", + 45, + 20, + 45 + ], + "is: === and == operator" + ], Caml_obj.equal({ + a: 1 + }, { + a: 1 + }), eq, true); + +Test.run([ + [ + "ObjectTests.res", + 47, + 20, + 31 + ], + "is: zeros" + ], Object.is(0, 0), eq, true); + +Test.run([ + [ + "ObjectTests.res", + 48, + 20, + 31 + ], + "is: zeros" + ], Object.is(-0.0, -0.0), eq, true); + +Test.run([ + [ + "ObjectTests.res", + 49, + 20, + 31 + ], + "is: zeros" + ], Object.is(0.0, -0.0), eq, false); + +function mkBig(s) { + return BigInt(s); +} + +Test.run([ + [ + "ObjectTests.res", + 52, + 20, + 32 + ], + "is: bigint" + ], Object.is(BigInt("123456789"), BigInt("123456789")), eq, true); + +Test.run([ + [ + "ObjectTests.res", + 53, + 20, + 32 + ], + "is: bigint" + ], Object.is(BigInt("123489"), BigInt("123456789")), eq, false); + +Test.run([ + [ + "ObjectTests.res", + 54, + 20, + 32 + ], + "is: bigint" + ], Object.is(BigInt("000000000"), BigInt("0")), eq, true); + +Test.run([ + [ + "ObjectTests.res", + 55, + 20, + 32 + ], + "is: bigint" + ], Caml_obj.equal(BigInt("123"), BigInt("123")), eq, true); + +Test.run([ + [ + "ObjectTests.res", + 56, + 20, + 32 + ], + "is: bigint" + ], BigInt("123") === BigInt("123"), eq, true); + +export { + eq , + nums , + d , + x , + mkBig , +} +/* Not a pure module */ diff --git a/test/ObjectTests.res b/test/ObjectTests.res new file mode 100644 index 00000000..5c1a4b8d --- /dev/null +++ b/test/ObjectTests.res @@ -0,0 +1,56 @@ +open RescriptCore + +let eq = (a, b) => a == b + +// ===== is ===== + +// Test.run(__POS_OF__("is: different types"), Object.is("abc", false), eq, false) + +Test.run(__POS_OF__("is: ints"), Object.is(25, 25), eq, true) + +Test.run(__POS_OF__("is: strings"), Object.is("abc", "abc"), eq, true) +Test.run(__POS_OF__("is: strings"), Object.is("abc", "ABC"), eq, false) + +Test.run(__POS_OF__("is: null and undefined"), Object.is(null, undefined), eq, false) +Test.run(__POS_OF__("is: null and undefined"), Object.is(undefined, undefined), eq, true) +Test.run(__POS_OF__("is: null and undefined"), Object.is(null, null), eq, true) +// Test.run(__POS_OF__("is: null and undefined"), Object.is(null, None), eq, false) +// Test.run(__POS_OF__("is: undefined and None"), Object.is(undefined, None), eq, true) + +let nums = [1, 2, 3] +Test.run(__POS_OF__("is: arrays"), Object.is([1, 2, 3], [1, 2, 3]), eq, false) +Test.run(__POS_OF__("is: arrays"), Object.is(nums, nums), eq, true) +Test.run(__POS_OF__("is: arrays"), [1, 2, 3] == [1, 2, 3], eq, true) +Test.run(__POS_OF__("is: arrays"), [1, 2, 3] === [1, 2, 3], eq, false) + +Test.run(__POS_OF__("is: list"), Object.is(list{1, 2, 3}, list{1, 2, 3}), eq, false) +Test.run(__POS_OF__("is: list"), list{1, 2, 3} == list{1, 2, 3}, eq, true) +Test.run(__POS_OF__("is: list"), list{1, 2, 3} === list{1, 2, 3}, eq, false) + +let d = Date.makeWithYM(~year=2000, ~month=1) +Test.run( + __POS_OF__("is: date"), + Object.is(Date.makeWithYM(~year=2000, ~month=1), Date.makeWithYM(~year=2000, ~month=1)), + eq, + false, +) +Test.run(__POS_OF__("is: date"), Object.is(d, d), eq, true) + +let x = {"a": 1} +Test.run(__POS_OF__("is: objects"), Object.is(x, x), eq, true) +Test.run(__POS_OF__("is: objects"), Object.is({"a": 1}, {"a": 1}), eq, false) +Test.run(__POS_OF__("is: objects"), Object.is(Object.empty(), Object.empty()), eq, false) // hmm... +Test.run(__POS_OF__("is: === and == operator"), x === x, eq, true) +Test.run(__POS_OF__("is: === and == operator"), x == x, eq, true) +Test.run(__POS_OF__("is: === and == operator"), {"a": 1} == {"a": 1}, eq, true) + +Test.run(__POS_OF__("is: zeros"), Object.is(-0, -0), eq, true) +Test.run(__POS_OF__("is: zeros"), Object.is(-0.0, -0.0), eq, true) +Test.run(__POS_OF__("is: zeros"), Object.is(0.0, -0.0), eq, false) + +let mkBig = s => BigInt.fromString(s) +Test.run(__POS_OF__("is: bigint"), Object.is(mkBig("123456789"), mkBig("123456789")), eq, true) +Test.run(__POS_OF__("is: bigint"), Object.is(mkBig("123489"), mkBig("123456789")), eq, false) +Test.run(__POS_OF__("is: bigint"), Object.is(mkBig("000000000"), mkBig("0")), eq, true) +Test.run(__POS_OF__("is: bigint"), mkBig("123") == mkBig("123"), eq, true) +Test.run(__POS_OF__("is: bigint"), mkBig("123") === mkBig("123"), eq, true) diff --git a/test/TestSuite.mjs b/test/TestSuite.mjs index c968bd8f..f5084781 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,18 @@ var Concurrently = PromiseTest.Concurrently; var panicTest = ErrorTests.panicTest; -var eq = IntTests.eq; - var $$catch = IntTests.$$catch; +var eq = ObjectTests.eq; + +var nums = ObjectTests.nums; + +var d = ObjectTests.d; + +var x = ObjectTests.x; + +var mkBig = ObjectTests.mkBig; + export { bign , TestError , @@ -41,7 +50,11 @@ export { Catching , Concurrently , panicTest , - eq , $$catch , + eq , + nums , + d , + x , + mkBig , } /* 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