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