]> Lady’s Gitweb - Pisces/blob - function.test.js
Treat object function args more consistently
[Pisces] / function.test.js
1 // ♓🌟 Piscēs ∷ function.test.js
2 // ====================================================================
3 //
4 // Copyright © 2022 Lady [@ Lady’s Computer].
5 //
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/>.
9
10 import {
11 assert,
12 assertEquals,
13 assertStrictEquals,
14 describe,
15 it,
16 } from "./dev-deps.js";
17 import {
18 bind,
19 call,
20 construct,
21 identity,
22 isCallable,
23 isConstructor,
24 makeCallable,
25 ordinaryHasInstance,
26 } from "./function.js";
27
28 describe("bind", () => {
29 it("[[Call]] binds this", () => {
30 assertStrictEquals(
31 bind(
32 function () {
33 return this;
34 },
35 "pass",
36 [],
37 ).call("fail"),
38 "pass",
39 );
40 });
41
42 it("[[Call]] binds arguments", () => {
43 assertEquals(
44 bind(
45 function (...args) {
46 return [this, ...args];
47 },
48 "etaoin",
49 ["shrdlu"],
50 ).call("failure", "cmfwyp"),
51 ["etaoin", "shrdlu", "cmfwyp"],
52 );
53 });
54
55 it("[[Call]] works with any arraylike third argument", () => {
56 assertEquals(
57 bind(
58 function (...args) {
59 return [this, ...args];
60 },
61 "etaoin",
62 {
63 1: "shrdlu",
64 3: "failure",
65 length: 3,
66 },
67 ).call("failure", "cmfwyp"),
68 ["etaoin", undefined, "shrdlu", undefined, "cmfwyp"],
69 );
70 });
71 });
72
73 describe("call", () => {
74 it("[[Call]] calls with the provided this value", () => {
75 assertStrictEquals(
76 call(
77 function () {
78 return this;
79 },
80 "pass",
81 [],
82 ),
83 "pass",
84 );
85 });
86
87 it("[[Call]] calls with the provided arguments", () => {
88 assertEquals(
89 call(
90 function (...args) {
91 return [this, ...args];
92 },
93 "etaoin",
94 ["shrdlu", "cmfwyp"],
95 ),
96 ["etaoin", "shrdlu", "cmfwyp"],
97 );
98 });
99
100 it("[[Call]] works with any arraylike third argument", () => {
101 assertEquals(
102 call(
103 function (...args) {
104 return [this, ...args];
105 },
106 "etaoin",
107 {
108 1: "shrdlu",
109 3: "cmfwyp",
110 4: "failure",
111 length: 4,
112 },
113 ),
114 ["etaoin", undefined, "shrdlu", undefined, "cmfwyp"],
115 );
116 });
117 });
118
119 describe("construct", () => {
120 it("[[Call]] defaults to the constructor as the target", () => {
121 const constructor = class {};
122 assertStrictEquals(
123 Object.getPrototypeOf(construct(
124 constructor,
125 [],
126 )),
127 constructor.prototype,
128 );
129 });
130
131 it("[[Call]] constructs with the provided new target", () => {
132 const target = function () {};
133 assertStrictEquals(
134 construct(
135 function () {
136 return new.target;
137 },
138 [],
139 target,
140 ),
141 target,
142 );
143 });
144
145 it("[[Call]] constructs with the provided arguments", () => {
146 assertEquals(
147 construct(
148 function (...args) {
149 return [new.target.value, ...args];
150 },
151 ["shrdlu", "cmfwyp"],
152 Object.assign(function () {}, { value: "etaoin" }),
153 ),
154 ["etaoin", "shrdlu", "cmfwyp"],
155 );
156 });
157
158 it("[[Call]] works with any arraylike third argument", () => {
159 assertEquals(
160 construct(
161 function (...args) {
162 return [new.target.value, ...args];
163 },
164 {
165 1: "shrdlu",
166 3: "cmfwyp",
167 4: "failure",
168 length: 4,
169 },
170 Object.assign(function () {}, { value: "etaoin" }),
171 ),
172 ["etaoin", undefined, "shrdlu", undefined, "cmfwyp"],
173 );
174 });
175 });
176
177 describe("identity", () => {
178 it("[[Call]] returns what it is given", () => {
179 const value = {};
180 assertStrictEquals(identity(value), value);
181 });
182
183 it("[[Construct]] is constructable", () => {
184 const value = {};
185 assertStrictEquals(new identity(value), value);
186 });
187
188 it("[[Construct]] is subclassable", () => {
189 const value = {};
190 assertStrictEquals(new class extends identity {}(value), value);
191 });
192 });
193
194 describe("isCallable", () => {
195 it("[[Call]] returns true for ordinary functions", () => {
196 assert(isCallable(function () {}));
197 });
198
199 it("[[Call]] returns true for arrow functions", () => {
200 assert(isCallable(() => {}));
201 });
202
203 it("[[Call]] returns true for generator functions", () => {
204 assert(isCallable(function* () {}));
205 });
206
207 it("[[Call]] returns true for classes", () => {
208 assert(isCallable(class {}));
209 });
210
211 it("[[Call]] returns true for builtin functions", () => {
212 assert(isCallable(Math.ceil));
213 });
214
215 it("[[Call]] returns false for null", () => {
216 assert(!isCallable(null));
217 });
218
219 it("[[Call]] returns false for objects", () => {
220 assert(!isCallable({}));
221 });
222 });
223
224 describe("isConstructor", () => {
225 it("[[Call]] returns true for ordinary functions", () => {
226 assert(isConstructor(function () {}));
227 });
228
229 it("[[Call]] returns false for arrow functions", () => {
230 assert(!isConstructor(() => {}));
231 });
232
233 it("[[Call]] returns false for generator functions", () => {
234 assert(!isConstructor(function* () {}));
235 });
236
237 it("[[Call]] returns true for classes", () => {
238 assert(isConstructor(class {}));
239 });
240
241 it("[[Call]] returns false for builtin functions", () => {
242 assert(!isConstructor(Math.ceil));
243 });
244
245 it("[[Call]] returns false for null", () => {
246 assert(!isConstructor(null));
247 });
248
249 it("[[Call]] returns false for objects", () => {
250 assert(!isConstructor({}));
251 });
252 });
253
254 describe("makeCallable", () => {
255 it("[[Call]] transfers the first argument to this", () => {
256 assertStrictEquals(
257 makeCallable(
258 function () {
259 return this;
260 },
261 ).call("fail", "pass"),
262 "pass",
263 );
264 });
265
266 it("[[Call]] transfers the remaining arguments", () => {
267 assertEquals(
268 makeCallable(
269 function (...args) {
270 return [this, ...args];
271 },
272 ).call("failure", "etaoin", "shrdlu", "cmfwyp"),
273 ["etaoin", "shrdlu", "cmfwyp"],
274 );
275 });
276 });
277
278 describe("ordinaryHasInstance", () => {
279 it("[[Call]] walks the prototype chain", () => {
280 const constructor = class {
281 [Symbol.hasInstance]() {
282 return false;
283 }
284 };
285 assert(
286 ordinaryHasInstance(
287 constructor,
288 new class extends constructor {}(),
289 ),
290 );
291 });
292 });
This page took 0.066319 seconds and 5 git commands to generate.