]>
Lady’s Gitweb - Pisces/blob - function.test.js
1165d03da1defd41ff58239b22e257090451762f
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("[[Construct]] throws an error", () => {
292 assertThrows(() => new createCallableFunction(function () {}));
295 describe(".length", () => {
296 it("[[Get]] returns the correct length", () => {
297 assertStrictEquals(createCallableFunction
.length
, 1);
301 describe(".name", () => {
302 it("[[Get]] returns the correct name", () => {
304 createCallableFunction
.name
,
305 "createCallableFunction",
311 describe("createIllegalConstructor", () => {
312 it("[[Call]] returns a constructor", () => {
313 assert(isConstructor(createIllegalConstructor()));
316 it("[[Call]] works as expected when provided with no arguments", () => {
317 const constructor = createIllegalConstructor();
319 Object
.getPrototypeOf(constructor),
323 Object
.getPrototypeOf(constructor.prototype),
326 assertEquals(constructor.prototype, {});
328 !Object
.getOwnPropertyDescriptor(constructor, "prototype")
331 assertStrictEquals(constructor.name
, "");
334 it("[[Call]] returns a correctly‐formed constructor when provided one argument", () => {
335 const constructorPrototype
= Object
.create(null, {
336 name
: { value
: "etaoin" },
337 prototype: { value
: {} },
339 const constructor = createIllegalConstructor(
340 Object
.create(constructorPrototype
),
342 assert(isConstructor(constructor));
344 Object
.getPrototypeOf(constructor),
345 constructorPrototype
,
347 assert(Object
.hasOwn(constructor, "prototype"));
349 constructor.prototype,
350 constructorPrototype
.prototype,
353 !Object
.getOwnPropertyDescriptor(constructor, "prototype")
356 assertStrictEquals(constructor.name
, "etaoin");
359 it("[[Call]] allows the second argument to override the prototype of the constructor", () => {
360 const constructorPrototype
= Object
.create(null, {
361 name
: { value
: "etaoin" },
362 prototype: { value
: {} },
364 const expectedPrototype
= Object
.create(null, {
365 name
: { value
: "shrdlu" },
366 prototype: { value
: {} },
368 const constructor = createIllegalConstructor(
369 Object
.create(constructorPrototype
),
372 assert(isConstructor(constructor));
374 Object
.getPrototypeOf(constructor),
377 assert(Object
.hasOwn(constructor, "prototype"));
379 constructor.prototype,
380 constructorPrototype
.prototype,
383 !Object
.getOwnPropertyDescriptor(constructor, "prototype")
386 assertStrictEquals(constructor.name
, "etaoin");
389 it("[[Construct]] throws an error", () => {
390 assertThrows(() => new createIllegalConstructor(function () {}));
393 describe("~", () => {
394 it("[[Call]] throws an error", () => {
396 createIllegalConstructor(function () {})();
400 it("[[Construct]] throws an error", () => {
402 createIllegalConstructor(function () {})();
407 describe(".length", () => {
408 it("[[Get]] returns the correct length", () => {
409 assertStrictEquals(createIllegalConstructor
.length
, 1);
413 describe(".name", () => {
414 it("[[Get]] returns the correct name", () => {
416 createIllegalConstructor
.name
,
417 "createIllegalConstructor",
423 describe("identity", () => {
424 it("[[Call]] returns what it is given", () => {
426 assertStrictEquals(identity(value
), value
);
429 it("[[Construct]] is constructable", () => {
431 assertStrictEquals(new identity(value
), value
);
434 it("[[Construct]] is subclassable", () => {
436 assertStrictEquals(new class extends identity
{}(value
), value
);
439 describe(".length", () => {
440 it("[[Get]] returns the correct length", () => {
441 assertStrictEquals(identity
.length
, 1);
445 describe(".name", () => {
446 it("[[Get]] returns the correct name", () => {
447 assertStrictEquals(identity
.name
, "identity");
452 describe("isCallable", () => {
453 it("[[Call]] returns true for ordinary functions", () => {
454 assertStrictEquals(isCallable(function () {}), true);
457 it("[[Call]] returns true for arrow functions", () => {
458 assertStrictEquals(isCallable(() => {}), true);
461 it("[[Call]] returns true for generator functions", () => {
462 assertStrictEquals(isCallable(function* () {}), true);
465 it("[[Call]] returns true for classes", () => {
466 assertStrictEquals(isCallable(class {}), true);
469 it("[[Call]] returns true for builtin functions", () => {
470 assertStrictEquals(isCallable(Math
.ceil
), true);
473 it("[[Call]] returns true for getters", () => {
476 Object
.getOwnPropertyDescriptor({
486 it("[[Call]] returns true for setters", () => {
489 Object
.getOwnPropertyDescriptor({
499 it("[[Call]] returns false for null", () => {
500 assertStrictEquals(isCallable(null), false);
503 it("[[Call]] returns false for objects", () => {
504 assertStrictEquals(isCallable({}), false);
507 it("[[Construct]] throws an error", () => {
508 assertThrows(() => new isCallable(function () {}));
511 describe(".length", () => {
512 it("[[Get]] returns the correct length", () => {
513 assertStrictEquals(isCallable
.length
, 1);
517 describe(".name", () => {
518 it("[[Get]] returns the correct name", () => {
519 assertStrictEquals(isCallable
.name
, "isCallable");
524 describe("isConstructor", () => {
525 it("[[Call]] returns true for ordinary functions", () => {
526 assertStrictEquals(isConstructor(function () {}), true);
529 it("[[Call]] returns false for arrow functions", () => {
530 assertStrictEquals(isConstructor(() => {}), false);
533 it("[[Call]] returns false for generator functions", () => {
534 assertStrictEquals(isConstructor(function* () {}), false);
537 it("[[Call]] returns true for classes", () => {
538 assertStrictEquals(isConstructor(class {}), true);
541 it("[[Call]] returns false for builtin functions", () => {
542 assertStrictEquals(isConstructor(Math
.ceil
), false);
545 it("[[Call]] returns false for getters", () => {
548 Object
.getOwnPropertyDescriptor({
558 it("[[Call]] returns false for setters", () => {
561 Object
.getOwnPropertyDescriptor({
571 it("[[Call]] returns false for null", () => {
572 assertStrictEquals(isConstructor(null), false);
575 it("[[Call]] returns false for objects", () => {
576 assertStrictEquals(isConstructor({}), false);
579 it("[[Construct]] throws an error", () => {
580 assertThrows(() => new isConstructor(function () {}));
583 describe(".length", () => {
584 it("[[Get]] returns the correct length", () => {
585 assertStrictEquals(isConstructor
.length
, 1);
589 describe(".name", () => {
590 it("[[Get]] returns the correct name", () => {
591 assertStrictEquals(isConstructor
.name
, "isConstructor");
596 describe("ordinaryHasInstance", () => {
597 it("[[Call]] walks the prototype chain", () => {
598 const constructor = class {
599 [Symbol
.hasInstance
]() {
606 new class extends constructor {}(),
612 it("[[Construct]] throws an error", () => {
613 assertThrows(() => new ordinaryHasInstance(function () {}, {}));
616 describe(".length", () => {
617 it("[[Get]] returns the correct length", () => {
618 assertStrictEquals(ordinaryHasInstance
.length
, 2);
622 describe(".name", () => {
623 it("[[Get]] returns the correct name", () => {
625 ordinaryHasInstance
.name
,
626 "ordinaryHasInstance",
632 describe("toFunctionName", () => {
633 it("[[Call]] works with strings and no prefix", () => {
634 assertStrictEquals(toFunctionName("etaoin"), "etaoin");
637 it("[[Call]] works with objects and no prefix", () => {
648 it("[[Call]] works with descriptionless symbols and no prefix", () => {
649 assertStrictEquals(toFunctionName(Symbol()), "");
652 it("[[Call]] works with empty description symbols and no prefix", () => {
653 assertStrictEquals(toFunctionName(Symbol("")), "[]");
656 it("[[Call]] works with described symbols and no prefix", () => {
657 assertStrictEquals(toFunctionName(Symbol("etaoin")), "[etaoin]");
660 it("[[Call]] works with strings and a prefix", () => {
661 assertStrictEquals(toFunctionName("etaoin", "foo"), "foo etaoin");
664 it("[[Call]] works with objects and no prefix", () => {
675 it("[[Call]] works with descriptionless symbols and no prefix", () => {
676 assertStrictEquals(toFunctionName(Symbol(), "foo"), "foo ");
679 it("[[Call]] works with empty description symbols and no prefix", () => {
680 assertStrictEquals(toFunctionName(Symbol(""), "foo"), "foo []");
683 it("[[Call]] works with described symbols and no prefix", () => {
685 toFunctionName(Symbol("etaoin"), "foo"),
690 it("[[Construct]] throws an error", () => {
691 assertThrows(() => new toFunctionName(""));
694 describe(".length", () => {
695 it("[[Get]] returns the correct length", () => {
696 assertStrictEquals(toFunctionName
.length
, 1);
700 describe(".name", () => {
701 it("[[Get]] returns the correct name", () => {
This page took 0.171838 seconds and 3 git commands to generate.