]> Lady’s Gitweb - Pisces/blob - iterable.test.js
Minor refactors to numeric.js
[Pisces] / iterable.test.js
1 // SPDX-FileCopyrightText: 2023, 2025 Lady <https://www.ladys.computer/about/#lady>
2 // SPDX-License-Identifier: MPL-2.0
3 /**
4 * ⁌ ♓🧩 Piscēs ∷ iterable.test.js
5 *
6 * Copyright © 2023, 2025 Lady [@ Ladys Computer].
7 *
8 * This Source Code Form is subject to the terms of the Mozilla Public
9 * License, v. 2.0. If a copy of the MPL was not distributed with this
10 * file, You can obtain one at <https://mozilla.org/MPL/2.0/>.
11 */
12
13 import {
14 assertEquals,
15 assertStrictEquals,
16 assertThrows,
17 describe,
18 it,
19 } from "./dev-deps.js";
20 import {
21 arrayIteratorFunction,
22 generatorIteratorFunction,
23 mapIteratorFunction,
24 setIteratorFunction,
25 stringIteratorFunction,
26 } from "./iterable.js";
27
28 describe("arrayIteratorFunction", () => {
29 it("[[Call]] returns a function", () => {
30 assertStrictEquals(typeof arrayIteratorFunction(), "function");
31 });
32
33 it("[[Call]] returns a value which has a prototype of %FunctionPrototype%", () => {
34 assertStrictEquals(
35 Object.getPrototypeOf(arrayIteratorFunction()),
36 Function.prototype,
37 );
38 });
39
40 it("[[Construct]] throws an error", () => {
41 assertThrows(() => new arrayIteratorFunction());
42 });
43
44 describe(".length", () => {
45 it("[[Get]] returns the correct length", () => {
46 assertStrictEquals(arrayIteratorFunction.length, 1);
47 });
48 });
49
50 describe(".name", () => {
51 it("[[Get]] returns the correct name", () => {
52 assertStrictEquals(
53 arrayIteratorFunction.name,
54 "arrayIteratorFunction",
55 );
56 });
57 });
58
59 describe("()", () => {
60 it("[[Call]] returns a value which inherits from %IteratorPrototype%", () => {
61 const iteratorProto = Object.getPrototypeOf(
62 Object.getPrototypeOf([][Symbol.iterator]),
63 );
64 const iterator = arrayIteratorFunction();
65 assertStrictEquals(
66 iterator([]) instanceof Object.assign(
67 function () {},
68 { prototype: iteratorProto },
69 ),
70 true,
71 );
72 });
73
74 it("[[Call]] returns a value with the provided string tag", () => {
75 const iterator = arrayIteratorFunction(null, "My Iterator");
76 assertStrictEquals(
77 iterator([])[Symbol.toStringTag],
78 "My Iterator",
79 );
80 });
81
82 it("[[Call]] yields the values", () => {
83 const iterator = arrayIteratorFunction();
84 assertEquals(
85 [...iterator(["etaoin", "shrdlu"])],
86 ["etaoin", "shrdlu"],
87 );
88 });
89
90 it("[[Call]] maps the values", () => {
91 const iterator = arrayIteratorFunction(function* ($) {
92 yield $.toUpperCase();
93 });
94 assertEquals(
95 [...iterator(["etaoin", "shrdlu"])],
96 ["ETAOIN", "SHRDLU"],
97 );
98 });
99
100 it("[[Call]] can map to nothing", () => {
101 const iterator = arrayIteratorFunction(function* () {});
102 assertEquals(
103 [...iterator(["etaoin", "shrdlu"])],
104 [],
105 );
106 });
107
108 it("[[Call]] can map to multiple values", () => {
109 const iterator = arrayIteratorFunction(function* ($) {
110 yield* $;
111 });
112 assertEquals(
113 [...iterator(["etaoin", "shrdlu"])],
114 [..."etaoinshrdlu"],
115 );
116 });
117
118 it("[[Call]] throws if not provided with any arguments", () => {
119 const iterator = arrayIteratorFunction();
120 assertThrows(() => {
121 iterator();
122 });
123 });
124
125 it("[[Call]] throws if not provided an arraylike", () => {
126 const iterator = arrayIteratorFunction();
127 assertThrows(() => {
128 iterator(null);
129 });
130 });
131
132 it("[[Construct]] throws an error", () => {
133 const iterator = arrayIteratorFunction();
134 assertThrows(() => new iterator([]));
135 });
136
137 describe(".length", () => {
138 it("[[Get]] returns the correct length", () => {
139 assertStrictEquals(arrayIteratorFunction().length, 1);
140 });
141 });
142
143 describe(".name", () => {
144 it("[[Get]] returns the correct name", () => {
145 assertStrictEquals(
146 arrayIteratorFunction().name,
147 "values",
148 );
149 });
150 });
151
152 describe("::next", () => {
153 it("[[Call]] throws if there are values and the mapper is not a generator function", () => {
154 const iterator = arrayIteratorFunction(function () {});
155 assertThrows(() => {
156 iterator(["etaoin"]).next();
157 });
158 });
159 });
160 });
161 });
162
163 describe("generatorIteratorFunction", () => {
164 it("[[Call]] returns a function", () => {
165 assertStrictEquals(typeof generatorIteratorFunction(), "function");
166 });
167
168 it("[[Call]] returns a value which has a prototype of %FunctionPrototype%", () => {
169 assertStrictEquals(
170 Object.getPrototypeOf(generatorIteratorFunction()),
171 Function.prototype,
172 );
173 });
174
175 it("[[Construct]] throws an error", () => {
176 assertThrows(() => new generatorIteratorFunction());
177 });
178
179 describe(".length", () => {
180 it("[[Get]] returns the correct length", () => {
181 assertStrictEquals(generatorIteratorFunction.length, 1);
182 });
183 });
184
185 describe(".name", () => {
186 it("[[Get]] returns the correct name", () => {
187 assertStrictEquals(
188 generatorIteratorFunction.name,
189 "generatorIteratorFunction",
190 );
191 });
192 });
193
194 describe("()", () => {
195 it("[[Call]] returns a value which inherits from %IteratorPrototype%", () => {
196 const iteratorProto = Object.getPrototypeOf(
197 Object.getPrototypeOf([][Symbol.iterator]),
198 );
199 const iterator = generatorIteratorFunction();
200 assertStrictEquals(
201 iterator(function* () {}) instanceof Object.assign(
202 function () {},
203 { prototype: iteratorProto },
204 ),
205 true,
206 );
207 });
208
209 it("[[Call]] returns a value with the provided string tag", () => {
210 const iterator = generatorIteratorFunction(null, "My Iterator");
211 assertStrictEquals(
212 iterator(function* () {})[Symbol.toStringTag],
213 "My Iterator",
214 );
215 });
216
217 it("[[Call]] yields the values", () => {
218 const generator = function* () {
219 yield* ["etaoin", "shrdlu"];
220 };
221 const iterator = generatorIteratorFunction();
222 assertEquals(
223 [...iterator(generator)],
224 ["etaoin", "shrdlu"],
225 );
226 });
227
228 it("[[Call]] maps the values", () => {
229 const generator = function* () {
230 yield* ["etaoin", "shrdlu"];
231 };
232 const iterator = generatorIteratorFunction(function* ($) {
233 yield $.toUpperCase();
234 });
235 assertEquals(
236 [...iterator(generator)],
237 ["ETAOIN", "SHRDLU"],
238 );
239 });
240
241 it("[[Call]] can map to nothing", () => {
242 const generator = function* () {
243 yield* ["etaoin", "shrdlu"];
244 };
245 const iterator = generatorIteratorFunction(function* () {});
246 assertEquals(
247 [...iterator(generator)],
248 [],
249 );
250 });
251
252 it("[[Call]] can map to multiple values", () => {
253 const generator = function* () {
254 yield* ["etaoin", "shrdlu"];
255 };
256 const iterator = generatorIteratorFunction(function* ($) {
257 yield* $;
258 });
259 assertEquals(
260 [...iterator(generator)],
261 [..."etaoinshrdlu"],
262 );
263 });
264
265 it("[[Call]] throws if not provided with any arguments", () => {
266 const iterator = generatorIteratorFunction();
267 assertThrows(() => {
268 iterator();
269 });
270 });
271
272 it("[[Call]] throws if not provided a function", () => {
273 const iterator = generatorIteratorFunction();
274 assertThrows(() => {
275 iterator([]);
276 });
277 });
278
279 it("[[Construct]] throws an error", () => {
280 const iterator = generatorIteratorFunction();
281 assertThrows(() => new iterator(function* () {}));
282 });
283
284 describe(".length", () => {
285 it("[[Get]] returns the correct length", () => {
286 assertStrictEquals(generatorIteratorFunction().length, 1);
287 });
288 });
289
290 describe(".name", () => {
291 it("[[Get]] returns the correct name", () => {
292 assertStrictEquals(
293 generatorIteratorFunction().name,
294 "yields",
295 );
296 });
297 });
298
299 describe("::next", () => {
300 it("[[Call]] throws if there are values and the mapper is not a generator function", () => {
301 const generator = function* () {
302 yield "etaoin";
303 };
304 const iterator = generatorIteratorFunction(function () {});
305 assertThrows(() => {
306 iterator(generator).next();
307 });
308 });
309
310 it("[[Call]] throws if not constructed with a generator function", () => {
311 const iterator = generatorIteratorFunction();
312 assertThrows(() => {
313 iterator(Array.prototype[Symbol.iterator].bind([])).next();
314 });
315 });
316 });
317 });
318 });
319
320 describe("mapIteratorFunction", () => {
321 it("[[Call]] returns a function", () => {
322 assertStrictEquals(typeof mapIteratorFunction(), "function");
323 });
324
325 it("[[Call]] returns a value which has a prototype of %FunctionPrototype%", () => {
326 assertStrictEquals(
327 Object.getPrototypeOf(mapIteratorFunction()),
328 Function.prototype,
329 );
330 });
331
332 it("[[Construct]] throws an error", () => {
333 assertThrows(() => new mapIteratorFunction());
334 });
335
336 describe(".length", () => {
337 it("[[Get]] returns the correct length", () => {
338 assertStrictEquals(mapIteratorFunction.length, 1);
339 });
340 });
341
342 describe(".name", () => {
343 it("[[Get]] returns the correct name", () => {
344 assertStrictEquals(
345 mapIteratorFunction.name,
346 "mapIteratorFunction",
347 );
348 });
349 });
350
351 describe("()", () => {
352 it("[[Call]] returns a value which inherits from %IteratorPrototype%", () => {
353 const iteratorProto = Object.getPrototypeOf(
354 Object.getPrototypeOf([][Symbol.iterator]),
355 );
356 const iterator = mapIteratorFunction();
357 assertStrictEquals(
358 iterator(new Map()) instanceof Object.assign(
359 function () {},
360 { prototype: iteratorProto },
361 ),
362 true,
363 );
364 });
365
366 it("[[Call]] returns a value with the provided string tag", () => {
367 const iterator = mapIteratorFunction(null, "My Iterator");
368 assertStrictEquals(
369 iterator(new Map())[Symbol.toStringTag],
370 "My Iterator",
371 );
372 });
373
374 it("[[Call]] yields the values", () => {
375 const iterator = mapIteratorFunction();
376 assertEquals(
377 [...iterator(new Map([["etaoin", "shrdlu"]]))],
378 [["etaoin", "shrdlu"]],
379 );
380 });
381
382 it("[[Call]] maps the values", () => {
383 const iterator = mapIteratorFunction(function* ([k, v]) {
384 yield [k.toUpperCase(), v.toUpperCase()];
385 });
386 assertEquals(
387 [...iterator(new Map([["etaoin", "shrdlu"]]))],
388 [["ETAOIN", "SHRDLU"]],
389 );
390 });
391
392 it("[[Call]] can map to nothing", () => {
393 const iterator = mapIteratorFunction(function* () {});
394 assertEquals(
395 [...iterator(new Map([["etaoin", "shrdlu"]]))],
396 [],
397 );
398 });
399
400 it("[[Call]] can map to multiple values", () => {
401 const iterator = mapIteratorFunction(function* ($) {
402 yield* $;
403 });
404 assertEquals(
405 [...iterator(new Map([["etaoin", "shrdlu"]]))],
406 ["etaoin", "shrdlu"],
407 );
408 });
409
410 it("[[Call]] throws if not provided with any arguments", () => {
411 const iterator = mapIteratorFunction();
412 assertThrows(() => {
413 iterator();
414 });
415 });
416
417 it("[[Call]] throws if not provided a map", () => {
418 const iterator = mapIteratorFunction();
419 assertThrows(() => {
420 iterator([]);
421 });
422 });
423
424 it("[[Construct]] throws an error", () => {
425 const iterator = mapIteratorFunction();
426 assertThrows(() => new iterator(new Map()));
427 });
428
429 describe(".length", () => {
430 it("[[Get]] returns the correct length", () => {
431 assertStrictEquals(mapIteratorFunction().length, 1);
432 });
433 });
434
435 describe(".name", () => {
436 it("[[Get]] returns the correct name", () => {
437 assertStrictEquals(
438 mapIteratorFunction().name,
439 "entries",
440 );
441 });
442 });
443
444 describe("::next", () => {
445 it("[[Call]] throws if there are values and the mapper is not a generator function", () => {
446 const iterator = mapIteratorFunction(function () {});
447 assertThrows(() => {
448 iterator(new Map([["etaoin", "shrdlu"]])).next();
449 });
450 });
451 });
452 });
453 });
454
455 describe("setIteratorFunction", () => {
456 it("[[Call]] returns a function", () => {
457 assertStrictEquals(typeof setIteratorFunction(), "function");
458 });
459
460 it("[[Call]] returns a value which has a prototype of %FunctionPrototype%", () => {
461 assertStrictEquals(
462 Object.getPrototypeOf(setIteratorFunction()),
463 Function.prototype,
464 );
465 });
466
467 it("[[Construct]] throws an error", () => {
468 assertThrows(() => new setIteratorFunction());
469 });
470
471 describe(".length", () => {
472 it("[[Get]] returns the correct length", () => {
473 assertStrictEquals(setIteratorFunction.length, 1);
474 });
475 });
476
477 describe(".name", () => {
478 it("[[Get]] returns the correct name", () => {
479 assertStrictEquals(
480 setIteratorFunction.name,
481 "setIteratorFunction",
482 );
483 });
484 });
485
486 describe("()", () => {
487 it("[[Call]] returns a value which inherits from %IteratorPrototype%", () => {
488 const iteratorProto = Object.getPrototypeOf(
489 Object.getPrototypeOf([][Symbol.iterator]),
490 );
491 const iterator = setIteratorFunction();
492 assertStrictEquals(
493 iterator(new Set()) instanceof Object.assign(
494 function () {},
495 { prototype: iteratorProto },
496 ),
497 true,
498 );
499 });
500
501 it("[[Call]] returns a value with the provided string tag", () => {
502 const iterator = setIteratorFunction(null, "My Iterator");
503 assertStrictEquals(
504 iterator(new Set())[Symbol.toStringTag],
505 "My Iterator",
506 );
507 });
508
509 it("[[Call]] yields the values", () => {
510 const iterator = setIteratorFunction();
511 assertEquals(
512 [...iterator(new Set(["etaoin", "shrdlu"]))],
513 ["etaoin", "shrdlu"],
514 );
515 });
516
517 it("[[Call]] maps the values", () => {
518 const iterator = setIteratorFunction(function* ($) {
519 yield $.toUpperCase();
520 });
521 assertEquals(
522 [...iterator(new Set(["etaoin", "shrdlu"]))],
523 ["ETAOIN", "SHRDLU"],
524 );
525 });
526
527 it("[[Call]] can map to nothing", () => {
528 const iterator = setIteratorFunction(function* () {});
529 assertEquals(
530 [...iterator(new Set(["etaoin", "shrdlu"]))],
531 [],
532 );
533 });
534
535 it("[[Call]] can map to multiple values", () => {
536 const iterator = setIteratorFunction(function* ($) {
537 yield* $;
538 });
539 assertEquals(
540 [...iterator(new Set(["etaoin", "shrdlu"]))],
541 [..."etaoinshrdlu"],
542 );
543 });
544
545 it("[[Call]] throws if not provided with any arguments", () => {
546 const iterator = setIteratorFunction();
547 assertThrows(() => {
548 iterator();
549 });
550 });
551
552 it("[[Call]] throws if not provided a set", () => {
553 const iterator = setIteratorFunction();
554 assertThrows(() => {
555 iterator([]);
556 });
557 });
558
559 it("[[Construct]] throws an error", () => {
560 const iterator = setIteratorFunction();
561 assertThrows(() => new iterator(new Set()));
562 });
563
564 describe(".length", () => {
565 it("[[Get]] returns the correct length", () => {
566 assertStrictEquals(setIteratorFunction().length, 1);
567 });
568 });
569
570 describe(".name", () => {
571 it("[[Get]] returns the correct name", () => {
572 assertStrictEquals(
573 setIteratorFunction().name,
574 "values",
575 );
576 });
577 });
578
579 describe("::next", () => {
580 it("[[Call]] throws if there are values and the mapper is not a generator function", () => {
581 const iterator = setIteratorFunction(function () {});
582 assertThrows(() => {
583 iterator(new Set(["etaoin"])).next();
584 });
585 });
586 });
587 });
588 });
589
590 describe("stringIteratorFunction", () => {
591 it("[[Call]] returns a function", () => {
592 assertStrictEquals(typeof stringIteratorFunction(), "function");
593 });
594
595 it("[[Call]] returns a value which has a prototype of %FunctionPrototype%", () => {
596 assertStrictEquals(
597 Object.getPrototypeOf(stringIteratorFunction()),
598 Function.prototype,
599 );
600 });
601
602 it("[[Construct]] throws an error", () => {
603 assertThrows(() => new stringIteratorFunction());
604 });
605
606 describe(".length", () => {
607 it("[[Get]] returns the correct length", () => {
608 assertStrictEquals(stringIteratorFunction.length, 1);
609 });
610 });
611
612 describe(".name", () => {
613 it("[[Get]] returns the correct name", () => {
614 assertStrictEquals(
615 stringIteratorFunction.name,
616 "stringIteratorFunction",
617 );
618 });
619 });
620
621 describe("()", () => {
622 it("[[Call]] returns a value which inherits from %IteratorPrototype%", () => {
623 const iteratorProto = Object.getPrototypeOf(
624 Object.getPrototypeOf([][Symbol.iterator]),
625 );
626 const iterator = stringIteratorFunction();
627 assertStrictEquals(
628 iterator("") instanceof Object.assign(
629 function () {},
630 { prototype: iteratorProto },
631 ),
632 true,
633 );
634 });
635
636 it("[[Call]] returns a value with the provided string tag", () => {
637 const iterator = stringIteratorFunction(null, "My Iterator");
638 assertStrictEquals(
639 iterator("")[Symbol.toStringTag],
640 "My Iterator",
641 );
642 });
643
644 it("[[Call]] yields the values", () => {
645 const iterator = stringIteratorFunction();
646 assertEquals(
647 [...iterator("etaoin👀")],
648 [..."etaoin👀"],
649 );
650 });
651
652 it("[[Call]] maps the values", () => {
653 const iterator = stringIteratorFunction(function* ($) {
654 yield $.toUpperCase();
655 });
656 assertEquals(
657 [...iterator("etaoin👀")],
658 [..."ETAOIN👀"],
659 );
660 });
661
662 it("[[Call]] can map to nothing", () => {
663 const iterator = stringIteratorFunction(function* () {});
664 assertEquals(
665 [...iterator("etaoin👀")],
666 [],
667 );
668 });
669
670 it("[[Call]] can map to multiple values", () => {
671 const iterator = stringIteratorFunction(function* ($) {
672 yield $;
673 yield $;
674 });
675 assertEquals(
676 [...iterator("etaoin👀")],
677 [..."eettaaooiinn👀👀"],
678 );
679 });
680
681 it("[[Call]] throws if not provided with any arguments", () => {
682 const iterator = stringIteratorFunction();
683 assertThrows(() => {
684 iterator();
685 });
686 });
687
688 it("[[Call]] throws if not provided something convertible to a string", () => {
689 const iterator = stringIteratorFunction();
690 assertThrows(() => {
691 iterator({
692 toString() {
693 throw null;
694 },
695 });
696 });
697 });
698
699 it("[[Construct]] throws an error", () => {
700 const iterator = stringIteratorFunction();
701 assertThrows(() => new iterator(""));
702 });
703
704 describe(".length", () => {
705 it("[[Get]] returns the correct length", () => {
706 assertStrictEquals(stringIteratorFunction().length, 1);
707 });
708 });
709
710 describe(".name", () => {
711 it("[[Get]] returns the correct name", () => {
712 assertStrictEquals(
713 stringIteratorFunction().name,
714 "characters",
715 );
716 });
717 });
718
719 describe("::next", () => {
720 it("[[Call]] throws if there are values and the mapper is not a generator function", () => {
721 const iterator = stringIteratorFunction(function () {});
722 assertThrows(() => {
723 iterator("etaoin").next();
724 });
725 });
726 });
727 });
728 });
This page took 0.890281 seconds and 5 git commands to generate.