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