]> Lady’s Gitweb - Pisces/blob - value.test.js
ae2b7d850793cdd139c7064124064e3ff6db687c
[Pisces] / value.test.js
1 // ♓🌟 Piscēs ∷ value.test.js
2 // ====================================================================
3 //
4 // Copyright © 2022–2023 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 assertStrictEquals,
12 assertThrows,
13 describe,
14 it,
15 } from "./dev-deps.js";
16 import {
17 ASYNC_ITERATOR,
18 HAS_INSTANCE,
19 IS_CONCAT_SPREADABLE,
20 ITERATOR,
21 MATCH,
22 MATCH_ALL,
23 NULL,
24 ordinaryToPrimitive,
25 REPLACE,
26 sameValue,
27 sameValueZero,
28 SPECIES,
29 SPLIT,
30 TO_PRIMITIVE,
31 TO_STRING_TAG,
32 toPrimitive,
33 type,
34 UNDEFINED,
35 UNSCOPABLES,
36 } from "./value.js";
37
38 describe("ASYNC_ITERATOR", () => {
39 it("[[Get]] is @@asyncIterator", () => {
40 assertStrictEquals(ASYNC_ITERATOR, Symbol.asyncIterator);
41 });
42 });
43
44 describe("HAS_INSTANCE", () => {
45 it("[[Get]] is @@hasInstance", () => {
46 assertStrictEquals(HAS_INSTANCE, Symbol.hasInstance);
47 });
48 });
49
50 describe("IS_CONCAT_SPREADABLE", () => {
51 it("[[Get]] is @@isConcatSpreadable", () => {
52 assertStrictEquals(
53 IS_CONCAT_SPREADABLE,
54 Symbol.isConcatSpreadable,
55 );
56 });
57 });
58
59 describe("ITERATOR", () => {
60 it("[[Get]] is @@iterator", () => {
61 assertStrictEquals(ITERATOR, Symbol.iterator);
62 });
63 });
64
65 describe("MATCH", () => {
66 it("[[Get]] is @@match", () => {
67 assertStrictEquals(MATCH, Symbol.match);
68 });
69 });
70
71 describe("MATCH_ALL", () => {
72 it("[[Get]] is @@matchAll", () => {
73 assertStrictEquals(MATCH_ALL, Symbol.matchAll);
74 });
75 });
76
77 describe("NULL", () => {
78 it("[[Get]] is null", () => {
79 assertStrictEquals(NULL, null);
80 });
81 });
82
83 describe("REPLACE", () => {
84 it("[[Get]] is @@replace", () => {
85 assertStrictEquals(REPLACE, Symbol.replace);
86 });
87 });
88
89 describe("SPECIES", () => {
90 it("[[Get]] is @@species", () => {
91 assertStrictEquals(SPECIES, Symbol.species);
92 });
93 });
94
95 describe("SPLIT", () => {
96 it("[[Get]] is @@split", () => {
97 assertStrictEquals(SPLIT, Symbol.split);
98 });
99 });
100
101 describe("TO_PRIMITIVE", () => {
102 it("[[Get]] is @@toPrimitive", () => {
103 assertStrictEquals(TO_PRIMITIVE, Symbol.toPrimitive);
104 });
105 });
106
107 describe("TO_STRING_TAG", () => {
108 it("[[Get]] is @@toStringTag", () => {
109 assertStrictEquals(TO_STRING_TAG, Symbol.toStringTag);
110 });
111 });
112
113 describe("UNDEFINED", () => {
114 it("[[Get]] is undefined", () => {
115 assertStrictEquals(UNDEFINED, void {});
116 });
117 });
118
119 describe("UNSCOPABLES", () => {
120 it("[[Get]] is @@unscopables", () => {
121 assertStrictEquals(UNSCOPABLES, Symbol.unscopables);
122 });
123 });
124
125 describe("ordinaryToPrimitive", () => {
126 it("[[Call]] prefers `valueOf` by default", () => {
127 const obj = {
128 toString() {
129 return "failure";
130 },
131 valueOf() {
132 return "success";
133 },
134 };
135 assertStrictEquals(ordinaryToPrimitive(obj), "success");
136 assertStrictEquals(ordinaryToPrimitive(obj, "default"), "success");
137 });
138
139 it('[[Call]] prefers `valueOf` for a "number" hint', () => {
140 const obj = {
141 toString() {
142 return "failure";
143 },
144 valueOf() {
145 return "success";
146 },
147 };
148 assertStrictEquals(ordinaryToPrimitive(obj, "number"), "success");
149 });
150
151 it('[[Call]] prefers `toString` for a "string" hint', () => {
152 const obj = {
153 toString() {
154 return "success";
155 },
156 valueOf() {
157 return "failure";
158 },
159 };
160 assertStrictEquals(ordinaryToPrimitive(obj, "string"), "success");
161 });
162
163 it("[[Call]] falls back to the other method if the first isn’t callable", () => {
164 const obj = {
165 toString() {
166 return "success";
167 },
168 valueOf: "failure",
169 };
170 assertStrictEquals(ordinaryToPrimitive(obj), "success");
171 });
172
173 it("[[Call]] falls back to the other method if the first returns an object", () => {
174 const obj = {
175 toString() {
176 return "success";
177 },
178 valueOf() {
179 return new String("failure");
180 },
181 };
182 assertStrictEquals(ordinaryToPrimitive(obj), "success");
183 });
184
185 it("[[Call]] throws an error if neither method is callable", () => {
186 const obj = {
187 toString: "failure",
188 valueOf: "failure",
189 };
190 assertThrows(() => ordinaryToPrimitive(obj));
191 });
192
193 it("[[Call]] throws an error if neither method returns an object", () => {
194 const obj = {
195 toString() {
196 return new String("failure");
197 },
198 valueOf() {
199 return new String("failure");
200 },
201 };
202 assertThrows(() => ordinaryToPrimitive(obj));
203 });
204
205 it("[[Construct]] throws an error", () => {
206 assertThrows(() => new ordinaryToPrimitive(""));
207 });
208
209 describe(".length", () => {
210 it("[[Get]] returns the correct length", () => {
211 assertStrictEquals(ordinaryToPrimitive.length, 2);
212 });
213 });
214
215 describe(".name", () => {
216 it("[[Get]] returns the correct name", () => {
217 assertStrictEquals(
218 ordinaryToPrimitive.name,
219 "ordinaryToPrimitive",
220 );
221 });
222 });
223 });
224
225 describe("sameValue", () => {
226 it("[[Call]] returns false for null 🆚 undefined", () => {
227 assertStrictEquals(sameValue(null, undefined), false);
228 });
229
230 it("[[Call]] returns false for null 🆚 an object", () => {
231 assertStrictEquals(sameValue(null, {}), false);
232 });
233
234 it("[[Call]] returns true for null 🆚 null", () => {
235 assertStrictEquals(sameValue(null, null), true);
236 });
237
238 it("[[Call]] returns false for two different objects", () => {
239 assertStrictEquals(sameValue({}, {}), false);
240 });
241
242 it("[[Call]] returns true for the same object", () => {
243 const obj = {};
244 assertStrictEquals(sameValue(obj, obj), true);
245 });
246
247 it("[[Call]] returns false for ±0", () => {
248 assertStrictEquals(sameValue(0, -0), false);
249 });
250
251 it("[[Call]] returns true for -0", () => {
252 assertStrictEquals(sameValue(-0, -0), true);
253 });
254
255 it("[[Call]] returns true for nan", () => {
256 assertStrictEquals(sameValue(0 / 0, 0 / 0), true);
257 });
258
259 it("[[Call]] returns false for a primitive and its wrapped object", () => {
260 assertStrictEquals(sameValue(false, new Boolean(false)), false);
261 });
262
263 it("[[Construct]] throws an error", () => {
264 assertThrows(() => new sameValue(true, true));
265 });
266
267 describe(".length", () => {
268 it("[[Get]] returns the correct length", () => {
269 assertStrictEquals(sameValue.length, 2);
270 });
271 });
272
273 describe(".name", () => {
274 it("[[Get]] returns the correct name", () => {
275 assertStrictEquals(sameValue.name, "sameValue");
276 });
277 });
278 });
279
280 describe("sameValueZero", () => {
281 it("[[Call]] returns false for null 🆚 undefined", () => {
282 assertStrictEquals(sameValueZero(null, undefined), false);
283 });
284
285 it("[[Call]] returns false for null 🆚 an object", () => {
286 assertStrictEquals(sameValueZero(null, {}), false);
287 });
288
289 it("[[Call]] returns true for null 🆚 null", () => {
290 assertStrictEquals(sameValueZero(null, null), true);
291 });
292
293 it("[[Call]] returns false for two different objects", () => {
294 assertStrictEquals(sameValueZero({}, {}), false);
295 });
296
297 it("[[Call]] returns true for the same object", () => {
298 const obj = {};
299 assertStrictEquals(sameValueZero(obj, obj), true);
300 });
301
302 it("[[Call]] returns true for ±0", () => {
303 assertStrictEquals(sameValueZero(0, -0), true);
304 });
305
306 it("[[Call]] returns true for -0", () => {
307 assertStrictEquals(sameValueZero(-0, -0), true);
308 });
309
310 it("[[Call]] returns true for nan", () => {
311 assertStrictEquals(sameValueZero(0 / 0, 0 / 0), true);
312 });
313
314 it("[[Call]] returns false for a primitive and its wrapped object", () => {
315 assertStrictEquals(
316 sameValueZero(false, new Boolean(false)),
317 false,
318 );
319 });
320
321 it("[[Construct]] throws an error", () => {
322 assertThrows(() => new sameValueZero(true, true));
323 });
324
325 describe(".length", () => {
326 it("[[Get]] returns the correct length", () => {
327 assertStrictEquals(sameValueZero.length, 2);
328 });
329 });
330
331 describe(".name", () => {
332 it("[[Get]] returns the correct name", () => {
333 assertStrictEquals(sameValueZero.name, "sameValueZero");
334 });
335 });
336 });
337
338 describe("toPrimitive", () => {
339 it("[[Call]] returns the argument when passed a primitive", () => {
340 const value = Symbol();
341 assertStrictEquals(toPrimitive(value), value);
342 });
343
344 it("[[Call]] works with nullish values", () => {
345 assertStrictEquals(toPrimitive(null), null);
346 assertStrictEquals(toPrimitive(), void {});
347 });
348
349 it("[[Call]] calls ordinaryToPrimitive by default", () => {
350 const value = Object.assign(
351 Object.create(null),
352 {
353 valueOf() {
354 return "success";
355 },
356 },
357 );
358 assertStrictEquals(toPrimitive(value), "success");
359 });
360
361 it("[[Call]] accepts a hint", () => {
362 const value = Object.assign(
363 Object.create(null),
364 {
365 toString() {
366 return "success";
367 },
368 valueOf() {
369 return "failure";
370 },
371 },
372 );
373 assertStrictEquals(toPrimitive(value, "string"), "success");
374 });
375
376 it("[[Call]] uses the exotic toPrimitive method if available", () => {
377 const value = Object.assign(
378 Object.create(null),
379 {
380 [Symbol.toPrimitive]() {
381 return "success";
382 },
383 },
384 );
385 assertStrictEquals(toPrimitive(value), "success");
386 });
387
388 it("[[Call]] passes the hint to the exotic toPrimitive", () => {
389 const value = Object.assign(
390 Object.create(null),
391 {
392 [Symbol.toPrimitive](hint) {
393 return hint === "string" ? "success" : "failure";
394 },
395 },
396 );
397 assertStrictEquals(toPrimitive(value, "string"), "success");
398 });
399
400 it('[[Call]] passes a "default" hint by default', () => {
401 const value = Object.assign(
402 Object.create(null),
403 {
404 [Symbol.toPrimitive](hint) {
405 return hint === "default" ? "success" : "failure";
406 },
407 },
408 );
409 assertStrictEquals(toPrimitive(value), "success");
410 });
411
412 it("[[Call]] throws for an invalid hint", () => {
413 const value1 = Object.assign(
414 Object.create(null),
415 {
416 [Symbol.toPrimitive]() {
417 return "success";
418 },
419 },
420 );
421 const value2 = Object.assign(
422 Object.create(null),
423 {
424 valueOf() {
425 return true;
426 },
427 },
428 );
429 assertThrows(() => toPrimitive(value1, "badhint"));
430 assertThrows(() => toPrimitive(value2, "badhint"));
431 assertThrows(() => toPrimitive(true, "badhint"));
432 });
433
434 it("[[Construct]] throws an error", () => {
435 assertThrows(() => new toPrimitive(true));
436 });
437
438 describe(".length", () => {
439 it("[[Get]] returns the correct length", () => {
440 assertStrictEquals(toPrimitive.length, 1);
441 });
442 });
443
444 describe(".name", () => {
445 it("[[Get]] returns the correct name", () => {
446 assertStrictEquals(toPrimitive.name, "toPrimitive");
447 });
448 });
449 });
450
451 describe("type", () => {
452 it('[[Call]] returns "null" for null', () => {
453 assertStrictEquals(type(null), "null");
454 });
455
456 it('[[Call]] returns "undefined" for undefined', () => {
457 assertStrictEquals(type(void {}), "undefined");
458 });
459
460 it('[[Call]] returns "object" for non‐callable objects', () => {
461 assertStrictEquals(type(Object.create(null)), "object");
462 });
463
464 it('[[Call]] returns "object" for callable objects', () => {
465 assertStrictEquals(type(() => {}), "object");
466 });
467
468 it('[[Call]] returns "object" for constructable objects', () => {
469 assertStrictEquals(type(class {}), "object");
470 });
471
472 it("[[Construct]] throws an error", () => {
473 assertThrows(() => new type({}));
474 });
475
476 describe(".length", () => {
477 it("[[Get]] returns the correct length", () => {
478 assertStrictEquals(type.length, 1);
479 });
480 });
481
482 describe(".name", () => {
483 it("[[Get]] returns the correct name", () => {
484 assertStrictEquals(type.name, "type");
485 });
486 });
487 });
This page took 0.084436 seconds and 3 git commands to generate.