]> Lady’s Gitweb - Pisces/blobdiff - value.test.js
Split some object code into value and unit test
[Pisces] / value.test.js
diff --git a/value.test.js b/value.test.js
new file mode 100644 (file)
index 0000000..6729b85
--- /dev/null
@@ -0,0 +1,315 @@
+// ♓🌟 Piscēs ∷ value.test.js
+// ====================================================================
+//
+// Copyright © 2022 Lady [@ Lady’s Computer].
+//
+// 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 <https://mozilla.org/MPL/2.0/>.
+
+import {
+  assert,
+  assertStrictEquals,
+  assertThrows,
+  describe,
+  it,
+} from "./dev-deps.js";
+import {
+  NULL,
+  ordinaryToPrimitive,
+  sameValue,
+  sameValueZero,
+  toPrimitive,
+  type,
+  UNDEFINED,
+} from "./value.js";
+
+describe("NULL", () => {
+  it("[[Get]] is null", () => {
+    assertStrictEquals(NULL, null);
+  });
+});
+
+describe("UNDEFINED", () => {
+  it("[[Get]] is undefined", () => {
+    assertStrictEquals(UNDEFINED, void {});
+  });
+});
+
+describe("ordinaryToPrimitive", () => {
+  it("[[Call]] prefers `valueOf` by default", () => {
+    const obj = {
+      toString() {
+        return "failure";
+      },
+      valueOf() {
+        return "success";
+      },
+    };
+    assertStrictEquals(ordinaryToPrimitive(obj), "success");
+    assertStrictEquals(ordinaryToPrimitive(obj, "default"), "success");
+  });
+
+  it('[[Call]] prefers `valueOf` for a "number" hint', () => {
+    const obj = {
+      toString() {
+        return "failure";
+      },
+      valueOf() {
+        return "success";
+      },
+    };
+    assertStrictEquals(ordinaryToPrimitive(obj, "number"), "success");
+  });
+
+  it('[[Call]] prefers `toString` for a "string" hint', () => {
+    const obj = {
+      toString() {
+        return "success";
+      },
+      valueOf() {
+        return "failure";
+      },
+    };
+    assertStrictEquals(ordinaryToPrimitive(obj, "string"), "success");
+  });
+
+  it("[[Call]] falls back to the other method if the first isn’t callable", () => {
+    const obj = {
+      toString() {
+        return "success";
+      },
+      valueOf: "failure",
+    };
+    assertStrictEquals(ordinaryToPrimitive(obj), "success");
+  });
+
+  it("[[Call]] falls back to the other method if the first returns an object", () => {
+    const obj = {
+      toString() {
+        return "success";
+      },
+      valueOf() {
+        return new String("failure");
+      },
+    };
+    assertStrictEquals(ordinaryToPrimitive(obj), "success");
+  });
+
+  it("[[Call]] throws an error if neither method is callable", () => {
+    const obj = {
+      toString: "failure",
+      valueOf: "failure",
+    };
+    assertThrows(() => ordinaryToPrimitive(obj));
+  });
+
+  it("[[Call]] throws an error if neither method returns an object", () => {
+    const obj = {
+      toString() {
+        return new String("failure");
+      },
+      valueOf() {
+        return new String("failure");
+      },
+    };
+    assertThrows(() => ordinaryToPrimitive(obj));
+  });
+});
+
+describe("sameValue", () => {
+  it("[[Call]] returns false for null 🆚 undefined", () => {
+    assert(!sameValue(null, void {}));
+  });
+
+  it("[[Call]] returns false for null 🆚 an object", () => {
+    assert(!sameValue(null, {}));
+  });
+
+  it("[[Call]] returns true for null 🆚 null", () => {
+    assert(sameValue(null, null));
+  });
+
+  it("[[Call]] returns false for two different objects", () => {
+    assert(!sameValue({}, {}));
+  });
+
+  it("[[Call]] returns true for the same object", () => {
+    const obj = {};
+    assert(sameValue(obj, obj));
+  });
+
+  it("[[Call]] returns false for ±0", () => {
+    assert(!sameValue(0, -0));
+  });
+
+  it("[[Call]] returns true for -0", () => {
+    assert(sameValue(-0, -0));
+  });
+
+  it("[[Call]] returns true for nan", () => {
+    assert(sameValue(0 / 0, 0 / 0));
+  });
+
+  it("[[Call]] returns false for a primitive and its wrapped object", () => {
+    assert(!sameValue(false, new Boolean(false)));
+  });
+});
+
+describe("sameValueZero", () => {
+  it("[[Call]] returns false for null 🆚 undefined", () => {
+    assert(!sameValueZero(null, void {}));
+  });
+
+  it("[[Call]] returns false for null 🆚 an object", () => {
+    assert(!sameValueZero(null, {}));
+  });
+
+  it("[[Call]] returns true for null 🆚 null", () => {
+    assert(sameValueZero(null, null));
+  });
+
+  it("[[Call]] returns false for two different objects", () => {
+    assert(!sameValueZero({}, {}));
+  });
+
+  it("[[Call]] returns true for the same object", () => {
+    const obj = {};
+    assert(sameValueZero(obj, obj));
+  });
+
+  it("[[Call]] returns true for ±0", () => {
+    assert(sameValueZero(0, -0));
+  });
+
+  it("[[Call]] returns true for -0", () => {
+    assert(sameValueZero(-0, -0));
+  });
+
+  it("[[Call]] returns true for nan", () => {
+    assert(sameValueZero(0 / 0, 0 / 0));
+  });
+
+  it("[[Call]] returns false for a primitive and its wrapped object", () => {
+    assert(!sameValueZero(false, new Boolean(false)));
+  });
+});
+
+describe("toPrimitive", () => {
+  it("[[Call]] returns the argument when passed a primitive", () => {
+    const value = Symbol();
+    assertStrictEquals(toPrimitive(value), value);
+  });
+
+  it("[[Call]] works with nullish values", () => {
+    assertStrictEquals(toPrimitive(null), null);
+    assertStrictEquals(toPrimitive(), void {});
+  });
+
+  it("[[Call]] calls ordinaryToPrimitive by default", () => {
+    const value = Object.assign(
+      Object.create(null),
+      {
+        valueOf() {
+          return "success";
+        },
+      },
+    );
+    assertStrictEquals(toPrimitive(value), "success");
+  });
+
+  it("[[Call]] accepts a hint", () => {
+    const value = Object.assign(
+      Object.create(null),
+      {
+        toString() {
+          return "success";
+        },
+        valueOf() {
+          return "failure";
+        },
+      },
+    );
+    assertStrictEquals(toPrimitive(value, "string"), "success");
+  });
+
+  it("[[Call]] uses the exotic toPrimitive method if available", () => {
+    const value = Object.assign(
+      Object.create(null),
+      {
+        [Symbol.toPrimitive]() {
+          return "success";
+        },
+      },
+    );
+    assertStrictEquals(toPrimitive(value), "success");
+  });
+
+  it("[[Call]] passes the hint to the exotic toPrimitive", () => {
+    const value = Object.assign(
+      Object.create(null),
+      {
+        [Symbol.toPrimitive](hint) {
+          return hint === "string" ? "success" : "failure";
+        },
+      },
+    );
+    assertStrictEquals(toPrimitive(value, "string"), "success");
+  });
+
+  it('[[Call]] passes a "default" hint by default', () => {
+    const value = Object.assign(
+      Object.create(null),
+      {
+        [Symbol.toPrimitive](hint) {
+          return hint === "default" ? "success" : "failure";
+        },
+      },
+    );
+    assertStrictEquals(toPrimitive(value, "default"), "success");
+  });
+
+  it("[[Call]] throws for an invalid hint", () => {
+    const value1 = Object.assign(
+      Object.create(null),
+      {
+        [Symbol.toPrimitive]() {
+          return "success";
+        },
+      },
+    );
+    const value2 = Object.assign(
+      Object.create(null),
+      {
+        valueOf() {
+          return true;
+        },
+      },
+    );
+    assertThrows(() => toPrimitive(value1, "badhint"));
+    assertThrows(() => toPrimitive(value2, "badhint"));
+    assertThrows(() => toPrimitive(true, "badhint"));
+  });
+});
+
+describe("type", () => {
+  it('[[Call]] returns "null" for null', () => {
+    assertStrictEquals(type(null), "null");
+  });
+
+  it('[[Call]] returns "undefined" for undefined', () => {
+    assertStrictEquals(type(void {}), "undefined");
+  });
+
+  it('[[Call]] returns "object" for non‐callable objects', () => {
+    assertStrictEquals(type(Object.create(null)), "object");
+  });
+
+  it('[[Call]] returns "object" for callable objects', () => {
+    assertStrictEquals(type(() => {}), "object");
+  });
+
+  it('[[Call]] returns "object" for constructable objects', () => {
+    assertStrictEquals(type(class {}), "object");
+  });
+});
This page took 0.115095 seconds and 4 git commands to generate.