]>
Lady’s Gitweb - Pisces/blob - function.test.js
dd9b642a48ba85353cadf607787ecb6152314674
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";
23 createCallableFunction
,
24 createIllegalConstructor
,
30 } from "./function.js";
32 describe("bind", () => {
33 it("[[Call]] binds this", () => {
46 it("[[Call]] binds arguments", () => {
50 return [this, ...args
];
54 ).call("failure", "cmfwyp"),
55 ["etaoin", "shrdlu", "cmfwyp"],
59 it("[[Call]] works with any arraylike third argument", () => {
63 return [this, ...args
];
71 ).call("failure", "cmfwyp"),
72 ["etaoin", undefined, "shrdlu", undefined, "cmfwyp"],
76 it("[[Construct]] throws an error", () => {
77 assertThrows(() => new bind(function () {}));
80 describe(".length", () => {
81 it("[[Get]] returns the correct length", () => {
82 assertStrictEquals(bind
.length
, 3);
86 describe(".name", () => {
87 it("[[Get]] returns the correct name", () => {
88 assertStrictEquals(bind
.name
, "bind");
93 describe("call", () => {
94 it("[[Call]] calls with the provided this value", () => {
107 it("[[Call]] calls with the provided arguments", () => {
111 return [this, ...args
];
114 ["shrdlu", "cmfwyp"],
116 ["etaoin", "shrdlu", "cmfwyp"],
120 it("[[Call]] works with any arraylike third argument", () => {
124 return [this, ...args
];
134 ["etaoin", undefined, "shrdlu", undefined, "cmfwyp"],
138 it("[[Construct]] throws an error", () => {
139 assertThrows(() => new call(function () {}, null, []));
142 describe(".length", () => {
143 it("[[Get]] returns the correct length", () => {
144 assertStrictEquals(call
.length
, 3);
148 describe(".name", () => {
149 it("[[Get]] returns the correct name", () => {
150 assertStrictEquals(call
.name
, "call");
155 describe("completesNormally", () => {
156 it("[[Call]] returns true for functions which complete normally", () => {
157 assertStrictEquals(completesNormally(() => {}), true);
160 it("[[Call]] returns false for functions which throw", () => {
162 completesNormally(() => {
169 it("[[Call]] throws when the argument is not callable", () => {
170 assertThrows(() => completesNormally(null));
173 it("[[Call]] throws when the argument is not provided", () => {
174 assertThrows(() => completesNormally());
177 it("[[Construct]] throws an error", () => {
178 assertThrows(() => new completesNormally(function () {}));
181 describe(".length", () => {
182 it("[[Get]] returns the correct length", () => {
183 assertStrictEquals(completesNormally
.length
, 1);
187 describe(".name", () => {
188 it("[[Get]] returns the correct name", () => {
189 assertStrictEquals(completesNormally
.name
, "completesNormally");
194 describe("construct", () => {
195 it("[[Call]] defaults to the constructor as the target", () => {
196 const constructor = class {};
198 Object
.getPrototypeOf(construct(
202 constructor.prototype,
206 it("[[Call]] constructs with the provided new target", () => {
207 const target = function () {};
220 it("[[Call]] constructs with the provided arguments", () => {
224 return [new.target
.value
, ...args
];
226 ["shrdlu", "cmfwyp"],
227 Object
.assign(function () {}, { value
: "etaoin" }),
229 ["etaoin", "shrdlu", "cmfwyp"],
233 it("[[Call]] works with any arraylike third argument", () => {
237 return [new.target
.value
, ...args
];
245 Object
.assign(function () {}, { value
: "etaoin" }),
247 ["etaoin", undefined, "shrdlu", undefined, "cmfwyp"],
251 it("[[Construct]] throws an error", () => {
252 assertThrows(() => new construct(function () {}, []));
255 describe(".length", () => {
256 it("[[Get]] returns the correct length", () => {
257 assertStrictEquals(construct
.length
, 2);
261 describe(".name", () => {
262 it("[[Get]] returns the correct name", () => {
263 assertStrictEquals(construct
.name
, "construct");
268 describe("createCallableFunction", () => {
269 it("[[Call]] transfers the first argument to this", () => {
271 createCallableFunction(
275 ).call("fail", "pass"),
280 it("[[Call]] transfers the remaining arguments", () => {
282 createCallableFunction(
284 return [this, ...args
];
286 ).call("failure", "etaoin", "shrdlu", "cmfwyp"),
287 ["etaoin", "shrdlu", "cmfwyp"],
291 it("[[Call]] correctly sets the length", () => {
293 createCallableFunction(
294 function (_a
, _b
, _c
) {},
300 it("[[Call]] correctly sets the name", () => {
302 createCallableFunction(
303 function etaoin() {},
309 it("[[Call]] allows the name to be overridden", () => {
311 createCallableFunction(
312 function etaoin() {},
319 it("[[Construct]] throws an error", () => {
320 assertThrows(() => new createCallableFunction(function () {}));
323 describe(".length", () => {
324 it("[[Get]] returns the correct length", () => {
325 assertStrictEquals(createCallableFunction
.length
, 1);
329 describe(".name", () => {
330 it("[[Get]] returns the correct name", () => {
332 createCallableFunction
.name
,
333 "createCallableFunction",
339 describe("createIllegalConstructor", () => {
340 it("[[Call]] returns a constructor", () => {
341 assert(isConstructor(createIllegalConstructor()));
344 it("[[Call]] works as expected when provided with no arguments", () => {
345 const constructor = createIllegalConstructor();
347 Object
.getPrototypeOf(constructor),
351 Object
.getPrototypeOf(constructor.prototype),
354 assertEquals(constructor.prototype, {});
356 !Object
.getOwnPropertyDescriptor(constructor, "prototype")
359 assertStrictEquals(constructor.name
, "");
362 it("[[Call]] returns a correctly‐formed constructor when provided one argument", () => {
363 const constructorPrototype
= Object
.create(null, {
364 name
: { value
: "etaoin" },
365 prototype: { value
: {} },
367 const constructor = createIllegalConstructor(
368 Object
.create(constructorPrototype
),
370 assert(isConstructor(constructor));
372 Object
.getPrototypeOf(constructor),
373 constructorPrototype
,
375 assert(Object
.hasOwn(constructor, "prototype"));
377 constructor.prototype,
378 constructorPrototype
.prototype,
381 !Object
.getOwnPropertyDescriptor(constructor, "prototype")
384 assertStrictEquals(constructor.name
, "etaoin");
387 it("[[Call]] allows the second argument to override the prototype of the constructor", () => {
388 const constructorPrototype
= Object
.create(null, {
389 name
: { value
: "etaoin" },
390 prototype: { value
: {} },
392 const expectedPrototype
= Object
.create(null, {
393 name
: { value
: "shrdlu" },
394 prototype: { value
: {} },
396 const constructor = createIllegalConstructor(
397 Object
.create(constructorPrototype
),
400 assert(isConstructor(constructor));
402 Object
.getPrototypeOf(constructor),
405 assert(Object
.hasOwn(constructor, "prototype"));
407 constructor.prototype,
408 constructorPrototype
.prototype,
411 !Object
.getOwnPropertyDescriptor(constructor, "prototype")
414 assertStrictEquals(constructor.name
, "etaoin");
417 it("[[Construct]] throws an error", () => {
418 assertThrows(() => new createIllegalConstructor(function () {}));
421 describe("~", () => {
422 it("[[Call]] throws an error", () => {
424 createIllegalConstructor(function () {})();
428 it("[[Construct]] throws an error", () => {
430 createIllegalConstructor(function () {})();
435 describe(".length", () => {
436 it("[[Get]] returns the correct length", () => {
437 assertStrictEquals(createIllegalConstructor
.length
, 1);
441 describe(".name", () => {
442 it("[[Get]] returns the correct name", () => {
444 createIllegalConstructor
.name
,
445 "createIllegalConstructor",
451 describe("identity", () => {
452 it("[[Call]] returns what it is given", () => {
454 assertStrictEquals(identity(value
), value
);
457 it("[[Construct]] is constructable", () => {
459 assertStrictEquals(new identity(value
), value
);
462 it("[[Construct]] is subclassable", () => {
464 assertStrictEquals(new class extends identity
{}(value
), value
);
467 describe(".length", () => {
468 it("[[Get]] returns the correct length", () => {
469 assertStrictEquals(identity
.length
, 1);
473 describe(".name", () => {
474 it("[[Get]] returns the correct name", () => {
475 assertStrictEquals(identity
.name
, "identity");
480 describe("isCallable", () => {
481 it("[[Call]] returns true for ordinary functions", () => {
482 assertStrictEquals(isCallable(function () {}), true);
485 it("[[Call]] returns true for arrow functions", () => {
486 assertStrictEquals(isCallable(() => {}), true);
489 it("[[Call]] returns true for generator functions", () => {
490 assertStrictEquals(isCallable(function* () {}), true);
493 it("[[Call]] returns true for classes", () => {
494 assertStrictEquals(isCallable(class {}), true);
497 it("[[Call]] returns true for builtin functions", () => {
498 assertStrictEquals(isCallable(Math
.ceil
), true);
501 it("[[Call]] returns true for getters", () => {
504 Object
.getOwnPropertyDescriptor({
514 it("[[Call]] returns true for setters", () => {
517 Object
.getOwnPropertyDescriptor({
527 it("[[Call]] returns false for null", () => {
528 assertStrictEquals(isCallable(null), false);
531 it("[[Call]] returns false for objects", () => {
532 assertStrictEquals(isCallable({}), false);
535 it("[[Construct]] throws an error", () => {
536 assertThrows(() => new isCallable(function () {}));
539 describe(".length", () => {
540 it("[[Get]] returns the correct length", () => {
541 assertStrictEquals(isCallable
.length
, 1);
545 describe(".name", () => {
546 it("[[Get]] returns the correct name", () => {
547 assertStrictEquals(isCallable
.name
, "isCallable");
552 describe("isConstructor", () => {
553 it("[[Call]] returns true for ordinary functions", () => {
554 assertStrictEquals(isConstructor(function () {}), true);
557 it("[[Call]] returns false for arrow functions", () => {
558 assertStrictEquals(isConstructor(() => {}), false);
561 it("[[Call]] returns false for generator functions", () => {
562 assertStrictEquals(isConstructor(function* () {}), false);
565 it("[[Call]] returns true for classes", () => {
566 assertStrictEquals(isConstructor(class {}), true);
569 it("[[Call]] returns false for builtin functions", () => {
570 assertStrictEquals(isConstructor(Math
.ceil
), false);
573 it("[[Call]] returns false for getters", () => {
576 Object
.getOwnPropertyDescriptor({
586 it("[[Call]] returns false for setters", () => {
589 Object
.getOwnPropertyDescriptor({
599 it("[[Call]] returns false for null", () => {
600 assertStrictEquals(isConstructor(null), false);
603 it("[[Call]] returns false for objects", () => {
604 assertStrictEquals(isConstructor({}), false);
607 it("[[Construct]] throws an error", () => {
608 assertThrows(() => new isConstructor(function () {}));
611 describe(".length", () => {
612 it("[[Get]] returns the correct length", () => {
613 assertStrictEquals(isConstructor
.length
, 1);
617 describe(".name", () => {
618 it("[[Get]] returns the correct name", () => {
619 assertStrictEquals(isConstructor
.name
, "isConstructor");
624 describe("ordinaryHasInstance", () => {
625 it("[[Call]] walks the prototype chain", () => {
626 const constructor = class {
627 [Symbol
.hasInstance
]() {
634 new class extends constructor {}(),
640 it("[[Construct]] throws an error", () => {
641 assertThrows(() => new ordinaryHasInstance(function () {}, {}));
644 describe(".length", () => {
645 it("[[Get]] returns the correct length", () => {
646 assertStrictEquals(ordinaryHasInstance
.length
, 2);
650 describe(".name", () => {
651 it("[[Get]] returns the correct name", () => {
653 ordinaryHasInstance
.name
,
654 "ordinaryHasInstance",
660 describe("toFunctionName", () => {
661 it("[[Call]] works with strings and no prefix", () => {
662 assertStrictEquals(toFunctionName("etaoin"), "etaoin");
665 it("[[Call]] works with objects and no prefix", () => {
676 it("[[Call]] works with descriptionless symbols and no prefix", () => {
677 assertStrictEquals(toFunctionName(Symbol()), "");
680 it("[[Call]] works with empty description symbols and no prefix", () => {
681 assertStrictEquals(toFunctionName(Symbol("")), "[]");
684 it("[[Call]] works with described symbols and no prefix", () => {
685 assertStrictEquals(toFunctionName(Symbol("etaoin")), "[etaoin]");
688 it("[[Call]] works with strings and a prefix", () => {
689 assertStrictEquals(toFunctionName("etaoin", "foo"), "foo etaoin");
692 it("[[Call]] works with objects and no prefix", () => {
703 it("[[Call]] works with descriptionless symbols and no prefix", () => {
704 assertStrictEquals(toFunctionName(Symbol(), "foo"), "foo ");
707 it("[[Call]] works with empty description symbols and no prefix", () => {
708 assertStrictEquals(toFunctionName(Symbol(""), "foo"), "foo []");
711 it("[[Call]] works with described symbols and no prefix", () => {
713 toFunctionName(Symbol("etaoin"), "foo"),
718 it("[[Construct]] throws an error", () => {
719 assertThrows(() => new toFunctionName(""));
722 describe(".length", () => {
723 it("[[Get]] returns the correct length", () => {
724 assertStrictEquals(toFunctionName
.length
, 1);
728 describe(".name", () => {
729 it("[[Get]] returns the correct name", () => {
This page took 0.113392 seconds and 3 git commands to generate.