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 describe("()", () => {
38 it("[[Call]] returns a value which inherits from %IteratorPrototype%", () => {
39 const iteratorProto
= Object
.getPrototypeOf(
40 Object
.getPrototypeOf([][Symbol
.iterator
]),
42 const iterator
= arrayIteratorFunction();
44 iterator([]) instanceof Object
.assign(
46 { prototype: iteratorProto
},
52 it("[[Call]] returns a value with the provided string tag", () => {
53 const iterator
= arrayIteratorFunction(null, "My Iterator");
55 iterator([])[Symbol
.toStringTag
],
60 it("[[Call]] yields the values", () => {
61 const iterator
= arrayIteratorFunction();
63 [...iterator(["etaoin", "shrdlu"])],
68 it("[[Call]] maps the values", () => {
69 const iterator
= arrayIteratorFunction(function* ($) {
70 yield $.toUpperCase();
73 [...iterator(["etaoin", "shrdlu"])],
78 it("[[Call]] can map to nothing", () => {
79 const iterator
= arrayIteratorFunction(function* () {});
81 [...iterator(["etaoin", "shrdlu"])],
86 it("[[Call]] can map to multiple values", () => {
87 const iterator
= arrayIteratorFunction(function* ($) {
91 [...iterator(["etaoin", "shrdlu"])],
96 it("[[Call]] throws if not provided with any arguments", () => {
97 const iterator
= arrayIteratorFunction();
103 it("[[Call]] throws if not provided an arraylike", () => {
104 const iterator
= arrayIteratorFunction();
110 describe("::next", () => {
111 it("[[Call]] throws if there are values and the mapper is not a generator function", () => {
112 const iterator
= arrayIteratorFunction(function () {});
114 iterator(["etaoin"]).next();
121 describe("generatorIteratorFunction", () => {
122 it("[[Call]] returns a function", () => {
123 assertStrictEquals(typeof generatorIteratorFunction(), "function");
126 it("[[Call]] returns a value which has a prototype of %FunctionPrototype%", () => {
128 Object
.getPrototypeOf(generatorIteratorFunction()),
133 describe("()", () => {
134 it("[[Call]] returns a value which inherits from %IteratorPrototype%", () => {
135 const iteratorProto
= Object
.getPrototypeOf(
136 Object
.getPrototypeOf([][Symbol
.iterator
]),
138 const iterator
= generatorIteratorFunction();
140 iterator(function* () {}) instanceof Object
.assign(
142 { prototype: iteratorProto
},
148 it("[[Call]] returns a value with the provided string tag", () => {
149 const iterator
= generatorIteratorFunction(null, "My Iterator");
151 iterator(function* () {})[Symbol
.toStringTag
],
156 it("[[Call]] yields the values", () => {
157 const generator
= function* () {
158 yield* ["etaoin", "shrdlu"];
160 const iterator
= generatorIteratorFunction();
162 [...iterator(generator
)],
163 ["etaoin", "shrdlu"],
167 it("[[Call]] maps the values", () => {
168 const generator
= function* () {
169 yield* ["etaoin", "shrdlu"];
171 const iterator
= generatorIteratorFunction(function* ($) {
172 yield $.toUpperCase();
175 [...iterator(generator
)],
176 ["ETAOIN", "SHRDLU"],
180 it("[[Call]] can map to nothing", () => {
181 const generator
= function* () {
182 yield* ["etaoin", "shrdlu"];
184 const iterator
= generatorIteratorFunction(function* () {});
186 [...iterator(generator
)],
191 it("[[Call]] can map to multiple values", () => {
192 const generator
= function* () {
193 yield* ["etaoin", "shrdlu"];
195 const iterator
= generatorIteratorFunction(function* ($) {
199 [...iterator(generator
)],
204 it("[[Call]] throws if not provided with any arguments", () => {
205 const iterator
= generatorIteratorFunction();
211 it("[[Call]] throws if not provided a function", () => {
212 const iterator
= generatorIteratorFunction();
218 describe("::next", () => {
219 it("[[Call]] throws if there are values and the mapper is not a generator function", () => {
220 const generator
= function* () {
223 const iterator
= generatorIteratorFunction(function () {});
225 iterator(generator
).next();
229 it("[[Call]] throws if not constructed with a generator function", () => {
230 const iterator
= generatorIteratorFunction();
232 iterator(Array
.prototype[Symbol
.iterator
].bind([])).next();
239 describe("mapIteratorFunction", () => {
240 it("[[Call]] returns a function", () => {
241 assertStrictEquals(typeof mapIteratorFunction(), "function");
244 it("[[Call]] returns a value which has a prototype of %FunctionPrototype%", () => {
246 Object
.getPrototypeOf(mapIteratorFunction()),
251 describe("()", () => {
252 it("[[Call]] returns a value which inherits from %IteratorPrototype%", () => {
253 const iteratorProto
= Object
.getPrototypeOf(
254 Object
.getPrototypeOf([][Symbol
.iterator
]),
256 const iterator
= mapIteratorFunction();
258 iterator(new Map()) instanceof Object
.assign(
260 { prototype: iteratorProto
},
266 it("[[Call]] returns a value with the provided string tag", () => {
267 const iterator
= mapIteratorFunction(null, "My Iterator");
269 iterator(new Map())[Symbol
.toStringTag
],
274 it("[[Call]] yields the values", () => {
275 const iterator
= mapIteratorFunction();
277 [...iterator(new Map([["etaoin", "shrdlu"]]))],
278 [["etaoin", "shrdlu"]],
282 it("[[Call]] maps the values", () => {
283 const iterator
= mapIteratorFunction(function* ([k
, v
]) {
284 yield [k
.toUpperCase(), v
.toUpperCase()];
287 [...iterator(new Map([["etaoin", "shrdlu"]]))],
288 [["ETAOIN", "SHRDLU"]],
292 it("[[Call]] can map to nothing", () => {
293 const iterator
= mapIteratorFunction(function* () {});
295 [...iterator(new Map([["etaoin", "shrdlu"]]))],
300 it("[[Call]] can map to multiple values", () => {
301 const iterator
= mapIteratorFunction(function* ($) {
305 [...iterator(new Map([["etaoin", "shrdlu"]]))],
306 ["etaoin", "shrdlu"],
310 it("[[Call]] throws if not provided with any arguments", () => {
311 const iterator
= mapIteratorFunction();
317 it("[[Call]] throws if not provided a map", () => {
318 const iterator
= mapIteratorFunction();
324 describe("::next", () => {
325 it("[[Call]] throws if there are values and the mapper is not a generator function", () => {
326 const iterator
= mapIteratorFunction(function () {});
328 iterator(new Map([["etaoin", "shrdlu"]])).next();
335 describe("setIteratorFunction", () => {
336 it("[[Call]] returns a function", () => {
337 assertStrictEquals(typeof setIteratorFunction(), "function");
340 it("[[Call]] returns a value which has a prototype of %FunctionPrototype%", () => {
342 Object
.getPrototypeOf(setIteratorFunction()),
347 describe("()", () => {
348 it("[[Call]] returns a value which inherits from %IteratorPrototype%", () => {
349 const iteratorProto
= Object
.getPrototypeOf(
350 Object
.getPrototypeOf([][Symbol
.iterator
]),
352 const iterator
= setIteratorFunction();
354 iterator(new Set()) instanceof Object
.assign(
356 { prototype: iteratorProto
},
362 it("[[Call]] returns a value with the provided string tag", () => {
363 const iterator
= setIteratorFunction(null, "My Iterator");
365 iterator(new Set())[Symbol
.toStringTag
],
370 it("[[Call]] yields the values", () => {
371 const iterator
= setIteratorFunction();
373 [...iterator(new Set(["etaoin", "shrdlu"]))],
374 ["etaoin", "shrdlu"],
378 it("[[Call]] maps the values", () => {
379 const iterator
= setIteratorFunction(function* ($) {
380 yield $.toUpperCase();
383 [...iterator(new Set(["etaoin", "shrdlu"]))],
384 ["ETAOIN", "SHRDLU"],
388 it("[[Call]] can map to nothing", () => {
389 const iterator
= setIteratorFunction(function* () {});
391 [...iterator(new Set(["etaoin", "shrdlu"]))],
396 it("[[Call]] can map to multiple values", () => {
397 const iterator
= setIteratorFunction(function* ($) {
401 [...iterator(new Set(["etaoin", "shrdlu"]))],
406 it("[[Call]] throws if not provided with any arguments", () => {
407 const iterator
= setIteratorFunction();
413 it("[[Call]] throws if not provided a set", () => {
414 const iterator
= setIteratorFunction();
420 describe("::next", () => {
421 it("[[Call]] throws if there are values and the mapper is not a generator function", () => {
422 const iterator
= setIteratorFunction(function () {});
424 iterator(new Set(["etaoin"])).next();
431 describe("stringIteratorFunction", () => {
432 it("[[Call]] returns a function", () => {
433 assertStrictEquals(typeof stringIteratorFunction(), "function");
436 it("[[Call]] returns a value which has a prototype of %FunctionPrototype%", () => {
438 Object
.getPrototypeOf(stringIteratorFunction()),
443 describe("()", () => {
444 it("[[Call]] returns a value which inherits from %IteratorPrototype%", () => {
445 const iteratorProto
= Object
.getPrototypeOf(
446 Object
.getPrototypeOf([][Symbol
.iterator
]),
448 const iterator
= stringIteratorFunction();
450 iterator("") instanceof Object
.assign(
452 { prototype: iteratorProto
},
458 it("[[Call]] returns a value with the provided string tag", () => {
459 const iterator
= stringIteratorFunction(null, "My Iterator");
461 iterator("")[Symbol
.toStringTag
],
466 it("[[Call]] yields the values", () => {
467 const iterator
= stringIteratorFunction();
469 [...iterator("etaoin👀")],
474 it("[[Call]] maps the values", () => {
475 const iterator
= stringIteratorFunction(function* ($) {
476 yield $.toUpperCase();
479 [...iterator("etaoin👀")],
484 it("[[Call]] can map to nothing", () => {
485 const iterator
= stringIteratorFunction(function* () {});
487 [...iterator("etaoin👀")],
492 it("[[Call]] can map to multiple values", () => {
493 const iterator
= stringIteratorFunction(function* ($) {
498 [...iterator("etaoin👀")],
499 [..."eettaaooiinn👀👀"],
503 it("[[Call]] throws if not provided with any arguments", () => {
504 const iterator
= stringIteratorFunction();
510 it("[[Call]] throws if not provided something convertible to a string", () => {
511 const iterator
= stringIteratorFunction();
521 describe("::next", () => {
522 it("[[Call]] throws if there are values and the mapper is not a generator function", () => {
523 const iterator
= stringIteratorFunction(function () {});
525 iterator("etaoin").next();