]>
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";
23 createCallableFunction
,
24 createIllegalConstructor
,
29 } from "./function.js";
31 describe("bind", () => {
32 it("[[Call]] binds this", () => {
45 it("[[Call]] binds arguments", () => {
49 return [this, ...args
];
53 ).call("failure", "cmfwyp"),
54 ["etaoin", "shrdlu", "cmfwyp"],
58 it("[[Call]] works with any arraylike third argument", () => {
62 return [this, ...args
];
70 ).call("failure", "cmfwyp"),
71 ["etaoin", undefined, "shrdlu", undefined, "cmfwyp"],
75 it("[[Construct]] throws an error", () => {
76 assertThrows(() => new bind(function () {}));
79 describe(".name", () => {
80 it("[[Get]] returns the correct name", () => {
81 assertStrictEquals(bind
.name
, "bind");
86 describe("call", () => {
87 it("[[Call]] calls with the provided this value", () => {
100 it("[[Call]] calls with the provided arguments", () => {
104 return [this, ...args
];
107 ["shrdlu", "cmfwyp"],
109 ["etaoin", "shrdlu", "cmfwyp"],
113 it("[[Call]] works with any arraylike third argument", () => {
117 return [this, ...args
];
127 ["etaoin", undefined, "shrdlu", undefined, "cmfwyp"],
131 it("[[Construct]] throws an error", () => {
132 assertThrows(() => new call(function () {}, null, []));
135 describe(".name", () => {
136 it("[[Get]] returns the correct name", () => {
137 assertStrictEquals(call
.name
, "call");
142 describe("completesNormally", () => {
143 it("[[Call]] returns true for functions which complete normally", () => {
144 assertStrictEquals(completesNormally(() => {}), true);
147 it("[[Call]] returns false for functions which throw", () => {
149 completesNormally(() => {
156 it("[[Call]] throws when the argument is not callable", () => {
157 assertThrows(() => completesNormally(null));
160 it("[[Call]] throws when the argument is not provided", () => {
161 assertThrows(() => completesNormally());
164 it("[[Construct]] throws an error", () => {
165 assertThrows(() => new completesNormally(function () {}));
168 describe(".name", () => {
169 it("[[Get]] returns the correct name", () => {
170 assertStrictEquals(completesNormally
.name
, "completesNormally");
175 describe("construct", () => {
176 it("[[Call]] defaults to the constructor as the target", () => {
177 const constructor = class {};
179 Object
.getPrototypeOf(construct(
183 constructor.prototype,
187 it("[[Call]] constructs with the provided new target", () => {
188 const target = function () {};
201 it("[[Call]] constructs with the provided arguments", () => {
205 return [new.target
.value
, ...args
];
207 ["shrdlu", "cmfwyp"],
208 Object
.assign(function () {}, { value
: "etaoin" }),
210 ["etaoin", "shrdlu", "cmfwyp"],
214 it("[[Call]] works with any arraylike third argument", () => {
218 return [new.target
.value
, ...args
];
226 Object
.assign(function () {}, { value
: "etaoin" }),
228 ["etaoin", undefined, "shrdlu", undefined, "cmfwyp"],
232 it("[[Construct]] throws an error", () => {
233 assertThrows(() => new construct(function () {}, []));
236 describe(".name", () => {
237 it("[[Get]] returns the correct name", () => {
238 assertStrictEquals(construct
.name
, "construct");
243 describe("createCallableFunction", () => {
244 it("[[Call]] transfers the first argument to this", () => {
246 createCallableFunction(
250 ).call("fail", "pass"),
255 it("[[Call]] transfers the remaining arguments", () => {
257 createCallableFunction(
259 return [this, ...args
];
261 ).call("failure", "etaoin", "shrdlu", "cmfwyp"),
262 ["etaoin", "shrdlu", "cmfwyp"],
266 it("[[Construct]] throws an error", () => {
267 assertThrows(() => new createCallableFunction(function () {}));
270 describe(".name", () => {
271 it("[[Get]] returns the correct name", () => {
273 createCallableFunction
.name
,
274 "createCallableFunction",
280 describe("createIllegalConstructor", () => {
281 it("[[Call]] returns a constructor", () => {
282 assert(isConstructor(createIllegalConstructor()));
285 it("[[Call]] works as expected when provided with no arguments", () => {
286 const constructor = createIllegalConstructor();
288 Object
.getPrototypeOf(constructor),
292 Object
.getPrototypeOf(constructor.prototype),
295 assertEquals(constructor.prototype, {});
297 !Object
.getOwnPropertyDescriptor(constructor, "prototype")
300 assertStrictEquals(constructor.name
, "");
303 it("[[Call]] returns a correctly‐formed constructor when provided one argument", () => {
304 const constructorPrototype
= Object
.create(null, {
305 name
: { value
: "etaoin" },
306 prototype: { value
: {} },
308 const constructor = createIllegalConstructor(
309 Object
.create(constructorPrototype
),
311 assert(isConstructor(constructor));
313 Object
.getPrototypeOf(constructor),
314 constructorPrototype
,
316 assert(Object
.hasOwn(constructor, "prototype"));
318 constructor.prototype,
319 constructorPrototype
.prototype,
322 !Object
.getOwnPropertyDescriptor(constructor, "prototype")
325 assertStrictEquals(constructor.name
, "etaoin");
328 it("[[Call]] allows the second argument to override the prototype of the constructor", () => {
329 const constructorPrototype
= Object
.create(null, {
330 name
: { value
: "etaoin" },
331 prototype: { value
: {} },
333 const expectedPrototype
= Object
.create(null, {
334 name
: { value
: "shrdlu" },
335 prototype: { value
: {} },
337 const constructor = createIllegalConstructor(
338 Object
.create(constructorPrototype
),
341 assert(isConstructor(constructor));
343 Object
.getPrototypeOf(constructor),
346 assert(Object
.hasOwn(constructor, "prototype"));
348 constructor.prototype,
349 constructorPrototype
.prototype,
352 !Object
.getOwnPropertyDescriptor(constructor, "prototype")
355 assertStrictEquals(constructor.name
, "etaoin");
358 it("[[Construct]] throws an error", () => {
359 assertThrows(() => new createIllegalConstructor(function () {}));
362 describe("~", () => {
363 it("[[Call]] throws an error", () => {
365 createIllegalConstructor(function () {})();
369 it("[[Construct]] throws an error", () => {
371 createIllegalConstructor(function () {})();
376 describe(".name", () => {
377 it("[[Get]] returns the correct name", () => {
379 createIllegalConstructor
.name
,
380 "createIllegalConstructor",
386 describe("identity", () => {
387 it("[[Call]] returns what it is given", () => {
389 assertStrictEquals(identity(value
), value
);
392 it("[[Construct]] is constructable", () => {
394 assertStrictEquals(new identity(value
), value
);
397 it("[[Construct]] is subclassable", () => {
399 assertStrictEquals(new class extends identity
{}(value
), value
);
402 describe(".name", () => {
403 it("[[Get]] returns the correct name", () => {
404 assertStrictEquals(identity
.name
, "identity");
409 describe("isCallable", () => {
410 it("[[Call]] returns true for ordinary functions", () => {
411 assertStrictEquals(isCallable(function () {}), true);
414 it("[[Call]] returns true for arrow functions", () => {
415 assertStrictEquals(isCallable(() => {}), true);
418 it("[[Call]] returns true for generator functions", () => {
419 assertStrictEquals(isCallable(function* () {}), true);
422 it("[[Call]] returns true for classes", () => {
423 assertStrictEquals(isCallable(class {}), true);
426 it("[[Call]] returns true for builtin functions", () => {
427 assertStrictEquals(isCallable(Math
.ceil
), true);
430 it("[[Call]] returns true for getters", () => {
433 Object
.getOwnPropertyDescriptor({
443 it("[[Call]] returns true for setters", () => {
446 Object
.getOwnPropertyDescriptor({
456 it("[[Call]] returns false for null", () => {
457 assertStrictEquals(isCallable(null), false);
460 it("[[Call]] returns false for objects", () => {
461 assertStrictEquals(isCallable({}), false);
464 it("[[Construct]] throws an error", () => {
465 assertThrows(() => new isCallable(function () {}));
468 describe(".name", () => {
469 it("[[Get]] returns the correct name", () => {
470 assertStrictEquals(isCallable
.name
, "isCallable");
475 describe("isConstructor", () => {
476 it("[[Call]] returns true for ordinary functions", () => {
477 assertStrictEquals(isConstructor(function () {}), true);
480 it("[[Call]] returns false for arrow functions", () => {
481 assertStrictEquals(isConstructor(() => {}), false);
484 it("[[Call]] returns false for generator functions", () => {
485 assertStrictEquals(isConstructor(function* () {}), false);
488 it("[[Call]] returns true for classes", () => {
489 assertStrictEquals(isConstructor(class {}), true);
492 it("[[Call]] returns false for builtin functions", () => {
493 assertStrictEquals(isConstructor(Math
.ceil
), false);
496 it("[[Call]] returns false for getters", () => {
499 Object
.getOwnPropertyDescriptor({
509 it("[[Call]] returns false for setters", () => {
512 Object
.getOwnPropertyDescriptor({
522 it("[[Call]] returns false for null", () => {
523 assertStrictEquals(isConstructor(null), false);
526 it("[[Call]] returns false for objects", () => {
527 assertStrictEquals(isConstructor({}), false);
530 it("[[Construct]] throws an error", () => {
531 assertThrows(() => new isConstructor(function () {}));
534 describe(".name", () => {
535 it("[[Get]] returns the correct name", () => {
536 assertStrictEquals(isConstructor
.name
, "isConstructor");
541 describe("ordinaryHasInstance", () => {
542 it("[[Call]] walks the prototype chain", () => {
543 const constructor = class {
544 [Symbol
.hasInstance
]() {
551 new class extends constructor {}(),
557 it("[[Construct]] throws an error", () => {
558 assertThrows(() => new ordinaryHasInstance(function () {}, {}));
561 describe(".name", () => {
562 it("[[Get]] returns the correct name", () => {
564 ordinaryHasInstance
.name
,
565 "ordinaryHasInstance",
This page took 0.207625 seconds and 5 git commands to generate.