X-Git-Url: https://git.ladys.computer/Pisces/blobdiff_plain/e59e8454940d56a20e22c8eb5154ca542e478a0a..e1cb83c479df2a3e4a5e918867a135ff9dde8121:/function.test.js?ds=inline diff --git a/function.test.js b/function.test.js index 0a58a36..a5c8311 100644 --- a/function.test.js +++ b/function.test.js @@ -1,19 +1,26 @@ -// ♓🌟 Piscēs ∷ function.test.js -// ==================================================================== -// -// Copyright © 2022–2023 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 . +// SPDX-FileCopyrightText: 2022, 2023, 2025 Lady +// SPDX-License-Identifier: MPL-2.0 +/** + * ⁌ ♓🧩 Piscēs ∷ function.test.js + * + * Copyright © 2022–2023, 2025 Lady [@ Ladys 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 . + */ import { assert, assertEquals, + assertNotStrictEquals, + assertSpyCall, + assertSpyCalls, assertStrictEquals, assertThrows, describe, it, + spy, } from "./dev-deps.js"; import { bind, @@ -27,6 +34,7 @@ import { identity, isCallable, isConstructor, + maybe, ordinaryHasInstance, } from "./function.js"; @@ -333,8 +341,8 @@ describe("createArrowFunction", () => { it("[[Call]] returns a function with no prototype property", () => { assert( - !("prototype" in - createArrowFunction(function () {}, { prototype: {} })), + !("prototype" + in createArrowFunction(function () {}, { prototype: {} })), ); }); @@ -425,8 +433,8 @@ describe("createCallableFunction", () => { it("[[Call]] returns a function with no prototype property", () => { assert( - !("prototype" in - createCallableFunction(function () {}, { prototype: {} })), + !("prototype" + in createCallableFunction(function () {}, { prototype: {} })), ); }); @@ -465,9 +473,6 @@ describe("createIllegalConstructor", () => { Object.getPrototypeOf(constructor.prototype), Object.prototype, ); - console.dir( - Object.getOwnPropertyDescriptors(constructor.prototype), - ); assertEquals( constructor.prototype, Object.create(Object.prototype, { @@ -708,6 +713,95 @@ describe("createProxyConstructor", () => { }); }); + describe("~is[[.name]]", () => { + it("[[GetOwnProperty]] defines the appropriate method", () => { + assertNotStrictEquals( + Object.getOwnPropertyDescriptor( + createProxyConstructor({}), + "isProxy", + ), + undefined, + ); + assertNotStrictEquals( + Object.getOwnPropertyDescriptor( + createProxyConstructor({}, function Base() {}), + "isBaseProxy", + ), + undefined, + ); + assertNotStrictEquals( + Object.getOwnPropertyDescriptor( + createProxyConstructor({}, function Bad() {}, undefined, { + name: "⸺", + }), + "is⸺", + ), + undefined, + ); + }); + + it("[[GetOwnProperty]] has the correct descriptor", () => { + const proxyConstructor = createProxyConstructor({}); + assertEquals( + Object.getOwnPropertyDescriptor( + proxyConstructor, + "isProxy", + ), + { + configurable: true, + enumerable: false, + value: proxyConstructor.isProxy, + writable: true, + }, + ); + }); + + it("[[Call]] returns true for created proxies", () => { + const proxyConstructor = createProxyConstructor({}); + const proxy = new proxyConstructor(); + assertStrictEquals( + proxyConstructor.isProxy(proxy), + true, + ); + }); + + it("[[Call]] returns false for nonproxies", () => { + const constructor = function Base() {}; + const proxyConstructor = createProxyConstructor({}, constructor); + assertStrictEquals( + proxyConstructor.isBaseProxy(new constructor()), + false, + ); + }); + + it("[[Construct]] throws an error", () => { + const proxyConstructor = createProxyConstructor({}); + assertThrows(() => new proxyConstructor.isProxy({})); + }); + + describe(".length", () => { + it("[[Get]] returns the correct length", () => { + const proxyConstructor = createProxyConstructor({}); + assertStrictEquals(proxyConstructor.isProxy.length, 1); + }); + }); + + describe(".name", () => { + it("[[Get]] returns the correct name", () => { + const proxyConstructor = createProxyConstructor({}); + assertStrictEquals(proxyConstructor.isProxy.name, "isProxy"); + const otherProxyConstructor = createProxyConstructor( + {}, + function Base() {}, + ); + assertStrictEquals( + otherProxyConstructor.isBaseProxy.name, + "isBaseProxy", + ); + }); + }); + }); + describe("~length", () => { it("[[GetOwnProperty]] has the correct descriptor", () => { assertEquals( @@ -735,7 +829,7 @@ describe("createProxyConstructor", () => { { configurable: true, enumerable: false, - value: "ObjectProxy", + value: "Proxy", writable: false, }, ); @@ -991,6 +1085,42 @@ describe("isConstructor", () => { }); }); +describe("maybe", () => { + it("[[Call]] calls if not nullish", () => { + const wrapper = spy(() => "success"); + assertStrictEquals(maybe(0, wrapper), "success"); + assertSpyCalls(wrapper, 1); + assertSpyCall(wrapper, 0, { + args: [0], + self: undefined, + returned: "success", + }); + }); + + it("[[Call]] does not call if nullish", () => { + const wrapper = spy(() => "success"); + assertStrictEquals(maybe(null, wrapper), null); + assertStrictEquals(maybe(undefined, wrapper), undefined); + assertSpyCalls(wrapper, 0); + }); + + it("[[Construct]] throws an error", () => { + assertThrows(() => new maybe(true, ($) => $)); + }); + + describe(".length", () => { + it("[[Get]] returns the correct length", () => { + assertStrictEquals(maybe.length, 2); + }); + }); + + describe(".name", () => { + it("[[Get]] returns the correct name", () => { + assertStrictEquals(maybe.name, "maybe"); + }); + }); +}); + describe("ordinaryHasInstance", () => { it("[[Call]] walks the prototype chain", () => { const constructor = class {