1 // ♓🌟 Piscēs ∷ iterable.test.js
2 // ====================================================================
4 // Copyright © 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/>.
16 } from "./dev-deps.js";
18 arrayIteratorFunction
,
19 generatorIteratorFunction
,
22 stringIteratorFunction
,
23 } from "./iterable.js";
25 describe("arrayIteratorFunction", () => {
26 it("[[Call]] returns a function", () => {
27 assertStrictEquals(typeof arrayIteratorFunction(), "function");
30 it("[[Call]] returns a value which has a prototype of %FunctionPrototype%", () => {
32 Object
.getPrototypeOf(arrayIteratorFunction()),
37 it("[[Construct]] throws an error", () => {
38 assertThrows(() => new arrayIteratorFunction());
41 describe(".length", () => {
42 it("[[Get]] returns the correct length", () => {
43 assertStrictEquals(arrayIteratorFunction
.length
, 1);
47 describe(".name", () => {
48 it("[[Get]] returns the correct name", () => {
50 arrayIteratorFunction
.name
,
51 "arrayIteratorFunction",
56 describe("()", () => {
57 it("[[Call]] returns a value which inherits from %IteratorPrototype%", () => {
58 const iteratorProto
= Object
.getPrototypeOf(
59 Object
.getPrototypeOf([][Symbol
.iterator
]),
61 const iterator
= arrayIteratorFunction();
63 iterator([]) instanceof Object
.assign(
65 { prototype: iteratorProto
},
71 it("[[Call]] returns a value with the provided string tag", () => {
72 const iterator
= arrayIteratorFunction(null, "My Iterator");
74 iterator([])[Symbol
.toStringTag
],
79 it("[[Call]] yields the values", () => {
80 const iterator
= arrayIteratorFunction();
82 [...iterator(["etaoin", "shrdlu"])],
87 it("[[Call]] maps the values", () => {
88 const iterator
= arrayIteratorFunction(function* ($) {
89 yield $.toUpperCase();
92 [...iterator(["etaoin", "shrdlu"])],
97 it("[[Call]] can map to nothing", () => {
98 const iterator
= arrayIteratorFunction(function* () {});
100 [...iterator(["etaoin", "shrdlu"])],
105 it("[[Call]] can map to multiple values", () => {
106 const iterator
= arrayIteratorFunction(function* ($) {
110 [...iterator(["etaoin", "shrdlu"])],
115 it("[[Call]] throws if not provided with any arguments", () => {
116 const iterator
= arrayIteratorFunction();
122 it("[[Call]] throws if not provided an arraylike", () => {
123 const iterator
= arrayIteratorFunction();
129 describe("::next", () => {
130 it("[[Call]] throws if there are values and the mapper is not a generator function", () => {
131 const iterator
= arrayIteratorFunction(function () {});
133 iterator(["etaoin"]).next();
140 describe("generatorIteratorFunction", () => {
141 it("[[Call]] returns a function", () => {
142 assertStrictEquals(typeof generatorIteratorFunction(), "function");
145 it("[[Call]] returns a value which has a prototype of %FunctionPrototype%", () => {
147 Object
.getPrototypeOf(generatorIteratorFunction()),
152 it("[[Construct]] throws an error", () => {
153 assertThrows(() => new generatorIteratorFunction());
156 describe(".length", () => {
157 it("[[Get]] returns the correct length", () => {
158 assertStrictEquals(generatorIteratorFunction
.length
, 1);
162 describe(".name", () => {
163 it("[[Get]] returns the correct name", () => {
165 generatorIteratorFunction
.name
,
166 "generatorIteratorFunction",
171 describe("()", () => {
172 it("[[Call]] returns a value which inherits from %IteratorPrototype%", () => {
173 const iteratorProto
= Object
.getPrototypeOf(
174 Object
.getPrototypeOf([][Symbol
.iterator
]),
176 const iterator
= generatorIteratorFunction();
178 iterator(function* () {}) instanceof Object
.assign(
180 { prototype: iteratorProto
},
186 it("[[Call]] returns a value with the provided string tag", () => {
187 const iterator
= generatorIteratorFunction(null, "My Iterator");
189 iterator(function* () {})[Symbol
.toStringTag
],
194 it("[[Call]] yields the values", () => {
195 const generator
= function* () {
196 yield* ["etaoin", "shrdlu"];
198 const iterator
= generatorIteratorFunction();
200 [...iterator(generator
)],
201 ["etaoin", "shrdlu"],
205 it("[[Call]] maps the values", () => {
206 const generator
= function* () {
207 yield* ["etaoin", "shrdlu"];
209 const iterator
= generatorIteratorFunction(function* ($) {
210 yield $.toUpperCase();
213 [...iterator(generator
)],
214 ["ETAOIN", "SHRDLU"],
218 it("[[Call]] can map to nothing", () => {
219 const generator
= function* () {
220 yield* ["etaoin", "shrdlu"];
222 const iterator
= generatorIteratorFunction(function* () {});
224 [...iterator(generator
)],
229 it("[[Call]] can map to multiple values", () => {
230 const generator
= function* () {
231 yield* ["etaoin", "shrdlu"];
233 const iterator
= generatorIteratorFunction(function* ($) {
237 [...iterator(generator
)],
242 it("[[Call]] throws if not provided with any arguments", () => {
243 const iterator
= generatorIteratorFunction();
249 it("[[Call]] throws if not provided a function", () => {
250 const iterator
= generatorIteratorFunction();
256 describe("::next", () => {
257 it("[[Call]] throws if there are values and the mapper is not a generator function", () => {
258 const generator
= function* () {
261 const iterator
= generatorIteratorFunction(function () {});
263 iterator(generator
).next();
267 it("[[Call]] throws if not constructed with a generator function", () => {
268 const iterator
= generatorIteratorFunction();
270 iterator(Array
.prototype[Symbol
.iterator
].bind([])).next();
277 describe("mapIteratorFunction", () => {
278 it("[[Call]] returns a function", () => {
279 assertStrictEquals(typeof mapIteratorFunction(), "function");
282 it("[[Call]] returns a value which has a prototype of %FunctionPrototype%", () => {
284 Object
.getPrototypeOf(mapIteratorFunction()),
289 it("[[Construct]] throws an error", () => {
290 assertThrows(() => new mapIteratorFunction());
293 describe(".length", () => {
294 it("[[Get]] returns the correct length", () => {
295 assertStrictEquals(mapIteratorFunction
.length
, 1);
299 describe(".name", () => {
300 it("[[Get]] returns the correct name", () => {
302 mapIteratorFunction
.name
,
303 "mapIteratorFunction",
308 describe("()", () => {
309 it("[[Call]] returns a value which inherits from %IteratorPrototype%", () => {
310 const iteratorProto
= Object
.getPrototypeOf(
311 Object
.getPrototypeOf([][Symbol
.iterator
]),
313 const iterator
= mapIteratorFunction();
315 iterator(new Map()) instanceof Object
.assign(
317 { prototype: iteratorProto
},
323 it("[[Call]] returns a value with the provided string tag", () => {
324 const iterator
= mapIteratorFunction(null, "My Iterator");
326 iterator(new Map())[Symbol
.toStringTag
],
331 it("[[Call]] yields the values", () => {
332 const iterator
= mapIteratorFunction();
334 [...iterator(new Map([["etaoin", "shrdlu"]]))],
335 [["etaoin", "shrdlu"]],
339 it("[[Call]] maps the values", () => {
340 const iterator
= mapIteratorFunction(function* ([k
, v
]) {
341 yield [k
.toUpperCase(), v
.toUpperCase()];
344 [...iterator(new Map([["etaoin", "shrdlu"]]))],
345 [["ETAOIN", "SHRDLU"]],
349 it("[[Call]] can map to nothing", () => {
350 const iterator
= mapIteratorFunction(function* () {});
352 [...iterator(new Map([["etaoin", "shrdlu"]]))],
357 it("[[Call]] can map to multiple values", () => {
358 const iterator
= mapIteratorFunction(function* ($) {
362 [...iterator(new Map([["etaoin", "shrdlu"]]))],
363 ["etaoin", "shrdlu"],
367 it("[[Call]] throws if not provided with any arguments", () => {
368 const iterator
= mapIteratorFunction();
374 it("[[Call]] throws if not provided a map", () => {
375 const iterator
= mapIteratorFunction();
381 describe("::next", () => {
382 it("[[Call]] throws if there are values and the mapper is not a generator function", () => {
383 const iterator
= mapIteratorFunction(function () {});
385 iterator(new Map([["etaoin", "shrdlu"]])).next();
392 describe("setIteratorFunction", () => {
393 it("[[Call]] returns a function", () => {
394 assertStrictEquals(typeof setIteratorFunction(), "function");
397 it("[[Call]] returns a value which has a prototype of %FunctionPrototype%", () => {
399 Object
.getPrototypeOf(setIteratorFunction()),
404 it("[[Construct]] throws an error", () => {
405 assertThrows(() => new setIteratorFunction());
408 describe(".length", () => {
409 it("[[Get]] returns the correct length", () => {
410 assertStrictEquals(setIteratorFunction
.length
, 1);
414 describe(".name", () => {
415 it("[[Get]] returns the correct name", () => {
417 setIteratorFunction
.name
,
418 "setIteratorFunction",
423 describe("()", () => {
424 it("[[Call]] returns a value which inherits from %IteratorPrototype%", () => {
425 const iteratorProto
= Object
.getPrototypeOf(
426 Object
.getPrototypeOf([][Symbol
.iterator
]),
428 const iterator
= setIteratorFunction();
430 iterator(new Set()) instanceof Object
.assign(
432 { prototype: iteratorProto
},
438 it("[[Call]] returns a value with the provided string tag", () => {
439 const iterator
= setIteratorFunction(null, "My Iterator");
441 iterator(new Set())[Symbol
.toStringTag
],
446 it("[[Call]] yields the values", () => {
447 const iterator
= setIteratorFunction();
449 [...iterator(new Set(["etaoin", "shrdlu"]))],
450 ["etaoin", "shrdlu"],
454 it("[[Call]] maps the values", () => {
455 const iterator
= setIteratorFunction(function* ($) {
456 yield $.toUpperCase();
459 [...iterator(new Set(["etaoin", "shrdlu"]))],
460 ["ETAOIN", "SHRDLU"],
464 it("[[Call]] can map to nothing", () => {
465 const iterator
= setIteratorFunction(function* () {});
467 [...iterator(new Set(["etaoin", "shrdlu"]))],
472 it("[[Call]] can map to multiple values", () => {
473 const iterator
= setIteratorFunction(function* ($) {
477 [...iterator(new Set(["etaoin", "shrdlu"]))],
482 it("[[Call]] throws if not provided with any arguments", () => {
483 const iterator
= setIteratorFunction();
489 it("[[Call]] throws if not provided a set", () => {
490 const iterator
= setIteratorFunction();
496 describe("::next", () => {
497 it("[[Call]] throws if there are values and the mapper is not a generator function", () => {
498 const iterator
= setIteratorFunction(function () {});
500 iterator(new Set(["etaoin"])).next();
507 describe("stringIteratorFunction", () => {
508 it("[[Call]] returns a function", () => {
509 assertStrictEquals(typeof stringIteratorFunction(), "function");
512 it("[[Call]] returns a value which has a prototype of %FunctionPrototype%", () => {
514 Object
.getPrototypeOf(stringIteratorFunction()),
519 it("[[Construct]] throws an error", () => {
520 assertThrows(() => new stringIteratorFunction());
523 describe(".length", () => {
524 it("[[Get]] returns the correct length", () => {
525 assertStrictEquals(stringIteratorFunction
.length
, 1);
529 describe(".name", () => {
530 it("[[Get]] returns the correct name", () => {
532 stringIteratorFunction
.name
,
533 "stringIteratorFunction",
538 describe("()", () => {
539 it("[[Call]] returns a value which inherits from %IteratorPrototype%", () => {
540 const iteratorProto
= Object
.getPrototypeOf(
541 Object
.getPrototypeOf([][Symbol
.iterator
]),
543 const iterator
= stringIteratorFunction();
545 iterator("") instanceof Object
.assign(
547 { prototype: iteratorProto
},
553 it("[[Call]] returns a value with the provided string tag", () => {
554 const iterator
= stringIteratorFunction(null, "My Iterator");
556 iterator("")[Symbol
.toStringTag
],
561 it("[[Call]] yields the values", () => {
562 const iterator
= stringIteratorFunction();
564 [...iterator("etaoin👀")],
569 it("[[Call]] maps the values", () => {
570 const iterator
= stringIteratorFunction(function* ($) {
571 yield $.toUpperCase();
574 [...iterator("etaoin👀")],
579 it("[[Call]] can map to nothing", () => {
580 const iterator
= stringIteratorFunction(function* () {});
582 [...iterator("etaoin👀")],
587 it("[[Call]] can map to multiple values", () => {
588 const iterator
= stringIteratorFunction(function* ($) {
593 [...iterator("etaoin👀")],
594 [..."eettaaooiinn👀👀"],
598 it("[[Call]] throws if not provided with any arguments", () => {
599 const iterator
= stringIteratorFunction();
605 it("[[Call]] throws if not provided something convertible to a string", () => {
606 const iterator
= stringIteratorFunction();
616 describe("::next", () => {
617 it("[[Call]] throws if there are values and the mapper is not a generator function", () => {
618 const iterator
= stringIteratorFunction(function () {});
620 iterator("etaoin").next();