addon-sdk/source/test/test-sequence.js

branch
TOR_BUG_9701
changeset 10
ac0c01689b40
equal deleted inserted replaced
-1:000000000000 0:022eed993452
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 "use strict";
5
6 let { seq, iterate, filter, map, reductions, reduce, count,
7 isEmpty, every, isEvery, some, take, takeWhile, drop,
8 dropWhile, concat, first, rest, nth, last, dropLast,
9 distinct, remove, mapcat, fromEnumerator, string,
10 object, pairs, keys, values, each
11 } = require("sdk/util/sequence");
12
13 const boom = () => { throw new Error("Boom!"); };
14 const broken = seq(function*() {
15 yield 1;
16 throw new Error("Boom!");
17 });
18
19 exports["test seq"] = assert => {
20 let xs = seq(function*() {
21 yield 1;
22 yield 2;
23 yield 3;
24 });
25
26 assert.deepEqual([...seq(null)], [], "seq of null is empty");
27 assert.deepEqual([...seq(void(0))], [], "seq of void is empty");
28 assert.deepEqual([...xs], [1, 2, 3], "seq of 1 2 3");
29 assert.deepEqual([...seq(xs)], [1, 2, 3], "seq of seq is seq");
30
31 assert.deepEqual([...seq([])], [], "seq of emtpy array is empty");
32 assert.deepEqual([...seq([1])], [1], "seq of lonly array is single element");
33 assert.deepEqual([...seq([1, 2, 3])], [1, 2, 3], "seq of array is it's elements");
34
35 assert.deepEqual([...seq("")], [], "seq of emtpy string is empty");
36 assert.deepEqual([...seq("o")], ["o"], "seq of char is single char seq");
37 assert.deepEqual([...seq("hello")], ["h", "e", "l", "l", "o"],
38 "seq of string are chars");
39
40 assert.deepEqual([...seq(new Set())], [], "seq of emtpy set is empty");
41 assert.deepEqual([...seq(new Set([1]))], [1], "seq of lonely set is single");
42 assert.deepEqual([...seq(new Set([1, 2, 3]))], [1, 2, 3], "seq of lonely set is single");
43
44 assert.deepEqual([...seq(new Map())], [], "seq of emtpy map is empty");
45 assert.deepEqual([...seq(new Map([[1, 2]]))], [[1, 2]], "seq single mapping is that mapping");
46 assert.deepEqual([...seq(new Map([[1, 2], [3, 4], [5, 6]]))],
47 [[1, 2], [3, 4], [5, 6]],
48 "seq of map is key value mappings");
49
50 [function(){}, 1, /foo/, true].forEach(x => {
51 assert.throws(() => seq(x), "Type is not seq-able");
52 });
53
54 assert.throws(() => [...broken],
55 /Boom/,
56 "broken sequence errors propagate");
57 };
58
59 exports["test seq casting"] = assert => {
60 const xs = seq(function*() { yield 1; yield 2; yield 3; });
61 const ys = seq(function*() { yield 1; });
62 const zs = seq(function*() {});
63 const kvs = seq(function*() { yield ["a", 1]; yield ["b", 2]; });
64 const kv = seq(function*() { yield ["a", 1]; });
65
66 assert.deepEqual([...xs], [1, 2, 3], "cast to array");
67 assert.deepEqual([...ys], [1], "cast to of one element");
68 assert.deepEqual([...zs], [], "cast empty array");
69
70 assert.deepEqual(string(...xs), "123", "cast to string");
71 assert.deepEqual(string(...ys), "1", "cast to char");
72 assert.deepEqual(string(...zs), "", "cast to empty string");
73
74 assert.deepEqual(new Set(xs), new Set([1, 2, 3]),
75 "cast to set of items");
76 assert.deepEqual(new Set(ys), new Set([1]),
77 "cast to set of one item");
78 assert.deepEqual(new Set(zs), new Set(),
79 "cast to set of one item");
80
81 assert.deepEqual(new Map(kvs), new Map([["a", 1], ["b", 2]]),
82 "cast to map");
83 assert.deepEqual(new Map(kv), new Map([["a", 1]]),
84 "cast to single mapping");
85 assert.deepEqual(new Map(zs), new Map(),
86 "cast to empty map");
87
88 assert.deepEqual(object(...kvs), {a: 1, b: 2},
89 "cast to object");
90 assert.deepEqual(object(...kv), {a: 1},
91 "cast to single pair");
92 assert.deepEqual(object(...zs), {},
93 "cast to empty object");
94 };
95
96 exports["test pairs"] = assert => {
97 assert.deepEqual([...pairs(null)], [], "pairs on null is empty");
98 assert.deepEqual([...pairs(void(0))], [], "pairs on void is empty");
99 assert.deepEqual([...pairs({})], [], "empty sequence");
100 assert.deepEqual([...pairs({a: 1})], [["a", 1]], "single pair");
101 assert.deepEqual([...pairs({a: 1, b: 2, c: 3})].sort(),
102 [["a", 1], ["b", 2], ["c", 3]],
103 "creates pairs");
104 let items = [];
105 for (let [key, value] of pairs({a: 1, b: 2, c: 3}))
106 items.push([key, value]);
107
108 assert.deepEqual(items.sort(),
109 [["a", 1], ["b", 2], ["c", 3]],
110 "for of works on pairs");
111
112
113 assert.deepEqual([...pairs([])], [], "pairs on empty array is empty");
114 assert.deepEqual([...pairs([1])], [[0, 1]], "pairs on array is [index, element]");
115 assert.deepEqual([...pairs([1, 2, 3])],
116 [[0, 1], [1, 2], [2, 3]],
117 "for arrays it pair of [index, element]");
118
119 assert.deepEqual([...pairs("")], [], "pairs on empty string is empty");
120 assert.deepEqual([...pairs("a")], [[0, "a"]], "pairs on char is [0, char]");
121 assert.deepEqual([...pairs("hello")],
122 [[0, "h"], [1, "e"], [2, "l"], [3, "l"], [4, "o"]],
123 "for strings it's pair of [index, char]");
124
125 assert.deepEqual([...pairs(new Map())],
126 [],
127 "pairs on empty map is empty");
128 assert.deepEqual([...pairs(new Map([[1, 3]]))],
129 [[1, 3]],
130 "pairs on single mapping single mapping");
131 assert.deepEqual([...pairs(new Map([[1, 2], [3, 4]]))],
132 [[1, 2], [3, 4]],
133 "pairs on map returs key vaule pairs");
134
135 assert.throws(() => pairs(new Set()),
136 "can't pair set");
137
138 assert.throws(() => pairs(4),
139 "can't pair number");
140
141 assert.throws(() => pairs(true),
142 "can't pair boolean");
143 };
144
145 exports["test keys"] = assert => {
146 assert.deepEqual([...keys(null)], [], "keys on null is empty");
147 assert.deepEqual([...keys(void(0))], [], "keys on void is empty");
148 assert.deepEqual([...keys({})], [], "empty sequence");
149 assert.deepEqual([...keys({a: 1})], ["a"], "single key");
150 assert.deepEqual([...keys({a: 1, b: 2, c: 3})].sort(),
151 ["a", "b", "c"],
152 "all keys");
153
154 let items = [];
155 for (let key of keys({a: 1, b: 2, c: 3}))
156 items.push(key);
157
158 assert.deepEqual(items.sort(),
159 ["a", "b", "c"],
160 "for of works on keys");
161
162
163 assert.deepEqual([...keys([])], [], "keys on empty array is empty");
164 assert.deepEqual([...keys([1])], [0], "keys on array is indexes");
165 assert.deepEqual([...keys([1, 2, 3])],
166 [0, 1, 2],
167 "keys on arrays returns indexes");
168
169 assert.deepEqual([...keys("")], [], "keys on empty string is empty");
170 assert.deepEqual([...keys("a")], [0], "keys on char is 0");
171 assert.deepEqual([...keys("hello")],
172 [0, 1, 2, 3, 4],
173 "keys on strings is char indexes");
174
175 assert.deepEqual([...keys(new Map())],
176 [],
177 "keys on empty map is empty");
178 assert.deepEqual([...keys(new Map([[1, 3]]))],
179 [1],
180 "keys on single mapping single mapping is single key");
181 assert.deepEqual([...keys(new Map([[1, 2], [3, 4]]))],
182 [1, 3],
183 "keys on map is keys from map");
184
185 assert.throws(() => keys(new Set()),
186 "can't keys set");
187
188 assert.throws(() => keys(4),
189 "can't keys number");
190
191 assert.throws(() => keys(true),
192 "can't keys boolean");
193 };
194
195 exports["test values"] = assert => {
196 assert.deepEqual([...values({})], [], "empty sequence");
197 assert.deepEqual([...values({a: 1})], [1], "single value");
198 assert.deepEqual([...values({a: 1, b: 2, c: 3})].sort(),
199 [1, 2, 3],
200 "all values");
201
202 let items = [];
203 for (let value of values({a: 1, b: 2, c: 3}))
204 items.push(value);
205
206 assert.deepEqual(items.sort(),
207 [1, 2, 3],
208 "for of works on values");
209
210 assert.deepEqual([...values([])], [], "values on empty array is empty");
211 assert.deepEqual([...values([1])], [1], "values on array elements");
212 assert.deepEqual([...values([1, 2, 3])],
213 [1, 2, 3],
214 "values on arrays returns elements");
215
216 assert.deepEqual([...values("")], [], "values on empty string is empty");
217 assert.deepEqual([...values("a")], ["a"], "values on char is char");
218 assert.deepEqual([...values("hello")],
219 ["h", "e", "l", "l", "o"],
220 "values on strings is chars");
221
222 assert.deepEqual([...values(new Map())],
223 [],
224 "values on empty map is empty");
225 assert.deepEqual([...values(new Map([[1, 3]]))],
226 [3],
227 "keys on single mapping single mapping is single key");
228 assert.deepEqual([...values(new Map([[1, 2], [3, 4]]))],
229 [2, 4],
230 "values on map is values from map");
231
232 assert.deepEqual([...values(new Set())], [], "values on empty set is empty");
233 assert.deepEqual([...values(new Set([1]))], [1], "values on set is it's items");
234 assert.deepEqual([...values(new Set([1, 2, 3]))],
235 [1, 2, 3],
236 "values on set is it's items");
237
238
239 assert.throws(() => values(4),
240 "can't values number");
241
242 assert.throws(() => values(true),
243 "can't values boolean");
244 };
245
246 exports["test fromEnumerator"] = assert => {
247 const { Cc, Ci } = require("chrome");
248 const { enumerateObservers,
249 addObserver,
250 removeObserver } = Cc["@mozilla.org/observer-service;1"].
251 getService(Ci.nsIObserverService);
252
253
254 const topic = "sec:" + Math.random().toString(32).substr(2);
255 const [a, b, c] = [{wrappedJSObject: {}},
256 {wrappedJSObject: {}},
257 {wrappedJSObject: {}}];
258 const unwrap = x => x.wrappedJSObject;
259
260 [a, b, c].forEach(x => addObserver(x, topic, false));
261
262 const xs = fromEnumerator(() => enumerateObservers(topic));
263 const ys = map(unwrap, xs);
264
265 assert.deepEqual([...ys], [a, b, c].map(unwrap),
266 "all observers are there");
267
268 removeObserver(b, topic);
269
270 assert.deepEqual([...ys], [a, c].map(unwrap),
271 "b was removed");
272
273 removeObserver(a, topic);
274
275 assert.deepEqual([...ys], [c].map(unwrap),
276 "a was removed");
277
278 removeObserver(c, topic);
279
280 assert.deepEqual([...ys], [],
281 "c was removed, now empty");
282
283 addObserver(a, topic, false);
284
285 assert.deepEqual([...ys], [a].map(unwrap),
286 "a was added");
287
288 removeObserver(a, topic);
289
290 assert.deepEqual([...ys], [].map(unwrap),
291 "a was removed, now empty");
292
293 };
294
295 exports["test filter"] = assert => {
296 const isOdd = x => x % 2;
297 const odds = seq(function*() { yield 1; yield 3; yield 5; });
298 const evens = seq(function*() { yield 2; yield 4; yield 6; });
299 const mixed = seq(function*() {
300 yield 1;
301 yield 2;
302 yield 3;
303 yield 4;
304 });
305
306 assert.deepEqual([...filter(isOdd, mixed)], [1, 3],
307 "filtered odds");
308 assert.deepEqual([...filter(isOdd, odds)], [1, 3, 5],
309 "kept all");
310 assert.deepEqual([...filter(isOdd, evens)], [],
311 "kept none");
312
313
314 let xs = filter(boom, mixed);
315 assert.throws(() => [...xs], /Boom/, "errors propagate");
316
317 assert.throws(() => [...filter(isOdd, broken)], /Boom/,
318 "sequence errors propagate");
319 };
320
321 exports["test filter array"] = assert => {
322 let isOdd = x => x % 2;
323 let xs = filter(isOdd, [1, 2, 3, 4]);
324 let ys = filter(isOdd, [1, 3, 5]);
325 let zs = filter(isOdd, [2, 4, 6]);
326
327 assert.deepEqual([...xs], [1, 3], "filteres odds");
328 assert.deepEqual([...ys], [1, 3, 5], "kept all");
329 assert.deepEqual([...zs], [], "kept none");
330 assert.ok(!Array.isArray(xs));
331 };
332
333 exports["test filter set"] = assert => {
334 let isOdd = x => x % 2;
335 let xs = filter(isOdd, new Set([1, 2, 3, 4]));
336 let ys = filter(isOdd, new Set([1, 3, 5]));
337 let zs = filter(isOdd, new Set([2, 4, 6]));
338
339 assert.deepEqual([...xs], [1, 3], "filteres odds");
340 assert.deepEqual([...ys], [1, 3, 5], "kept all");
341 assert.deepEqual([...zs], [], "kept none");
342 };
343
344 exports["test filter string"] = assert => {
345 let isUpperCase = x => x.toUpperCase() === x;
346 let xs = filter(isUpperCase, "aBcDe");
347 let ys = filter(isUpperCase, "ABC");
348 let zs = filter(isUpperCase, "abcd");
349
350 assert.deepEqual([...xs], ["B", "D"], "filteres odds");
351 assert.deepEqual([...ys], ["A", "B", "C"], "kept all");
352 assert.deepEqual([...zs], [], "kept none");
353 };
354
355 exports["test filter lazy"] = assert => {
356 const x = 1;
357 let y = 2;
358
359 const xy = seq(function*() { yield x; yield y; });
360 const isOdd = x => x % 2;
361 const actual = filter(isOdd, xy);
362
363 assert.deepEqual([...actual], [1], "only one odd number");
364 y = 3;
365 assert.deepEqual([...actual], [1, 3], "filter is lazy");
366 };
367
368 exports["test filter non sequences"] = assert => {
369 const False = _ => false;
370 assert.throws(() => [...filter(False, 1)],
371 "can't iterate number");
372 assert.throws(() => [...filter(False, {a: 1, b:2})],
373 "can't iterate object");
374 };
375
376 exports["test map"] = assert => {
377 let inc = x => x + 1;
378 let xs = seq(function*() { yield 1; yield 2; yield 3; });
379 let ys = map(inc, xs);
380
381 assert.deepEqual([...ys], [2, 3, 4], "incremented each item");
382
383 assert.deepEqual([...map(inc, null)], [], "mapping null is empty");
384 assert.deepEqual([...map(inc, void(0))], [], "mapping void is empty");
385 assert.deepEqual([...map(inc, new Set([1, 2, 3]))], [2, 3, 4], "maps set items");
386 };
387
388 exports["test map two inputs"] = assert => {
389 let sum = (x, y) => x + y;
390 let xs = seq(function*() { yield 1; yield 2; yield 3; });
391 let ys = seq(function*() { yield 4; yield 5; yield 6; });
392
393 let zs = map(sum, xs, ys);
394
395 assert.deepEqual([...zs], [5, 7, 9], "summed numbers");
396 };
397
398 exports["test map diff sized inputs"] = assert => {
399 let sum = (x, y) => x + y;
400 let xs = seq(function*() { yield 1; yield 2; yield 3; });
401 let ys = seq(function*() { yield 4; yield 5; yield 6; yield 7; yield 8; });
402
403 let zs = map(sum, xs, ys);
404
405 assert.deepEqual([...zs], [5, 7, 9], "summed numbers");
406 assert.deepEqual([...map(sum, ys, xs)], [5, 7, 9],
407 "index of exhasting input is irrelevant");
408 };
409
410 exports["test map multi"] = assert => {
411 let sum = (x, y, z, w) => x + y + z + w;
412 let xs = seq(function*() { yield 1; yield 2; yield 3; yield 4; });
413 let ys = seq(function*() { yield 4; yield 5; yield 6; yield 7; yield 8; });
414 let zs = seq(function*() { yield 10; yield 11; yield 12; });
415 let ws = seq(function*() { yield 0; yield 20; yield 40; yield 60; });
416
417 let actual = map(sum, xs, ys, zs, ws);
418
419 assert.deepEqual([...actual], [15, 38, 61], "summed numbers");
420 };
421
422 exports["test map errors"] = assert => {
423 assert.deepEqual([...map(boom, [])], [],
424 "won't throw if empty");
425
426 const xs = map(boom, [1, 2, 4]);
427
428 assert.throws(() => [...xs], /Boom/, "propagates errors");
429
430 assert.throws(() => [...map(x => x, broken)], /Boom/,
431 "sequence errors propagate");
432 };
433
434 exports["test reductions"] = assert => {
435 let sum = (...xs) => xs.reduce((x, y) => x + y, 0);
436
437 assert.deepEqual([...reductions(sum, [1, 1, 1, 1])],
438 [1, 2, 3, 4],
439 "works with arrays");
440 assert.deepEqual([...reductions(sum, 5, [1, 1, 1, 1])],
441 [5, 6, 7, 8, 9],
442 "array with initial");
443
444 assert.deepEqual([...reductions(sum, seq(function*() {
445 yield 1;
446 yield 2;
447 yield 3;
448 }))],
449 [1, 3, 6],
450 "works with sequences");
451
452 assert.deepEqual([...reductions(sum, 10, seq(function*() {
453 yield 1;
454 yield 2;
455 yield 3;
456 }))],
457 [10, 11, 13, 16],
458 "works with sequences");
459
460 assert.deepEqual([...reductions(sum, [])], [0],
461 "invokes accumulator with no args");
462
463 assert.throws(() => [...reductions(boom, 1, [1])],
464 /Boom/,
465 "arg errors errors propagate");
466 assert.throws(() => [...reductions(sum, 1, broken)],
467 /Boom/,
468 "sequence errors propagate");
469 };
470
471 exports["test reduce"] = assert => {
472 let sum = (...xs) => xs.reduce((x, y) => x + y, 0);
473
474 assert.deepEqual(reduce(sum, [1, 2, 3, 4, 5]),
475 15,
476 "works with arrays");
477
478 assert.deepEqual(reduce(sum, seq(function*() {
479 yield 1;
480 yield 2;
481 yield 3;
482 })),
483 6,
484 "works with sequences");
485
486 assert.deepEqual(reduce(sum, 10, [1, 2, 3, 4, 5]),
487 25,
488 "works with array & initial");
489
490 assert.deepEqual(reduce(sum, 5, seq(function*() {
491 yield 1;
492 yield 2;
493 yield 3;
494 })),
495 11,
496 "works with sequences & initial");
497
498 assert.deepEqual(reduce(sum, []), 0, "reduce with no args");
499 assert.deepEqual(reduce(sum, "a", []), "a", "reduce with initial");
500 assert.deepEqual(reduce(sum, 1, [1]), 2, "reduce with single & initial");
501
502 assert.throws(() => [...reduce(boom, 1, [1])],
503 /Boom/,
504 "arg errors errors propagate");
505 assert.throws(() => [...reduce(sum, 1, broken)],
506 /Boom/,
507 "sequence errors propagate");
508 };
509
510 exports["test each"] = assert => {
511 const collect = xs => {
512 let result = [];
513 each((...etc) => result.push(...etc), xs);
514 return result;
515 };
516
517 assert.deepEqual(collect(null), [], "each ignores null");
518 assert.deepEqual(collect(void(0)), [], "each ignores void");
519
520 assert.deepEqual(collect([]), [], "each ignores empty");
521 assert.deepEqual(collect([1]), [1], "each works on single item arrays");
522 assert.deepEqual(collect([1, 2, 3, 4, 5]),
523 [1, 2, 3, 4, 5],
524 "works with arrays");
525
526 assert.deepEqual(collect(seq(function*() {
527 yield 1;
528 yield 2;
529 yield 3;
530 })),
531 [1, 2, 3],
532 "works with sequences");
533
534 assert.deepEqual(collect(""), [], "ignores empty strings");
535 assert.deepEqual(collect("a"), ["a"], "works on chars");
536 assert.deepEqual(collect("hello"), ["h", "e", "l", "l", "o"],
537 "works on strings");
538
539 assert.deepEqual(collect(new Set()), [], "ignores empty sets");
540 assert.deepEqual(collect(new Set(["a"])), ["a"],
541 "works on single item sets");
542 assert.deepEqual(collect(new Set([1, 2, 3])), [1, 2, 3],
543 "works on muti item tests");
544
545 assert.deepEqual(collect(new Map()), [], "ignores empty maps");
546 assert.deepEqual(collect(new Map([["a", 1]])), [["a", 1]],
547 "works on single mapping maps");
548 assert.deepEqual(collect(new Map([[1, 2], [3, 4], [5, 6]])),
549 [[1, 2], [3, 4], [5, 6]],
550 "works on muti mapping maps");
551
552 assert.throws(() => collect({}), "objects arn't supported");
553 assert.throws(() => collect(1), "numbers arn't supported");
554 assert.throws(() => collect(true), "booleas arn't supported");
555 };
556
557 exports["test count"] = assert => {
558 assert.equal(count(null), 0, "null counts to 0");
559 assert.equal(count(), 0, "undefined counts to 0");
560 assert.equal(count([]), 0, "empty array");
561 assert.equal(count([1, 2, 3]), 3, "non-empty array");
562 assert.equal(count(""), 0, "empty string");
563 assert.equal(count("hello"), 5, "non-empty string");
564 assert.equal(count(new Map()), 0, "empty map");
565 assert.equal(count(new Map([[1, 2], [2, 3]])), 2, "non-empty map");
566 assert.equal(count(new Set()), 0, "empty set");
567 assert.equal(count(new Set([1, 2, 3, 4])), 4, "non-empty set");
568 assert.equal(count(seq(function*() {})), 0, "empty sequence");
569 assert.equal(count(seq(function*() { yield 1; yield 2; })), 2,
570 "non-empty sequence");
571
572 assert.throws(() => count(broken),
573 /Boom/,
574 "sequence errors propagate");
575 };
576
577 exports["test isEmpty"] = assert => {
578 assert.equal(isEmpty(null), true, "null is empty");
579 assert.equal(isEmpty(), true, "undefined is empty");
580 assert.equal(isEmpty([]), true, "array is array");
581 assert.equal(isEmpty([1, 2, 3]), false, "array isn't empty");
582 assert.equal(isEmpty(""), true, "string is empty");
583 assert.equal(isEmpty("hello"), false, "non-empty string");
584 assert.equal(isEmpty(new Map()), true, "empty map");
585 assert.equal(isEmpty(new Map([[1, 2], [2, 3]])), false, "non-empty map");
586 assert.equal(isEmpty(new Set()), true, "empty set");
587 assert.equal(isEmpty(new Set([1, 2, 3, 4])), false , "non-empty set");
588 assert.equal(isEmpty(seq(function*() {})), true, "empty sequence");
589 assert.equal(isEmpty(seq(function*() { yield 1; yield 2; })), false,
590 "non-empty sequence");
591
592 assert.equal(isEmpty(broken), false, "hasn't reached error");
593 };
594
595 exports["test isEvery"] = assert => {
596 let isOdd = x => x % 2;
597 let isTrue = x => x === true;
598 let isFalse = x => x === false;
599
600 assert.equal(isEvery(isOdd, seq(function*() {
601 yield 1;
602 yield 3;
603 yield 5;
604 })), true, "all are odds");
605
606 assert.equal(isEvery(isOdd, seq(function*() {
607 yield 1;
608 yield 2;
609 yield 3;
610 })), false, "contains even");
611
612 assert.equal(isEvery(isTrue, seq(function*() {})), true, "true if empty");
613 assert.equal(isEvery(isFalse, seq(function*() {})), true, "true if empty");
614
615 assert.equal(isEvery(isTrue, null), true, "true for null");
616 assert.equal(isEvery(isTrue, undefined), true, "true for undefined");
617
618 assert.throws(() => isEvery(boom, [1, 2]),
619 /Boom/,
620 "arg errors errors propagate");
621 assert.throws(() => isEvery(x => true, broken),
622 /Boom/,
623 "sequence errors propagate");
624
625 assert.equal(isEvery(x => false, broken), false,
626 "hasn't reached error");
627 };
628
629 exports["test some"] = assert => {
630 let isOdd = x => x % 2;
631 let isTrue = x => x === true;
632 let isFalse = x => x === false;
633
634 assert.equal(some(isOdd, seq(function*() {
635 yield 2;
636 yield 4;
637 yield 6;
638 })), null, "all are even");
639
640 assert.equal(some(isOdd, seq(function*() {
641 yield 2;
642 yield 3;
643 yield 4;
644 })), true, "contains odd");
645
646 assert.equal(some(isTrue, seq(function*() {})), null,
647 "null if empty")
648 assert.equal(some(isFalse, seq(function*() {})), null,
649 "null if empty")
650
651 assert.equal(some(isTrue, null), null, "null for null");
652 assert.equal(some(isTrue, undefined), null, "null for undefined");
653
654 assert.throws(() => some(boom, [1, 2]),
655 /Boom/,
656 "arg errors errors propagate");
657 assert.throws(() => some(x => false, broken),
658 /Boom/,
659 "sequence errors propagate");
660
661 assert.equal(some(x => true, broken), true,
662 "hasn't reached error");
663 };
664
665 exports["test take"] = assert => {
666 let xs = seq(function*() {
667 yield 1;
668 yield 2;
669 yield 3;
670 yield 4;
671 yield 5;
672 yield 6;
673 });
674
675 assert.deepEqual([...take(3, xs)], [1, 2, 3], "took 3 items");
676 assert.deepEqual([...take(3, [1, 2, 3, 4, 5])], [1, 2, 3],
677 "took 3 from array");
678
679 let ys = seq(function*() { yield 1; yield 2; });
680 assert.deepEqual([...take(3, ys)], [1, 2], "takes at max n");
681 assert.deepEqual([...take(3, [1, 2])], [1, 2],
682 "takes at max n from arary");
683
684 let empty = seq(function*() {});
685 assert.deepEqual([...take(5, empty)], [], "nothing to take");
686
687 assert.throws(() => [...take(3, broken)],
688 /Boom/,
689 "sequence errors propagate");
690
691 assert.deepEqual([...take(1, broken)], [1],
692 "hasn't reached error");
693 };
694
695 exports["test iterate"] = assert => {
696 let inc = x => x + 1;
697 let nums = iterate(inc, 0);
698
699 assert.deepEqual([...take(5, nums)], [0, 1, 2, 3, 4], "took 5");
700 assert.deepEqual([...take(10, nums)], [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], "took 10");
701
702 let xs = iterate(x => x * 3, 2);
703 assert.deepEqual([...take(4, xs)], [2, 6, 18, 54], "took 4");
704
705 assert.throws(() => [...iterate(boom, 0)],
706 /Boom/,
707 "function exceptions propagate");
708 };
709
710 exports["test takeWhile"] = assert => {
711 let isNegative = x => x < 0;
712 let xs = seq(function*() {
713 yield -2;
714 yield -1;
715 yield 0;
716 yield 1;
717 yield 2;
718 yield 3;
719 });
720
721 assert.deepEqual([...takeWhile(isNegative, xs)], [-2, -1],
722 "took until 0");
723
724 let ys = seq(function*() {});
725 assert.deepEqual([...takeWhile(isNegative, ys)], [],
726 "took none");
727
728 let zs = seq(function*() {
729 yield 0;
730 yield 1;
731 yield 2;
732 yield 3;
733 });
734
735 assert.deepEqual([...takeWhile(isNegative, zs)], [],
736 "took none");
737
738 assert.throws(() => [...takeWhile(boom, zs)],
739 /Boom/,
740 "function errors errors propagate");
741 assert.throws(() => [...takeWhile(x => true, broken)],
742 /Boom/,
743 "sequence errors propagate");
744
745 assert.deepEqual([...takeWhile(x => false, broken)],
746 [],
747 "hasn't reached error");
748 };
749
750 exports["test drop"] = assert => {
751 let testDrop = xs => {
752 assert.deepEqual([...drop(2, xs)],
753 [3, 4],
754 "dropped two elements");
755
756 assert.deepEqual([...drop(1, xs)],
757 [2, 3, 4],
758 "dropped one");
759
760 assert.deepEqual([...drop(0, xs)],
761 [1, 2, 3, 4],
762 "dropped 0");
763
764 assert.deepEqual([...drop(-2, xs)],
765 [1, 2, 3, 4],
766 "dropped 0 on negative `n`");
767
768 assert.deepEqual([...drop(5, xs)],
769 [],
770 "dropped all items");
771 };
772
773 testDrop([1, 2, 3, 4]);
774 testDrop(seq(function*() {
775 yield 1;
776 yield 2;
777 yield 3;
778 yield 4;
779 }));
780
781 assert.throws(() => [...drop(1, broken)],
782 /Boom/,
783 "sequence errors propagate");
784 };
785
786
787 exports["test dropWhile"] = assert => {
788 let isNegative = x => x < 0;
789 let True = _ => true;
790 let False = _ => false;
791
792 let test = xs => {
793 assert.deepEqual([...dropWhile(isNegative, xs)],
794 [0, 1, 2],
795 "dropped negative");
796
797 assert.deepEqual([...dropWhile(True, xs)],
798 [],
799 "drop all");
800
801 assert.deepEqual([...dropWhile(False, xs)],
802 [-2, -1, 0, 1, 2],
803 "keep all");
804 };
805
806 test([-2, -1, 0, 1, 2]);
807 test(seq(function*() {
808 yield -2;
809 yield -1;
810 yield 0;
811 yield 1;
812 yield 2;
813 }));
814
815 assert.throws(() => [...dropWhile(boom, [1, 2, 3])],
816 /Boom/,
817 "function errors errors propagate");
818 assert.throws(() => [...dropWhile(x => true, broken)],
819 /Boom/,
820 "sequence errors propagate");
821 };
822
823
824 exports["test concat"] = assert => {
825 let test = (a, b, c, d) => {
826 assert.deepEqual([...concat()],
827 [],
828 "nothing to concat");
829 assert.deepEqual([...concat(a)],
830 [1, 2, 3],
831 "concat with nothing returns same as first");
832 assert.deepEqual([...concat(a, b)],
833 [1, 2, 3, 4, 5],
834 "concat items from both");
835 assert.deepEqual([...concat(a, b, a)],
836 [1, 2, 3, 4, 5, 1, 2, 3],
837 "concat itself");
838 assert.deepEqual([...concat(c)],
839 [],
840 "concat of empty is empty");
841 assert.deepEqual([...concat(a, c)],
842 [1, 2, 3],
843 "concat with empty");
844 assert.deepEqual([...concat(c, c, c)],
845 [],
846 "concat of empties is empty");
847 assert.deepEqual([...concat(c, b)],
848 [4, 5],
849 "empty can be in front");
850 assert.deepEqual([...concat(d)],
851 [7],
852 "concat singular");
853 assert.deepEqual([...concat(d, d)],
854 [7, 7],
855 "concat singulars");
856
857 assert.deepEqual([...concat(a, a, b, c, d, c, d, d)],
858 [1, 2, 3, 1, 2, 3, 4, 5, 7, 7, 7],
859 "many concats");
860
861 let ab = concat(a, b);
862 let abcd = concat(ab, concat(c, d));
863 let cdabcd = concat(c, d, abcd);
864
865 assert.deepEqual([...cdabcd],
866 [7, 1, 2, 3, 4, 5, 7],
867 "nested concats");
868 };
869
870 test([1, 2, 3],
871 [4, 5],
872 [],
873 [7]);
874
875 test(seq(function*() { yield 1; yield 2; yield 3; }),
876 seq(function*() { yield 4; yield 5; }),
877 seq(function*() { }),
878 seq(function*() { yield 7; }));
879
880 assert.throws(() => [...concat(broken, [1, 2, 3])],
881 /Boom/,
882 "function errors errors propagate");
883 };
884
885
886 exports["test first"] = assert => {
887 let test = (xs, empty) => {
888 assert.equal(first(xs), 1, "returns first");
889 assert.equal(first(empty), null, "returns null empty");
890 };
891
892 test("1234", "");
893 test([1, 2, 3], []);
894 test([1, 2, 3], null);
895 test([1, 2, 3], undefined);
896 test(seq(function*() { yield 1; yield 2; yield 3; }),
897 seq(function*() { }));
898 assert.equal(first(broken), 1, "did not reached error");
899 };
900
901 exports["test rest"] = assert => {
902 let test = (xs, x, nil) => {
903 assert.deepEqual([...rest(xs)], ["b", "c"],
904 "rest items");
905 assert.deepEqual([...rest(x)], [],
906 "empty when singular");
907 assert.deepEqual([...rest(nil)], [],
908 "empty when empty");
909 };
910
911 test("abc", "a", "");
912 test(["a", "b", "c"], ["d"], []);
913 test(seq(function*() { yield "a"; yield "b"; yield "c"; }),
914 seq(function*() { yield "d"; }),
915 seq(function*() {}));
916 test(["a", "b", "c"], ["d"], null);
917 test(["a", "b", "c"], ["d"], undefined);
918
919 assert.throws(() => [...rest(broken)],
920 /Boom/,
921 "sequence errors propagate");
922 };
923
924
925 exports["test nth"] = assert => {
926 let notFound = {};
927 let test = xs => {
928 assert.equal(nth(xs, 0), "h", "first");
929 assert.equal(nth(xs, 1), "e", "second");
930 assert.equal(nth(xs, 5), void(0), "out of bound");
931 assert.equal(nth(xs, 5, notFound), notFound, "out of bound");
932 assert.equal(nth(xs, -1), void(0), "out of bound");
933 assert.equal(nth(xs, -1, notFound), notFound, "out of bound");
934 assert.equal(nth(xs, 4), "o", "5th");
935 };
936
937 let testEmpty = xs => {
938 assert.equal(nth(xs, 0), void(0), "no first in empty");
939 assert.equal(nth(xs, 5), void(0), "no 5th in empty");
940 assert.equal(nth(xs, 0, notFound), notFound, "notFound on out of bound");
941 };
942
943 test("hello");
944 test(["h", "e", "l", "l", "o"]);
945 test(seq(function*() {
946 yield "h";
947 yield "e";
948 yield "l";
949 yield "l";
950 yield "o";
951 }));
952 testEmpty(null);
953 testEmpty(undefined);
954 testEmpty([]);
955 testEmpty("");
956 testEmpty(seq(function*() {}));
957
958
959 assert.throws(() => nth(broken, 1),
960 /Boom/,
961 "sequence errors propagate");
962 assert.equal(nth(broken, 0), 1, "have not reached error");
963 };
964
965
966 exports["test last"] = assert => {
967 assert.equal(last(null), null, "no last in null");
968 assert.equal(last(void(0)), null, "no last in undefined");
969 assert.equal(last([]), null, "no last in []");
970 assert.equal(last(""), null, "no last in ''");
971 assert.equal(last(seq(function*() { })), null, "no last in empty");
972
973 assert.equal(last("hello"), "o", "last from string");
974 assert.equal(last([1, 2, 3]), 3, "last from array");
975 assert.equal(last([1]), 1, "last from singular");
976 assert.equal(last(seq(function*() {
977 yield 1;
978 yield 2;
979 yield 3;
980 })), 3, "last from sequence");
981
982 assert.throws(() => last(broken),
983 /Boom/,
984 "sequence errors propagate");
985 };
986
987
988 exports["test dropLast"] = assert => {
989 let test = xs => {
990 assert.deepEqual([...dropLast(xs)],
991 [1, 2, 3, 4],
992 "dropped last");
993 assert.deepEqual([...dropLast(0, xs)],
994 [1, 2, 3, 4, 5],
995 "dropped none on 0");
996 assert.deepEqual([...dropLast(-3, xs)],
997 [1, 2, 3, 4, 5],
998 "drop none on negative");
999 assert.deepEqual([...dropLast(3, xs)],
1000 [1, 2],
1001 "dropped given number");
1002 assert.deepEqual([...dropLast(5, xs)],
1003 [],
1004 "dropped all");
1005 };
1006
1007 let testEmpty = xs => {
1008 assert.deepEqual([...dropLast(xs)],
1009 [],
1010 "nothing to drop");
1011 assert.deepEqual([...dropLast(0, xs)],
1012 [],
1013 "dropped none on 0");
1014 assert.deepEqual([...dropLast(-3, xs)],
1015 [],
1016 "drop none on negative");
1017 assert.deepEqual([...dropLast(3, xs)],
1018 [],
1019 "nothing to drop");
1020 };
1021
1022 test([1, 2, 3, 4, 5]);
1023 test(seq(function*() {
1024 yield 1;
1025 yield 2;
1026 yield 3;
1027 yield 4;
1028 yield 5;
1029 }));
1030 testEmpty([]);
1031 testEmpty("");
1032 testEmpty(seq(function*() {}));
1033
1034 assert.throws(() => [...dropLast(broken)],
1035 /Boom/,
1036 "sequence errors propagate");
1037 };
1038
1039
1040 exports["test distinct"] = assert => {
1041 let test = (xs, message) => {
1042 assert.deepEqual([...distinct(xs)],
1043 [1, 2, 3, 4, 5],
1044 message);
1045 };
1046
1047 test([1, 2, 1, 3, 1, 4, 1, 5], "works with arrays");
1048 test(seq(function*() {
1049 yield 1;
1050 yield 2;
1051 yield 1;
1052 yield 3;
1053 yield 1;
1054 yield 4;
1055 yield 1;
1056 yield 5;
1057 }), "works with sequences");
1058 test(new Set([1, 2, 1, 3, 1, 4, 1, 5]),
1059 "works with sets");
1060 test(seq(function*() {
1061 yield 1;
1062 yield 2;
1063 yield 2;
1064 yield 2;
1065 yield 1;
1066 yield 3;
1067 yield 1;
1068 yield 4;
1069 yield 4;
1070 yield 4;
1071 yield 1;
1072 yield 5;
1073 }), "works with multiple repeatitions");
1074 test([1, 2, 3, 4, 5], "work with distinct arrays");
1075 test(seq(function*() {
1076 yield 1;
1077 yield 2;
1078 yield 3;
1079 yield 4;
1080 yield 5;
1081 }), "works with distinct seqs");
1082 };
1083
1084
1085 exports["test remove"] = assert => {
1086 let isPositive = x => x > 0;
1087 let test = xs => {
1088 assert.deepEqual([...remove(isPositive, xs)],
1089 [-2, -1, 0],
1090 "removed positives");
1091 };
1092
1093 test([1, -2, 2, -1, 3, 7, 0]);
1094 test(seq(function*() {
1095 yield 1;
1096 yield -2;
1097 yield 2;
1098 yield -1;
1099 yield 3;
1100 yield 7;
1101 yield 0;
1102 }));
1103
1104 assert.throws(() => [...distinct(broken)],
1105 /Boom/,
1106 "sequence errors propagate");
1107 };
1108
1109
1110 exports["test mapcat"] = assert => {
1111 let upto = n => seq(function* () {
1112 let index = 0;
1113 while (index < n) {
1114 yield index;
1115 index = index + 1;
1116 }
1117 });
1118
1119 assert.deepEqual([...mapcat(upto, [1, 2, 3, 4])],
1120 [0, 0, 1, 0, 1, 2, 0, 1, 2, 3],
1121 "expands given sequence");
1122
1123 assert.deepEqual([...mapcat(upto, [0, 1, 2, 0])],
1124 [0, 0, 1],
1125 "expands given sequence");
1126
1127 assert.deepEqual([...mapcat(upto, [0, 0, 0])],
1128 [],
1129 "expands given sequence");
1130
1131 assert.deepEqual([...mapcat(upto, [])],
1132 [],
1133 "nothing to expand");
1134
1135 assert.deepEqual([...mapcat(upto, null)],
1136 [],
1137 "nothing to expand");
1138
1139 assert.deepEqual([...mapcat(upto, void(0))],
1140 [],
1141 "nothing to expand");
1142
1143 let xs = seq(function*() {
1144 yield 0;
1145 yield 1;
1146 yield 0;
1147 yield 2;
1148 yield 0;
1149 });
1150
1151 assert.deepEqual([...mapcat(upto, xs)],
1152 [0, 0, 1],
1153 "expands given sequence");
1154
1155 assert.throws(() => [...mapcat(boom, xs)],
1156 /Boom/,
1157 "function errors errors propagate");
1158 assert.throws(() => [...mapcat(upto, broken)],
1159 /Boom/,
1160 "sequence errors propagate");
1161 };
1162
1163 require("sdk/test").run(exports);

mercurial