]> Lady’s Gitweb - Pisces/blob - value.test.js
d68ff653e091b9573b5e69b5526c791fdcc76f61
[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 lengthOfArraylike,
22 MATCH,
23 MATCH_ALL,
24 NULL,
25 ordinaryToPrimitive,
26 REPLACE,
27 sameValue,
28 sameValueZero,
29 SPECIES,
30 SPLIT,
31 TO_PRIMITIVE,
32 TO_STRING_TAG,
33 toIndex,
34 toLength,
35 toPrimitive,
36 type,
37 UNDEFINED,
38 UNSCOPABLES,
39 } from "./value.js";
40
41 describe("ASYNC_ITERATOR", () => {
42 it("[[Get]] is @@asyncIterator", () => {
43 assertStrictEquals(ASYNC_ITERATOR, Symbol.asyncIterator);
44 });
45 });
46
47 describe("HAS_INSTANCE", () => {
48 it("[[Get]] is @@hasInstance", () => {
49 assertStrictEquals(HAS_INSTANCE, Symbol.hasInstance);
50 });
51 });
52
53 describe("IS_CONCAT_SPREADABLE", () => {
54 it("[[Get]] is @@isConcatSpreadable", () => {
55 assertStrictEquals(
56 IS_CONCAT_SPREADABLE,
57 Symbol.isConcatSpreadable,
58 );
59 });
60 });
61
62 describe("ITERATOR", () => {
63 it("[[Get]] is @@iterator", () => {
64 assertStrictEquals(ITERATOR, Symbol.iterator);
65 });
66 });
67
68 describe("MATCH", () => {
69 it("[[Get]] is @@match", () => {
70 assertStrictEquals(MATCH, Symbol.match);
71 });
72 });
73
74 describe("MATCH_ALL", () => {
75 it("[[Get]] is @@matchAll", () => {
76 assertStrictEquals(MATCH_ALL, Symbol.matchAll);
77 });
78 });
79
80 describe("NULL", () => {
81 it("[[Get]] is null", () => {
82 assertStrictEquals(NULL, null);
83 });
84 });
85
86 describe("REPLACE", () => {
87 it("[[Get]] is @@replace", () => {
88 assertStrictEquals(REPLACE, Symbol.replace);
89 });
90 });
91
92 describe("SPECIES", () => {
93 it("[[Get]] is @@species", () => {
94 assertStrictEquals(SPECIES, Symbol.species);
95 });
96 });
97
98 describe("SPLIT", () => {
99 it("[[Get]] is @@split", () => {
100 assertStrictEquals(SPLIT, Symbol.split);
101 });
102 });
103
104 describe("TO_PRIMITIVE", () => {
105 it("[[Get]] is @@toPrimitive", () => {
106 assertStrictEquals(TO_PRIMITIVE, Symbol.toPrimitive);
107 });
108 });
109
110 describe("TO_STRING_TAG", () => {
111 it("[[Get]] is @@toStringTag", () => {
112 assertStrictEquals(TO_STRING_TAG, Symbol.toStringTag);
113 });
114 });
115
116 describe("UNDEFINED", () => {
117 it("[[Get]] is undefined", () => {
118 assertStrictEquals(UNDEFINED, void {});
119 });
120 });
121
122 describe("UNSCOPABLES", () => {
123 it("[[Get]] is @@unscopables", () => {
124 assertStrictEquals(UNSCOPABLES, Symbol.unscopables);
125 });
126 });
127
128 describe("lengthOfArraylike", () => {
129 it("[[Call]] returns the length", () => {
130 assertStrictEquals(
131 lengthOfArraylike({ length: 9007199254740991 }),
132 9007199254740991,
133 );
134 });
135
136 it("[[Call]] returns a non·nan result", () => {
137 assertStrictEquals(lengthOfArraylike({ length: NaN }), 0);
138 assertStrictEquals(lengthOfArraylike({ length: "failure" }), 0);
139 });
140
141 it("[[Call]] returns an integral result", () => {
142 assertStrictEquals(lengthOfArraylike({ length: 0.25 }), 0);
143 assertStrictEquals(lengthOfArraylike({ length: 1.1 }), 1);
144 });
145
146 it("[[Call]] returns a result greater than or equal to zero", () => {
147 assertStrictEquals(lengthOfArraylike({ length: -0 }), 0);
148 assertStrictEquals(lengthOfArraylike({ length: -1 }), 0);
149 assertStrictEquals(lengthOfArraylike({ length: -Infinity }), 0);
150 });
151
152 it("[[Call]] returns a result less than 2 ** 53", () => {
153 assertStrictEquals(
154 lengthOfArraylike({ length: 9007199254740992 }),
155 9007199254740991,
156 );
157 assertStrictEquals(
158 lengthOfArraylike({ length: Infinity }),
159 9007199254740991,
160 );
161 });
162
163 it("[[Call]] does not require an object argument", () => {
164 assertStrictEquals(lengthOfArraylike("string"), 6);
165 assertStrictEquals(lengthOfArraylike(Symbol()), 0);
166 });
167
168 it("[[Construct]] throws an error", () => {
169 assertThrows(() => new lengthOfArraylike(""));
170 });
171
172 describe(".length", () => {
173 it("[[Get]] returns the correct length", () => {
174 assertStrictEquals(lengthOfArraylike.length, 1);
175 });
176 });
177
178 describe(".name", () => {
179 it("[[Get]] returns the correct name", () => {
180 assertStrictEquals(lengthOfArraylike.name, "lengthOfArraylike");
181 });
182 });
183 });
184
185 describe("ordinaryToPrimitive", () => {
186 it("[[Call]] prefers `valueOf` by default", () => {
187 const obj = {
188 toString() {
189 return "failure";
190 },
191 valueOf() {
192 return "success";
193 },
194 };
195 assertStrictEquals(ordinaryToPrimitive(obj), "success");
196 assertStrictEquals(ordinaryToPrimitive(obj, "default"), "success");
197 });
198
199 it('[[Call]] prefers `valueOf` for a "number" hint', () => {
200 const obj = {
201 toString() {
202 return "failure";
203 },
204 valueOf() {
205 return "success";
206 },
207 };
208 assertStrictEquals(ordinaryToPrimitive(obj, "number"), "success");
209 });
210
211 it('[[Call]] prefers `toString` for a "string" hint', () => {
212 const obj = {
213 toString() {
214 return "success";
215 },
216 valueOf() {
217 return "failure";
218 },
219 };
220 assertStrictEquals(ordinaryToPrimitive(obj, "string"), "success");
221 });
222
223 it("[[Call]] falls back to the other method if the first isn’t callable", () => {
224 const obj = {
225 toString() {
226 return "success";
227 },
228 valueOf: "failure",
229 };
230 assertStrictEquals(ordinaryToPrimitive(obj), "success");
231 });
232
233 it("[[Call]] falls back to the other method if the first returns an object", () => {
234 const obj = {
235 toString() {
236 return "success";
237 },
238 valueOf() {
239 return new String("failure");
240 },
241 };
242 assertStrictEquals(ordinaryToPrimitive(obj), "success");
243 });
244
245 it("[[Call]] throws an error if neither method is callable", () => {
246 const obj = {
247 toString: "failure",
248 valueOf: "failure",
249 };
250 assertThrows(() => ordinaryToPrimitive(obj));
251 });
252
253 it("[[Call]] throws an error if neither method returns an object", () => {
254 const obj = {
255 toString() {
256 return new String("failure");
257 },
258 valueOf() {
259 return new String("failure");
260 },
261 };
262 assertThrows(() => ordinaryToPrimitive(obj));
263 });
264
265 it("[[Construct]] throws an error", () => {
266 assertThrows(() => new ordinaryToPrimitive(""));
267 });
268
269 describe(".length", () => {
270 it("[[Get]] returns the correct length", () => {
271 assertStrictEquals(ordinaryToPrimitive.length, 2);
272 });
273 });
274
275 describe(".name", () => {
276 it("[[Get]] returns the correct name", () => {
277 assertStrictEquals(
278 ordinaryToPrimitive.name,
279 "ordinaryToPrimitive",
280 );
281 });
282 });
283 });
284
285 describe("sameValue", () => {
286 it("[[Call]] returns false for null 🆚 undefined", () => {
287 assertStrictEquals(sameValue(null, undefined), false);
288 });
289
290 it("[[Call]] returns false for null 🆚 an object", () => {
291 assertStrictEquals(sameValue(null, {}), false);
292 });
293
294 it("[[Call]] returns true for null 🆚 null", () => {
295 assertStrictEquals(sameValue(null, null), true);
296 });
297
298 it("[[Call]] returns false for two different objects", () => {
299 assertStrictEquals(sameValue({}, {}), false);
300 });
301
302 it("[[Call]] returns true for the same object", () => {
303 const obj = {};
304 assertStrictEquals(sameValue(obj, obj), true);
305 });
306
307 it("[[Call]] returns false for ±0", () => {
308 assertStrictEquals(sameValue(0, -0), false);
309 });
310
311 it("[[Call]] returns true for -0", () => {
312 assertStrictEquals(sameValue(-0, -0), true);
313 });
314
315 it("[[Call]] returns true for nan", () => {
316 assertStrictEquals(sameValue(0 / 0, 0 / 0), true);
317 });
318
319 it("[[Call]] returns false for a primitive and its wrapped object", () => {
320 assertStrictEquals(sameValue(false, new Boolean(false)), false);
321 });
322
323 it("[[Construct]] throws an error", () => {
324 assertThrows(() => new sameValue(true, true));
325 });
326
327 describe(".length", () => {
328 it("[[Get]] returns the correct length", () => {
329 assertStrictEquals(sameValue.length, 2);
330 });
331 });
332
333 describe(".name", () => {
334 it("[[Get]] returns the correct name", () => {
335 assertStrictEquals(sameValue.name, "sameValue");
336 });
337 });
338 });
339
340 describe("sameValueZero", () => {
341 it("[[Call]] returns false for null 🆚 undefined", () => {
342 assertStrictEquals(sameValueZero(null, undefined), false);
343 });
344
345 it("[[Call]] returns false for null 🆚 an object", () => {
346 assertStrictEquals(sameValueZero(null, {}), false);
347 });
348
349 it("[[Call]] returns true for null 🆚 null", () => {
350 assertStrictEquals(sameValueZero(null, null), true);
351 });
352
353 it("[[Call]] returns false for two different objects", () => {
354 assertStrictEquals(sameValueZero({}, {}), false);
355 });
356
357 it("[[Call]] returns true for the same object", () => {
358 const obj = {};
359 assertStrictEquals(sameValueZero(obj, obj), true);
360 });
361
362 it("[[Call]] returns true for ±0", () => {
363 assertStrictEquals(sameValueZero(0, -0), true);
364 });
365
366 it("[[Call]] returns true for -0", () => {
367 assertStrictEquals(sameValueZero(-0, -0), true);
368 });
369
370 it("[[Call]] returns true for nan", () => {
371 assertStrictEquals(sameValueZero(0 / 0, 0 / 0), true);
372 });
373
374 it("[[Call]] returns false for a primitive and its wrapped object", () => {
375 assertStrictEquals(
376 sameValueZero(false, new Boolean(false)),
377 false,
378 );
379 });
380
381 it("[[Construct]] throws an error", () => {
382 assertThrows(() => new sameValueZero(true, true));
383 });
384
385 describe(".length", () => {
386 it("[[Get]] returns the correct length", () => {
387 assertStrictEquals(sameValueZero.length, 2);
388 });
389 });
390
391 describe(".name", () => {
392 it("[[Get]] returns the correct name", () => {
393 assertStrictEquals(sameValueZero.name, "sameValueZero");
394 });
395 });
396 });
397
398 describe("toIndex", () => {
399 it("[[Call]] returns an index", () => {
400 assertStrictEquals(toIndex(9007199254740991), 9007199254740991);
401 });
402
403 it("[[Call]] returns zero for a zerolike argument", () => {
404 assertStrictEquals(toIndex(NaN), 0);
405 assertStrictEquals(toIndex("failure"), 0);
406 assertStrictEquals(toIndex(-0), 0);
407 });
408
409 it("[[Call]] rounds down to the nearest integer", () => {
410 assertStrictEquals(toIndex(0.25), 0);
411 assertStrictEquals(toIndex(1.1), 1);
412 });
413
414 it("[[Call]] throws when provided a negative number", () => {
415 assertThrows(() => toIndex(-1));
416 assertThrows(() => toIndex(-Infinity));
417 });
418
419 it("[[Call]] throws when provided a number greater than or equal to 2 ** 53", () => {
420 assertThrows(() => toIndex(9007199254740992));
421 assertThrows(() => toIndex(Infinity));
422 });
423
424 it("[[Construct]] throws an error", () => {
425 assertThrows(() => new toIndex(0));
426 });
427
428 describe(".length", () => {
429 it("[[Get]] returns the correct length", () => {
430 assertStrictEquals(toIndex.length, 1);
431 });
432 });
433
434 describe(".name", () => {
435 it("[[Get]] returns the correct name", () => {
436 assertStrictEquals(toIndex.name, "toIndex");
437 });
438 });
439 });
440
441 describe("toLength", () => {
442 it("[[Call]] returns a length", () => {
443 assertStrictEquals(toLength(9007199254740991), 9007199254740991);
444 });
445
446 it("[[Call]] returns zero for a nan argument", () => {
447 assertStrictEquals(toLength(NaN), 0);
448 assertStrictEquals(toLength("failure"), 0);
449 });
450
451 it("[[Call]] rounds down to the nearest integer", () => {
452 assertStrictEquals(toLength(0.25), 0);
453 assertStrictEquals(toLength(1.1), 1);
454 });
455
456 it("[[Call]] returns a result greater than or equal to zero", () => {
457 assertStrictEquals(toLength(-0), 0);
458 assertStrictEquals(toLength(-1), 0);
459 assertStrictEquals(toLength(-Infinity), 0);
460 });
461
462 it("[[Call]] returns a result less than 2 ** 53", () => {
463 assertStrictEquals(toLength(9007199254740992), 9007199254740991);
464 assertStrictEquals(toLength(Infinity), 9007199254740991);
465 });
466
467 it("[[Construct]] throws an error", () => {
468 assertThrows(() => new toLength(0));
469 });
470
471 describe(".length", () => {
472 it("[[Get]] returns the correct length", () => {
473 assertStrictEquals(toLength.length, 1);
474 });
475 });
476
477 describe(".name", () => {
478 it("[[Get]] returns the correct name", () => {
479 assertStrictEquals(toLength.name, "toLength");
480 });
481 });
482 });
483
484 describe("toPrimitive", () => {
485 it("[[Call]] returns the argument when passed a primitive", () => {
486 const value = Symbol();
487 assertStrictEquals(toPrimitive(value), value);
488 });
489
490 it("[[Call]] works with nullish values", () => {
491 assertStrictEquals(toPrimitive(null), null);
492 assertStrictEquals(toPrimitive(), void {});
493 });
494
495 it("[[Call]] calls ordinaryToPrimitive by default", () => {
496 const value = Object.assign(
497 Object.create(null),
498 {
499 valueOf() {
500 return "success";
501 },
502 },
503 );
504 assertStrictEquals(toPrimitive(value), "success");
505 });
506
507 it("[[Call]] accepts a hint", () => {
508 const value = Object.assign(
509 Object.create(null),
510 {
511 toString() {
512 return "success";
513 },
514 valueOf() {
515 return "failure";
516 },
517 },
518 );
519 assertStrictEquals(toPrimitive(value, "string"), "success");
520 });
521
522 it("[[Call]] uses the exotic toPrimitive method if available", () => {
523 const value = Object.assign(
524 Object.create(null),
525 {
526 [Symbol.toPrimitive]() {
527 return "success";
528 },
529 },
530 );
531 assertStrictEquals(toPrimitive(value), "success");
532 });
533
534 it("[[Call]] passes the hint to the exotic toPrimitive", () => {
535 const value = Object.assign(
536 Object.create(null),
537 {
538 [Symbol.toPrimitive](hint) {
539 return hint === "string" ? "success" : "failure";
540 },
541 },
542 );
543 assertStrictEquals(toPrimitive(value, "string"), "success");
544 });
545
546 it('[[Call]] passes a "default" hint by default', () => {
547 const value = Object.assign(
548 Object.create(null),
549 {
550 [Symbol.toPrimitive](hint) {
551 return hint === "default" ? "success" : "failure";
552 },
553 },
554 );
555 assertStrictEquals(toPrimitive(value), "success");
556 });
557
558 it("[[Call]] throws for an invalid hint", () => {
559 const value1 = Object.assign(
560 Object.create(null),
561 {
562 [Symbol.toPrimitive]() {
563 return "success";
564 },
565 },
566 );
567 const value2 = Object.assign(
568 Object.create(null),
569 {
570 valueOf() {
571 return true;
572 },
573 },
574 );
575 assertThrows(() => toPrimitive(value1, "badhint"));
576 assertThrows(() => toPrimitive(value2, "badhint"));
577 assertThrows(() => toPrimitive(true, "badhint"));
578 });
579
580 it("[[Construct]] throws an error", () => {
581 assertThrows(() => new toPrimitive(true));
582 });
583
584 describe(".length", () => {
585 it("[[Get]] returns the correct length", () => {
586 assertStrictEquals(toPrimitive.length, 1);
587 });
588 });
589
590 describe(".name", () => {
591 it("[[Get]] returns the correct name", () => {
592 assertStrictEquals(toPrimitive.name, "toPrimitive");
593 });
594 });
595 });
596
597 describe("type", () => {
598 it('[[Call]] returns "null" for null', () => {
599 assertStrictEquals(type(null), "null");
600 });
601
602 it('[[Call]] returns "undefined" for undefined', () => {
603 assertStrictEquals(type(void {}), "undefined");
604 });
605
606 it('[[Call]] returns "object" for non‐callable objects', () => {
607 assertStrictEquals(type(Object.create(null)), "object");
608 });
609
610 it('[[Call]] returns "object" for callable objects', () => {
611 assertStrictEquals(type(() => {}), "object");
612 });
613
614 it('[[Call]] returns "object" for constructable objects', () => {
615 assertStrictEquals(type(class {}), "object");
616 });
617
618 it("[[Construct]] throws an error", () => {
619 assertThrows(() => new type({}));
620 });
621
622 describe(".length", () => {
623 it("[[Get]] returns the correct length", () => {
624 assertStrictEquals(type.length, 1);
625 });
626 });
627
628 describe(".name", () => {
629 it("[[Get]] returns the correct name", () => {
630 assertStrictEquals(type.name, "type");
631 });
632 });
633 });
This page took 0.094123 seconds and 3 git commands to generate.