]>
Lady’s Gitweb - Pisces/blob - function.test.js
1 // ♓🌟 Piscēs ∷ function.test.js
2 // ====================================================================
4 // Copyright © 2022–2023 Lady [@ Lady’s Computer].
6 // This Source Code Form is subject to the terms of the Mozilla Public
7 // License, v. 2.0. If a copy of the MPL was not distributed with this
8 // file, You can obtain one at <https://mozilla.org/MPL/2.0/>.
17 } from "./dev-deps.js";
24 createCallableFunction
,
25 createIllegalConstructor
,
31 } from "./function.js";
33 describe("bind", () => {
34 it("[[Call]] binds this", () => {
47 it("[[Call]] binds arguments", () => {
51 return [this, ...args
];
55 ).call("failure", "cmfwyp"),
56 ["etaoin", "shrdlu", "cmfwyp"],
60 it("[[Call]] works with any arraylike third argument", () => {
64 return [this, ...args
];
72 ).call("failure", "cmfwyp"),
73 ["etaoin", undefined, "shrdlu", undefined, "cmfwyp"],
77 it("[[Construct]] throws an error", () => {
78 assertThrows(() => new bind(function () {}));
81 describe(".length", () => {
82 it("[[Get]] returns the correct length", () => {
83 assertStrictEquals(bind
.length
, 3);
87 describe(".name", () => {
88 it("[[Get]] returns the correct name", () => {
89 assertStrictEquals(bind
.name
, "bind");
94 describe("call", () => {
95 it("[[Call]] calls with the provided this value", () => {
108 it("[[Call]] calls with the provided arguments", () => {
112 return [this, ...args
];
115 ["shrdlu", "cmfwyp"],
117 ["etaoin", "shrdlu", "cmfwyp"],
121 it("[[Call]] works with any arraylike third argument", () => {
125 return [this, ...args
];
135 ["etaoin", undefined, "shrdlu", undefined, "cmfwyp"],
139 it("[[Construct]] throws an error", () => {
140 assertThrows(() => new call(function () {}, null, []));
143 describe(".length", () => {
144 it("[[Get]] returns the correct length", () => {
145 assertStrictEquals(call
.length
, 3);
149 describe(".name", () => {
150 it("[[Get]] returns the correct name", () => {
151 assertStrictEquals(call
.name
, "call");
156 describe("completesNormally", () => {
157 it("[[Call]] returns true for functions which complete normally", () => {
158 assertStrictEquals(completesNormally(() => {}), true);
161 it("[[Call]] returns false for functions which throw", () => {
163 completesNormally(() => {
170 it("[[Call]] throws when the argument is not callable", () => {
171 assertThrows(() => completesNormally(null));
174 it("[[Call]] throws when the argument is not provided", () => {
175 assertThrows(() => completesNormally());
178 it("[[Construct]] throws an error", () => {
179 assertThrows(() => new completesNormally(function () {}));
182 describe(".length", () => {
183 it("[[Get]] returns the correct length", () => {
184 assertStrictEquals(completesNormally
.length
, 1);
188 describe(".name", () => {
189 it("[[Get]] returns the correct name", () => {
190 assertStrictEquals(completesNormally
.name
, "completesNormally");
195 describe("construct", () => {
196 it("[[Call]] defaults to the constructor as the target", () => {
197 const constructor = class {};
199 Object
.getPrototypeOf(construct(
203 constructor.prototype,
207 it("[[Call]] constructs with the provided new target", () => {
208 const target = function () {};
221 it("[[Call]] constructs with the provided arguments", () => {
225 return [new.target
.value
, ...args
];
227 ["shrdlu", "cmfwyp"],
228 Object
.assign(function () {}, { value
: "etaoin" }),
230 ["etaoin", "shrdlu", "cmfwyp"],
234 it("[[Call]] works with any arraylike third argument", () => {
238 return [new.target
.value
, ...args
];
246 Object
.assign(function () {}, { value
: "etaoin" }),
248 ["etaoin", undefined, "shrdlu", undefined, "cmfwyp"],
252 it("[[Construct]] throws an error", () => {
253 assertThrows(() => new construct(function () {}, []));
256 describe(".length", () => {
257 it("[[Get]] returns the correct length", () => {
258 assertStrictEquals(construct
.length
, 2);
262 describe(".name", () => {
263 it("[[Get]] returns the correct name", () => {
264 assertStrictEquals(construct
.name
, "construct");
269 describe("createArrowFunction", () => {
270 it("[[Call]] sets this to undefined", () => {
281 it("[[Call]] transfers the provided arguments", () => {
285 return [this, ...args
];
287 ).call("failure", "etaoin", "shrdlu", "cmfwyp"),
288 [undefined, "etaoin", "shrdlu", "cmfwyp"],
292 it("[[Call]] correctly sets the length", () => {
295 function (_a
, _b
, _c
) {},
301 it("[[Call]] correctly sets the name", () => {
304 function etaoin() {},
310 it("[[Call]] allows the length to be overridden", () => {
313 function etaoin() {},
320 it("[[Call]] allows the name to be overridden", () => {
323 function etaoin() {},
330 it("[[Call]] returns an arrow function", () => {
331 assertThrows(() => new (createArrowFunction(function () {}))());
334 it("[[Call]] returns a function with no prototype property", () => {
337 createArrowFunction(function () {}, { prototype: {} })),
341 it("[[Construct]] throws an error", () => {
342 assertThrows(() => new createArrowFunction(function () {}));
345 describe(".length", () => {
346 it("[[Get]] returns the correct length", () => {
347 assertStrictEquals(createArrowFunction
.length
, 1);
351 describe(".name", () => {
352 it("[[Get]] returns the correct name", () => {
354 createArrowFunction
.name
,
355 "createArrowFunction",
361 describe("createCallableFunction", () => {
362 it("[[Call]] transfers the first argument to this", () => {
364 createCallableFunction(
368 ).call("fail", "pass"),
373 it("[[Call]] transfers the remaining arguments", () => {
375 createCallableFunction(
377 return [this, ...args
];
379 ).call("failure", "etaoin", "shrdlu", "cmfwyp"),
380 ["etaoin", "shrdlu", "cmfwyp"],
384 it("[[Call]] correctly sets the length", () => {
386 createCallableFunction(
387 function (_a
, _b
, _c
) {},
393 it("[[Call]] correctly sets the name", () => {
395 createCallableFunction(
396 function etaoin() {},
402 it("[[Call]] allows the length to be overridden", () => {
404 createCallableFunction(
405 function etaoin() {},
412 it("[[Call]] allows the name to be overridden", () => {
414 createCallableFunction(
415 function etaoin() {},
422 it("[[Call]] returns an arrow function", () => {
423 assertThrows(() => new (createCallableFunction(function () {}))());
426 it("[[Call]] returns a function with no prototype property", () => {
429 createCallableFunction(function () {}, { prototype: {} })),
433 it("[[Construct]] throws an error", () => {
434 assertThrows(() => new createCallableFunction(function () {}));
437 describe(".length", () => {
438 it("[[Get]] returns the correct length", () => {
439 assertStrictEquals(createCallableFunction
.length
, 1);
443 describe(".name", () => {
444 it("[[Get]] returns the correct name", () => {
446 createCallableFunction
.name
,
447 "createCallableFunction",
453 describe("createIllegalConstructor", () => {
454 it("[[Call]] returns a constructor", () => {
455 assert(isConstructor(createIllegalConstructor()));
458 it("[[Call]] works as expected when provided with no arguments", () => {
459 const constructor = createIllegalConstructor();
461 Object
.getPrototypeOf(constructor),
465 Object
.getPrototypeOf(constructor.prototype),
469 Object
.getOwnPropertyDescriptors(constructor.prototype),
472 constructor.prototype,
473 Object
.create(Object
.prototype, {
483 !Object
.getOwnPropertyDescriptor(constructor, "prototype")
486 assertStrictEquals(constructor.name
, "");
489 it("[[Call]] returns a correctly‐formed constructor when provided one argument", () => {
490 const constructorPrototype
= Object
.create(null, {
491 name
: { value
: "etaoin" },
492 prototype: { value
: {} },
494 const constructor = createIllegalConstructor(
495 Object
.create(constructorPrototype
),
497 assert(isConstructor(constructor));
499 Object
.getPrototypeOf(constructor),
500 constructorPrototype
,
502 assert(Object
.hasOwn(constructor, "prototype"));
504 constructor.prototype,
505 constructorPrototype
.prototype,
508 !Object
.getOwnPropertyDescriptor(constructor, "prototype")
511 assertStrictEquals(constructor.name
, "etaoin");
514 it("[[Construct]] throws an error", () => {
515 assertThrows(() => new createIllegalConstructor(function () {}));
518 describe("~", () => {
519 it("[[Call]] throws an error", () => {
521 createIllegalConstructor(function () {})();
525 it("[[Construct]] throws an error", () => {
527 createIllegalConstructor(function () {})();
532 describe(".length", () => {
533 it("[[Get]] returns the correct length", () => {
534 assertStrictEquals(createIllegalConstructor
.length
, 1);
538 describe(".name", () => {
539 it("[[Get]] returns the correct name", () => {
541 createIllegalConstructor
.name
,
542 "createIllegalConstructor",
548 describe("identity", () => {
549 it("[[Call]] returns what it is given", () => {
551 assertStrictEquals(identity(value
), value
);
554 it("[[Construct]] is constructable", () => {
556 assertStrictEquals(new identity(value
), value
);
559 it("[[Construct]] is subclassable", () => {
561 assertStrictEquals(new class extends identity
{}(value
), value
);
564 describe(".length", () => {
565 it("[[Get]] returns the correct length", () => {
566 assertStrictEquals(identity
.length
, 1);
570 describe(".name", () => {
571 it("[[Get]] returns the correct name", () => {
572 assertStrictEquals(identity
.name
, "identity");
577 describe("isCallable", () => {
578 it("[[Call]] returns true for ordinary functions", () => {
579 assertStrictEquals(isCallable(function () {}), true);
582 it("[[Call]] returns true for arrow functions", () => {
583 assertStrictEquals(isCallable(() => {}), true);
586 it("[[Call]] returns true for generator functions", () => {
587 assertStrictEquals(isCallable(function* () {}), true);
590 it("[[Call]] returns true for classes", () => {
591 assertStrictEquals(isCallable(class {}), true);
594 it("[[Call]] returns true for builtin functions", () => {
595 assertStrictEquals(isCallable(Math
.ceil
), true);
598 it("[[Call]] returns true for getters", () => {
601 Object
.getOwnPropertyDescriptor({
611 it("[[Call]] returns true for setters", () => {
614 Object
.getOwnPropertyDescriptor({
624 it("[[Call]] returns false for null", () => {
625 assertStrictEquals(isCallable(null), false);
628 it("[[Call]] returns false for objects", () => {
629 assertStrictEquals(isCallable({}), false);
632 it("[[Construct]] throws an error", () => {
633 assertThrows(() => new isCallable(function () {}));
636 describe(".length", () => {
637 it("[[Get]] returns the correct length", () => {
638 assertStrictEquals(isCallable
.length
, 1);
642 describe(".name", () => {
643 it("[[Get]] returns the correct name", () => {
644 assertStrictEquals(isCallable
.name
, "isCallable");
649 describe("isConstructor", () => {
650 it("[[Call]] returns true for ordinary functions", () => {
651 assertStrictEquals(isConstructor(function () {}), true);
654 it("[[Call]] returns false for arrow functions", () => {
655 assertStrictEquals(isConstructor(() => {}), false);
658 it("[[Call]] returns false for generator functions", () => {
659 assertStrictEquals(isConstructor(function* () {}), false);
662 it("[[Call]] returns true for classes", () => {
663 assertStrictEquals(isConstructor(class {}), true);
666 it("[[Call]] returns false for builtin functions", () => {
667 assertStrictEquals(isConstructor(Math
.ceil
), false);
670 it("[[Call]] returns false for getters", () => {
673 Object
.getOwnPropertyDescriptor({
683 it("[[Call]] returns false for setters", () => {
686 Object
.getOwnPropertyDescriptor({
696 it("[[Call]] returns false for null", () => {
697 assertStrictEquals(isConstructor(null), false);
700 it("[[Call]] returns false for objects", () => {
701 assertStrictEquals(isConstructor({}), false);
704 it("[[Construct]] throws an error", () => {
705 assertThrows(() => new isConstructor(function () {}));
708 describe(".length", () => {
709 it("[[Get]] returns the correct length", () => {
710 assertStrictEquals(isConstructor
.length
, 1);
714 describe(".name", () => {
715 it("[[Get]] returns the correct name", () => {
716 assertStrictEquals(isConstructor
.name
, "isConstructor");
721 describe("ordinaryHasInstance", () => {
722 it("[[Call]] walks the prototype chain", () => {
723 const constructor = class {
724 [Symbol
.hasInstance
]() {
731 new class extends constructor {}(),
737 it("[[Construct]] throws an error", () => {
738 assertThrows(() => new ordinaryHasInstance(function () {}, {}));
741 describe(".length", () => {
742 it("[[Get]] returns the correct length", () => {
743 assertStrictEquals(ordinaryHasInstance
.length
, 2);
747 describe(".name", () => {
748 it("[[Get]] returns the correct name", () => {
750 ordinaryHasInstance
.name
,
751 "ordinaryHasInstance",
757 describe("toFunctionName", () => {
758 it("[[Call]] works with strings and no prefix", () => {
759 assertStrictEquals(toFunctionName("etaoin"), "etaoin");
762 it("[[Call]] works with objects and no prefix", () => {
773 it("[[Call]] works with descriptionless symbols and no prefix", () => {
774 assertStrictEquals(toFunctionName(Symbol()), "");
777 it("[[Call]] works with empty description symbols and no prefix", () => {
778 assertStrictEquals(toFunctionName(Symbol("")), "[]");
781 it("[[Call]] works with described symbols and no prefix", () => {
782 assertStrictEquals(toFunctionName(Symbol("etaoin")), "[etaoin]");
785 it("[[Call]] works with strings and a prefix", () => {
786 assertStrictEquals(toFunctionName("etaoin", "foo"), "foo etaoin");
789 it("[[Call]] works with objects and no prefix", () => {
800 it("[[Call]] works with descriptionless symbols and no prefix", () => {
801 assertStrictEquals(toFunctionName(Symbol(), "foo"), "foo ");
804 it("[[Call]] works with empty description symbols and no prefix", () => {
805 assertStrictEquals(toFunctionName(Symbol(""), "foo"), "foo []");
808 it("[[Call]] works with described symbols and no prefix", () => {
810 toFunctionName(Symbol("etaoin"), "foo"),
815 it("[[Construct]] throws an error", () => {
816 assertThrows(() => new toFunctionName(""));
819 describe(".length", () => {
820 it("[[Get]] returns the correct length", () => {
821 assertStrictEquals(toFunctionName
.length
, 1);
825 describe(".name", () => {
826 it("[[Get]] returns the correct name", () => {
This page took 0.181309 seconds and 5 git commands to generate.