]> Lady’s Gitweb - Pisces/blobdiff - function.test.js
Remove dependencies of function.js; add tests
[Pisces] / function.test.js
diff --git a/function.test.js b/function.test.js
new file mode 100644 (file)
index 0000000..4cfa85f
--- /dev/null
@@ -0,0 +1,292 @@
+// ♓🌟 Piscēs ∷ function.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,
+  assertEquals,
+  assertStrictEquals,
+  describe,
+  it,
+} from "./dev-deps.js";
+import {
+  bind,
+  call,
+  construct,
+  identity,
+  isCallable,
+  isConstructor,
+  makeCallable,
+  ordinaryHasInstance,
+} from "./function.js";
+
+describe("bind", () => {
+  it("[[Call]] binds this", () => {
+    assertStrictEquals(
+      bind(
+        function () {
+          return this;
+        },
+        "pass",
+        [],
+      ).call("fail"),
+      "pass",
+    );
+  });
+
+  it("[[Call]] binds arguments", () => {
+    assertEquals(
+      bind(
+        function (...args) {
+          return [this, ...args];
+        },
+        "etaoin",
+        ["shrdlu"],
+      ).call("failure", "cmfwyp"),
+      ["etaoin", "shrdlu", "cmfwyp"],
+    );
+  });
+
+  it("[[Call]] works with any arraylike third argument", () => {
+    assertEquals(
+      bind(
+        function (...args) {
+          return [this, ...args];
+        },
+        "etaoin",
+        {
+          1: "shrdlu",
+          3: "failure",
+          length: 3,
+        },
+      ).call("failure", "cmfwyp"),
+      ["etaoin", undefined, "shrdlu", undefined, "cmfwyp"],
+    );
+  });
+});
+
+describe("call", () => {
+  it("[[Call]] calls with the provided this value", () => {
+    assertStrictEquals(
+      call(
+        function () {
+          return this;
+        },
+        "pass",
+        [],
+      ),
+      "pass",
+    );
+  });
+
+  it("[[Call]] calls with the provided arguments", () => {
+    assertEquals(
+      call(
+        function (...args) {
+          return [this, ...args];
+        },
+        "etaoin",
+        ["shrdlu", "cmfwyp"],
+      ),
+      ["etaoin", "shrdlu", "cmfwyp"],
+    );
+  });
+
+  it("[[Call]] works with any arraylike third argument", () => {
+    assertEquals(
+      call(
+        function (...args) {
+          return [this, ...args];
+        },
+        "etaoin",
+        {
+          1: "shrdlu",
+          3: "cmfwyp",
+          4: "failure",
+          length: 4,
+        },
+      ),
+      ["etaoin", undefined, "shrdlu", undefined, "cmfwyp"],
+    );
+  });
+});
+
+describe("construct", () => {
+  it("[[Call]] defaults to the constructor as the target", () => {
+    const constructor = class {};
+    assertStrictEquals(
+      Object.getPrototypeOf(construct(
+        constructor,
+        [],
+      )),
+      constructor.prototype,
+    );
+  });
+
+  it("[[Call]] constructs with the provided new target", () => {
+    const target = function () {};
+    assertStrictEquals(
+      construct(
+        function () {
+          return new.target;
+        },
+        [],
+        target,
+      ),
+      target,
+    );
+  });
+
+  it("[[Call]] constructs with the provided arguments", () => {
+    assertEquals(
+      construct(
+        function (...args) {
+          return [new.target.value, ...args];
+        },
+        ["shrdlu", "cmfwyp"],
+        Object.assign(function () {}, { value: "etaoin" }),
+      ),
+      ["etaoin", "shrdlu", "cmfwyp"],
+    );
+  });
+
+  it("[[Call]] works with any arraylike third argument", () => {
+    assertEquals(
+      construct(
+        function (...args) {
+          return [new.target.value, ...args];
+        },
+        {
+          1: "shrdlu",
+          3: "cmfwyp",
+          4: "failure",
+          length: 4,
+        },
+        Object.assign(function () {}, { value: "etaoin" }),
+      ),
+      ["etaoin", undefined, "shrdlu", undefined, "cmfwyp"],
+    );
+  });
+});
+
+describe("identity", () => {
+  it("[[Call]] returns what it is given", () => {
+    const value = {};
+    assertStrictEquals(identity(value), value);
+  });
+
+  it("[[Construct]] is constructable", () => {
+    const value = {};
+    assertStrictEquals(new identity(value), value);
+  });
+
+  it("[[Construct]] is subclassable", () => {
+    const value = {};
+    assertStrictEquals(new class extends identity {}(value), value);
+  });
+});
+
+describe("isCallable", () => {
+  it("[[Call]] returns true for ordinary functions", () => {
+    assert(isCallable(function () {}));
+  });
+
+  it("[[Call]] returns true for arrow functions", () => {
+    assert(isCallable(() => {}));
+  });
+
+  it("[[Call]] returns true for generator functions", () => {
+    assert(isCallable(function* () {}));
+  });
+
+  it("[[Call]] returns true for classes", () => {
+    assert(isCallable(class {}));
+  });
+
+  it("[[Call]] returns true for builtin functions", () => {
+    assert(isCallable(Math.ceil));
+  });
+
+  it("[[Call]] returns false for null", () => {
+    assert(!isCallable(null));
+  });
+
+  it("[[Call]] returns false for objects", () => {
+    assert(!isCallable({}));
+  });
+});
+
+describe("isConstructor", () => {
+  it("[[Call]] returns true for ordinary functions", () => {
+    assert(isConstructor(function () {}));
+  });
+
+  it("[[Call]] returns false for arrow functions", () => {
+    assert(!isConstructor(() => {}));
+  });
+
+  it("[[Call]] returns false for generator functions", () => {
+    assert(!isConstructor(function* () {}));
+  });
+
+  it("[[Call]] returns true for classes", () => {
+    assert(isConstructor(class {}));
+  });
+
+  it("[[Call]] returns false for builtin functions", () => {
+    assert(!isConstructor(Math.ceil));
+  });
+
+  it("[[Call]] returns false for null", () => {
+    assert(!isConstructor(null));
+  });
+
+  it("[[Call]] returns false for objects", () => {
+    assert(!isConstructor({}));
+  });
+});
+
+describe("makeCallable", () => {
+  it("[[Call]] transfers the first argument to this", () => {
+    assertStrictEquals(
+      makeCallable(
+        function () {
+          return this;
+        },
+      ).call("fail", "pass"),
+      "pass",
+    );
+  });
+
+  it("[[Call]] transfers the remaining arguments", () => {
+    assertEquals(
+      makeCallable(
+        function (...args) {
+          return [this, ...args];
+        },
+      ).call("failure", "etaoin", "shrdlu", "cmfwyp"),
+      ["etaoin", "shrdlu", "cmfwyp"],
+    );
+  });
+});
+
+describe("ordinaryHasInstance", () => {
+  it("[[Call]] walks the prototype chain", () => {
+    const constructor = class {
+      [Symbol.hasInstance]() {
+        return false;
+      }
+    };
+    assert(
+      ordinaryHasInstance(
+        constructor,
+        new class extends constructor {}(),
+      ),
+    );
+  });
+});
This page took 0.412947 seconds and 4 git commands to generate.