1 // ♓🌟 Piscēs ∷ value.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/>.
15 } from "./dev-deps.js";
18 canonicalNumericIndexString
,
43 describe("ASYNC_ITERATOR", () => {
44 it("[[Get]] is @@asyncIterator", () => {
45 assertStrictEquals(ASYNC_ITERATOR
, Symbol
.asyncIterator
);
49 describe("HAS_INSTANCE", () => {
50 it("[[Get]] is @@hasInstance", () => {
51 assertStrictEquals(HAS_INSTANCE
, Symbol
.hasInstance
);
55 describe("IS_CONCAT_SPREADABLE", () => {
56 it("[[Get]] is @@isConcatSpreadable", () => {
59 Symbol
.isConcatSpreadable
,
64 describe("ITERATOR", () => {
65 it("[[Get]] is @@iterator", () => {
66 assertStrictEquals(ITERATOR
, Symbol
.iterator
);
70 describe("MATCH", () => {
71 it("[[Get]] is @@match", () => {
72 assertStrictEquals(MATCH
, Symbol
.match
);
76 describe("MATCH_ALL", () => {
77 it("[[Get]] is @@matchAll", () => {
78 assertStrictEquals(MATCH_ALL
, Symbol
.matchAll
);
82 describe("NULL", () => {
83 it("[[Get]] is null", () => {
84 assertStrictEquals(NULL
, null);
88 describe("REPLACE", () => {
89 it("[[Get]] is @@replace", () => {
90 assertStrictEquals(REPLACE
, Symbol
.replace
);
94 describe("SPECIES", () => {
95 it("[[Get]] is @@species", () => {
96 assertStrictEquals(SPECIES
, Symbol
.species
);
100 describe("SPLIT", () => {
101 it("[[Get]] is @@split", () => {
102 assertStrictEquals(SPLIT
, Symbol
.split
);
106 describe("TO_PRIMITIVE", () => {
107 it("[[Get]] is @@toPrimitive", () => {
108 assertStrictEquals(TO_PRIMITIVE
, Symbol
.toPrimitive
);
112 describe("TO_STRING_TAG", () => {
113 it("[[Get]] is @@toStringTag", () => {
114 assertStrictEquals(TO_STRING_TAG
, Symbol
.toStringTag
);
118 describe("UNDEFINED", () => {
119 it("[[Get]] is undefined", () => {
120 assertStrictEquals(UNDEFINED
, void {});
124 describe("UNSCOPABLES", () => {
125 it("[[Get]] is @@unscopables", () => {
126 assertStrictEquals(UNSCOPABLES
, Symbol
.unscopables
);
130 describe("canonicalNumericIndexString", () => {
131 it("[[Call]] returns undefined for nonstrings", () => {
132 assertStrictEquals(canonicalNumericIndexString(1), void {});
135 it("[[Call]] returns undefined for noncanonical strings", () => {
136 assertStrictEquals(canonicalNumericIndexString(""), void {});
137 assertStrictEquals(canonicalNumericIndexString("01"), void {});
139 canonicalNumericIndexString("9007199254740993"),
144 it('[[Call]] returns -0 for "-0"', () => {
145 assertStrictEquals(canonicalNumericIndexString("-0"), -0);
148 it("[[Call]] returns the corresponding number for canonical strings", () => {
149 assertStrictEquals(canonicalNumericIndexString("0"), 0);
150 assertStrictEquals(canonicalNumericIndexString("-0.25"), -0.25);
152 canonicalNumericIndexString("9007199254740992"),
155 assertStrictEquals(canonicalNumericIndexString("NaN"), 0 / 0);
156 assertStrictEquals(canonicalNumericIndexString("Infinity"), 1 / 0);
158 canonicalNumericIndexString("-Infinity"),
163 it("[[Construct]] throws an error", () => {
164 assertThrows(() => new canonicalNumericIndexString(""));
167 describe(".length", () => {
168 it("[[Get]] returns the correct length", () => {
169 assertStrictEquals(canonicalNumericIndexString
.length
, 1);
173 describe(".name", () => {
174 it("[[Get]] returns the correct name", () => {
176 canonicalNumericIndexString
.name
,
177 "canonicalNumericIndexString",
183 describe("isIntegerIndexString", () => {
184 it("[[Call]] returns false for nonstrings", () => {
185 assertStrictEquals(isIntegerIndexString(1), false);
188 it("[[Call]] returns false for noncanonical strings", () => {
189 assertStrictEquals(isIntegerIndexString(""), false);
190 assertStrictEquals(isIntegerIndexString("01"), false);
192 isIntegerIndexString("9007199254740993"),
197 it("[[Call]] returns false for nonfinite numbers", () => {
198 assertStrictEquals(isIntegerIndexString("NaN"), false);
199 assertStrictEquals(isIntegerIndexString("Infinity"), false);
200 assertStrictEquals(isIntegerIndexString("-Infinity"), false);
203 it("[[Call]] returns false for negative numbers", () => {
204 assertStrictEquals(isIntegerIndexString("-0"), false);
205 assertStrictEquals(isIntegerIndexString("-1"), false);
208 it("[[Call]] returns false for nonintegers", () => {
209 assertStrictEquals(isIntegerIndexString("0.25"), false);
210 assertStrictEquals(isIntegerIndexString("1.1"), false);
213 it("[[Call]] returns false for numbers greater than or equal to 2 ** 53", () => {
215 isIntegerIndexString("9007199254740992"),
220 it("[[Call]] returns true for safe canonical integer strings", () => {
221 assertStrictEquals(isIntegerIndexString("0"), true);
222 assertStrictEquals(isIntegerIndexString("9007199254740991"), true);
226 describe("lengthOfArraylike", () => {
227 it("[[Call]] returns the length", () => {
229 lengthOfArraylike({ length
: 9007199254740991 }),
234 it("[[Call]] returns a non·nan result", () => {
235 assertStrictEquals(lengthOfArraylike({ length
: NaN
}), 0);
236 assertStrictEquals(lengthOfArraylike({ length
: "failure" }), 0);
239 it("[[Call]] returns an integral result", () => {
240 assertStrictEquals(lengthOfArraylike({ length
: 0.25 }), 0);
241 assertStrictEquals(lengthOfArraylike({ length
: 1.1 }), 1);
244 it("[[Call]] returns a result greater than or equal to zero", () => {
245 assertStrictEquals(lengthOfArraylike({ length
: -0 }), 0);
246 assertStrictEquals(lengthOfArraylike({ length
: -1 }), 0);
247 assertStrictEquals(lengthOfArraylike({ length
: -Infinity
}), 0);
250 it("[[Call]] returns a result less than 2 ** 53", () => {
252 lengthOfArraylike({ length
: 9007199254740992 }),
256 lengthOfArraylike({ length
: Infinity
}),
261 it("[[Call]] does not require an object argument", () => {
262 assertStrictEquals(lengthOfArraylike("string"), 6);
263 assertStrictEquals(lengthOfArraylike(Symbol()), 0);
266 it("[[Construct]] throws an error", () => {
267 assertThrows(() => new lengthOfArraylike(""));
270 describe(".length", () => {
271 it("[[Get]] returns the correct length", () => {
272 assertStrictEquals(lengthOfArraylike
.length
, 1);
276 describe(".name", () => {
277 it("[[Get]] returns the correct name", () => {
278 assertStrictEquals(lengthOfArraylike
.name
, "lengthOfArraylike");
283 describe("ordinaryToPrimitive", () => {
284 it("[[Call]] prefers `valueOf` by default", () => {
293 assertStrictEquals(ordinaryToPrimitive(obj
), "success");
294 assertStrictEquals(ordinaryToPrimitive(obj
, "default"), "success");
297 it('[[Call]] prefers `valueOf` for a "number" hint', () => {
306 assertStrictEquals(ordinaryToPrimitive(obj
, "number"), "success");
309 it('[[Call]] prefers `toString` for a "string" hint', () => {
318 assertStrictEquals(ordinaryToPrimitive(obj
, "string"), "success");
321 it("[[Call]] falls back to the other method if the first isn’t callable", () => {
328 assertStrictEquals(ordinaryToPrimitive(obj
), "success");
331 it("[[Call]] falls back to the other method if the first returns an object", () => {
337 return new String("failure");
340 assertStrictEquals(ordinaryToPrimitive(obj
), "success");
343 it("[[Call]] throws an error if neither method is callable", () => {
348 assertThrows(() => ordinaryToPrimitive(obj
));
351 it("[[Call]] throws an error if neither method returns an object", () => {
354 return new String("failure");
357 return new String("failure");
360 assertThrows(() => ordinaryToPrimitive(obj
));
363 it("[[Construct]] throws an error", () => {
364 assertThrows(() => new ordinaryToPrimitive(""));
367 describe(".length", () => {
368 it("[[Get]] returns the correct length", () => {
369 assertStrictEquals(ordinaryToPrimitive
.length
, 2);
373 describe(".name", () => {
374 it("[[Get]] returns the correct name", () => {
376 ordinaryToPrimitive
.name
,
377 "ordinaryToPrimitive",
383 describe("sameValue", () => {
384 it("[[Call]] returns false for null 🆚 undefined", () => {
385 assertStrictEquals(sameValue(null, undefined), false);
388 it("[[Call]] returns false for null 🆚 an object", () => {
389 assertStrictEquals(sameValue(null, {}), false);
392 it("[[Call]] returns true for null 🆚 null", () => {
393 assertStrictEquals(sameValue(null, null), true);
396 it("[[Call]] returns false for two different objects", () => {
397 assertStrictEquals(sameValue({}, {}), false);
400 it("[[Call]] returns true for the same object", () => {
402 assertStrictEquals(sameValue(obj
, obj
), true);
405 it("[[Call]] returns false for ±0", () => {
406 assertStrictEquals(sameValue(0, -0), false);
409 it("[[Call]] returns true for -0", () => {
410 assertStrictEquals(sameValue(-0, -0), true);
413 it("[[Call]] returns true for nan", () => {
414 assertStrictEquals(sameValue(0 / 0, 0 / 0), true);
417 it("[[Call]] returns false for a primitive and its wrapped object", () => {
418 assertStrictEquals(sameValue(false, new Boolean(false)), false);
421 it("[[Construct]] throws an error", () => {
422 assertThrows(() => new sameValue(true, true));
425 describe(".length", () => {
426 it("[[Get]] returns the correct length", () => {
427 assertStrictEquals(sameValue
.length
, 2);
431 describe(".name", () => {
432 it("[[Get]] returns the correct name", () => {
433 assertStrictEquals(sameValue
.name
, "sameValue");
438 describe("sameValueZero", () => {
439 it("[[Call]] returns false for null 🆚 undefined", () => {
440 assertStrictEquals(sameValueZero(null, undefined), false);
443 it("[[Call]] returns false for null 🆚 an object", () => {
444 assertStrictEquals(sameValueZero(null, {}), false);
447 it("[[Call]] returns true for null 🆚 null", () => {
448 assertStrictEquals(sameValueZero(null, null), true);
451 it("[[Call]] returns false for two different objects", () => {
452 assertStrictEquals(sameValueZero({}, {}), false);
455 it("[[Call]] returns true for the same object", () => {
457 assertStrictEquals(sameValueZero(obj
, obj
), true);
460 it("[[Call]] returns true for ±0", () => {
461 assertStrictEquals(sameValueZero(0, -0), true);
464 it("[[Call]] returns true for -0", () => {
465 assertStrictEquals(sameValueZero(-0, -0), true);
468 it("[[Call]] returns true for nan", () => {
469 assertStrictEquals(sameValueZero(0 / 0, 0 / 0), true);
472 it("[[Call]] returns false for a primitive and its wrapped object", () => {
474 sameValueZero(false, new Boolean(false)),
479 it("[[Construct]] throws an error", () => {
480 assertThrows(() => new sameValueZero(true, true));
483 describe(".length", () => {
484 it("[[Get]] returns the correct length", () => {
485 assertStrictEquals(sameValueZero
.length
, 2);
489 describe(".name", () => {
490 it("[[Get]] returns the correct name", () => {
491 assertStrictEquals(sameValueZero
.name
, "sameValueZero");
496 describe("toIndex", () => {
497 it("[[Call]] returns an index", () => {
498 assertStrictEquals(toIndex(9007199254740991), 9007199254740991);
501 it("[[Call]] returns zero for a zerolike argument", () => {
502 assertStrictEquals(toIndex(NaN
), 0);
503 assertStrictEquals(toIndex("failure"), 0);
504 assertStrictEquals(toIndex(-0), 0);
507 it("[[Call]] rounds down to the nearest integer", () => {
508 assertStrictEquals(toIndex(0.25), 0);
509 assertStrictEquals(toIndex(1.1), 1);
512 it("[[Call]] throws when provided a negative number", () => {
513 assertThrows(() => toIndex(-1));
514 assertThrows(() => toIndex(-Infinity
));
517 it("[[Call]] throws when provided a number greater than or equal to 2 ** 53", () => {
518 assertThrows(() => toIndex(9007199254740992));
519 assertThrows(() => toIndex(Infinity
));
522 it("[[Construct]] throws an error", () => {
523 assertThrows(() => new toIndex(0));
526 describe(".length", () => {
527 it("[[Get]] returns the correct length", () => {
528 assertStrictEquals(toIndex
.length
, 1);
532 describe(".name", () => {
533 it("[[Get]] returns the correct name", () => {
534 assertStrictEquals(toIndex
.name
, "toIndex");
539 describe("toLength", () => {
540 it("[[Call]] returns a length", () => {
541 assertStrictEquals(toLength(9007199254740991), 9007199254740991);
544 it("[[Call]] returns zero for a nan argument", () => {
545 assertStrictEquals(toLength(NaN
), 0);
546 assertStrictEquals(toLength("failure"), 0);
549 it("[[Call]] rounds down to the nearest integer", () => {
550 assertStrictEquals(toLength(0.25), 0);
551 assertStrictEquals(toLength(1.1), 1);
554 it("[[Call]] returns a result greater than or equal to zero", () => {
555 assertStrictEquals(toLength(-0), 0);
556 assertStrictEquals(toLength(-1), 0);
557 assertStrictEquals(toLength(-Infinity
), 0);
560 it("[[Call]] returns a result less than 2 ** 53", () => {
561 assertStrictEquals(toLength(9007199254740992), 9007199254740991);
562 assertStrictEquals(toLength(Infinity
), 9007199254740991);
565 it("[[Construct]] throws an error", () => {
566 assertThrows(() => new toLength(0));
569 describe(".length", () => {
570 it("[[Get]] returns the correct length", () => {
571 assertStrictEquals(toLength
.length
, 1);
575 describe(".name", () => {
576 it("[[Get]] returns the correct name", () => {
577 assertStrictEquals(toLength
.name
, "toLength");
582 describe("toPrimitive", () => {
583 it("[[Call]] returns the argument when passed a primitive", () => {
584 const value
= Symbol();
585 assertStrictEquals(toPrimitive(value
), value
);
588 it("[[Call]] works with nullish values", () => {
589 assertStrictEquals(toPrimitive(null), null);
590 assertStrictEquals(toPrimitive(), void {});
593 it("[[Call]] calls ordinaryToPrimitive by default", () => {
594 const value
= Object
.assign(
602 assertStrictEquals(toPrimitive(value
), "success");
605 it("[[Call]] accepts a hint", () => {
606 const value
= Object
.assign(
617 assertStrictEquals(toPrimitive(value
, "string"), "success");
620 it("[[Call]] uses the exotic toPrimitive method if available", () => {
621 const value
= Object
.assign(
624 [Symbol
.toPrimitive
]() {
629 assertStrictEquals(toPrimitive(value
), "success");
632 it("[[Call]] passes the hint to the exotic toPrimitive", () => {
633 const value
= Object
.assign(
636 [Symbol
.toPrimitive
](hint
) {
637 return hint
=== "string" ? "success" : "failure";
641 assertStrictEquals(toPrimitive(value
, "string"), "success");
644 it('[[Call]] passes a "default" hint by default', () => {
645 const value
= Object
.assign(
648 [Symbol
.toPrimitive
](hint
) {
649 return hint
=== "default" ? "success" : "failure";
653 assertStrictEquals(toPrimitive(value
), "success");
656 it("[[Call]] throws for an invalid hint", () => {
657 const value1
= Object
.assign(
660 [Symbol
.toPrimitive
]() {
665 const value2
= Object
.assign(
673 assertThrows(() => toPrimitive(value1
, "badhint"));
674 assertThrows(() => toPrimitive(value2
, "badhint"));
675 assertThrows(() => toPrimitive(true, "badhint"));
678 it("[[Construct]] throws an error", () => {
679 assertThrows(() => new toPrimitive(true));
682 describe(".length", () => {
683 it("[[Get]] returns the correct length", () => {
684 assertStrictEquals(toPrimitive
.length
, 1);
688 describe(".name", () => {
689 it("[[Get]] returns the correct name", () => {
690 assertStrictEquals(toPrimitive
.name
, "toPrimitive");
695 describe("type", () => {
696 it('[[Call]] returns "null" for null', () => {
697 assertStrictEquals(type(null), "null");
700 it('[[Call]] returns "undefined" for undefined', () => {
701 assertStrictEquals(type(void {}), "undefined");
704 it('[[Call]] returns "object" for non‐callable objects', () => {
705 assertStrictEquals(type(Object
.create(null)), "object");
708 it('[[Call]] returns "object" for callable objects', () => {
709 assertStrictEquals(type(() => {}), "object");
712 it('[[Call]] returns "object" for constructable objects', () => {
713 assertStrictEquals(type(class {}), "object");
716 it("[[Construct]] throws an error", () => {
717 assertThrows(() => new type({}));
720 describe(".length", () => {
721 it("[[Get]] returns the correct length", () => {
722 assertStrictEquals(type
.length
, 1);
726 describe(".name", () => {
727 it("[[Get]] returns the correct name", () => {
728 assertStrictEquals(type
.name
, "type");