├── .eslintignore
├── .eslintrc
├── .gitignore
├── .travis.yml
├── APIDOC.md
├── CONTRIBUTING.md
├── Gruntfile.js
├── LICENSE
├── README.md
├── bower.json
├── package.json
├── perf
├── perf.html
└── perf.js
├── stream-min.js
├── stream-min.map
├── stream.js
└── test
├── .eslintrc
├── index.html
├── test-allMatch.js
├── test-anyMatch.js
├── test-average.js
├── test-collect.js
├── test-constructors-compiled.js
├── test-constructors-compiled.js.map
├── test-constructors.es6
├── test-constructors.js
├── test-count.js
├── test-distinct.js
├── test-dropWhile.js
├── test-examples.js
├── test-filter.js
├── test-findFirst.js
├── test-flatMap.js
├── test-forEach.js
├── test-groupBy.js
├── test-introduction-compiled.js
├── test-introduction-compiled.js.map
├── test-introduction.es6
├── test-iterator.js
├── test-joining.js
├── test-limit.js
├── test-map.js
├── test-max.js
├── test-min.js
├── test-misc.js
├── test-nashorn.js
├── test-node.js
├── test-noneMatch.js
├── test-optional.js
├── test-partitionBy.js
├── test-peek.js
├── test-reduce.js
├── test-reverse.js
├── test-shuffle.js
├── test-skip.js
├── test-slice.js
├── test-sorted.js
├── test-sum.js
├── test-takeWhile.js
└── test-toMap.js
/.eslintignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | **/*-compiled.js
3 | **/*-nashorn.js
4 | stream-min.js
--------------------------------------------------------------------------------
/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "eslint:recommended",
3 | "env": {
4 | "browser": true,
5 | "node": true,
6 | "amd": true
7 | },
8 | "rules": {
9 | "strict": [2, "function"],
10 | "semi": [2, "always"],
11 | "curly": 2,
12 | "dot-notation": 2,
13 | "radix": 2,
14 | "wrap-iife": 2,
15 | "eqeqeq": 2,
16 | "block-scoped-var": 2,
17 | "consistent-return": 2,
18 | "no-console": 0,
19 | "no-alert": 2,
20 | "no-new-wrappers": 2,
21 | "no-native-reassign": 2,
22 | "no-extend-native": 2,
23 | "no-implicit-coercion": 2,
24 | "no-sequences": 2,
25 | "no-unused-expressions": 2,
26 | "no-useless-call": 2,
27 | "no-useless-concat": 2,
28 | "no-warning-comments": 2,
29 | "no-shadow-restricted-names": 2,
30 | "no-undef-init": 2,
31 | "no-with": 2
32 | }
33 | }
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .idea
2 | *.iml
3 | .DS_Store
4 | node_modules
5 | npm-debug.log
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | sudo: false
3 | node_js:
4 | - "0.10"
5 | before_install: npm install -g grunt-cli
6 | install: npm install
7 | script: grunt test --verbose
--------------------------------------------------------------------------------
/APIDOC.md:
--------------------------------------------------------------------------------
1 | # API Documentation
2 |
3 | Stream.js is a lightweight dependency-free utility library for ECMAScript 5 compatible JavaScript engines, such as browsers, Node.js or the Java 8 Nashorn engine. No native JavaScript types are modified in any way. Instead Stream.js exposes a single function `Stream` which serves as the constructor for creating and working with streams of in-memory data. It also serves as namespace for additional types such as `Stream.Optional`.
4 |
5 | ## Naming Conventions
6 |
7 | Stream.js is a functional programming library and follows strict naming conventions to describe different kind of function arguments. Please keep in mind that all functions passed as stream operations must be _stateless_. That means those functions should not modify the internal state of the streams underlying data structure (e.g. add or remove elements from the input array). Stateful functions may result in non-deterministic or incorrect behavior.
8 |
9 | > ##### Predicate
10 |
11 | Predicate functions accept a single element of the stream as the first argument and return a boolean.
12 |
13 | ```js
14 | var predicate = function(num) {
15 | return num % 2 === 1;
16 | }
17 | ```
18 |
19 | > ##### Mapping Function
20 |
21 | Mapping functions accept a single element of the stream as the first argument and transform this argument into something else, returning another object.
22 |
23 | ```js
24 | var mappingFn = function(num) {
25 | return {a: num};
26 | }
27 | ```
28 |
29 | > ##### Supplier
30 |
31 | Supplier functions return new objects out of nowhere. No arguments are passed.
32 |
33 | ```js
34 | var supplier = function() {
35 | return Math.random();
36 | }
37 | ```
38 |
39 | > ##### Consumer
40 |
41 | Consumer functions accept a single element of the stream as the first argument and perform some custom actions, returning nothing.
42 |
43 | ```js
44 | var consumer = function (obj) {
45 | console.log("consuming", obj);
46 | }
47 | ```
48 |
49 | > ##### Comparator
50 |
51 | Comparator functions accept two arguments and compare those arguments for order, returning 0, 1 or -1.
52 |
53 | ```js
54 | var defaultComparator = function (a, b) {
55 | if (a === b) {
56 | return 0;
57 | }
58 | return a > b ? 1 : -1;
59 | };
60 | ```
61 |
62 | > ##### Accumulator
63 |
64 | Accumulator functions accept two arguments and return an object, e.g. by merging both arguments into a single result. Normally those functions are called multiple times for all elements of the stream, passing the last accumulator result as first argument and the current element of the stream as second argument.
65 |
66 | ```js
67 | var accumulator = function(result, obj) {
68 | return result + " " + obj;
69 | }
70 | ```
71 |
72 | ## Stream
73 |
74 | ### Constructors
75 |
76 | The following constructor functions can be used to create different kind of streams.
77 |
78 | > ##### Stream(array)
79 |
80 | Returns a new stream for the given array.
81 |
82 | ```js
83 | Stream([1, 2, 3, 4, 5])
84 | .filter(function(i) {
85 | return i % 2 === 1;
86 | })
87 | .toArray(); // => 1, 3, 5
88 | ```
89 |
90 | Alias: `Stream.from`
91 |
92 | > ##### Stream(objectHash)
93 |
94 | Returns a new stream for the given object hash by streaming upon the values of each key.
95 |
96 | ```js
97 | Stream({a: 1, b: 2, c: 3, d: 4, e: 5})
98 | .filter(function(i) {
99 | return i % 2 === 1;
100 | })
101 | .toArray(); // => 1, 3, 5
102 | ```
103 |
104 | Alias: `Stream.from`
105 |
106 | > ##### Stream(set)
107 |
108 | Returns a new stream for the given set.
109 |
110 | ```js
111 | // ES6 Set
112 | var mySet = new Set([1, 2, 3, 4, 5]);
113 |
114 | Stream(mySet)
115 | .filter(function(i) {
116 | return i % 2 === 1;
117 | })
118 | .toArray(); // => 1, 3, 5
119 | ```
120 |
121 | Alias: `Stream.from`
122 |
123 | > ##### Stream(map)
124 |
125 | Returns a new stream for the given map.
126 |
127 | ```js
128 | // ES6 Map
129 | var myMap = new Map();
130 | data.set("key1", 1);
131 | data.set("key2", 2);
132 | data.set("key3", 3);
133 | data.set("key3", 4);
134 | data.set("key3", 5);
135 |
136 | Stream(myMap)
137 | .filter(function(i) {
138 | return i % 2 === 1;
139 | })
140 | .toArray(); // => 1, 3, 5
141 | ```
142 |
143 | Alias: `Stream.from`
144 |
145 | > ##### Stream(iterator)
146 |
147 | Returns a new stream for the given iterator. The iterator must conform to the [Iterator Protocol](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols#iterator).
148 |
149 | ```js
150 | // ES6 Generator
151 | function* iterator() {
152 | yield 1;
153 | yield 2;
154 | yield 3;
155 | yield 4;
156 | yield 5;
157 | yield 6;
158 | }
159 |
160 | Stream(iterator())
161 | .filter(function(i) {
162 | return i % 2 === 1;
163 | })
164 | .toArray(); // => 1, 3, 5
165 | ```
166 |
167 | Alias: `Stream.from`
168 |
169 | > ##### Stream(string)
170 |
171 | Returns a new stream for the given string. The string will be splitted by characters.
172 |
173 | ```js
174 | var stream = Stream("ABCDEFG");
175 | ```
176 |
177 | Alias: `Stream.from`
178 |
179 | > ##### Stream(string, separator)
180 |
181 | Returns a new stream for the given string. The string will be split by the `separator` string.
182 |
183 | ```js
184 | var stream = Stream("a,b,c,d", ","); // creates a stream with 4 items
185 |
186 | // creates a stream with 4 items - the trailing comma is not taken into account
187 | stream = Stream("a,b,c,d,", ",");
188 | ```
189 |
190 | Alias: `Stream.from`
191 |
192 |
193 | > ##### Stream.of(args...)
194 |
195 | Returns a new stream for the given arguments.
196 |
197 | ```js
198 | var stream = Stream.of(1, 2, 3, 4);
199 | ```
200 |
201 | > ##### Stream.empty()
202 |
203 | Returns a new empty stream.
204 |
205 | ```js
206 | var stream = Stream.empty();
207 | ```
208 |
209 | > ##### Stream.range(startInclusive, endExclusive)
210 |
211 | Returns a new stream for the given number range.
212 |
213 | ```js
214 | var stream = Stream.range(0, 10); // => 0..9
215 | ```
216 |
217 | > ##### Stream.rangeClosed(startInclusive, endInclusive)
218 |
219 | Returns a new stream for the given number range.
220 |
221 | ```js
222 | var stream = Stream.rangeClosed(0, 9); // => 0..9
223 | ```
224 |
225 | > ##### Stream.generate(supplier)
226 |
227 | Returns a new infinite stream. The elements of the stream are generated by the given supplier function.
228 |
229 | ```js
230 | // generate random numbers between 1 and 10
231 | var stream = Stream.generate(function() {
232 | return Math.floor(Math.random() * 10) + 1;
233 | });
234 | ```
235 |
236 | > ##### Stream.iterate(seed, fn)
237 |
238 | Returns a new infinite stream. The elements of the stream are generated by utilizing the given iterator function, starting with `seed` at n=0, then calling fn(seed) for n=1, fn(fn(seed)) for n=2 etc.
239 |
240 | ```js
241 | // 1, 2, 4, 8, 16, 32, ...
242 | var stream = Stream.iterate(1, function (num) {
243 | return num * 2;
244 | });
245 | ```
246 |
247 | ### Intermediate Operations
248 |
249 | Intermediate operations all return a stream, thus enabling you to chain multiple operations one after another without using semicolons.
250 |
251 | > ##### filter(predicate)
252 |
253 | Filters the elements of the stream to match the given predicate function and returns the stream.
254 |
255 | ```js
256 | Stream([1, 2, 3, 4, 5])
257 | .filter(function (num) {
258 | return num % 2 === 1; // => 1, 3, 5
259 | });
260 | ```
261 |
262 | > ##### filter(regexp)
263 |
264 | Filters the elements of the stream to match the given regular expression and returns the stream.
265 |
266 | ```js
267 | // starts with a
268 | Stream(["a1", "a2", "b1"])
269 | .filter(/a.*/); // => a1, a2
270 | ```
271 |
272 | > ##### filter(sample)
273 |
274 | Filters the elements of the stream to match the given sample object and returns the stream.
275 |
276 | ```js
277 | var data = [
278 | {a: 1, b: 1},
279 | {a: 2, b: 2},
280 | {a: 1, b: 3}
281 | ];
282 |
283 | Stream(data)
284 | .filter({a: 1});
285 |
286 | // => {a: 1, b: 1}, {a: 1, b: 3}
287 | ```
288 |
289 | > ##### filterNull()
290 |
291 | Filters (removes) the `null` values of the stream. It performs a strongly typed check, so it keeps every other
292 | [falsy](https://developer.mozilla.org/en-US/docs/Glossary/Falsy) values.
293 |
294 | ```js
295 | Stream([1, null, false, NaN, undefined, 0, ""])
296 | .filterNull()
297 | // => 1, false, NaN, undefined, 0, ""
298 |
299 | ```
300 |
301 | > ##### filterFalsy()
302 |
303 | Filters (removes) the [falsy](https://developer.mozilla.org/en-US/docs/Glossary/Falsy) values of the stream.
304 |
305 | ```js
306 | Stream([1, false, 2, null, NaN, undefined, 0, ""])
307 | .filterFalsy()
308 | // => 1, 2
309 | ```
310 |
311 |
312 | > ##### map(mappingFn)
313 |
314 | Applies the given mapping function to each element of the stream and returns the stream.
315 |
316 | ```js
317 | Stream(numbers)
318 | .map(function (num) {
319 | return {a: num};
320 | });
321 | ```
322 |
323 | > ##### map(path)
324 |
325 | Maps each element of the stream by resolving the given string `path` and returns the stream.
326 |
327 | E.g. `map('a.b.c')` is equivalent to `map(function(obj) { return obj.a.b.c; })`.
328 |
329 | ```js
330 | Stream([{foo: {bar: 'foobar'}}, ...])
331 | .map('foo.bar');
332 | ```
333 |
334 | > ##### flatMap(mappingFn)
335 |
336 | Applies the given mapping function to each element of the stream and flattens the results by replacing each element with the contents of the element in case of collections, then returns the stream.
337 |
338 | ```js
339 | Stream([{nums: [1, 2, 3], ...])
340 | .flatMap(function(obj) {
341 | return obj.nums;
342 | });
343 | ```
344 |
345 | > ##### flatMap(path)
346 |
347 | Maps each element of the stream by resolving the given string `path` and flattens the results by replacing each elemet with the contents of the element in case of collections, then returns the stream.
348 |
349 | E.g. `flatMap('a.b.c')` is equivalent to `flatMap(function(obj) { return obj.a.b.c; })`.
350 |
351 | ```js
352 | Stream([{foo: {bar: [1, 2, 3]}}, ...])
353 | .map('foo.bar');
354 | ```
355 |
356 | > ##### sorted()
357 |
358 | Sorts the elements of the stream according to the natural order and returns the stream.
359 |
360 | Alias: `sort`
361 |
362 | ```js
363 | Stream([7, 3, 3, 1])
364 | .sorted(); // => 1, 3, 3, 7
365 | ```
366 |
367 | > ##### sorted(comparator)
368 |
369 | Sorts the elements of the stream according to the given comparator and returns the stream.
370 |
371 | Alias: `sort`
372 |
373 | ```js
374 | Stream([{foo: 'bar'}, ...])
375 | .sorted(function(a, b) {
376 | if (a.foo === b.foo) return 0;
377 | if (a.foo < b.foo) return -1;
378 | return 1;
379 | });
380 | ```
381 |
382 | > ##### sorted(path)
383 |
384 | Sorts the elements of the stream according to the given string path and returns the stream.
385 |
386 | Alias: `sort`
387 |
388 | ```js
389 | var data = [{a: 4}, {a: 1}, {a: 3}, {a: 2}];
390 | Stream(data)
391 | .sorted("a");
392 | // => {a: 1}, {a: 2}, {a: 3}, {a: 4}
393 | ```
394 |
395 | > ##### shuffle()
396 |
397 | Randomly reorder all elements of the stream.
398 |
399 | ```js
400 | Stream([1, 2, 3, 4])
401 | .shuffle(); // => 4, 1, 3, 2
402 | ```
403 |
404 | > ##### reverse()
405 |
406 | Reverse the order of each elements of the stream.
407 |
408 | ```js
409 | Stream([1, 2, 3, 4])
410 | .reverse(); // => 4, 3, 2, 1
411 | ```
412 |
413 | > ##### distinct()
414 |
415 | Returns the stream consisting of the distinct elements of this stream.
416 |
417 | ```js
418 | Stream([1, 1, 2, 3, 3, 4])
419 | .distinct(); // => 1, 2, 3, 4
420 | ```
421 |
422 | > ##### limit(maxSize)
423 |
424 | Truncates the elements of the stream to be no longer than `maxSize` and returns the stream.
425 |
426 | ```js
427 | Stream([1, 2, 3, 4])
428 | .limit(2); // => 1, 2
429 | ```
430 |
431 | > ##### skip(n)
432 |
433 | Discards the first `n` elements and returns the stream.
434 |
435 | ```js
436 | Stream([1, 2, 3, 4])
437 | .skip(2); // => 3, 4
438 | ```
439 |
440 | > ##### slice(begin, end)
441 |
442 | Discards all elements except those between the zero-based indices `begin` (included) and `end` (excluded).
443 |
444 | ```js
445 | Stream([1, 2, 3, 4])
446 | .slice(1, 3); // => 2, 3
447 | ```
448 |
449 | > ##### peek(consumer)
450 |
451 | Performs the consumer function for each element and returns the stream.
452 |
453 | ```js
454 | Stream([1, 2, 3, 4])
455 | .peek(function (num) {
456 | console.log(num);
457 | });
458 | ```
459 |
460 | > ##### takeWhile(predicate)
461 |
462 | Takes all elements of the stream as long as `predicate` is true. All elements are rejected from the moment `predicate` is false for the first time.
463 |
464 | ```js
465 | Stream([1, 2, 3, 2, 1])
466 | .takeWhile(function (num) {
467 | return num < 3;
468 | })
469 | .toArray(); // => 1, 2
470 | ```
471 |
472 | > ##### takeWhile(regexp)
473 |
474 | Takes all elements of the stream as long as `regexp` matches. All elements are rejected from the moment `regexp` doesn't match for the first time.
475 |
476 | ```js
477 | Stream(["a1", "a2", "b3", "a4"])
478 | .takeWhile(/a.*/)
479 | .toArray(); // => a1, a2
480 | ```
481 |
482 | > ##### takeWhile(sample)
483 |
484 | Takes all elements of the stream as long as `sample` matches. All elements are rejected from the moment `sample` doesn't match for the first time.
485 |
486 | ```js
487 | var data = [
488 | {a: 1, b: 1},
489 | {a: 1, b: 2},
490 | {a: 2, b: 3},
491 | {a: 1, b: 4}
492 | ];
493 |
494 | Stream(data)
495 | .takeWhile({a: 1})
496 | .toArray(); // => {a: 1, b: 1}, {a: 1, b: 2}
497 | ```
498 |
499 | > ##### dropWhile(predicate)
500 |
501 | Rejects all elements of the stream as long as `predicate` is true. All elements are accepted from the moment `predicate` is false for the first time.
502 |
503 | ```js
504 | Stream([1, 2, 3, 2, 1])
505 | .dropWhile(function (num) {
506 | return num < 3;
507 | })
508 | .toArray(); // => 3, 2, 1
509 | ```
510 |
511 | > ##### dropWhile(regexp)
512 |
513 | Rejects all elements of the stream as long as `regexp` matches. All elements are accepted from the moment `regexp` doesn't match for the first time.
514 |
515 | ```js
516 | Stream(["a1", "a2", "b3", "a4"])
517 | .dropWhile(/a.*/)
518 | .toArray(); // => b3, a4
519 | ```
520 |
521 | > ##### dropWhile(sample)
522 |
523 | Rejects all elements of the stream as long as `sample` matches. All elements are accepted from the moment `sample` doesn't match for the first time.
524 |
525 | ```js
526 | var data = [
527 | {a: 1, b: 1},
528 | {a: 1, b: 2},
529 | {a: 2, b: 3},
530 | {a: 1, b: 4}
531 | ];
532 |
533 | Stream(data)
534 | .dropWhile({a: 1})
535 | .toArray(); // => {a: 2, b: 3}, {a: 1, b: 4}
536 | ```
537 |
538 | ### Terminal Operations
539 |
540 | Terminal operations return a result (or nothing), so each streaming pipeline consists of 0 to n intermediate operations followed by exactly one terminal operation.
541 |
542 | > ##### toArray()
543 |
544 | Returns an array containing the elements of the stream.
545 |
546 | Alias: `toList`
547 |
548 | ```js
549 | var result = Stream([1, 2, 3, 4, 5])
550 | .filter(function (num) {
551 | return num % 2 === 1;
552 | })
553 | .toArray(); // => [1, 3, 5]
554 | ```
555 |
556 | > ##### forEach(consumer)
557 |
558 | Performs the consumer function for each element of the stream.
559 |
560 | Alias: `each`
561 |
562 | ```js
563 | Stream([1, 2, 3, 4])
564 | .forEach(function (num) {
565 | console.log(num);
566 | });
567 | ```
568 |
569 | > ##### findFirst()
570 |
571 | Returns an `Optional` wrapping the first element of the stream or `Optional.empty()` if the stream is empty.
572 |
573 | Alias: `findAny`
574 |
575 | ```js
576 | Stream([1, 2, 3, 4])
577 | .findFirst()
578 | .ifPresent(function (first) {
579 | console.log(first); // => 1
580 | });
581 | ```
582 |
583 | > ##### min()
584 |
585 | Returns an `Optional` wrapping the minimum element of the stream (according the natural order) or `Optional.empty()` if the stream is empty.
586 |
587 | ```js
588 | Stream([4, 1, 3, 2])
589 | .min()
590 | .ifPresent(function (min) {
591 | console.log(min); // => 1
592 | });
593 | ```
594 |
595 | > ##### min(comparator)
596 |
597 | Returns an `Optional` wrapping the minimum element of the stream (according the given comparator function) or `Optional.empty()` if the stream is empty.
598 |
599 | ```js
600 | Stream([{a: 3}, {a: 1}, {a: 2}])
601 | .min(function (obj1, obj2) {
602 | if (obj1.a === obj2.a) return 0;
603 | return obj1.a > obj2.a ? 1 : -1;
604 | })
605 | .ifPresent(function (min) {
606 | console.log(min); // => {a: 1}
607 | });
608 | ```
609 |
610 | > ##### min(path)
611 |
612 | Returns an `Optional` wrapping the minimum element of the stream (according the given string path) or `Optional.empty()` if the stream is empty.
613 |
614 | ```js
615 | Stream([{a: 3}, {a: 1}, {a: 2}])
616 | .min("a")
617 | .ifPresent(function (min) {
618 | console.log(min); // => {a: 1}
619 | });
620 | ```
621 |
622 | > ##### max()
623 |
624 | Returns an `Optional` wrapping the maximum element of the stream (according the natural order) or `Optional.empty()` if the stream is empty.
625 |
626 | ```js
627 | Stream([4, 1, 3, 2])
628 | .max()
629 | .ifPresent(function (min) {
630 | console.log(min); // => 1
631 | });
632 | ```
633 |
634 | > ##### max(comparator)
635 |
636 | Returns an `Optional` wrapping the maximum element of the stream (according the given comparator function) or `Optional.empty()` if the stream is empty.
637 |
638 | ```js
639 | Stream([{a: 3}, {a: 1}, {a: 2}])
640 | .max(function (obj1, obj2) {
641 | if (obj1.a === obj2.a) return 0;
642 | return obj1.a > obj2.a ? 1 : -1;
643 | })
644 | .ifPresent(function (min) {
645 | console.log(min); // => {a: 3}
646 | });
647 | ```
648 |
649 | > ##### max(path)
650 |
651 | Returns an `Optional` wrapping the maximum element of the stream (according the given string path) or `Optional.empty()` if the stream is empty.
652 |
653 | ```js
654 | Stream([{a: 3}, {a: 1}, {a: 2}])
655 | .min("a")
656 | .ifPresent(function (min) {
657 | console.log(min); // => {a: 3}
658 | });
659 | ```
660 |
661 | > ##### sum()
662 |
663 | Returns the sum of all elements in this stream.
664 |
665 | ```js
666 | Stream([1, 2, 3, 4])
667 | .sum(); // => 10
668 | ```
669 |
670 | > ##### sum(path)
671 |
672 | Returns the sum of all elements for the given path in this stream.
673 |
674 | ```js
675 | Stream([{a: 1}, {a: 2}, {a: 3}])
676 | .sum("a"); // => 6
677 | ```
678 |
679 | > ##### average()
680 |
681 | Returns an `Optional` wrapping the arithmetic mean of all elements of this stream or `Optional.empty()` if the stream is empty.
682 |
683 | Alias: `avg`
684 |
685 | ```js
686 | Stream([1, 2, 3, 4])
687 | .average()
688 | .ifPresent(function (avg) {
689 | console.log(avg); // => 2.5
690 | });
691 | ```
692 |
693 | > ##### average(path)
694 |
695 | Returns an `Optional` wrapping the arithmetic mean of all elements of this stream or `Optional.empty()` if the stream is empty, by resolving the given path for each element.
696 |
697 | Alias: `avg`
698 |
699 | ```js
700 | Stream([{a: 1}, {a: 2}, {a: 3}, {a: 4}])
701 | .average("a")
702 | .ifPresent(function (avg) {
703 | console.log(avg); // => 2.5
704 | });
705 | ```
706 |
707 | > ##### count()
708 |
709 | Returns the number of elements of the stream.
710 |
711 | Alias: `size`
712 |
713 | ```js
714 | Stream([1, 2, 3, 4])
715 | .count(); // => 4
716 | ```
717 |
718 | > ##### allMatch(predicate)
719 |
720 | Returns whether all elements of the stream match the given predicate function.
721 |
722 | ```js
723 | Stream([1, 2, 3, 4])
724 | .allMatch(function (num) {
725 | return num > 1; // => false
726 | });
727 | ```
728 |
729 | > ##### allMatch(sample)
730 |
731 | Returns whether all elements of the stream match the given sample object.
732 |
733 | ```js
734 | Stream([{a: 1}, {a: 2}])
735 | .allMatch({a: 1}); // => false
736 | ```
737 |
738 | > ##### allMatch(regexp)
739 |
740 | Returns whether all elements of the stream match the given regexp pattern.
741 |
742 | ```js
743 | Stream(["a1", "a2", "b3"])
744 | .allMatch(/a.*/); // => false
745 | ```
746 |
747 | > ##### anyMatch(predicate)
748 |
749 | Returns whether any element of the stream matches the given predicate function.
750 |
751 | ```js
752 | Stream([1, 2, 3, 4])
753 | .anyMatch(function (num) {
754 | return num > 1; // => true
755 | });
756 | ```
757 |
758 | > ##### anyMatch(sample)
759 |
760 | Returns whether any element of the stream match the given sample object.
761 |
762 | ```js
763 | Stream([{a: 1}, {a: 2}])
764 | .anyMatch({a: 1}); // => true
765 | ```
766 |
767 | > ##### anyMatch(regexp)
768 |
769 | Returns whether any element of the stream matches the given regexp pattern.
770 |
771 | ```js
772 | Stream(["a1", "a2", "b3"])
773 | .anyMatch(/a.*/); // => true
774 | ```
775 |
776 | > ##### noneMatch(predicate)
777 |
778 | Returns whether no element of the stream matches the given predicate function.
779 |
780 | ```js
781 | Stream([1, 2, 3, 4])
782 | .noneMatch(function (num) {
783 | return num > 1; // => false
784 | });
785 | ```
786 |
787 | > ##### allMatch(sample)
788 |
789 | Returns whether no element of the stream match the given sample object.
790 |
791 | ```js
792 | Stream([{a: 1}, {a: 2}])
793 | .noneMatch({a: 1}); // => false
794 | ```
795 |
796 | > ##### noneMatch(regexp)
797 |
798 | Returns whether no element of the stream matches the given regexp pattern.
799 |
800 | ```js
801 | Stream(["a1", "a2", "a3"])
802 | .noneMatch(/b.*/); // => true
803 | ```
804 |
805 | > ##### reduce(identity, accumulator)
806 |
807 | Performs a reduction operation using the provided `identity` object as initial value and the accumulator function and returns the reduced value.
808 |
809 | ```js
810 | Stream([1, 2, 3, 4])
811 | .reduce(1000, function (result, num) {
812 | return result + num; // => 1010
813 | });
814 | ```
815 |
816 | > ##### reduce(accumulator)
817 |
818 | Performs a reduction operation using the first element of the stream as as initial value and the accumulator function and returns the reduced value wrapped as `Optional`.
819 |
820 | ```js
821 | Stream([1, 2, 3, 4])
822 | .reduce(function (result, num) {
823 | return result + num;
824 | })
825 | .ifPresent(function (result) {
826 | console.log(result); // => 10
827 | });
828 | ```
829 |
830 | > ##### collect(collector)
831 |
832 | Performs a generalized reduction operation denoted by the given collector and returns the reduced value. A collector consists of a supplier function, an accumulator function and an optional finisher function.
833 |
834 | ```js
835 | Stream([1, 2, 3, 4])
836 | .collect({
837 | supplier: function () {
838 | return "Data: ";
839 | },
840 | accumulator: function (val, num) {
841 | return val + num + " ";
842 | },
843 | finisher: function (val) {
844 | return val + "!";
845 | }
846 | });
847 | // => Data: 1 2 3 4 !
848 | ```
849 |
850 | > ##### groupingBy(keyMapper)
851 |
852 | Groups all elements of the stream by applying the given keyMapper function and returns an object map, assigning an array value for each key.
853 |
854 | Alias: `groupBy`
855 |
856 | ```js
857 | Stream([{a: "foo", b: 1}, {a: "bar", b: 2}, {a: "bar", b: 3}])
858 | .groupBy(function (obj) {
859 | return obj.a;
860 | });
861 |
862 | // => { foo: [{a: "foo", b: 1}], bar: [{a: "bar", b: 2}, {a: "bar", b: 3}] }
863 | ```
864 |
865 | > ##### groupingBy(path)
866 |
867 | Groups all elements of the stream by resolving the given string `path` for each element of the stream and returns an object map, assigning an array value for each key.
868 |
869 | ```js
870 | Stream([{a: "foo", b: 1}, {a: "bar", b: 2}, {a: "bar", b: 3}])
871 | .groupBy('a');
872 |
873 | // => { foo: [{a: "foo", b: 1}], bar: [{a: "bar", b: 2}, {a: "bar", b: 3}] }
874 | ```
875 |
876 | Alias: `groupBy`
877 |
878 | > ##### toMap(keyMapper, mergeFunction)
879 |
880 | Groups all elements of the stream by applying the given keyMapper function and returns an object map, assigning a single value for each key. Multiple values for the same key will be merged using the given merge function. The second argument `mergeFunction` is not required. If no merge function is present and multiple values are found for the same key, an error is thrown.
881 |
882 | Alias: `indexBy`
883 |
884 | ```js
885 | Stream([{a: "foo", b: 1}, {a: "bar", b: 2}])
886 | .toMap(function (obj) {
887 | return obj.a;
888 | });
889 |
890 | // => { foo: {a: "foo", b: 1}, bar: {a: "bar", b: 2} }
891 | ```
892 |
893 | > ##### toMap(path, mergeFunction)
894 |
895 | Groups all elements of the stream by resolving the given `path` for each element of the stream and returns an object map, assigning a single value for each key. Multiple values for the same key will be merged using the given merge function. The second argument `mergeFunction` is not required. If no merge function is present and multiple values are found for the same key, an error is thrown.
896 |
897 | Alias: `indexBy`
898 |
899 | ```js
900 | Stream([{a: "foo", b: 1}, {a: "bar", b: 2}])
901 | .toMap("a");
902 |
903 | // => { foo: {a: "foo", b: 1}, bar: {a: "bar", b: 2} }
904 | ```
905 |
906 | > ##### partitioningBy(predicate)
907 |
908 | Groups all elements of the stream by the results of applying the given predicate to each element of the stream, returning an object with two keys `true` and `false`.
909 |
910 | Alias: `partitionBy`
911 |
912 | ```js
913 | Stream([1, 2, 3, 4])
914 | .partitionBy(function (num) {
915 | return num % 2 === 0;
916 | });
917 |
918 | // => {"true": [2, 4], "false": [1, 3]}
919 | ```
920 |
921 | > ##### partitioningBy(sample)
922 |
923 | Groups all elements of the stream by the results of matching the given sample object to each element of the stream, returning an object with two keys `true` and `false`.
924 |
925 | Alias: `partitionBy`
926 |
927 | ```js
928 | var data = [
929 | {a: 1, b: 1},
930 | {a: 2, b: 1},
931 | {a: 3, b: 5}
932 | ];
933 | Stream(data)
934 | .partitionBy({b: 1});
935 | // => {"true": [{a: 1, b: 1}, {a: 2, b: 1}], "false": [{a: 3, b: 5}]}
936 | ```
937 |
938 | > ##### partitioningBy(regexp)
939 |
940 | Groups all elements of the stream by the results of testing the given regexp pattern to each element of the stream, returning an object with two keys `true` and `false`.
941 |
942 | Alias: `partitionBy`
943 |
944 | ```js
945 | Stream(["a1", "a2", "b1"])
946 | .partitionBy(/a.*/);
947 |
948 | // => {"true": ["a1", "a2"], "false": ["b1"]}
949 | ```
950 |
951 | > ##### partitioningBy(size)
952 |
953 | Groups all elements of the stream by chunks of the given size, returning an array of arrays.
954 |
955 | Alias: `partitionBy`
956 |
957 | ```js
958 | Stream([1, 2, 3, 4])
959 | .partitionBy(2);
960 |
961 | // => [[1, 2,], [3, 4]]
962 | ```
963 |
964 | > ##### joining()
965 |
966 | Joins all elements of the stream into a string.
967 |
968 | Alias: `join`
969 |
970 | ```js
971 | Stream([1, 2, 3, 4])
972 | .joining(); // => "1234"
973 | ```
974 |
975 | > ##### joining(delimiter)
976 |
977 | Joins all elements of the stream into a string, using the given delimiter.
978 |
979 | Alias: `join`
980 |
981 | ```js
982 | Stream([1, 2, 3, 4])
983 | .joining("-"); // => "1-2-3-4"
984 | ```
985 |
986 | > ##### joining(options)
987 |
988 | Joins all elements of the stream into a string, using the following non-required options: `options.delimiter`, `options.prefix`, `options.suffix`.
989 |
990 | Alias: `join`
991 |
992 | ```js
993 | Stream([1, 2, 3, 4])
994 | .joining({
995 | prefix: "PREFIX_",
996 | suffix: "_SUFFIX",
997 | delimiter: ","
998 | });
999 | // => "PREFIX_1,2,3,4_SUFFIX"
1000 | ```
1001 |
1002 | > ##### iterator()
1003 |
1004 | Returns a `StreamIterator` to traverse upon the elements described by this stream. `StreamIterator` defines a single method `next`, returning an object holding the next `value` and a boolean flag `done` indicating if the iterator has been finished.
1005 |
1006 | ```js
1007 | var iterator = stream.iterator(), result;
1008 | while (true) {
1009 | result = iterator.next();
1010 | console.log(result.value);
1011 | if (result.done) {
1012 | break;
1013 | }
1014 | }
1015 | ```
1016 |
1017 | ## Stream.Optional
1018 |
1019 | Wraps a single value which may be `null` or `undefined`.
1020 |
1021 | ### Constructors
1022 |
1023 | > ##### Optional.of(value)
1024 |
1025 | Creates a new optional wrapper for the given non-null and non-undefined value.
1026 |
1027 | ```js
1028 | Stream.Optional.of(1);
1029 | ```
1030 |
1031 | > ##### Optional.ofNullable(value)
1032 |
1033 | Creates a new optional wrapper for the given value. The value may be null or undefined.
1034 |
1035 | ```js
1036 | Stream.Optional.ofNullable(null);
1037 | ```
1038 |
1039 | > ##### Optional.empty()
1040 |
1041 | Creates a new empty optional wrapper (same as `Optional.ofNullable(null)`).
1042 |
1043 | ```js
1044 | Stream.Optional.empty();
1045 | ```
1046 |
1047 | ### Intermediate Operations
1048 |
1049 | > ##### filter(predicate)
1050 |
1051 | If a value is present and value matches the given predicate function, returns this optional, otherwise return an empty optional.
1052 |
1053 | ```js
1054 | var optional = Stream.Optional.of({a: 23})
1055 | .filter(function (obj) {
1056 | return obj.a % 2 === 0;
1057 | });
1058 | optional.isPresent(); // => false
1059 | ```
1060 |
1061 | > ##### map(mappingFn)
1062 |
1063 | If a value is present apply the given mapping function and wrap the resulting value with an optional.
1064 |
1065 | ```js
1066 | var optional = Stream.Optional.of({a: 23})
1067 | .map(function (obj) {
1068 | return obj.a;
1069 | });
1070 | optional.get(); // => 23
1071 | ```
1072 |
1073 | > ##### flatMap(mappingFn)
1074 |
1075 | If a value is present apply the given optional-returning mapping function, and return the optional result or empty.
1076 |
1077 | ```js
1078 | var optional = Stream.Optional.of({a: 23})
1079 | .flatMap(function (obj) {
1080 | return Stream.Optional.of(obj.a);
1081 | });
1082 | optional.get(); // => 23
1083 | ```
1084 |
1085 | ### Terminal Operations
1086 |
1087 | > ##### isPresent()
1088 |
1089 | Check if a value is present.
1090 |
1091 | ```js
1092 | var optional = Stream.Optional.of(23);
1093 | optional.isPresent(); // => true
1094 | ```
1095 |
1096 | > ##### get()
1097 |
1098 | Returns the value if a value is present, otherwise throws an error.
1099 |
1100 | ```js
1101 | var optional = Stream.Optional.of(23);
1102 | optional.get(); // => 23
1103 | ```
1104 |
1105 | > ##### ifPresent(consumer)
1106 |
1107 | Invoke the given consumer function for the specified value if present.
1108 |
1109 | ```js
1110 | Stream.Optional.of(23)
1111 | .ifPresent(function (num) {
1112 | console.log(num); // => 23
1113 | });
1114 | ```
1115 |
1116 | > ##### orElse(other)
1117 |
1118 | Returns the value if present, otherwise return the given `other` value.
1119 |
1120 | ```js
1121 | var optional = Stream.Optional.empty();
1122 | optional.orElse(3); // => 3
1123 | ```
1124 |
1125 | > ##### orElseGet(supplier)
1126 |
1127 | Returns the value if present, otherwise return the result of invoking the supplier function.
1128 |
1129 | ```js
1130 | var optional = Stream.Optional.empty();
1131 | optional.orElseGet(function () {
1132 | return 1337;
1133 | });
1134 | ```
1135 |
1136 | > ##### orElseThrow(error)
1137 |
1138 | Returns the value if present, otherwise throw the given error.
1139 |
1140 | ```js
1141 | var optional = Stream.Optional.empty();
1142 | optional.orElseThrow("something went wrong");
1143 | ```
1144 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | ## How to contribute to Stream.js
2 |
3 | * Please [search](https://github.com/winterbe/streamjs/issues) for previous discussions about the same feature or issue before opening new tickets.
4 |
5 | * Before sending a pull request for a feature, make sure a corresponding [issue](https://github.com/winterbe/streamjs/issues) exists, so discussions can take place beforehand.
6 |
7 | * All code changes must be covered by [qunit tests](https://github.com/winterbe/streamjs/tree/master/test). Run `grunt test` before sending a pull request.
8 |
9 | * Use the same coding style as the rest of the [codebase](https://github.com/winterbe/streamjs/blob/master/streamjs.js).
10 |
11 | * New features must be well documented in the [APIDOC](https://github.com/winterbe/streamjs/blob/master/APIDOC.md). Do not put the minified `stream-min.js` in your pull request.
--------------------------------------------------------------------------------
/Gruntfile.js:
--------------------------------------------------------------------------------
1 | module.exports = function (grunt) {
2 | "use strict";
3 |
4 | require('load-grunt-tasks')(grunt);
5 |
6 | grunt.initConfig({
7 | pkg: grunt.file.readJSON('package.json'),
8 | uglify: {
9 | options: {
10 | banner: '/*! Stream.js v<%= pkg.version %> (<%= grunt.template.today("yyyy-mm-dd") %>) */',
11 | sourceMap: true,
12 | sourceMapName: 'stream-min.map'
13 | },
14 | dist: {
15 | files: {
16 | 'stream-min.js': ['stream.js']
17 | }
18 | }
19 | },
20 | qunit: {
21 | files: ['test/index.html']
22 | },
23 | eslint: {
24 | target: ['stream.js', 'test']
25 | }
26 | });
27 |
28 | grunt.registerTask('test', ['eslint', 'qunit']);
29 | grunt.registerTask('default', ['eslint', 'qunit', 'uglify']);
30 | };
31 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2014-2016 Benjamin Winterberg
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Stream.js [](https://travis-ci.org/winterbe/streamjs)
2 | ========================
3 |
4 | **ATTENTION: Stream.js is no longer maintained in favor of it's successor library [Sequency](https://github.com/winterbe/sequency). If you already use Stream.js in your project I recommend switching to [Sequency](https://github.com/winterbe/sequency). But don't worry, Stream.js still works fine so no hurry. 😉**
5 |
6 | > Lazy Object Streaming Pipeline for JavaScript - inspired by the [Java 8 Streams API](http://winterbe.com/posts/2014/07/31/java8-stream-tutorial-examples/)
7 |
8 | ```js
9 | Stream(people)
10 | .filter({age: 23})
11 | .flatMap("children")
12 | .map("firstName")
13 | .distinct()
14 | .filter(/a.*/i)
15 | .join(", ");
16 | ```
17 |
18 |
19 | Follow on Twitter for Updates
20 |
21 |
22 | # Getting started
23 |
24 | Stream.js is a lightweight (**2.6 KB minified, gzipped**), intensely tested (**700+ assertions, 97% coverage**) functional programming library for operating upon collections of in-memory data. It requires EcmaScript 5+, has built-in support for [ES6 features](https://github.com/lukehoban/es6features) and works in all current browsers, [Node.js](http://nodejs.org/) and Java 8 [Nashorn](http://openjdk.java.net/projects/nashorn/).
25 |
26 | Download the [latest release](https://github.com/winterbe/streamjs/releases) from GitHub or install Stream.js via [NPM](https://www.npmjs.com/package/streamjs) or [Bower](http://bower.io/):
27 |
28 | ```bash
29 | npm install streamjs
30 |
31 | # or
32 |
33 | bower install streamjs
34 | ```
35 |
36 |
37 | Read the APIDOC
38 |
39 |
40 | # Examples
41 |
42 | Before explaining how Stream.js works in detail, here's a few real world code samples.
43 |
44 | Filter and sort a collection of persons, then group everything by age.
45 |
46 | ```js
47 | Stream(people)
48 | .filter({married: true, gender: 'male'})
49 | .sorted("lastName")
50 | .groupBy("age");
51 | ```
52 |
53 | Filter and transform a collection of tweets to its text content, then limit the tweets to a maximum of 100 and partition the results into 10 tweets per page:
54 |
55 | ```js
56 | Stream(tweets)
57 | .filter(function (tweet) {
58 | return tweet.author !== me;
59 | })
60 | .map("text")
61 | .filter(/.*streamjs.*/i)
62 | .limit(100)
63 | .partitionBy(10);
64 | ```
65 |
66 | Create an array of 100 odd random numbers between 1 and 1000:
67 |
68 | ```js
69 | Stream
70 | .generate(function() {
71 | return Math.floor(Math.random() * 1000) + 1;
72 | })
73 | .filter(function (num) {
74 | return num % 2 === 1;
75 | })
76 | .limit(100)
77 | .toArray();
78 | ```
79 |
80 | Create an infinite iterator, generating an odd random number between 1 and 1000 on each call to `next()`:
81 |
82 | ```js
83 | var iterator = Stream
84 | .generate(function() {
85 | return Math.floor(Math.random() * 1000) + 1;
86 | })
87 | .filter(function (num) {
88 | return num % 2 === 1;
89 | })
90 | .iterator();
91 |
92 | iterator.next();
93 | iterator.next();
94 | ```
95 |
96 | Create an array of 100 parent objects, each holding an array of 10 children:
97 |
98 | ```js
99 | Stream
100 | .range(0, 100)
101 | .map(function (num) {
102 | return {
103 | parentId: num,
104 | type: 'parent',
105 | children: []
106 | };
107 | })
108 | .peek(function (parent) {
109 | parent.children = Stream
110 | .range(0, 10)
111 | .map(function (num) {
112 | return {
113 | childId: num,
114 | type: 'child',
115 | parent: parent
116 | };
117 | })
118 | .toArray();
119 | })
120 | .toArray();
121 | ```
122 |
123 | # How Streams work
124 |
125 | Stream.js defines a single function `Stream` to create new streams from different input collections like _arrays_, _maps_ or _number ranges_:
126 |
127 | ```js
128 | Stream([1, 2, 3]);
129 | Stream({a: 1, b: 2, c: 3});
130 | Stream.of(1, 2, 3);
131 | Stream.range(1, 4);
132 | ```
133 |
134 | Streams are monadic types with a bunch of useful operations. Those functions can be chained one after another to make complex computations upon the input elements. Operations are either *intermediate* or *terminal*. Intermediate operations are lazy and return the stream itself to enable method chaining. Terminal operations return a single result (or nothing at all). Some terminal operations return a special monadic `Optional` type which is described later.
135 |
136 | Streams are not limited to finite data sources like collections. You can also create *infinite* streams of elements by utilizing generator or iterator functions.
137 |
138 | ```js
139 | Stream.generate(function() {
140 | return 1337 * Math.random();
141 | );
142 | ```
143 |
144 | ```js
145 | Stream.iterate(1, function (seed) {
146 | return seed * 2;
147 | });
148 | ```
149 |
150 | # Why Stream.js?
151 |
152 | What's so different between Stream.js and other functional libraries like Underscore.js?
153 |
154 | Stream.js is built around a lazily evaluated operation pipeline. Instead of consecutively performing each operation on the whole input collection, objects are passed vertically and one by one upon the chain. Interim results will _not_ be stored in internal collections (except for some stateful operations like `sorted`). Instead objects are directly piped into the resulting object as specified by the terminal operation. This results in **minimized memory consumption** and internal state.
155 |
156 | Stream operations are lazily evaluated to avoid examining all of the input data when it's not necessary. Streams always perform the minimal amount of operations to gain results. E.g. in a `filter - map - findFirst` stream you don't have to filter and map the whole data. Instead `map` and `findFirst` are executed just one time before returning the single result. This results in **increased performance** when operation upon large amounts of input elements.
157 |
158 | ```js
159 | Stream([1, 2, 3, 4])
160 | .filter(function(num) { // called twice
161 | return num % 2 === 0;
162 | })
163 | .map(function(even) { // called once
164 | return "even" + even;
165 | })
166 | .findFirst(); // called once
167 | ```
168 |
169 | # [API Documentation](https://github.com/winterbe/streamjs/blob/master/APIDOC.md)
170 |
171 | The Stream.js API is described in detail [here](https://github.com/winterbe/streamjs/blob/master/APIDOC.md). For more information about Java 8 Streams I recommend reading the official [Javadoc](http://docs.oracle.com/javase/8/docs/api/java/util/stream/package-summary.html) and this [blog post](http://winterbe.com/posts/2014/07/31/java8-stream-tutorial-examples/).
172 |
173 | A type definition for using Stream.js with **Typescript** is available [here](https://github.com/borisyankov/DefinitelyTyped/tree/master/streamjs).
174 |
175 | # Contributing
176 |
177 | Found a bug or missing feature? Please open an [issue](https://github.com/winterbe/streamjs/issues)! Your feedback and help is highly appreciated. Please refer to the [contributing rules](https://github.com/winterbe/streamjs/blob/master/CONTRIBUTING.md) before sending a pull request. I would also love to hear your feedback via [Twitter](https://twitter.com/benontherun).
178 |
179 | # Copyright and license
180 |
181 | Created and copyright (c) 2014-2016 by Benjamin Winterberg.
182 |
183 | Stream.js may be freely distributed under the [MIT license](https://github.com/winterbe/streamjs/blob/master/LICENSE).
184 |
--------------------------------------------------------------------------------
/bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "streamjs",
3 | "version": "1.6.4",
4 | "homepage": "https://github.com/winterbe/streamjs",
5 | "authors": ["Benjamin Winterberg"],
6 | "description": "Lazy Object Streaming Pipeline for JavaScript - inspired by the Java 8 Streams API",
7 | "main": "stream.js",
8 | "moduleType": [
9 | "amd",
10 | "globals"
11 | ],
12 | "keywords": [
13 | "functional",
14 | "collection",
15 | "pipeline",
16 | "stream",
17 | "lazy",
18 | "utils",
19 | "java",
20 | "array"
21 | ],
22 | "license": "MIT",
23 | "ignore": [
24 | "node_modules",
25 | "bower_components",
26 | "test",
27 | "perf",
28 | "*.yml",
29 | ".jshintrc"
30 | ]
31 | }
32 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "streamjs",
3 | "version": "1.6.4",
4 | "description": "Lazy Object Streaming Pipeline for JavaScript - inspired by the Java 8 Streams API",
5 | "homepage": "https://github.com/winterbe/streamjs",
6 | "author": {
7 | "name": "Benjamin Winterberg",
8 | "url": "http://winterbe.com"
9 | },
10 | "keywords": [
11 | "functional",
12 | "collection",
13 | "pipeline",
14 | "stream",
15 | "lazy",
16 | "utils",
17 | "java",
18 | "array"
19 | ],
20 | "repository": {
21 | "type": "git",
22 | "url": "git://github.com/winterbe/streamjs.git"
23 | },
24 | "bugs": {
25 | "url": "https://github.com/winterbe/streamjs/issues"
26 | },
27 | "devDependencies": {
28 | "babel-core": "6.2.1",
29 | "babel-polyfill": "6.2.0",
30 | "blanket": "1.1.7",
31 | "eslint": "1.10.2",
32 | "grunt": "0.4.5",
33 | "grunt-contrib-jshint": "0.11.3",
34 | "grunt-contrib-qunit": "0.7.0",
35 | "grunt-contrib-uglify": "0.11.0",
36 | "grunt-eslint": "17.1.0",
37 | "load-grunt-tasks": "3.2.0"
38 | },
39 | "license": "MIT",
40 | "engines": {
41 | "node": ">=0.10"
42 | },
43 | "main": "stream.js",
44 | "files": [
45 | "stream.js",
46 | "stream-min.js",
47 | "LICENSE"
48 | ]
49 | }
50 |
--------------------------------------------------------------------------------
/perf/perf.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Performance Test
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/perf/perf.js:
--------------------------------------------------------------------------------
1 | /* global Stream, _ */
2 |
3 | (function () {
4 | "use strict";
5 |
6 | var buffer = [];
7 |
8 | var measure = function (name, input, fn) {
9 | var i,
10 | t0,
11 | time,
12 | repeat = 5,
13 | runs = [],
14 | min = null,
15 | max = null,
16 | sum = 0;
17 |
18 | for (i = 0; i < repeat; i++) {
19 | t0 = Date.now();
20 | var val = fn.call({}, input);
21 | buffer.push(val);
22 | time = Date.now() - t0;
23 | runs.push({
24 | name: name,
25 | time: time
26 | });
27 | }
28 |
29 | for (i = 0; i < runs.length; i++) {
30 | var run = runs[i];
31 | sum += run.time;
32 | if (min === null || min > run.time) {
33 | min = run.time;
34 | }
35 | if (max === null || max < run.time) {
36 | max = run.time;
37 | }
38 | }
39 |
40 | return {
41 | name: name,
42 | min: min,
43 | max: max,
44 | avg: sum / repeat
45 | };
46 | };
47 |
48 | var createInput = function (size) {
49 | return Stream.range(0, size)
50 | .map(function () {
51 | return Math.floor(Math.random() * size) + 1;
52 | })
53 | .toArray();
54 | };
55 |
56 |
57 | var input = createInput(100000);
58 | console.log("input.length: %o", input.length);
59 |
60 | var result;
61 |
62 | result = measure("Stream.js [filter - map - toArray]", input, function () {
63 | return Stream(input)
64 | .filter(function (num) {
65 | return num % 2 === 1;
66 | })
67 | .map(function (num) {
68 | return {num: num};
69 | })
70 | .toArray();
71 | });
72 |
73 | console.log(result);
74 |
75 | result = measure("Underscore.js [filter - map - value]", input, function () {
76 | return _.chain(input)
77 | .filter(function (num) {
78 | return num % 2 === 1;
79 | })
80 | .map(function (num) {
81 | return {num: num};
82 | })
83 | .value();
84 | });
85 |
86 | console.log(result);
87 |
88 | result = measure("Iterative [filter - map - array]", input, function () {
89 | var result = [];
90 | for (var i = 0; i < input.length; i++) {
91 | if (i % 2 === 1) {
92 | result.push({num: i});
93 | }
94 | }
95 | return result;
96 | });
97 |
98 | console.log(result);
99 |
100 | result = measure("Stream.js [filter - map - findFirst]", input, function () {
101 | return Stream(input)
102 | .filter(function (num) {
103 | return num % 2 === 1;
104 | })
105 | .map(function (num) {
106 | return {num: num};
107 | })
108 | .findFirst();
109 | });
110 |
111 | console.log(result);
112 |
113 | result = measure("Underscore.js [filter - map - first - value]", input, function () {
114 | return _.chain(input)
115 | .filter(function (num) {
116 | return num % 2 === 1;
117 | })
118 | .map(function (num) {
119 | return {num: num};
120 | })
121 | .first()
122 | .value();
123 | });
124 |
125 | console.log(result);
126 |
127 | result = measure("Iterative [filter - map - return first]", input, function () {
128 | for (var i = 0; i < input.length; i++) {
129 | if (i % 2 === 1) {
130 | return {num: i};
131 | }
132 | }
133 | return null;
134 | });
135 |
136 | console.log(result);
137 |
138 |
139 | }());
--------------------------------------------------------------------------------
/stream-min.js:
--------------------------------------------------------------------------------
1 | /*! Stream.js v1.6.4 (2016-05-19) */
2 | (function(){"use strict";function a(){}function b(a){this.initialize(a)}function c(a){this.iterator=a}function d(a){this.initialize(a)}function e(a){this.initialize(a)}function f(a){this.initialize(a)}function g(){this.next=null,this.prev=null}function h(b){this.iterator=a.of(b)}function i(a){this.fn=a}function j(a){this.fn=a,this.iterator=null}function k(a){this.fn=a}function l(a){this.prev=null,this.next=null,this.fn=a}function m(a){this.prev=null,this.next=null,this.filter=a.filter,this.finisher=a.finisher,this.merger=a.merger,this.customMerge=u(this.merger),this.buffer=null,this.i=0}function n(a,b){this.begin=a,this.end=b,this.i=0}function o(a){this.consumer=a,this.consoleFn=B(a)}function p(a){this.predicate=a}function q(a){this.predicate=a,this.border=!1}function r(b,c){var d,e=this;u(b)?d=new l(function(){return b.call(F)}):t(b)?(c=c||"",b.endsWith(c)&&(b=b.substring(0,b.length-c.length)),d=new h(b.split(c))):d=new h(b),this.add=function(a){if(null!==d){var b=d;a.prev=b,b.next=a}d=a},this.next=function(){return d.advance()},this.filter=function(){var a=arguments[0];return A(a)?this.add(new k(function(b){return a.test(b)})):z(a)?this.add(new k(function(b){return K(a,b)})):this.add(new k(a)),this},this.filterNull=function(){return this.add(new k(function(a){return null!==a})),this},this.filterFalsy=function(){return this.add(new k(function(a){return Boolean(a).valueOf()})),this},this.map=function(){var a=arguments[0];return t(a)?this.add(new i(J(a))):this.add(new i(a)),this},this.flatMap=function(){var a=arguments[0];return t(a)?this.add(new i(J(a))):this.add(new i(a)),this.add(new j),this},this.sorted=function(a){var b;return b=u(a)?a:t(a)?I(a):H,this.add(new m({finisher:function(a){a.sort(b)}})),this},this.shuffle=function(){return this.add(new m({merger:function(a,b){if(0===b.length)b.push(a);else{var c=Math.floor(Math.random()*b.length),d=b[c];b[c]=a,b.push(d)}}})),this},this.reverse=function(){return this.add(new m({merger:function(a,b){b.unshift(a)}})),this},this.distinct=function(){return this.add(new m({filter:function(a,b,c){return c.indexOf(a)<0}})),this},this.slice=function(a,b){if(a>b)throw"slice(): begin must not be greater than end";return this.add(new n(a,b)),this},this.skip=function(a){return this.add(new n(a,Number.MAX_VALUE)),this},this.limit=function(a){return this.add(new n(0,a)),this},this.peek=function(a){return this.add(new o(a)),this},this.takeWhile=function(){var a=arguments[0];return A(a)?this.add(new p(function(b){return a.test(b)})):z(a)?this.add(new p(function(b){return K(a,b)})):this.add(new p(a)),this},this.dropWhile=function(){var a=arguments[0];return A(a)?this.add(new q(function(b){return a.test(b)})):z(a)?this.add(new q(function(b){return K(a,b)})):this.add(new q(a)),this};var f={};f.toArray=function(){for(var a,b=[];(a=e.next())!==G;)b.push(a);return b},f.findFirst=function(){var a=e.next();return a===G?s.empty():s.ofNullable(a)},f.forEach=function(a){for(var b,c=B(a);(b=e.next())!==G;)a.call(c?console:F,b)},f.min=function(a){var b;b=u(a)?a:t(a)?I(a):H;for(var c,d=null;(c=e.next())!==G;)(null===d||b.call(F,c,d)<0)&&(d=c);return s.ofNullable(d)},f.max=function(a){var b;b=u(a)?a:t(a)?I(a):H;for(var c,d=null;(c=e.next())!==G;)(null===d||b.call(F,c,d)>0)&&(d=c);return s.ofNullable(d)},f.sum=function(a){for(var b,c=a?J(a):function(a){return a},d=0;(b=e.next())!==G;)d+=c.call(F,b);return d},f.average=function(a){for(var b,c=a?J(a):function(a){return a},d=0,f=0;(b=e.next())!==G;)f+=c.call(F,b),d++;return 0===f||0===d?s.empty():s.of(f/d)},f.count=function(){for(var a=0;e.next()!==G;)a++;return a},f.allMatch=function(){var a,b=arguments[0],c=b;for(A(b)?c=function(a){return b.test(a)}:z(b)&&(c=function(a){return K(b,a)});(a=e.next())!==G;){var d=c.call(F,a);if(!d)return!1}return!0},f.anyMatch=function(){var a,b=arguments[0],c=b;for(A(b)?c=function(a){return b.test(a)}:z(b)&&(c=function(a){return K(b,a)});(a=e.next())!==G;){var d=c.call(F,a);if(d)return!0}return!1},f.noneMatch=function(){var a,b=arguments[0],c=b;for(A(b)?c=function(a){return b.test(a)}:z(b)&&(c=function(a){return K(b,a)});(a=e.next())!==G;){var d=c.call(F,a);if(d)return!1}return!0},f.collect=function(a){for(var b,c=a.supplier.call(F),d=!0;(b=e.next())!==G;)c=a.accumulator.call(F,c,b,d),d=!1;return a.finisher&&(c=a.finisher.call(F,c)),c},f.reduce=function(){var a=arguments[0],b=arguments[1];return b?e.collect({supplier:function(){return a},accumulator:b}):g(a)};var g=function(a){var b,c=e.next();if(c===G)return s.empty();for(;(b=e.next())!==G;)c=a.call(F,c,b);return s.ofNullable(c)};f.groupBy=function(){var a=arguments[0];return t(a)&&(a=J(a)),e.collect({supplier:function(){return{}},accumulator:function(b,c){var d=a.call(F,c);return b.hasOwnProperty(d)||(b[d]=[]),void 0===b[d]&&(b[d]=[]),b[d].push(c),b}})},f.toMap=function(){var a=arguments[0];t(a)&&(a=J(a));var b=!1;return arguments.length>1&&(b=arguments[1]),e.collect({supplier:function(){return{}},accumulator:function(c,d){var e=a.call(F,d);if(c.hasOwnProperty(e)){if(!b)throw"duplicate mapping found for key: "+e;return c[e]=b.call(F,c[e],d),c}return c[e]=d,c}})},f.partitionBy=function(){var a=arguments[0];if(u(a))return r(a);if(v(a))return w(a);if(A(a))return r(function(b){return a.test(b)});if(z(a))return r(function(b){return K(a,b)});throw"partitionBy requires argument of type function, object, regexp or number"};var r=function(a){return e.collect({supplier:function(){return{"true":[],"false":[]}},accumulator:function(b,c){var d=a.call(F,c);return b.hasOwnProperty(d)||(b[d]=[]),b[d].push(c),b}})},w=function(a){return e.collect({supplier:function(){return[]},accumulator:function(b,c){if(0===b.length)return b.push([c]),b;var d=b[b.length-1];return d.length===a?(b.push([c]),b):(d.push(c),b)}})};f.joining=function(a){var b="",c="",d="";return a&&(t(a)?d=a:(b=a.prefix||b,c=a.suffix||c,d=a.delimiter||d)),e.collect({supplier:function(){return""},accumulator:function(a,b,c){var e=c?"":d;return a+e+String(b)},finisher:function(a){return b+a+c}})};var x=function(){this.value=e.next()};x.prototype=new a,x.prototype.next=function(){if(this.value===G)return{value:void 0,done:!0};var a=e.next(),b=a===G,c={value:this.value,done:b};return this.value=a,c},f.iterator=function(){return new x};var y=!1,C=function(a){return function(){try{if(y)throw"stream has already been operated upon";return a.apply(e,arguments)}finally{y=!0}}};for(var D in f)f.hasOwnProperty(D)&&(this[D]=C(f[D]));this.indexBy=this.toMap,this.partitioningBy=this.partitionBy,this.groupingBy=this.groupBy,this.each=this.forEach,this.toList=this.toArray,this.join=this.joining,this.avg=this.average,this.sort=this.sorted,this.size=this.count,this.findAny=this.findFirst}function s(a){this.isPresent=function(){return null!==a&&void 0!==a},this.get=function(){if(!this.isPresent())throw"optional value is not present";return a},this.ifPresent=function(b){this.isPresent()&&b.call(a,a)},this.orElse=function(b){return this.isPresent()?a:b},this.orElseGet=function(b){return this.isPresent()?a:b.call(F)},this.orElseThrow=function(b){if(this.isPresent())return a;throw b},this.filter=function(b){if(this.isPresent()){var c=b.call(F,a);return c?this:s.empty()}return this},this.map=function(b){if(this.isPresent()){var c=b.call(F,a);return s.ofNullable(c)}return this},this.flatMap=function(b){return this.isPresent()?b.call(F,a):this}}function t(a){return"[object String]"===L.call(a)}function u(a){return"function"==typeof a||!1}function v(a){return"[object Number]"===L.call(a)}function w(a){return Boolean(D.Set)&&a instanceof Set&&u(a.values)}function x(a){return Boolean(D.Map)&&a instanceof Map&&u(a.values)}function y(a){return Boolean(a)&&u(a.next)}function z(a){return Boolean(a)&&"object"==typeof a}function A(a){return"[object RegExp]"===L.call(a)}function B(a){return D.console?console.log===a||console.warn===a||console.error===a||console.trace===a:!1}function C(a,b){return new r(a,b)}var D="object"==typeof global&&global||this,E="1.6.4",F={},G={};a.of=function(a){return null===a||void 0===a?new f(a):M(a)?new b(a):x(a)||w(a)?new c(a.values()):y(a)?new c(a):z(a)?new d(a):new e(a)},b.prototype=new a,b.prototype.next=function(){if(this.origin>=this.fence)return G;try{return this.data[this.origin]}finally{this.origin++}},b.prototype.initialize=function(a){this.data=a||[],this.origin=0,this.fence=this.data.length},c.prototype=new a,c.prototype.next=function(){if(this.iterator){var a=this.iterator.next();return a.done&&delete this.iterator,a.value}return G},d.prototype=new a,d.prototype.initialize=function(a){this.data=a||{},this.keys=Object.keys(a),this.origin=0,this.fence=this.keys.length},d.prototype.next=function(){if(this.origin>=this.fence)return G;try{var a=this.keys[this.origin];return this.data[a]}finally{this.origin++}},e.prototype=new a,e.prototype.initialize=function(a){this.value=a,this.done=!1},e.prototype.next=function(){return this.done?G:(this.done=!0,this.value)},f.prototype=new a,f.prototype.initialize=function(a){this.value=a,this.done=!0},f.prototype.next=function(){return G},h.prototype=new g,h.prototype.advance=function(){var a=this.iterator.next();return a===G?a:null===this.next?a:this.next.pipe(a)},i.prototype=new g,i.prototype.advance=function(){return this.prev.advance()},i.prototype.pipe=function(a){var b=this.fn.call(F,a);return null===this.next?b:this.next.pipe(b)},j.prototype=new g,j.prototype.advance=function(){if(null===this.iterator)return this.prev.advance();var a=this.iterator.next();return a===G?(this.iterator=null,this.prev.advance()):null===this.next?a:this.next.pipe(a)},j.prototype.pipe=function(b){this.iterator=a.of(b);var c=this.iterator.next();return c===G?this.prev.advance():null===this.next?c:this.next.pipe(c)},k.prototype=new g,k.prototype.advance=function(){return this.prev.advance()},k.prototype.pipe=function(a){var b=this.fn.call(F,a);return b?null===this.next?a:this.next.pipe(a):this.prev.advance()},l.prototype.advance=function(){var a=this.fn.call(F);return this.next.pipe(a)},m.prototype.advance=function(){var a;if(null===this.buffer){for(this.buffer=[];(a=this.prev.advance())!==G;)this.i++;this.finisher&&this.finisher.call(F,this.buffer)}return 0===this.buffer.length?G:(a=this.buffer.shift(),null!==this.next?this.next.pipe(a):a)},m.prototype.pipe=function(a){this.filter&&this.filter.call(F,a,this.i,this.buffer)===!1||(this.customMerge?this.merger.call({},a,this.buffer):this.buffer.push(a))},n.prototype=new g,n.prototype.advance=function(){return this.prev.advance()},n.prototype.pipe=function(a){return this.i>=this.end?G:(this.i++,this.i<=this.begin?this.prev.advance():null===this.next?a:this.next.pipe(a))},o.prototype=new g,o.prototype.advance=function(){return this.prev.advance()},o.prototype.pipe=function(a){return this.consumer.call(this.consoleFn?console:F,a),null===this.next?a:this.next.pipe(a)},p.prototype=new g,p.prototype.advance=function(){return this.prev.advance()},p.prototype.pipe=function(a){var b=this.predicate.call(F,a);return b!==!0?G:null===this.next?a:this.next.pipe(a)},q.prototype=new g,q.prototype.advance=function(){return this.prev.advance()},q.prototype.pipe=function(a){if(!this.border){var b=this.predicate.call(F,a);if(b===!0)return this.prev.advance();this.border=!0}return null===this.next?a:this.next.pipe(a)},r.prototype.toString=function(){return"[object Stream]"},s.prototype.toString=function(){return"[object Optional]"},s.of=function(a){if(null===a||void 0===a)throw"value must be present";return new s(a)},s.ofNullable=function(a){return new s(a)},s.empty=function(){return new s(void 0)};var H=function(a,b){return a===b?0:a>b?1:-1},I=function(a){var b=J(a);return function(a,c){var d=b(a),e=b(c);return H(d,e)}},J=function(a){if(a.indexOf(".")<0)return function(b){return b[a]};var b=a.split(".");return function(a){for(var c=a,d=0;d=0};C.from=function(a,b){return C(a,b)},C.range=function(a,b){return C.iterate(a,function(a){return a+1}).limit(b-a)},C.rangeClosed=function(a,b){return C.range(a,b+1)},C.of=function(){var a=Array.prototype.slice.call(arguments);return C(a)},C.generate=function(a){return C(a)},C.iterate=function(a,b){var c=!0,d=a;return C(function(){return c?(c=!1,a):d=b.call(F,d)})},C.empty=function(){return C([])},C.VERSION=E,C.NAME="STREAMJS",C.Optional=s;var N;Boolean(D.Stream)&&D.Stream.NAME!==C.NAME&&(N=D.Stream),C.noConflict=function(){return D.Stream=N,C},"undefined"!=typeof module&&module.exports?module.exports=C:"function"==typeof define&&define.amd?define("streamjs",[],function(){return C}):D.Stream=C}).call(this);
3 | //# sourceMappingURL=stream-min.map
--------------------------------------------------------------------------------
/stream-min.map:
--------------------------------------------------------------------------------
1 | {"version":3,"sources":["stream.js"],"names":["Iterator","ArrayIterator","array","this","initialize","IteratorIterator","iterator","ObjectIterator","object","ValueIterator","value","EmptyIterator","PipelineOp","next","prev","IteratorOp","data","of","MapOp","fn","FlatOp","FilterOp","GeneratorOp","StatefulOp","options","filter","finisher","merger","customMerge","isFunction","buffer","i","SliceOp","begin","end","PeekOp","consumer","consoleFn","isConsoleFn","TakeWhileOp","predicate","DropWhileOp","border","Pipeline","input","separator","lastOp","pipeline","call","ctx","isString","endsWith","substring","length","split","add","op","advance","arg","arguments","isRegExp","obj","test","isObject","deepEquals","filterNull","filterFalsy","Boolean","valueOf","map","pathMapper","flatMap","sorted","comparator","pathComparator","defaultComparator","sort","shuffle","push","Math","floor","random","tmp","reverse","unshift","distinct","indexOf","slice","skip","num","Number","MAX_VALUE","limit","peek","takeWhile","dropWhile","terminal","toArray","current","result","nil","findFirst","Optional","empty","ofNullable","forEach","console","min","max","sum","path","average","count","allMatch","match","anyMatch","noneMatch","collect","collector","identity","supplier","first","accumulator","reduce","arg0","arg1","reduceFirst","groupBy","key","hasOwnProperty","undefined","toMap","partitionBy","partitionByPredicate","isNumber","partitionByNumber","true","false","partition","joining","prefix","suffix","delimiter","str","delim","String","StreamIterator","prototype","done","nextValue","consumed","terminalProxy","terminalFn","apply","name","indexBy","partitioningBy","groupingBy","each","toList","join","avg","size","findAny","val","isPresent","get","ifPresent","orElse","otherVal","orElseGet","orElseThrow","errorMsg","filtered","mapper","mappedVal","flatMapper","ObjToString","isSet","root","Set","values","isMap","Map","isIterator","log","warn","error","trace","Stream","global","version","isArrayLike","origin","fence","keys","Object","pipe","shift","toString","a","b","obj1","obj2","paths","prop","val1","val2","propEquals","from","range","startInclusive","endExclusive","iterate","rangeClosed","endInclusive","args","Array","generate","seed","VERSION","NAME","previousStream","noConflict","module","exports","define","amd"],"mappings":"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","file":"stream-min.js"}
--------------------------------------------------------------------------------
/test/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "eslint:recommended",
3 | "env": {
4 | "browser": true,
5 | "node": true,
6 | "amd": true,
7 | "qunit": true
8 | },
9 | "globals": {
10 | "Stream": true
11 | },
12 | "rules": {
13 | "no-console": 0,
14 | "no-constant-condition": 0
15 | }
16 | }
--------------------------------------------------------------------------------
/test/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Stream.js - All Tests
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
--------------------------------------------------------------------------------
/test/test-allMatch.js:
--------------------------------------------------------------------------------
1 | QUnit.test("allMatch true", function (assert) {
2 | var result = Stream([1, 2, 3, 4])
3 | .allMatch(function (num) {
4 | return num > 0;
5 | });
6 | assert.equal(result, true);
7 | });
8 |
9 | QUnit.test("allMatch false", function (assert) {
10 | var result = Stream([1, 2, 3, 4])
11 | .allMatch(function (num) {
12 | return num > 1;
13 | });
14 | assert.equal(result, false);
15 | });
16 |
17 | QUnit.test("allMatch empty", function (assert) {
18 | var result = Stream([])
19 | .allMatch(function (num) {
20 | return num > 1;
21 | });
22 | assert.equal(result, true);
23 | });
24 |
25 | QUnit.test("allMatch regexp true", function (assert) {
26 | var result = Stream(["a1", "a2", "a3"])
27 | .allMatch(/a.*/);
28 | assert.equal(result, true);
29 | });
30 |
31 | QUnit.test("allMatch regexp false", function (assert) {
32 | var result = Stream(["a1", "a2", "b3"])
33 | .allMatch(/a.*/);
34 | assert.equal(result, false);
35 | });
36 |
37 | QUnit.test("allMatch regexp empty", function (assert) {
38 | var result = Stream([])
39 | .allMatch(/a.*/);
40 | assert.equal(result, true);
41 | });
42 |
43 | QUnit.test("allMatch sample true", function (assert) {
44 | var result = Stream([{a: 1, b: 5}, {a: 2, b: 5}, {a: 3, b: 5}])
45 | .allMatch({b: 5});
46 | assert.equal(result, true);
47 | });
48 |
49 | QUnit.test("allMatch sample false", function (assert) {
50 | var result = Stream([{a: 1, b: 5}, {a: 2, b: 5}, {a: 3, b: 5}])
51 | .allMatch({a: 1});
52 | assert.equal(result, false);
53 | });
54 |
55 | QUnit.test("allMatch sample empty", function (assert) {
56 | var result = Stream([])
57 | .allMatch({a: 1});
58 | assert.equal(result, true);
59 | });
--------------------------------------------------------------------------------
/test/test-anyMatch.js:
--------------------------------------------------------------------------------
1 | QUnit.test("anyMatch true", function (assert) {
2 | var result = Stream([1, 2, 3, 4])
3 | .anyMatch(function (num) {
4 | return num === 4;
5 | });
6 | assert.equal(result, true);
7 | });
8 |
9 | QUnit.test("anyMatch false", function (assert) {
10 | var result = Stream([1, 2, 3, 4])
11 | .anyMatch(function (num) {
12 | return num === 5;
13 | });
14 | assert.equal(result, false);
15 | });
16 |
17 | QUnit.test("anyMatch empty", function (assert) {
18 | var result = Stream([])
19 | .anyMatch(function (num) {
20 | return num > 1;
21 | });
22 | assert.equal(result, false);
23 | });
24 |
25 | QUnit.test("anyMatch regexp true", function (assert) {
26 | var result = Stream(["a1", "a2", "a3"])
27 | .anyMatch(/a.*/);
28 | assert.equal(result, true);
29 | });
30 |
31 | QUnit.test("anyMatch regexp false", function (assert) {
32 | var result = Stream(["b1", "b2", "b3"])
33 | .anyMatch(/a.*/);
34 | assert.equal(result, false);
35 | });
36 |
37 | QUnit.test("anyMatch regexp empty", function (assert) {
38 | var result = Stream([])
39 | .anyMatch(/a.*/);
40 | assert.equal(result, false);
41 | });
42 |
43 | QUnit.test("anyMatch sample true", function (assert) {
44 | var result = Stream([{a: 1, b: 5}, {a: 2, b: 5}, {a: 3, b: 5}])
45 | .anyMatch({a: 1});
46 | assert.equal(result, true);
47 | });
48 |
49 | QUnit.test("anyMatch sample false", function (assert) {
50 | var result = Stream([{a: 1, b: 5}, {a: 2, b: 5}, {a: 3, b: 5}])
51 | .anyMatch({a: 4});
52 | assert.equal(result, false);
53 | });
54 |
55 | QUnit.test("anyMatch sample empty", function (assert) {
56 | var result = Stream([])
57 | .anyMatch({a: 1});
58 | assert.equal(result, false);
59 | });
--------------------------------------------------------------------------------
/test/test-average.js:
--------------------------------------------------------------------------------
1 | QUnit.test("average", function (assert) {
2 | var result = Stream([1, 2, 3, 4]).average();
3 | assert.equal(result, "[object Optional]");
4 | assert.equal(result.isPresent(), true);
5 | assert.equal(result.get(), 2.5);
6 | });
7 |
8 | QUnit.test("average empty", function (assert) {
9 | var result = Stream([]).average();
10 | assert.equal(result, "[object Optional]");
11 | assert.equal(result.isPresent(), false);
12 | });
13 |
14 | QUnit.test("average via path", function (assert) {
15 | var result = Stream.of({a: 1}, {a: 2}, {a: 3}, {a: 4})
16 | .average("a");
17 | assert.equal(result, "[object Optional]");
18 | assert.equal(result.get(), 2.5);
19 | });
20 |
21 | QUnit.test("average via path (empty)", function (assert) {
22 | var result = Stream
23 | .empty()
24 | .average("a");
25 | assert.equal(result, "[object Optional]");
26 | assert.equal(result.isPresent(), false);
27 | });
--------------------------------------------------------------------------------
/test/test-collect.js:
--------------------------------------------------------------------------------
1 | QUnit.test("collect", function (assert) {
2 | var result = Stream([1, 2, 3, 4]).collect({
3 | supplier: function () {
4 | return "Data: ";
5 | },
6 | accumulator: function (val, num) {
7 | return val + num + " ";
8 | },
9 | finisher: function (val) {
10 | return val + "!";
11 | }
12 | });
13 |
14 | assert.equal(result, "Data: 1 2 3 4 !");
15 | });
16 |
17 | QUnit.test("collect without finisher", function (assert) {
18 | var result = Stream([1, 2, 3, 4]).collect({
19 | supplier: function () {
20 | return "Data: ";
21 | },
22 | accumulator: function (val, num) {
23 | return val + num + " ";
24 | }
25 | });
26 |
27 | assert.equal(result, "Data: 1 2 3 4 ");
28 | });
29 |
30 | QUnit.test("collect empty", function (assert) {
31 | var result = Stream([]).collect({
32 | supplier: function () {
33 | return "Data: ";
34 | },
35 | accumulator: function (val, num) {
36 | return val + num + " ";
37 | },
38 | finisher: function (val) {
39 | return val + "!";
40 | }
41 | });
42 |
43 | assert.equal(result, "Data: !");
44 | });
--------------------------------------------------------------------------------
/test/test-constructors-compiled.js:
--------------------------------------------------------------------------------
1 | // I'm using Babel.js and Intellij IDEA File Watcher to automatically transpile es6 to js:
2 | // --source-maps --out-file $FileNameWithoutExtension$-compiled.js $FilePath$
3 |
4 | "use strict";
5 |
6 | QUnit.test("input ES6 iterator", function (assert) {
7 | var marked1$0 = [iterator].map(regeneratorRuntime.mark);
8 |
9 | function iterator() {
10 | return regeneratorRuntime.wrap(function iterator$(context$2$0) {
11 | while (1) switch (context$2$0.prev = context$2$0.next) {
12 | case 0:
13 | context$2$0.next = 2;
14 | return 1;
15 |
16 | case 2:
17 | context$2$0.next = 4;
18 | return 2;
19 |
20 | case 4:
21 | context$2$0.next = 6;
22 | return 3;
23 |
24 | case 6:
25 | context$2$0.next = 8;
26 | return 4;
27 |
28 | case 8:
29 | context$2$0.next = 10;
30 | return 5;
31 |
32 | case 10:
33 | context$2$0.next = 12;
34 | return 6;
35 |
36 | case 12:
37 | case "end":
38 | return context$2$0.stop();
39 | }
40 | }, marked1$0[0], this);
41 | }
42 |
43 | var result = Stream(iterator()).filter(function (i) {
44 | return i % 2 === 1;
45 | }).toArray();
46 |
47 | assert.equal(result.length, 3);
48 | assert.equal(result[0], 1);
49 | assert.equal(result[1], 3);
50 | assert.equal(result[2], 5);
51 | });
52 |
53 | QUnit.test("input ES6 set", function (assert) {
54 | var data = new Set([1, 2, 3, 4, 5, 6]);
55 |
56 | var result = Stream(data).filter(function (i) {
57 | return i % 2 === 1;
58 | }).toArray();
59 |
60 | assert.equal(result.length, 3);
61 | assert.equal(result[0], 1);
62 | assert.equal(result[1], 3);
63 | assert.equal(result[2], 5);
64 | });
65 |
66 | QUnit.test("input ES6 map", function (assert) {
67 | var data = new Map();
68 | data.set("key1", 1);
69 | data.set("key2", 2);
70 | data.set("key3", 3);
71 |
72 | var result = Stream(data).filter(function (i) {
73 | return i % 2 === 1;
74 | }).toArray();
75 |
76 | assert.equal(result.length, 2);
77 | assert.equal(result[0], 1);
78 | assert.equal(result[1], 3);
79 | });
80 |
81 | //# sourceMappingURL=test-constructors-compiled.js.map
--------------------------------------------------------------------------------
/test/test-constructors-compiled.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"sources":["test-constructors.es6"],"names":[],"mappings":";;;;;AAGA,KAAK,CAAC,IAAI,CAAC,oBAAoB,EAAE,UAAU,MAAM,EAAE;qBACrC,QAAQ;;AAAlB,aAAU,QAAQ;;;;;2BACR,CAAC;;;;2BACD,CAAC;;;;2BACD,CAAC;;;;2BACD,CAAC;;;;2BACD,CAAC;;;;2BACD,CAAC;;;;;;;KACV;;AAED,QAAI,MAAM,GAAG,MAAM,CAAC,QAAQ,EAAE,CAAC,CAC5B,MAAM,CAAC,UAAS,CAAC,EAAE;AAChB,eAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;KACtB,CAAC,CACD,OAAO,EAAE,CAAC;;AAEb,UAAM,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;AAC/B,UAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AAC3B,UAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AAC3B,UAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;CAC9B,CAAC,CAAC;;AAEH,KAAK,CAAC,IAAI,CAAC,eAAe,EAAE,UAAU,MAAM,EAAE;AAC1C,QAAI,IAAI,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;;AAEvC,QAAI,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,CACpB,MAAM,CAAC,UAAU,CAAC,EAAE;AACjB,eAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;KACtB,CAAC,CACD,OAAO,EAAE,CAAC;;AAEf,UAAM,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;AAC/B,UAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AAC3B,UAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AAC3B,UAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;CAC9B,CAAC,CAAC;;AAEH,KAAK,CAAC,IAAI,CAAC,eAAe,EAAE,UAAU,MAAM,EAAE;AAC1C,QAAI,IAAI,GAAG,IAAI,GAAG,EAAE,CAAC;AACrB,QAAI,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;AACpB,QAAI,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;AACpB,QAAI,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;;AAEpB,QAAI,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,CACpB,MAAM,CAAC,UAAU,CAAC,EAAE;AACjB,eAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;KACtB,CAAC,CACD,OAAO,EAAE,CAAC;;AAEf,UAAM,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;AAC/B,UAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AAC3B,UAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;CAC9B,CAAC,CAAC","file":"test-constructors-compiled.js","sourcesContent":["// I'm using Babel.js and Intellij IDEA File Watcher to automatically transpile es6 to js:\n// --source-maps --out-file $FileNameWithoutExtension$-compiled.js $FilePath$\n\nQUnit.test(\"input ES6 iterator\", function (assert) {\n function* iterator() {\n yield 1;\n yield 2;\n yield 3;\n yield 4;\n yield 5;\n yield 6;\n }\n\n var result = Stream(iterator())\n .filter(function(i) {\n return i % 2 === 1;\n })\n .toArray();\n\n assert.equal(result.length, 3);\n assert.equal(result[0], 1);\n assert.equal(result[1], 3);\n assert.equal(result[2], 5);\n});\n\nQUnit.test(\"input ES6 set\", function (assert) {\n var data = new Set([1, 2, 3, 4, 5, 6]);\n\n var result = Stream(data)\n .filter(function (i) {\n return i % 2 === 1;\n })\n .toArray();\n\n assert.equal(result.length, 3);\n assert.equal(result[0], 1);\n assert.equal(result[1], 3);\n assert.equal(result[2], 5);\n});\n\nQUnit.test(\"input ES6 map\", function (assert) {\n var data = new Map();\n data.set(\"key1\", 1);\n data.set(\"key2\", 2);\n data.set(\"key3\", 3);\n\n var result = Stream(data)\n .filter(function (i) {\n return i % 2 === 1;\n })\n .toArray();\n\n assert.equal(result.length, 2);\n assert.equal(result[0], 1);\n assert.equal(result[1], 3);\n});"]}
--------------------------------------------------------------------------------
/test/test-constructors.es6:
--------------------------------------------------------------------------------
1 | // I'm using Babel.js and Intellij IDEA File Watcher to automatically transpile es6 to js:
2 | // --source-maps --out-file $FileNameWithoutExtension$-compiled.js $FilePath$
3 |
4 | QUnit.test("input ES6 iterator", function (assert) {
5 | function* iterator() {
6 | yield 1;
7 | yield 2;
8 | yield 3;
9 | yield 4;
10 | yield 5;
11 | yield 6;
12 | }
13 |
14 | var result = Stream(iterator())
15 | .filter(function(i) {
16 | return i % 2 === 1;
17 | })
18 | .toArray();
19 |
20 | assert.equal(result.length, 3);
21 | assert.equal(result[0], 1);
22 | assert.equal(result[1], 3);
23 | assert.equal(result[2], 5);
24 | });
25 |
26 | QUnit.test("input ES6 set", function (assert) {
27 | var data = new Set([1, 2, 3, 4, 5, 6]);
28 |
29 | var result = Stream(data)
30 | .filter(function (i) {
31 | return i % 2 === 1;
32 | })
33 | .toArray();
34 |
35 | assert.equal(result.length, 3);
36 | assert.equal(result[0], 1);
37 | assert.equal(result[1], 3);
38 | assert.equal(result[2], 5);
39 | });
40 |
41 | QUnit.test("input ES6 map", function (assert) {
42 | var data = new Map();
43 | data.set("key1", 1);
44 | data.set("key2", 2);
45 | data.set("key3", 3);
46 |
47 | var result = Stream(data)
48 | .filter(function (i) {
49 | return i % 2 === 1;
50 | })
51 | .toArray();
52 |
53 | assert.equal(result.length, 2);
54 | assert.equal(result[0], 1);
55 | assert.equal(result[1], 3);
56 | });
--------------------------------------------------------------------------------
/test/test-constructors.js:
--------------------------------------------------------------------------------
1 | QUnit.test("input array", function (assert) {
2 | var input = [1, 2, 3];
3 | var result = Stream(input).toArray();
4 | assert.equal(result.length, 3);
5 | assert.equal(result[0], 1);
6 | assert.equal(result[1], 2);
7 | assert.equal(result[2], 3);
8 | });
9 |
10 | QUnit.test("input undefined", function (assert) {
11 | var result = Stream(undefined).toArray();
12 | assert.equal(result.length, 0);
13 | });
14 |
15 | QUnit.test("input null", function (assert) {
16 | var result = Stream(null).toArray();
17 | assert.equal(result.length, 0);
18 | });
19 |
20 | QUnit.test("input makeshift iterator", function (assert) {
21 | function iter(){
22 | var index = 0;
23 |
24 | return {
25 | next: function(){
26 | if (index >= 10) return;
27 | return { value: index++, done: (index >= 10) };
28 | }
29 | };
30 | }
31 |
32 | var input = iter();
33 | var result = Stream(input)
34 | .filter(function(i) {
35 | return i % 2;
36 | })
37 | .takeWhile(function(i) {
38 | return i < 7;
39 | })
40 | .toArray();
41 |
42 | assert.equal(result.length, 3);
43 | assert.equal(result[0], 1);
44 | assert.equal(result[1], 3);
45 | assert.equal(result[2], 5);
46 | });
47 |
48 | QUnit.test("input stream iterator", function (assert) {
49 | var input = Stream.of(1, 2, 3, 4, 5).iterator();
50 | var result = Stream(input)
51 | .filter(function(i) {
52 | return i % 2;
53 | })
54 | .toArray();
55 |
56 | assert.equal(result.length, 3);
57 | assert.equal(result[0], 1);
58 | assert.equal(result[1], 3);
59 | assert.equal(result[2], 5);
60 | });
61 |
62 | QUnit.test("input object", function (assert) {
63 | var input = {
64 | foo: 1, bar: 2, foobar: 3
65 | };
66 |
67 | var result = Stream(input).toArray();
68 | assert.equal(result.length, 3);
69 | assert.equal(result[0], 1);
70 | assert.equal(result[1], 2);
71 | assert.equal(result[2], 3);
72 | });
73 |
74 | QUnit.test("input string", function (assert) {
75 | var result = Stream("abcd")
76 | .filter(function (c) {
77 | return c !== 'b';
78 | })
79 | .map(function (c) {
80 | return c.toUpperCase();
81 | })
82 | .joining();
83 |
84 | assert.equal(result, "ACD");
85 | });
86 |
87 | QUnit.test("input string with separator", function(assert) {
88 | var result = Stream("a,b,c,d", ",").toArray();
89 | assert.equal(result.length, 4);
90 | });
91 |
92 | QUnit.test("Stream.from input string with separator", function(assert) {
93 | var result = Stream.from("a,b,c,d", ",").toArray();
94 | assert.equal(result.length, 4);
95 | });
96 |
97 |
98 | QUnit.test("input string with falsy separator", function(assert) {
99 | var result = Stream("abcd", undefined).toArray();
100 | assert.equal(result.length, 4);
101 | });
102 |
103 | QUnit.test("input string with trailing separator", function(assert) {
104 | var result = Stream("a,b,c,d,", ",").toArray();
105 | assert.equal(result.length, 4);
106 | });
107 |
108 | QUnit.test("input string with multi-char trailing separator", function(assert) {
109 | var result = Stream("a||b||c||d||", "||").toArray();
110 | assert.equal(result.length, 4);
111 | });
112 |
113 | QUnit.test("from array", function (assert) {
114 | var input = [1, 2, 3];
115 | var result = Stream.from(input).toArray();
116 | assert.equal(result.length, 3);
117 | assert.equal(result[0], 1);
118 | assert.equal(result[1], 2);
119 | assert.equal(result[2], 3);
120 | });
121 |
122 | QUnit.test("from undefined", function (assert) {
123 | var result = Stream.from(undefined).toArray();
124 | assert.equal(result.length, 0);
125 | });
126 |
127 | QUnit.test("from null", function (assert) {
128 | var result = Stream.from(null).toArray();
129 | assert.equal(result.length, 0);
130 | });
131 |
132 | QUnit.test("from object", function (assert) {
133 | var input = {
134 | foo: 1, bar: 2, foobar: 3
135 | };
136 |
137 | var result = Stream.from(input).toArray();
138 | assert.equal(result.length, 3);
139 | assert.equal(result[0], 1);
140 | assert.equal(result[1], 2);
141 | assert.equal(result[2], 3);
142 | });
143 |
144 | QUnit.test("from string", function (assert) {
145 | var result = Stream.from("abcd")
146 | .filter(function (c) {
147 | return c !== 'b';
148 | })
149 | .map(function (c) {
150 | return c.toUpperCase();
151 | })
152 | .joining();
153 |
154 | assert.equal(result, "ACD");
155 | });
156 |
157 | QUnit.test("of", function (assert) {
158 | var result = Stream.of(1, 2, 3, 4)
159 | .filter(function (num) {
160 | return num % 2 === 1;
161 | })
162 | .map(function (num) {
163 | return "odd" + num;
164 | })
165 | .toArray();
166 |
167 | assert.equal(result.length, 2);
168 | assert.equal(result[0], "odd1");
169 | assert.equal(result[1], "odd3");
170 | });
171 |
172 | QUnit.test("empty", function (assert) {
173 | var result = Stream.empty().toArray();
174 | assert.equal(result.length, 0);
175 | });
176 |
177 | QUnit.test("range", function (assert) {
178 | var result = Stream.range(0, 4).toArray();
179 | assert.equal(result.length, 4);
180 | assert.equal(result[0], 0);
181 | assert.equal(result[1], 1);
182 | assert.equal(result[2], 2);
183 | assert.equal(result[3], 3);
184 | });
185 |
186 | QUnit.test("rangeClosed", function (assert) {
187 | var result = Stream.rangeClosed(0, 4).toArray();
188 | assert.equal(result.length, 5);
189 | assert.equal(result[0], 0);
190 | assert.equal(result[1], 1);
191 | assert.equal(result[2], 2);
192 | assert.equal(result[3], 3);
193 | assert.equal(result[4], 4);
194 | });
195 |
196 | QUnit.test("generate", function (assert) {
197 | var result = Stream
198 | .generate(Math.random)
199 | .limit(10)
200 | .toArray();
201 |
202 | assert.equal(result.length, 10);
203 | });
204 |
205 | QUnit.test("iterate", function (assert) {
206 | var result = Stream
207 | .iterate(1, function (seed) {
208 | return seed * 2;
209 | })
210 | .limit(11)
211 | .toArray();
212 |
213 | assert.equal(result.length, 11);
214 | assert.equal(result[0], 1);
215 | assert.equal(result[1], 2);
216 | assert.equal(result[2], 4);
217 | assert.equal(result[3], 8);
218 | assert.equal(result[4], 16);
219 | assert.equal(result[5], 32);
220 | assert.equal(result[6], 64);
221 | assert.equal(result[7], 128);
222 | assert.equal(result[8], 256);
223 | assert.equal(result[9], 512);
224 | assert.equal(result[10], 1024);
225 | });
226 |
--------------------------------------------------------------------------------
/test/test-count.js:
--------------------------------------------------------------------------------
1 | QUnit.test("count", function (assert) {
2 | var result = Stream([1, 2, 3, 4]).count();
3 | assert.equal(result, 4);
4 | });
5 |
6 | QUnit.test("count empty", function (assert) {
7 | var result = Stream([]).count();
8 | assert.equal(result, 0);
9 | });
--------------------------------------------------------------------------------
/test/test-distinct.js:
--------------------------------------------------------------------------------
1 | QUnit.test("distinct", function (assert) {
2 | var result = Stream([1, 3, 3, 1])
3 | .distinct()
4 | .toArray();
5 |
6 | assert.equal(result.length, 2);
7 | assert.equal(result[0], 1);
8 | assert.equal(result[1], 3);
9 | });
10 |
11 | QUnit.test("distinct empty", function (assert) {
12 | var result = Stream([])
13 | .distinct()
14 | .toArray();
15 |
16 | assert.equal(result.length, 0);
17 | });
--------------------------------------------------------------------------------
/test/test-dropWhile.js:
--------------------------------------------------------------------------------
1 | QUnit.test("dropWhile num array", function (assert) {
2 | var data = [1, 2, 3, 2, 1];
3 |
4 | var result = Stream(data)
5 | .dropWhile(function (num) {
6 | return num < 3;
7 | })
8 | .toArray();
9 |
10 | assert.equal(result.length, 3);
11 | assert.equal(result[0], 3);
12 | assert.equal(result[1], 2);
13 | assert.equal(result[2], 1);
14 |
15 | // assert original data is untouched
16 | assert.equal(data.length, 5);
17 | assert.equal(data[0], 1);
18 | assert.equal(data[1], 2);
19 | assert.equal(data[2], 3);
20 | assert.equal(data[3], 2);
21 | assert.equal(data[4], 1);
22 | });
23 |
24 | QUnit.test("dropWhile object", function (assert) {
25 | var data = {a: 1, b: 2, c: 3, d: 1};
26 |
27 | var result = Stream(data)
28 | .dropWhile(function (num) {
29 | return num < 3;
30 | })
31 | .toArray();
32 |
33 | assert.equal(result.length, 2);
34 | assert.equal(result[0], 3);
35 | assert.equal(result[1], 1);
36 |
37 | // assert original data is untouched
38 | assert.equal(data.a, 1);
39 | assert.equal(data.b, 2);
40 | assert.equal(data.c, 3);
41 | assert.equal(data.d, 1);
42 | });
43 |
44 | QUnit.test("dropWhile empty", function (assert) {
45 | var result = Stream([])
46 | .dropWhile(function () {
47 | return true;
48 | })
49 | .toArray();
50 |
51 | assert.equal(result.length, 0);
52 | });
53 |
54 | QUnit.test("dropWhile via regexp literal", function (assert) {
55 | var data = ["a1", "a2", "b3", "a4"];
56 |
57 | var result = Stream(data)
58 | .dropWhile(/a.*/)
59 | .toArray();
60 |
61 | assert.equal(result.length, 2);
62 | assert.equal(result[0], "b3");
63 | assert.equal(result[1], "a4");
64 |
65 | // assert original data is untouched
66 | assert.equal(data.length, 4);
67 | assert.equal(data[0], "a1");
68 | assert.equal(data[1], "a2");
69 | assert.equal(data[2], "b3");
70 | assert.equal(data[3], "a4");
71 | });
72 |
73 | QUnit.test("dropWhile via regexp object", function (assert) {
74 | var data = ["a1", "a2", "b3", "a4"];
75 |
76 | var result = Stream(data)
77 | .dropWhile(new RegExp("a.*"))
78 | .toArray();
79 |
80 | assert.equal(result.length, 2);
81 | assert.equal(result[0], "b3");
82 | assert.equal(result[1], "a4");
83 |
84 | // assert original data is untouched
85 | assert.equal(data.length, 4);
86 | assert.equal(data[0], "a1");
87 | assert.equal(data[1], "a2");
88 | assert.equal(data[2], "b3");
89 | assert.equal(data[3], "a4");
90 | });
91 |
92 | QUnit.test("dropWhile via sample object (depth=1)", function (assert) {
93 | var data = [
94 | {a: 1, b: 1},
95 | {a: 1, b: 2},
96 | {a: 2, b: 3},
97 | {a: 1, b: 4}
98 | ];
99 |
100 | var result = Stream(data)
101 | .dropWhile({a: 1})
102 | .toArray();
103 |
104 | assert.equal(result.length, 2);
105 | assert.equal(result[0].a, 2);
106 | assert.equal(result[0].b, 3);
107 | assert.equal(result[1].a, 1);
108 | assert.equal(result[1].b, 4);
109 | });
110 |
111 | QUnit.test("dropWhile via sample object (depth=2)", function (assert) {
112 | var data = [
113 | {a: 1, b: 1, c: {x: "x1"}},
114 | {a: 1, b: 2, c: {x: "x1"}},
115 | {a: 2, b: 3, c: {x: "x3"}},
116 | {a: 1, b: 4, c: {x: "x1"}}
117 | ];
118 |
119 | var result = Stream(data)
120 | .dropWhile({a: 1, c: {x: "x1"}})
121 | .toArray();
122 |
123 | assert.equal(result.length, 2);
124 | assert.equal(result[0].a, 2);
125 | assert.equal(result[0].b, 3);
126 | assert.equal(result[0].c.x, "x3");
127 | assert.equal(result[1].a, 1);
128 | assert.equal(result[1].b, 4);
129 | assert.equal(result[1].c.x, "x1");
130 | });
--------------------------------------------------------------------------------
/test/test-examples.js:
--------------------------------------------------------------------------------
1 | QUnit.test("filter - flatMap - map - distinct - filter - join", function (assert) {
2 | var people = [];
3 |
4 | var names = Stream(people)
5 | .filter({married: true})
6 | .flatMap("children")
7 | .map("firstName")
8 | .distinct()
9 | .filter(/a.*/i)
10 | .join(", ");
11 |
12 | assert.equal(names, "");
13 | });
14 |
15 | QUnit.test("filter - map - toArray", function (assert) {
16 | var numFilter = 0;
17 | var numMap = 0;
18 |
19 | var data = [1, 2, 3, 4];
20 |
21 | var result =
22 | Stream(data)
23 | .filter(function (num) {
24 | numFilter++;
25 | return num % 2 === 1;
26 | })
27 | .map(function (num) {
28 | numMap++;
29 | return "obj" + num;
30 | })
31 | .toArray();
32 |
33 | assert.equal(result.length, 2);
34 | assert.equal(result[0], 'obj1');
35 | assert.equal(result[1], 'obj3');
36 | assert.equal(numFilter, 4);
37 | assert.equal(numMap, 2);
38 |
39 | // assert original data is untouched
40 | assert.equal(data.length, 4);
41 | assert.equal(data[0], 1);
42 | assert.equal(data[1], 2);
43 | assert.equal(data[2], 3);
44 | assert.equal(data[3], 4);
45 | });
46 |
47 | var createParents = function (numParents, numChildren) {
48 | return Stream
49 | .range(0, numParents)
50 | .map(function (num) {
51 | return {
52 | parentId: num,
53 | type: 'parent',
54 | children: []
55 | };
56 | })
57 | .peek(function (parent) {
58 | parent.children = Stream
59 | .range(0, numChildren)
60 | .map(function (num) {
61 | return {
62 | childId: num,
63 | type: 'child',
64 | parent: parent
65 | };
66 | })
67 | .toArray();
68 | })
69 | .toArray();
70 | };
71 |
72 | QUnit.test("parent / children 1", function (assert) {
73 | var parents = createParents(5, 3);
74 |
75 | assert.equal(parents.length, 5);
76 |
77 | for (var i = 0; i < parents.length; i++) {
78 | var parent = parents[i];
79 | assert.equal(parent.parentId, i);
80 | assert.equal(parent.type, 'parent');
81 | assert.equal(parent.children.length, 3);
82 | for (var j = 0; j < parent.children.length; j++) {
83 | var child = parent.children[j];
84 | assert.equal(child.childId, j);
85 | assert.equal(child.type, 'child');
86 | assert.equal(child.parent, parent);
87 | }
88 | }
89 | });
90 |
91 | QUnit.test("parent / children 2", function (assert) {
92 | var parents = createParents(5, 3);
93 |
94 | var children = Stream(parents)
95 | .filter(function (p) {
96 | return p.parentId > 2;
97 | })
98 | .flatMap(function (p) {
99 | return p.children;
100 | })
101 | .toArray();
102 |
103 | assert.equal(children.length, 6);
104 | assert.equal(children[0].childId, 0);
105 | assert.equal(children[1].childId, 1);
106 | assert.equal(children[2].childId, 2);
107 | assert.equal(children[3].childId, 0);
108 | assert.equal(children[4].childId, 1);
109 | assert.equal(children[5].childId, 2);
110 | });
--------------------------------------------------------------------------------
/test/test-filter.js:
--------------------------------------------------------------------------------
1 | QUnit.test("filter num array", function (assert) {
2 | var data = [1, 2, 3, 4];
3 |
4 | var result = Stream(data)
5 | .filter(function (num) {
6 | return num % 2 === 1;
7 | })
8 | .toArray();
9 |
10 | assert.equal(result.length, 2);
11 | assert.equal(result[0], 1);
12 | assert.equal(result[1], 3);
13 |
14 | // assert original data is untouched
15 | assert.equal(data.length, 4);
16 | assert.equal(data[0], 1);
17 | assert.equal(data[1], 2);
18 | assert.equal(data[2], 3);
19 | assert.equal(data[3], 4);
20 | });
21 |
22 | QUnit.test("filter object array", function (assert) {
23 | var data = [{a: 1}, {a: 2}, {a: 3}, {a: 4}];
24 |
25 | var result = Stream(data)
26 | .filter(function (obj) {
27 | return obj.a % 2 === 1;
28 | })
29 | .toArray();
30 |
31 | assert.equal(result.length, 2);
32 | assert.equal(result[0].a, 1);
33 | assert.equal(result[1].a, 3);
34 |
35 | // assert original data is untouched
36 | assert.equal(data.length, 4);
37 | assert.equal(data[0].a, 1);
38 | assert.equal(data[1].a, 2);
39 | assert.equal(data[2].a, 3);
40 | assert.equal(data[3].a, 4);
41 | });
42 |
43 | QUnit.test("filter object", function (assert) {
44 | var data = {a: 1, b: 2, c: 3, d: 4};
45 |
46 | var result = Stream(data)
47 | .filter(function (num) {
48 | return num % 2 === 1;
49 | })
50 | .toArray();
51 |
52 | assert.equal(result.length, 2);
53 | assert.equal(result[0], 1);
54 | assert.equal(result[1], 3);
55 |
56 | // assert original data is untouched
57 | assert.equal(data.a, 1);
58 | assert.equal(data.b, 2);
59 | assert.equal(data.c, 3);
60 | assert.equal(data.d, 4);
61 | });
62 |
63 | QUnit.test("filter empty", function (assert) {
64 | var result = Stream([])
65 | .filter(function () {
66 | return true;
67 | })
68 | .toArray();
69 |
70 | assert.equal(result.length, 0);
71 | });
72 |
73 | QUnit.test("filter with null", function (assert) {
74 | var result = Stream([1, null, undefined, 2])
75 | .filter(function () {
76 | return true;
77 | })
78 | .toArray();
79 |
80 | assert.equal(result.length, 4);
81 | assert.equal(result[0], 1);
82 | assert.equal(result[1], null);
83 | assert.equal(result[2], undefined);
84 | assert.equal(result[3], 2);
85 | });
86 |
87 | QUnit.test("filter via regexp literal", function (assert) {
88 | var data = ["a1", "a2", "b3"];
89 |
90 | var result = Stream(data)
91 | .filter(/a.*/)
92 | .toArray();
93 |
94 | assert.equal(result.length, 2);
95 | assert.equal(result[0], "a1");
96 | assert.equal(result[1], "a2");
97 |
98 | // assert original data is untouched
99 | assert.equal(data.length, 3);
100 | assert.equal(data[0], "a1");
101 | assert.equal(data[1], "a2");
102 | assert.equal(data[2], "b3");
103 | });
104 |
105 | QUnit.test("filter via regexp object", function (assert) {
106 | var data = ["a1", "a2", "b3"];
107 |
108 | var result = Stream(data)
109 | .filter(new RegExp("a.*"))
110 | .toArray();
111 |
112 | assert.equal(result.length, 2);
113 | assert.equal(result[0], "a1");
114 | assert.equal(result[1], "a2");
115 |
116 | // assert original data is untouched
117 | assert.equal(data.length, 3);
118 | assert.equal(data[0], "a1");
119 | assert.equal(data[1], "a2");
120 | assert.equal(data[2], "b3");
121 | });
122 |
123 | QUnit.test("filter via sample object (depth=1)", function (assert) {
124 | var data = [
125 | {a: 1, b: 1},
126 | {a: 2, b: 2},
127 | {a: 1, b: 3}
128 | ];
129 |
130 | var result = Stream(data)
131 | .filter({a: 1})
132 | .toArray();
133 |
134 | assert.equal(result.length, 2);
135 | assert.equal(result[0].a, 1);
136 | assert.equal(result[0].b, 1);
137 | assert.equal(result[1].a, 1);
138 | assert.equal(result[1].b, 3);
139 | });
140 |
141 | QUnit.test("filter via sample object (depth=2)", function (assert) {
142 | var data = [
143 | {a: 1, b: 1, c: {x: "x1"}},
144 | {a: 2, b: 2, c: {x: "x2"}},
145 | {a: 1, b: 3, c: {x: "x3"}},
146 | {a: 1, b: 4, c: {x: "x1"}}
147 | ];
148 |
149 | var result = Stream(data)
150 | .filter({a: 1, c: {x: "x1"}})
151 | .toArray();
152 |
153 | assert.equal(result.length, 2);
154 | assert.equal(result[0].a, 1);
155 | assert.equal(result[0].b, 1);
156 | assert.equal(result[0].c.x, "x1");
157 | assert.equal(result[1].a, 1);
158 | assert.equal(result[1].b, 4);
159 | assert.equal(result[1].c.x, "x1");
160 | });
161 |
162 | QUnit.test("filterNull", function(assert) {
163 | var actual = Stream([1, null, 2]).filterNull().toArray();
164 | assert.deepEqual(actual, [1, 2]);
165 | });
166 |
167 | QUnit.test("filterNull performs a strict type-safe check (keeps other falsy values)", function(assert) {
168 | var actual = Stream([1, null, false, NaN, undefined, 0, ""]).filterNull().toArray();
169 | assert.deepEqual(actual, [1, false, NaN, undefined, 0, ""]);
170 | });
171 |
172 | QUnit.test("filterFalsy performs an weakly typed check", function(assert) {
173 | var actual = Stream([1, false, 2, null, NaN, undefined, 0, ""]).filterFalsy().toArray();
174 | assert.deepEqual(actual, [1, 2]);
175 | });
176 |
--------------------------------------------------------------------------------
/test/test-findFirst.js:
--------------------------------------------------------------------------------
1 | QUnit.test("findFirst", function (assert) {
2 | var result = Stream([1, 2, 3, 4])
3 | .filter(function (num) {
4 | return num % 2 === 0;
5 | })
6 | .findFirst();
7 |
8 | assert.equal(result, "[object Optional]");
9 | assert.equal(result.isPresent(), true);
10 | assert.equal(result.get(), 2);
11 | });
12 |
13 | QUnit.test("findFirst empty", function (assert) {
14 | var result = Stream([]).findFirst();
15 |
16 | assert.equal(result, "[object Optional]");
17 | assert.equal(result.isPresent(), false);
18 | });
19 |
20 | QUnit.test("findFirst object", function (assert) {
21 | var result = Stream({a: 1, b: 2}).findFirst();
22 |
23 | assert.equal(result, "[object Optional]");
24 | assert.equal(result.isPresent(), true);
25 | assert.equal(result.get(), 1);
26 | });
--------------------------------------------------------------------------------
/test/test-flatMap.js:
--------------------------------------------------------------------------------
1 | QUnit.test("flatMap num array", function (assert) {
2 | var data = [1, 2, 3];
3 |
4 | var result = Stream(data)
5 | .flatMap(function (num) {
6 | return [num, num];
7 | })
8 | .toArray();
9 |
10 | assert.equal(result.length, 6);
11 | assert.equal(result[0], 1);
12 | assert.equal(result[1], 1);
13 | assert.equal(result[2], 2);
14 | assert.equal(result[3], 2);
15 | assert.equal(result[4], 3);
16 | assert.equal(result[5], 3);
17 |
18 | // assert original data is untouched
19 | assert.equal(data.length, 3);
20 | assert.equal(data[0], 1);
21 | assert.equal(data[1], 2);
22 | assert.equal(data[2], 3);
23 | });
24 |
25 | QUnit.test("flatMap object array", function (assert) {
26 | var data = [{a: 1}, {a: 2}, {a: 3}, {a: 4}];
27 |
28 | var result = Stream(data)
29 | .flatMap(function (obj) {
30 | return [{b: obj.a}, {b: obj.a}];
31 | })
32 | .toArray();
33 |
34 | assert.equal(result.length, 8);
35 | assert.equal(result[0].b, 1);
36 | assert.equal(result[1].b, 1);
37 | assert.equal(result[2].b, 2);
38 | assert.equal(result[3].b, 2);
39 | assert.equal(result[4].b, 3);
40 | assert.equal(result[5].b, 3);
41 | assert.equal(result[6].b, 4);
42 | assert.equal(result[7].b, 4);
43 |
44 | // assert original data is untouched
45 | assert.equal(data.length, 4);
46 | assert.equal(data[0].a, 1);
47 | assert.equal(data[1].a, 2);
48 | assert.equal(data[2].a, 3);
49 | assert.equal(data[3].a, 4);
50 | });
51 |
52 | QUnit.test("flatMap empty array", function (assert) {
53 | var result = Stream([])
54 | .flatMap(function (num) {
55 | return [num, num];
56 | })
57 | .toArray();
58 |
59 | assert.equal(result.length, 0);
60 | });
61 |
62 | QUnit.test("flatMap no array return", function (assert) {
63 | var result = Stream([1, 2, 3])
64 | .flatMap(function (num) {
65 | return String(num);
66 | })
67 | .toArray();
68 |
69 | assert.equal(result.length, 3);
70 | assert.equal(result[0], "1");
71 | assert.equal(result[1], "2");
72 | assert.equal(result[2], "3");
73 | });
74 |
75 | QUnit.test("flatMap returns object", function (assert) {
76 | var result = Stream([1])
77 | .flatMap(function (num) {
78 | return {a: num, b: num};
79 | })
80 | .toArray();
81 |
82 | assert.equal(result.length, 2);
83 | assert.equal(result[0], 1);
84 | assert.equal(result[1], 1);
85 | });
86 |
87 | QUnit.test("flatMap via path (depth 1)", function (assert) {
88 | var data = [{a: [1]}, {a: [2]}, {a: [3]}, {a: [4]}];
89 |
90 | var result = Stream(data)
91 | .flatMap("a")
92 | .toArray();
93 |
94 | assert.equal(result.length, 4);
95 | assert.equal(result[0], 1);
96 | assert.equal(result[1], 2);
97 | assert.equal(result[2], 3);
98 | assert.equal(result[3], 4);
99 |
100 | // assert original data is untouched
101 | assert.equal(data.length, 4);
102 | assert.equal(data[0].a, 1);
103 | assert.equal(data[1].a, 2);
104 | assert.equal(data[2].a, 3);
105 | assert.equal(data[3].a, 4);
106 | });
107 |
108 | QUnit.test("flatMap via path (depth 2)", function (assert) {
109 | var data = [{a: {b: [1]}}, {a: {b: [2]}}, {a: {b: [3]}}, {a: {b: [4]}}];
110 |
111 | var result = Stream(data)
112 | .flatMap("a.b")
113 | .toArray();
114 |
115 | assert.equal(result.length, 4);
116 | assert.equal(result[0], 1);
117 | assert.equal(result[1], 2);
118 | assert.equal(result[2], 3);
119 | assert.equal(result[3], 4);
120 |
121 | // assert original data is untouched
122 | assert.equal(data.length, 4);
123 | assert.equal(data[0].a.b, 1);
124 | assert.equal(data[1].a.b, 2);
125 | assert.equal(data[2].a.b, 3);
126 | assert.equal(data[3].a.b, 4);
127 | });
128 |
129 | QUnit.test("flatMap via path (depth 3)", function (assert) {
130 | var data = [{a: {b: {c: [1]}}}, {a: {b: {c: [2]}}}, {a: {b: {c: [3]}}}, {a: {b: {c: [4]}}}];
131 |
132 | var result = Stream(data)
133 | .flatMap("a.b.c")
134 | .toArray();
135 |
136 | assert.equal(result.length, 4);
137 | assert.equal(result[0], 1);
138 | assert.equal(result[1], 2);
139 | assert.equal(result[2], 3);
140 | assert.equal(result[3], 4);
141 |
142 | // assert original data is untouched
143 | assert.equal(data.length, 4);
144 | assert.equal(data[0].a.b.c, 1);
145 | assert.equal(data[1].a.b.c, 2);
146 | assert.equal(data[2].a.b.c, 3);
147 | assert.equal(data[3].a.b.c, 4);
148 | });
--------------------------------------------------------------------------------
/test/test-forEach.js:
--------------------------------------------------------------------------------
1 | QUnit.test("forEach", function (assert) {
2 | var data = [];
3 |
4 | Stream([1, 2, 3, 4])
5 | .forEach(function (num) {
6 | data.push(num);
7 | });
8 |
9 | assert.equal(data.length, 4);
10 | assert.equal(data[0], 1);
11 | assert.equal(data[1], 2);
12 | assert.equal(data[2], 3);
13 | assert.equal(data[3], 4);
14 | });
15 |
16 | QUnit.test("forEach empty", function (assert) {
17 | var called = false;
18 |
19 | Stream([])
20 | .forEach(function () {
21 | called = true;
22 | });
23 |
24 | assert.equal(called, false);
25 | });
26 |
27 | QUnit.test("forEach console.log", function (assert) {
28 | Stream(["forEach"])
29 | .forEach(console.log);
30 |
31 | assert.ok(true); // assert no error
32 | });
--------------------------------------------------------------------------------
/test/test-groupBy.js:
--------------------------------------------------------------------------------
1 | QUnit.test("groupBy", function (assert) {
2 | var data = [
3 | {firstName: "Peter", lastName: "Parker"},
4 | {firstName: "Sandra", lastName: "Parker"},
5 | {firstName: "John", lastName: "Doe"}
6 | ];
7 |
8 | var map = Stream(data)
9 | .groupBy(function (obj) {
10 | return obj["lastName"];
11 | });
12 |
13 | assert.equal(map.hasOwnProperty("Parker"), true);
14 | assert.equal(map.hasOwnProperty("Doe"), true);
15 | assert.equal(map["Parker"].length, 2);
16 | assert.equal(map["Doe"].length, 1);
17 | assert.equal(map["Parker"][0], data[0]);
18 | assert.equal(map["Parker"][1], data[1]);
19 | assert.equal(map["Doe"][0], data[2]);
20 | });
21 |
22 | QUnit.test("groupBy path", function (assert) {
23 | var data = [
24 | {firstName: "Peter", lastName: "Parker"},
25 | {firstName: "Sandra", lastName: "Parker"},
26 | {firstName: "John", lastName: "Doe"}
27 | ];
28 |
29 | var map = Stream(data)
30 | .groupBy("lastName");
31 |
32 | assert.equal(map.hasOwnProperty("Parker"), true);
33 | assert.equal(map.hasOwnProperty("Doe"), true);
34 | assert.equal(map["Parker"].length, 2);
35 | assert.equal(map["Doe"].length, 1);
36 | assert.equal(map["Parker"][0], data[0]);
37 | assert.equal(map["Parker"][1], data[1]);
38 | assert.equal(map["Doe"][0], data[2]);
39 | });
40 |
41 | QUnit.test("groupBy empty", function (assert) {
42 | var map = Stream([])
43 | .groupBy(function (obj) {
44 | return obj["lastName"];
45 | });
46 |
47 | assert.equal(Object.keys(map).length, 0);
48 | });
49 |
--------------------------------------------------------------------------------
/test/test-introduction-compiled.js:
--------------------------------------------------------------------------------
1 | // I'm using Babel.js and Intellij IDEA File Watcher to automatically transpile es6 to js:
2 | // --source-maps --out-file $FileNameWithoutExtension$-compiled.js $FilePath$
3 |
4 | "use strict";
5 |
6 | QUnit.test("sample 1", function (assert) {
7 | var myList = ["a1", "a2", "b1", "c2", "c1"];
8 |
9 | var result = Stream(myList).filter(function (s) {
10 | return s.indexOf("c") === 0;
11 | }).map(function (s) {
12 | return s.toUpperCase();
13 | }).sorted().toArray();
14 |
15 | assert.equal(result.length, 2);
16 | assert.equal(result[0], "C1");
17 | assert.equal(result[1], "C2");
18 | });
19 |
20 | QUnit.test("sample 2", function (assert) {
21 | Stream(["a1", "a2", "a3"]).findFirst().ifPresent(function (first) {
22 | return assert.equal(first, "a1");
23 | });
24 |
25 | Stream.of("a1", "a2", "a3").findFirst().ifPresent(function (first) {
26 | return assert.equal(first, "a1");
27 | });
28 |
29 | var result = Stream.range(1, 4).toArray();
30 |
31 | assert.equal(result.length, 3);
32 | assert.equal(result[0], 1);
33 | assert.equal(result[1], 2);
34 | assert.equal(result[2], 3);
35 | });
36 |
37 | QUnit.test("sample 3", function (assert) {
38 | Stream.of(1, 2, 3).map(function (n) {
39 | return 2 * n + 1;
40 | }).average().ifPresent(function (avg) {
41 | return assert.equal(avg, 5);
42 | });
43 | });
44 |
45 | QUnit.test("sample 4", function (assert) {
46 | Stream.of("a1", "a2", "a3").map(function (s) {
47 | return s.slice(1);
48 | }).map(function (s) {
49 | return parseInt(s, 10);
50 | }).max().ifPresent(function (max) {
51 | return assert.equal(max, 3);
52 | });
53 | });
54 |
55 | QUnit.test("sample 5", function (assert) {
56 | Stream.of("a1", "b2", "c3").filter(function (s) {
57 | console.log("filtering: %s", s);
58 | assert.ok(false);
59 | return true;
60 | });
61 |
62 | assert.ok(true);
63 | });
64 |
65 | QUnit.test("sample 6", function (assert) {
66 | var ops = [];
67 |
68 | Stream.of("a1", "b2", "c3").filter(function (s) {
69 | ops.push("filter: " + s);
70 | return true;
71 | }).forEach(function (s) {
72 | return ops.push("forEach: " + s);
73 | });
74 |
75 | assert.equal(ops.length, 6);
76 | assert.equal(ops[0], "filter: a1");
77 | assert.equal(ops[1], "forEach: a1");
78 | assert.equal(ops[2], "filter: b2");
79 | assert.equal(ops[3], "forEach: b2");
80 | assert.equal(ops[4], "filter: c3");
81 | assert.equal(ops[5], "forEach: c3");
82 | });
83 |
84 | QUnit.test("sample 6", function (assert) {
85 | var ops = [];
86 |
87 | Stream.of("d2", "a2", "b1", "b3", "c").map(function (s) {
88 | ops.push("map: " + s);
89 | return s.toUpperCase();
90 | }).anyMatch(function (s) {
91 | ops.push("anyMatch: " + s);
92 | return s.indexOf("A") === 0;
93 | });
94 |
95 | assert.equal(ops.length, 4);
96 | assert.equal(ops[0], "map: d2");
97 | assert.equal(ops[1], "anyMatch: D2");
98 | assert.equal(ops[2], "map: a2");
99 | assert.equal(ops[3], "anyMatch: A2");
100 | });
101 |
102 | QUnit.test("sample 7", function (assert) {
103 | var ops = [];
104 |
105 | Stream.of("d2", "a2", "b1", "b3", "c").filter(function (s) {
106 | ops.push("filter: " + s);
107 | return s.indexOf("a") === 0;
108 | }).map(function (s) {
109 | ops.push("map: " + s);
110 | return s.toUpperCase();
111 | }).forEach(function (s) {
112 | return ops.push("forEach: " + s);
113 | });
114 |
115 | assert.equal(ops.length, 7);
116 | assert.equal(ops[0], "filter: d2");
117 | assert.equal(ops[1], "filter: a2");
118 | assert.equal(ops[2], "map: a2");
119 | assert.equal(ops[3], "forEach: A2");
120 | assert.equal(ops[4], "filter: b1");
121 | assert.equal(ops[5], "filter: b3");
122 | assert.equal(ops[6], "filter: c");
123 | });
124 |
125 | QUnit.test("sample 8", function (assert) {
126 | assert.throws(function () {
127 | var stream = Stream.of(1, 2, 3).filter(function (n) {
128 | return n % 2 === 1;
129 | });
130 |
131 | stream.anyMatch(function (n) {
132 | return true;
133 | }); // ok
134 | stream.toArray(); // error
135 | });
136 | });
137 |
138 | QUnit.test("sample 9", function (assert) {
139 | var odd = function odd(array) {
140 | return Stream(array).filter(function (n) {
141 | return n % 2 === 1;
142 | });
143 | };
144 |
145 | assert.equal(odd([1, 2, 3]).anyMatch(function (n) {
146 | return true;
147 | }), true);
148 | assert.equal(odd([1, 2, 3]).toArray().length, 2);
149 | });
150 |
151 | var persons = [{ name: "Max", age: 18 }, { name: "Peter", age: 23 }, { name: "Pamela", age: 23 }, { name: "David", age: 12 }];
152 |
153 | QUnit.test("sample 10", function (assert) {
154 | var groups = Stream(persons).groupBy(function (p) {
155 | return p.age;
156 | });
157 |
158 | assert.equal(groups[18].length, 1);
159 | assert.equal(groups[23].length, 2);
160 | assert.equal(groups[12].length, 1);
161 | });
162 |
163 | QUnit.test("sample 10", function (assert) {
164 | var avg = Stream(persons).map(function (p) {
165 | return p.age;
166 | }).average().get();
167 |
168 | assert.equal(avg, 19);
169 |
170 | avg = Stream(persons).map("age").average().get();
171 |
172 | assert.equal(avg, 19);
173 | });
174 |
175 | QUnit.test("sample 11", function (assert) {
176 | var phrase = Stream(persons).filter(function (p) {
177 | return p.age >= 18;
178 | }).map(function (p) {
179 | return p.name;
180 | }).join({
181 | prefix: "In Germany ",
182 | suffix: " are of legal age.",
183 | delimiter: " and "
184 | });
185 |
186 | assert.equal(phrase, "In Germany Max and Peter and Pamela are of legal age.");
187 |
188 | phrase = Stream(persons).filter(function (p) {
189 | return p.age >= 18;
190 | }).map(function (p) {
191 | return p.name;
192 | }).join(" | ");
193 |
194 | assert.equal(phrase, "Max | Peter | Pamela");
195 | });
196 |
197 | QUnit.test("sample 12", function (assert) {
198 | var result = Stream(persons).collect({
199 | supplier: function supplier() {
200 | return "[";
201 | },
202 | accumulator: function accumulator(s, p) {
203 | return s + " " + p.name.toUpperCase();
204 | },
205 | finisher: function finisher(s) {
206 | return s + " ]";
207 | }
208 | });
209 |
210 | assert.equal(result, "[ MAX PETER PAMELA DAVID ]");
211 | });
212 |
213 | QUnit.test("sample 13", function (assert) {
214 | var oldest = Stream(persons).reduce(function (p1, p2) {
215 | return p1.age > p2.age ? p1 : p2;
216 | }).get();
217 |
218 | assert.equal(oldest.name, "Pamela");
219 | });
220 |
221 | QUnit.test("sample 13", function (assert) {
222 | var result = Stream(persons).sort("age").reverse().reduce({ names: [], sumOfAges: 0 }, function (res, p) {
223 | res.names.push(p.name);
224 | res.sumOfAges += p.age;
225 | return res;
226 | });
227 |
228 | assert.equal(result.names.length, 4);
229 | assert.equal(result.names[0], "Pamela");
230 | assert.equal(result.names[1], "Peter");
231 | assert.equal(result.names[2], "Max");
232 | assert.equal(result.names[3], "David");
233 | assert.equal(result.sumOfAges, 76);
234 | });
235 |
236 | QUnit.test("sample 14", function (assert) {
237 | var marked1$0 = [fibonacci].map(regeneratorRuntime.mark);
238 |
239 | function fibonacci() {
240 | var prev, cur, _ref;
241 |
242 | return regeneratorRuntime.wrap(function fibonacci$(context$2$0) {
243 | while (1) switch (context$2$0.prev = context$2$0.next) {
244 | case 0:
245 | prev = 0;
246 | cur = 1;
247 |
248 | case 2:
249 | if (!true) {
250 | context$2$0.next = 10;
251 | break;
252 | }
253 |
254 | _ref = [cur, prev + cur];
255 | prev = _ref[0];
256 | cur = _ref[1];
257 | context$2$0.next = 8;
258 | return cur;
259 |
260 | case 8:
261 | context$2$0.next = 2;
262 | break;
263 |
264 | case 10:
265 | case "end":
266 | return context$2$0.stop();
267 | }
268 | }, marked1$0[0], this);
269 | }
270 |
271 | var fib = Stream(fibonacci()).filter(function (n) {
272 | return n % 2;
273 | }).takeWhile(function (n) {
274 | return n < 50;
275 | }).toArray();
276 |
277 | assert.equal(fib.length, 5);
278 | assert.equal(fib[0], 1);
279 | assert.equal(fib[1], 3);
280 | assert.equal(fib[2], 5);
281 | assert.equal(fib[3], 13);
282 | assert.equal(fib[4], 21);
283 | });
284 |
285 | //# sourceMappingURL=test-introduction-compiled.js.map
--------------------------------------------------------------------------------
/test/test-introduction-compiled.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"sources":["test-introduction.es6"],"names":[],"mappings":"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","file":"test-introduction-compiled.js","sourcesContent":["// I'm using Babel.js and Intellij IDEA File Watcher to automatically transpile es6 to js:\n// --source-maps --out-file $FileNameWithoutExtension$-compiled.js $FilePath$\n\nQUnit.test(\"sample 1\", function (assert) {\n let myList = [\"a1\", \"a2\", \"b1\", \"c2\", \"c1\"];\n\n let result = Stream(myList)\n .filter(s => s.indexOf(\"c\") === 0)\n .map(s => s.toUpperCase())\n .sorted()\n .toArray();\n\n assert.equal(result.length, 2);\n assert.equal(result[0], \"C1\");\n assert.equal(result[1], \"C2\");\n});\n\nQUnit.test(\"sample 2\", function (assert) {\n Stream([\"a1\", \"a2\", \"a3\"])\n .findFirst()\n .ifPresent(first => assert.equal(first, \"a1\"));\n\n Stream.of(\"a1\", \"a2\", \"a3\")\n .findFirst()\n .ifPresent(first => assert.equal(first, \"a1\"));\n\n let result = Stream\n .range(1, 4)\n .toArray();\n\n assert.equal(result.length, 3);\n assert.equal(result[0], 1);\n assert.equal(result[1], 2);\n assert.equal(result[2], 3);\n});\n\nQUnit.test(\"sample 3\", function (assert) {\n Stream.of(1, 2, 3)\n .map(n => 2 * n + 1)\n .average()\n .ifPresent(avg => assert.equal(avg, 5.0));\n});\n\nQUnit.test(\"sample 4\", function (assert) {\n Stream.of(\"a1\", \"a2\", \"a3\")\n .map(s => s.slice(1))\n .map(s => parseInt(s, 10))\n .max()\n .ifPresent(max => assert.equal(max, 3));\n});\n\nQUnit.test(\"sample 5\", function (assert) {\n Stream.of(\"a1\", \"b2\", \"c3\")\n .filter(s => {\n console.log(\"filtering: %s\", s);\n assert.ok(false);\n return true;\n });\n\n assert.ok(true);\n});\n\nQUnit.test(\"sample 6\", function (assert) {\n let ops = [];\n\n Stream.of(\"a1\", \"b2\", \"c3\")\n .filter(s => {\n ops.push(\"filter: \" + s);\n return true;\n })\n .forEach(s => ops.push(\"forEach: \" + s));\n\n assert.equal(ops.length, 6);\n assert.equal(ops[0], \"filter: a1\");\n assert.equal(ops[1], \"forEach: a1\");\n assert.equal(ops[2], \"filter: b2\");\n assert.equal(ops[3], \"forEach: b2\");\n assert.equal(ops[4], \"filter: c3\");\n assert.equal(ops[5], \"forEach: c3\");\n});\n\nQUnit.test(\"sample 6\", function (assert) {\n let ops = [];\n\n Stream.of(\"d2\", \"a2\", \"b1\", \"b3\", \"c\")\n .map(s => {\n ops.push(\"map: \" + s);\n return s.toUpperCase();\n })\n .anyMatch(s => {\n ops.push(\"anyMatch: \" + s);\n return s.indexOf(\"A\") === 0;\n });\n\n assert.equal(ops.length, 4);\n assert.equal(ops[0], \"map: d2\");\n assert.equal(ops[1], \"anyMatch: D2\");\n assert.equal(ops[2], \"map: a2\");\n assert.equal(ops[3], \"anyMatch: A2\");\n});\n\nQUnit.test(\"sample 7\", function (assert) {\n let ops = [];\n\n Stream.of(\"d2\", \"a2\", \"b1\", \"b3\", \"c\")\n .filter(s => {\n ops.push(\"filter: \" + s);\n return s.indexOf(\"a\") === 0;\n })\n .map(s => {\n ops.push(\"map: \" + s);\n return s.toUpperCase();\n })\n .forEach(s => ops.push(\"forEach: \" + s));\n\n assert.equal(ops.length, 7);\n assert.equal(ops[0], \"filter: d2\");\n assert.equal(ops[1], \"filter: a2\");\n assert.equal(ops[2], \"map: a2\");\n assert.equal(ops[3], \"forEach: A2\");\n assert.equal(ops[4], \"filter: b1\");\n assert.equal(ops[5], \"filter: b3\");\n assert.equal(ops[6], \"filter: c\");\n});\n\nQUnit.test(\"sample 8\", function (assert) {\n assert.throws(function () {\n let stream = Stream.of(1, 2, 3)\n .filter(n => n % 2 === 1);\n\n stream.anyMatch(n => true); // ok\n stream.toArray(); // error\n });\n});\n\nQUnit.test(\"sample 9\", function (assert) {\n let odd = array =>\n Stream(array).filter(n => n % 2 === 1);\n\n assert.equal(odd([1, 2, 3]).anyMatch(n => true), true);\n assert.equal(odd([1, 2, 3]).toArray().length, 2);\n});\n\nvar persons = [\n {name: \"Max\", age: 18},\n {name: \"Peter\", age: 23},\n {name: \"Pamela\", age: 23},\n {name: \"David\", age: 12}\n];\n\nQUnit.test(\"sample 10\", function (assert) {\n var groups = Stream(persons)\n .groupBy(p => p.age);\n\n assert.equal(groups[18].length, 1);\n assert.equal(groups[23].length, 2);\n assert.equal(groups[12].length, 1);\n});\n\nQUnit.test(\"sample 10\", function (assert) {\n var avg = Stream(persons)\n .map(p => p.age)\n .average()\n .get();\n\n assert.equal(avg, 19);\n\n avg = Stream(persons)\n .map(\"age\")\n .average()\n .get();\n\n assert.equal(avg, 19);\n});\n\nQUnit.test(\"sample 11\", function (assert) {\n var phrase = Stream(persons)\n .filter(p => p.age >= 18)\n .map(p => p.name)\n .join({\n prefix: 'In Germany ',\n suffix: ' are of legal age.',\n delimiter: ' and '\n });\n\n assert.equal(phrase, 'In Germany Max and Peter and Pamela are of legal age.');\n\n phrase = Stream(persons)\n .filter(p => p.age >= 18)\n .map(p => p.name)\n .join(\" | \");\n\n assert.equal(phrase, 'Max | Peter | Pamela');\n});\n\nQUnit.test(\"sample 12\", function (assert) {\n var result = Stream(persons)\n .collect({\n supplier: () => '[',\n accumulator: (s, p) => s + ' ' + p.name.toUpperCase(),\n finisher: (s) => s + ' ]'\n });\n\n assert.equal(result, \"[ MAX PETER PAMELA DAVID ]\");\n});\n\nQUnit.test(\"sample 13\", function (assert) {\n var oldest = Stream(persons)\n .reduce((p1, p2) => p1.age > p2.age ? p1 : p2)\n .get();\n\n assert.equal(oldest.name, \"Pamela\");\n});\n\nQUnit.test(\"sample 13\", function (assert) {\n var result = Stream(persons)\n .sort(\"age\")\n .reverse()\n .reduce({names: [], sumOfAges: 0}, (res, p) => {\n res.names.push(p.name);\n res.sumOfAges += p.age;\n return res;\n });\n\n assert.equal(result.names.length, 4);\n assert.equal(result.names[0], \"Pamela\");\n assert.equal(result.names[1], \"Peter\");\n assert.equal(result.names[2], \"Max\");\n assert.equal(result.names[3], \"David\");\n assert.equal(result.sumOfAges, 76);\n});\n\nQUnit.test(\"sample 14\", function (assert) {\n function* fibonacci() {\n let [prev, cur] = [0, 1];\n while (true) {\n [prev, cur] = [cur, prev + cur];\n yield cur;\n }\n }\n\n var fib = Stream(fibonacci())\n .filter(n => n % 2)\n .takeWhile(n => n < 50)\n .toArray();\n\n assert.equal(fib.length, 5);\n assert.equal(fib[0], 1);\n assert.equal(fib[1], 3);\n assert.equal(fib[2], 5);\n assert.equal(fib[3], 13);\n assert.equal(fib[4], 21);\n});"]}
--------------------------------------------------------------------------------
/test/test-introduction.es6:
--------------------------------------------------------------------------------
1 | // I'm using Babel.js and Intellij IDEA File Watcher to automatically transpile es6 to js:
2 | // --source-maps --out-file $FileNameWithoutExtension$-compiled.js $FilePath$
3 |
4 | QUnit.test("sample 1", function (assert) {
5 | let myList = ["a1", "a2", "b1", "c2", "c1"];
6 |
7 | let result = Stream(myList)
8 | .filter(s => s.indexOf("c") === 0)
9 | .map(s => s.toUpperCase())
10 | .sorted()
11 | .toArray();
12 |
13 | assert.equal(result.length, 2);
14 | assert.equal(result[0], "C1");
15 | assert.equal(result[1], "C2");
16 | });
17 |
18 | QUnit.test("sample 2", function (assert) {
19 | Stream(["a1", "a2", "a3"])
20 | .findFirst()
21 | .ifPresent(first => assert.equal(first, "a1"));
22 |
23 | Stream.of("a1", "a2", "a3")
24 | .findFirst()
25 | .ifPresent(first => assert.equal(first, "a1"));
26 |
27 | let result = Stream
28 | .range(1, 4)
29 | .toArray();
30 |
31 | assert.equal(result.length, 3);
32 | assert.equal(result[0], 1);
33 | assert.equal(result[1], 2);
34 | assert.equal(result[2], 3);
35 | });
36 |
37 | QUnit.test("sample 3", function (assert) {
38 | Stream.of(1, 2, 3)
39 | .map(n => 2 * n + 1)
40 | .average()
41 | .ifPresent(avg => assert.equal(avg, 5.0));
42 | });
43 |
44 | QUnit.test("sample 4", function (assert) {
45 | Stream.of("a1", "a2", "a3")
46 | .map(s => s.slice(1))
47 | .map(s => parseInt(s, 10))
48 | .max()
49 | .ifPresent(max => assert.equal(max, 3));
50 | });
51 |
52 | QUnit.test("sample 5", function (assert) {
53 | Stream.of("a1", "b2", "c3")
54 | .filter(s => {
55 | console.log("filtering: %s", s);
56 | assert.ok(false);
57 | return true;
58 | });
59 |
60 | assert.ok(true);
61 | });
62 |
63 | QUnit.test("sample 6", function (assert) {
64 | let ops = [];
65 |
66 | Stream.of("a1", "b2", "c3")
67 | .filter(s => {
68 | ops.push("filter: " + s);
69 | return true;
70 | })
71 | .forEach(s => ops.push("forEach: " + s));
72 |
73 | assert.equal(ops.length, 6);
74 | assert.equal(ops[0], "filter: a1");
75 | assert.equal(ops[1], "forEach: a1");
76 | assert.equal(ops[2], "filter: b2");
77 | assert.equal(ops[3], "forEach: b2");
78 | assert.equal(ops[4], "filter: c3");
79 | assert.equal(ops[5], "forEach: c3");
80 | });
81 |
82 | QUnit.test("sample 6", function (assert) {
83 | let ops = [];
84 |
85 | Stream.of("d2", "a2", "b1", "b3", "c")
86 | .map(s => {
87 | ops.push("map: " + s);
88 | return s.toUpperCase();
89 | })
90 | .anyMatch(s => {
91 | ops.push("anyMatch: " + s);
92 | return s.indexOf("A") === 0;
93 | });
94 |
95 | assert.equal(ops.length, 4);
96 | assert.equal(ops[0], "map: d2");
97 | assert.equal(ops[1], "anyMatch: D2");
98 | assert.equal(ops[2], "map: a2");
99 | assert.equal(ops[3], "anyMatch: A2");
100 | });
101 |
102 | QUnit.test("sample 7", function (assert) {
103 | let ops = [];
104 |
105 | Stream.of("d2", "a2", "b1", "b3", "c")
106 | .filter(s => {
107 | ops.push("filter: " + s);
108 | return s.indexOf("a") === 0;
109 | })
110 | .map(s => {
111 | ops.push("map: " + s);
112 | return s.toUpperCase();
113 | })
114 | .forEach(s => ops.push("forEach: " + s));
115 |
116 | assert.equal(ops.length, 7);
117 | assert.equal(ops[0], "filter: d2");
118 | assert.equal(ops[1], "filter: a2");
119 | assert.equal(ops[2], "map: a2");
120 | assert.equal(ops[3], "forEach: A2");
121 | assert.equal(ops[4], "filter: b1");
122 | assert.equal(ops[5], "filter: b3");
123 | assert.equal(ops[6], "filter: c");
124 | });
125 |
126 | QUnit.test("sample 8", function (assert) {
127 | assert.throws(function () {
128 | let stream = Stream.of(1, 2, 3)
129 | .filter(n => n % 2 === 1);
130 |
131 | stream.anyMatch(n => true); // ok
132 | stream.toArray(); // error
133 | });
134 | });
135 |
136 | QUnit.test("sample 9", function (assert) {
137 | let odd = array =>
138 | Stream(array).filter(n => n % 2 === 1);
139 |
140 | assert.equal(odd([1, 2, 3]).anyMatch(n => true), true);
141 | assert.equal(odd([1, 2, 3]).toArray().length, 2);
142 | });
143 |
144 | var persons = [
145 | {name: "Max", age: 18},
146 | {name: "Peter", age: 23},
147 | {name: "Pamela", age: 23},
148 | {name: "David", age: 12}
149 | ];
150 |
151 | QUnit.test("sample 10", function (assert) {
152 | var groups = Stream(persons)
153 | .groupBy(p => p.age);
154 |
155 | assert.equal(groups[18].length, 1);
156 | assert.equal(groups[23].length, 2);
157 | assert.equal(groups[12].length, 1);
158 | });
159 |
160 | QUnit.test("sample 10", function (assert) {
161 | var avg = Stream(persons)
162 | .map(p => p.age)
163 | .average()
164 | .get();
165 |
166 | assert.equal(avg, 19);
167 |
168 | avg = Stream(persons)
169 | .map("age")
170 | .average()
171 | .get();
172 |
173 | assert.equal(avg, 19);
174 | });
175 |
176 | QUnit.test("sample 11", function (assert) {
177 | var phrase = Stream(persons)
178 | .filter(p => p.age >= 18)
179 | .map(p => p.name)
180 | .join({
181 | prefix: 'In Germany ',
182 | suffix: ' are of legal age.',
183 | delimiter: ' and '
184 | });
185 |
186 | assert.equal(phrase, 'In Germany Max and Peter and Pamela are of legal age.');
187 |
188 | phrase = Stream(persons)
189 | .filter(p => p.age >= 18)
190 | .map(p => p.name)
191 | .join(" | ");
192 |
193 | assert.equal(phrase, 'Max | Peter | Pamela');
194 | });
195 |
196 | QUnit.test("sample 12", function (assert) {
197 | var result = Stream(persons)
198 | .collect({
199 | supplier: () => '[',
200 | accumulator: (s, p) => s + ' ' + p.name.toUpperCase(),
201 | finisher: (s) => s + ' ]'
202 | });
203 |
204 | assert.equal(result, "[ MAX PETER PAMELA DAVID ]");
205 | });
206 |
207 | QUnit.test("sample 13", function (assert) {
208 | var oldest = Stream(persons)
209 | .reduce((p1, p2) => p1.age > p2.age ? p1 : p2)
210 | .get();
211 |
212 | assert.equal(oldest.name, "Pamela");
213 | });
214 |
215 | QUnit.test("sample 13", function (assert) {
216 | var result = Stream(persons)
217 | .sort("age")
218 | .reverse()
219 | .reduce({names: [], sumOfAges: 0}, (res, p) => {
220 | res.names.push(p.name);
221 | res.sumOfAges += p.age;
222 | return res;
223 | });
224 |
225 | assert.equal(result.names.length, 4);
226 | assert.equal(result.names[0], "Pamela");
227 | assert.equal(result.names[1], "Peter");
228 | assert.equal(result.names[2], "Max");
229 | assert.equal(result.names[3], "David");
230 | assert.equal(result.sumOfAges, 76);
231 | });
232 |
233 | QUnit.test("sample 14", function (assert) {
234 | function* fibonacci() {
235 | let [prev, cur] = [0, 1];
236 | while (true) {
237 | [prev, cur] = [cur, prev + cur];
238 | yield cur;
239 | }
240 | }
241 |
242 | var fib = Stream(fibonacci())
243 | .filter(n => n % 2)
244 | .takeWhile(n => n < 50)
245 | .toArray();
246 |
247 | assert.equal(fib.length, 5);
248 | assert.equal(fib[0], 1);
249 | assert.equal(fib[1], 3);
250 | assert.equal(fib[2], 5);
251 | assert.equal(fib[3], 13);
252 | assert.equal(fib[4], 21);
253 | });
--------------------------------------------------------------------------------
/test/test-iterator.js:
--------------------------------------------------------------------------------
1 | QUnit.test("iterator", function (assert) {
2 | var data = [1, 2, 3, 4];
3 |
4 | var iterator = Stream(data)
5 | .map(function (num) {
6 | return "obj" + num;
7 | })
8 | .iterator();
9 |
10 | var result = [], current = iterator.next();
11 | while (true) {
12 | result.push(current.value);
13 | if (current.done) {
14 | break;
15 | }
16 | current = iterator.next();
17 | }
18 |
19 | assert.equal(result.length, 4);
20 | assert.equal(result[0], 'obj1');
21 | assert.equal(result[1], 'obj2');
22 | assert.equal(result[2], 'obj3');
23 | assert.equal(result[3], 'obj4');
24 |
25 | // assert original data is untouched
26 | assert.equal(data.length, 4);
27 | assert.equal(data[0], 1);
28 | assert.equal(data[1], 2);
29 | assert.equal(data[2], 3);
30 | assert.equal(data[3], 4);
31 | });
32 |
33 | QUnit.test("iterator consumes stream", function (assert) {
34 | assert.throws(function () {
35 | var stream = Stream([1, 2, 3, 4])
36 | .map(function (num) {
37 | return "obj" + num;
38 | });
39 |
40 | var iterator = stream.iterator();
41 | iterator.next();
42 | stream.toArray();
43 | });
44 | });
--------------------------------------------------------------------------------
/test/test-joining.js:
--------------------------------------------------------------------------------
1 | QUnit.test("joining", function (assert) {
2 | var result = Stream([1, 2, 3, 4]).joining();
3 | assert.equal(result, "1234");
4 | });
5 |
6 | QUnit.test("joining empty", function (assert) {
7 | var result = Stream([]).joining();
8 | assert.equal(result, "");
9 | });
10 |
11 | QUnit.test("joining with options", function (assert) {
12 | var result = Stream([1, 2, 3, 4])
13 | .joining({
14 | prefix: "PREFIX_",
15 | suffix: "_SUFFIX",
16 | delimiter: ","
17 | });
18 | assert.equal(result, "PREFIX_1,2,3,4_SUFFIX");
19 | });
20 |
21 | QUnit.test("joining with delimiter", function (assert) {
22 | var result = Stream([1, 2, 3, 4])
23 | .joining(',');
24 | assert.equal(result, "1,2,3,4");
25 | });
26 |
27 | QUnit.test("joining empty with options", function (assert) {
28 | var result = Stream([])
29 | .joining({
30 | prefix: "PREFIX_",
31 | suffix: "_SUFFIX",
32 | delimiter: ","
33 | });
34 | assert.equal(result, "PREFIX__SUFFIX");
35 | });
--------------------------------------------------------------------------------
/test/test-limit.js:
--------------------------------------------------------------------------------
1 | QUnit.test("limit", function (assert) {
2 | var result = Stream([1, 2, 3, 4])
3 | .limit(2)
4 | .toArray();
5 |
6 | assert.equal(result.length, 2);
7 | assert.equal(result[0], 1);
8 | assert.equal(result[1], 2);
9 | });
10 |
11 | QUnit.test("limit empty", function (assert) {
12 | var result = Stream([])
13 | .limit(1)
14 | .toArray();
15 |
16 | assert.equal(result.length, 0);
17 | });
18 |
19 | QUnit.test("limit high", function (assert) {
20 | var result = Stream([1, 2, 3, 4])
21 | .limit(10)
22 | .toArray();
23 |
24 | assert.equal(result.length, 4);
25 | assert.equal(result[0], 1);
26 | assert.equal(result[1], 2);
27 | assert.equal(result[2], 3);
28 | assert.equal(result[3], 4);
29 | });
30 |
31 | QUnit.test("limit zero", function (assert) {
32 | var result = Stream([1, 2, 3, 4])
33 | .limit(0)
34 | .toArray();
35 |
36 | assert.equal(result.length, 0);
37 | });
38 |
39 | QUnit.test("limit negative", function (assert) {
40 | var result = Stream([1, 2, 3, 4])
41 | .limit(-1)
42 | .toArray();
43 |
44 | assert.equal(result.length, 0);
45 | });
--------------------------------------------------------------------------------
/test/test-map.js:
--------------------------------------------------------------------------------
1 | QUnit.test("map num array", function (assert) {
2 | var data = [1, 2, 3, 4];
3 |
4 | var result = Stream(data)
5 | .map(function (num) {
6 | return "obj" + num;
7 | })
8 | .toArray();
9 |
10 | assert.equal(result.length, 4);
11 | assert.equal(result[0], 'obj1');
12 | assert.equal(result[1], 'obj2');
13 | assert.equal(result[2], 'obj3');
14 | assert.equal(result[3], 'obj4');
15 |
16 | // assert original data is untouched
17 | assert.equal(data.length, 4);
18 | assert.equal(data[0], 1);
19 | assert.equal(data[1], 2);
20 | assert.equal(data[2], 3);
21 | assert.equal(data[3], 4);
22 | });
23 |
24 | QUnit.test("map object array", function (assert) {
25 | var data = [{a: 1}, {a: 2}, {a: 3}, {a: 4}];
26 |
27 | var result = Stream(data)
28 | .map(function (obj) {
29 | return {b: obj.a};
30 | })
31 | .toArray();
32 |
33 | assert.equal(result.length, 4);
34 | assert.equal(result[0].b, 1);
35 | assert.equal(result[1].b, 2);
36 | assert.equal(result[2].b, 3);
37 | assert.equal(result[3].b, 4);
38 |
39 | // assert original data is untouched
40 | assert.equal(data.length, 4);
41 | assert.equal(data[0].a, 1);
42 | assert.equal(data[1].a, 2);
43 | assert.equal(data[2].a, 3);
44 | assert.equal(data[3].a, 4);
45 | });
46 |
47 | QUnit.test("map empty array", function (assert) {
48 | var result = Stream([])
49 | .map(function (num) {
50 | return "obj" + num;
51 | })
52 | .toArray();
53 |
54 | assert.equal(result.length, 0);
55 | });
56 |
57 | QUnit.test("map with null", function (assert) {
58 | var data = [1, null, undefined, 4];
59 |
60 | var result = Stream(data)
61 | .map(function (val) {
62 | return "map_" + val;
63 | })
64 | .toArray();
65 |
66 | assert.equal(result.length, 4);
67 | assert.equal(result[0], 'map_1');
68 | assert.equal(result[1], 'map_null');
69 | assert.equal(result[2], 'map_undefined');
70 | assert.equal(result[3], 'map_4');
71 |
72 | // assert original data is untouched
73 | assert.equal(data.length, 4);
74 | assert.equal(data[0], 1);
75 | assert.equal(data[1], null);
76 | assert.equal(data[2], undefined);
77 | assert.equal(data[3], 4);
78 | });
79 |
80 | QUnit.test("map via path (depth 1)", function (assert) {
81 | var data = [{a: 1}, {a: 2}, {a: 3}, {a: 4}];
82 |
83 | var result = Stream(data)
84 | .map("a")
85 | .toArray();
86 |
87 | assert.equal(result.length, 4);
88 | assert.equal(result[0], 1);
89 | assert.equal(result[1], 2);
90 | assert.equal(result[2], 3);
91 | assert.equal(result[3], 4);
92 |
93 | // assert original data is untouched
94 | assert.equal(data.length, 4);
95 | assert.equal(data[0].a, 1);
96 | assert.equal(data[1].a, 2);
97 | assert.equal(data[2].a, 3);
98 | assert.equal(data[3].a, 4);
99 | });
100 |
101 | QUnit.test("map via path (depth 3)", function (assert) {
102 | var data = [{a: {b: 1}}, {a: {b: 2}}, {a: {b: 3}}, {a: {b: 4}}];
103 |
104 | var result = Stream(data)
105 | .map("a.b")
106 | .toArray();
107 |
108 | assert.equal(result.length, 4);
109 | assert.equal(result[0], 1);
110 | assert.equal(result[1], 2);
111 | assert.equal(result[2], 3);
112 | assert.equal(result[3], 4);
113 |
114 | // assert original data is untouched
115 | assert.equal(data.length, 4);
116 | assert.equal(data[0].a.b, 1);
117 | assert.equal(data[1].a.b, 2);
118 | assert.equal(data[2].a.b, 3);
119 | assert.equal(data[3].a.b, 4);
120 | });
121 |
122 | QUnit.test("map via path (depth 3)", function (assert) {
123 | var data = [{a: {b: {c: 1}}}, {a: {b: {c: 2}}}, {a: {b: {c: 3}}}, {a: {b: {c: 4}}}];
124 |
125 | var result = Stream(data)
126 | .map("a.b.c")
127 | .toArray();
128 |
129 | assert.equal(result.length, 4);
130 | assert.equal(result[0], 1);
131 | assert.equal(result[1], 2);
132 | assert.equal(result[2], 3);
133 | assert.equal(result[3], 4);
134 |
135 | // assert original data is untouched
136 | assert.equal(data.length, 4);
137 | assert.equal(data[0].a.b.c, 1);
138 | assert.equal(data[1].a.b.c, 2);
139 | assert.equal(data[2].a.b.c, 3);
140 | assert.equal(data[3].a.b.c, 4);
141 | });
--------------------------------------------------------------------------------
/test/test-max.js:
--------------------------------------------------------------------------------
1 | QUnit.test("max", function (assert) {
2 | var result = Stream([1, 2, 3, 4]).max();
3 | assert.equal(result, "[object Optional]");
4 | assert.equal(result.isPresent(), true);
5 | assert.equal(result.get(), 4);
6 | });
7 |
8 | QUnit.test("max empty", function (assert) {
9 | var result = Stream([]).max();
10 | assert.equal(result, "[object Optional]");
11 | assert.equal(result.isPresent(), false);
12 | });
13 |
14 | QUnit.test("max (comparator)", function (assert) {
15 | var result = Stream([1, 2, 3, 4])
16 | .max(function (a, b) {
17 | if (a === b) return 0;
18 | if (a > b) return -1;
19 | return 1;
20 | });
21 |
22 | assert.equal(result, "[object Optional]");
23 | assert.equal(result.isPresent(), true);
24 | assert.equal(result.get(), 1);
25 | });
26 |
27 | QUnit.test("max (path comparator)", function (assert) {
28 | var result = Stream([{a: 1}, {a: 2}, {a: 3}])
29 | .max("a");
30 | assert.equal(result, "[object Optional]");
31 | assert.equal(result.isPresent(), true);
32 | assert.equal(result.get().a, 3);
33 | });
--------------------------------------------------------------------------------
/test/test-min.js:
--------------------------------------------------------------------------------
1 | QUnit.test("min", function (assert) {
2 | var result = Stream([1, 2, 3, 4]).min();
3 | assert.equal(result, "[object Optional]");
4 | assert.equal(result.isPresent(), true);
5 | assert.equal(result.get(), 1);
6 | });
7 |
8 | QUnit.test("min empty", function (assert) {
9 | var result = Stream([]).min();
10 | assert.equal(result, "[object Optional]");
11 | assert.equal(result.isPresent(), false);
12 | });
13 |
14 | QUnit.test("min (comparator)", function (assert) {
15 | var result = Stream([1, 2, 3, 4])
16 | .min(function (a, b) {
17 | if (a === b) return 0;
18 | if (a > b) return -1;
19 | return 1;
20 | });
21 |
22 | assert.equal(result, "[object Optional]");
23 | assert.equal(result.isPresent(), true);
24 | assert.equal(result.get(), 4);
25 | });
26 |
27 | QUnit.test("min (path comparator)", function (assert) {
28 | var result = Stream([{a: 1}, {a: 2}, {a: 3}])
29 | .min("a");
30 | assert.equal(result, "[object Optional]");
31 | assert.equal(result.isPresent(), true);
32 | assert.equal(result.get().a, 1);
33 | });
--------------------------------------------------------------------------------
/test/test-misc.js:
--------------------------------------------------------------------------------
1 | QUnit.test("toArray twice", function (assert) {
2 | assert.throws(function () {
3 | var stream = Stream([1, 2, 3, 4]);
4 | stream.toArray();
5 | stream.toArray();
6 | });
7 | });
8 |
9 | QUnit.test("aliases", function (assert) {
10 | var stream = Stream([]);
11 | assert.strictEqual(stream.toMap, stream.indexBy);
12 | assert.strictEqual(stream.partitioningBy, stream.partitionBy);
13 | assert.strictEqual(stream.groupingBy, stream.groupBy);
14 | assert.strictEqual(stream.each, stream.forEach);
15 | assert.strictEqual(stream.toList, stream.toArray);
16 | assert.strictEqual(stream.sorted, stream.sort);
17 | assert.strictEqual(stream.count, stream.size);
18 | assert.strictEqual(stream.avg, stream.average);
19 | assert.strictEqual(stream.join, stream.joining);
20 | assert.strictEqual(stream.findAny, stream.findFirst);
21 | });
22 |
23 | QUnit.test("toString", function (assert) {
24 | var stream = Stream([]);
25 | assert.equal(stream.toString(), "[object Stream]");
26 | });
27 |
28 | QUnit.test("version", function (assert) {
29 | assert.equal(Stream.VERSION, "1.6.4");
30 | });
31 |
32 | QUnit.test("noConflict", function (assert) {
33 | var MyStream = Stream.noConflict();
34 | assert.equal(window.Stream, undefined);
35 | assert.ok(MyStream !== undefined);
36 | window.Stream = MyStream;
37 | });
--------------------------------------------------------------------------------
/test/test-nashorn.js:
--------------------------------------------------------------------------------
1 | // manually run this file via terminal:
2 | //
3 | // jjs test-nashorn.js
4 |
5 | load('../stream.js');
6 |
7 | var list = new java.util.ArrayList();
8 | list.add(1);
9 | list.add(2);
10 | list.add(3);
11 |
12 | Stream(list)
13 | .filter(function (num) {
14 | return num % 2 === 1;
15 | })
16 | .forEach(function (num) {
17 | print(num);
18 | });
--------------------------------------------------------------------------------
/test/test-node.js:
--------------------------------------------------------------------------------
1 | var Stream = require("../src/stream.js");
2 |
3 | var result = Stream([5, 9, 2, 4, 8, 1])
4 | .filter(function (num) {
5 | return num % 2 === 1;
6 | })
7 | .sorted()
8 | .map(function (num) {
9 | return "odd" + num;
10 | })
11 | .toArray();
12 |
13 | console.log(result);
--------------------------------------------------------------------------------
/test/test-noneMatch.js:
--------------------------------------------------------------------------------
1 | QUnit.test("noneMatch true", function (assert) {
2 | var result = Stream([1, 2, 3, 4])
3 | .noneMatch(function (num) {
4 | return num < 0;
5 | });
6 | assert.equal(result, true);
7 | });
8 |
9 | QUnit.test("noneMatch false", function (assert) {
10 | var result = Stream([1, 2, 3, 4])
11 | .noneMatch(function (num) {
12 | return num > 3;
13 | });
14 | assert.equal(result, false);
15 | });
16 |
17 | QUnit.test("noneMatch empty", function (assert) {
18 | var result = Stream([])
19 | .noneMatch(function (num) {
20 | return num > 1;
21 | });
22 | assert.equal(result, true);
23 | });
24 |
25 | QUnit.test("noneMatch regexp true", function (assert) {
26 | var result = Stream(["a1", "a2", "a3"])
27 | .noneMatch(/b.*/);
28 | assert.equal(result, true);
29 | });
30 |
31 | QUnit.test("noneMatch regexp false", function (assert) {
32 | var result = Stream(["b1", "a2", "b3"])
33 | .noneMatch(/a.*/);
34 | assert.equal(result, false);
35 | });
36 |
37 | QUnit.test("noneMatch regexp empty", function (assert) {
38 | var result = Stream([])
39 | .noneMatch(/a.*/);
40 | assert.equal(result, true);
41 | });
42 |
43 | QUnit.test("noneMatch sample true", function (assert) {
44 | var result = Stream([{a: 1, b: 5}, {a: 2, b: 5}, {a: 3, b: 5}])
45 | .noneMatch({a: 4});
46 | assert.equal(result, true);
47 | });
48 |
49 | QUnit.test("noneMatch sample false", function (assert) {
50 | var result = Stream([{a: 1, b: 5}, {a: 2, b: 5}, {a: 3, b: 5}])
51 | .noneMatch({a: 1});
52 | assert.equal(result, false);
53 | });
54 |
55 | QUnit.test("noneMatch sample empty", function (assert) {
56 | var result = Stream([])
57 | .noneMatch({a: 1});
58 | assert.equal(result, true);
59 | });
--------------------------------------------------------------------------------
/test/test-optional.js:
--------------------------------------------------------------------------------
1 | QUnit.test("Optional get 1", function (assert) {
2 | var result = Stream.Optional.of(1).get();
3 | assert.equal(result, 1);
4 | });
5 |
6 | QUnit.test("Optional get 2", function (assert) {
7 | assert.throws(function () {
8 | Stream.Optional.ofNullable(null).get();
9 | });
10 |
11 | assert.throws(function () {
12 | Stream.Optional.ofNullable(undefined).get();
13 | });
14 | });
15 |
16 | QUnit.test("Optional of", function (assert) {
17 | assert.throws(function () {
18 | Stream.Optional.of(null);
19 | });
20 |
21 | assert.throws(function () {
22 | Stream.Optional.of(undefined);
23 | });
24 | });
25 |
26 | QUnit.test("Optional ifPresent 1", function (assert) {
27 | var result = null;
28 | Stream.Optional.of(1)
29 | .ifPresent(function () {
30 | result = "called";
31 | });
32 | assert.equal(result, "called");
33 | });
34 |
35 | QUnit.test("Optional ifPresent 2", function (assert) {
36 | var result = null;
37 | Stream.Optional.empty()
38 | .ifPresent(function () {
39 | result = "called";
40 | });
41 | assert.equal(result, null);
42 | });
43 |
44 | QUnit.test("Optional orElse 1", function (assert) {
45 | var result = Stream.Optional.of(1).orElse(2);
46 | assert.equal(result, 1);
47 | });
48 |
49 | QUnit.test("Optional orElse 2", function (assert) {
50 | var result = Stream.Optional.empty().orElse(2);
51 | assert.equal(result, 2);
52 | });
53 |
54 | QUnit.test("Optional orElseGet 1", function (assert) {
55 | var result = Stream.Optional.of(1).orElseGet(function () {
56 | return 2;
57 | });
58 | assert.equal(result, 1);
59 | });
60 |
61 | QUnit.test("Optional orElseGet 2", function (assert) {
62 | var result = Stream.Optional.empty().orElseGet(function () {
63 | return 2;
64 | });
65 | assert.equal(result, 2);
66 | });
67 |
68 | QUnit.test("Optional orElseThrow 1", function (assert) {
69 | var result = Stream.Optional.of(1).orElseThrow("error");
70 | assert.equal(result, 1);
71 | });
72 |
73 | QUnit.test("Optional orElseThrow 2", function (assert) {
74 | assert.throws(function () {
75 | Stream.Optional.empty().orElseThrow("error");
76 | });
77 | });
78 |
79 | QUnit.test("Optional filter 1", function (assert) {
80 | var optional = Stream.Optional.of(3).filter(function (num) {
81 | return num > 2;
82 | });
83 | assert.equal(optional.isPresent(), true);
84 | assert.equal(optional.get(), 3);
85 | });
86 |
87 | QUnit.test("Optional filter 2", function (assert) {
88 | var optional = Stream.Optional.of(3).filter(function (num) {
89 | return num > 3;
90 | });
91 | assert.equal(optional.isPresent(), false);
92 | });
93 |
94 | QUnit.test("Optional filter 3", function (assert) {
95 | var optional = Stream.Optional.empty().filter(function (num) {
96 | return num > 3;
97 | });
98 | assert.equal(optional.isPresent(), false);
99 | });
100 |
101 | QUnit.test("Optional map 1", function (assert) {
102 | var optional = Stream.Optional.of(3).map(function (num) {
103 | return "num" + num;
104 | });
105 | assert.equal(optional.isPresent(), true);
106 | assert.equal(optional.get(), "num3");
107 | });
108 |
109 | QUnit.test("Optional map 2", function (assert) {
110 | var optional = Stream.Optional.empty().map(function (num) {
111 | return "num" + num;
112 | });
113 | assert.equal(optional.isPresent(), false);
114 | });
115 |
116 | QUnit.test("Optional flatMap 1", function (assert) {
117 | var optional = Stream.Optional.of(3).flatMap(function (num) {
118 | return Stream.Optional.of("num" + num);
119 | });
120 | assert.equal(optional.isPresent(), true);
121 | assert.equal(optional.get(), "num3");
122 | });
123 |
124 | QUnit.test("Optional flatMap 2", function (assert) {
125 | var optional = Stream.Optional.empty().map(function (num) {
126 | return Stream.Optional.of("num" + num);
127 | });
128 | assert.equal(optional.isPresent(), false);
129 | });
130 |
131 | QUnit.test("toString", function (assert) {
132 | var optional = Stream.Optional.empty();
133 | assert.equal(optional.toString(), "[object Optional]");
134 | });
--------------------------------------------------------------------------------
/test/test-partitionBy.js:
--------------------------------------------------------------------------------
1 | QUnit.test("partitionBy predicate", function (assert) {
2 | var data = [
3 | {firstName: "Peter", lastName: "Parker"},
4 | {firstName: "Sandra", lastName: "Parker"},
5 | {firstName: "John", lastName: "Doe"}
6 | ];
7 |
8 | var result = Stream(data)
9 | .partitionBy(function (person) {
10 | return person.lastName === 'Parker';
11 | });
12 |
13 | assert.equal(result[true].length, 2);
14 | assert.equal(result[false].length, 1);
15 | assert.equal(result[true][0], data[0]);
16 | assert.equal(result[true][1], data[1]);
17 | assert.equal(result[false][0], data[2]);
18 | });
19 |
20 | QUnit.test("partitionBy sample object", function (assert) {
21 | var data = [
22 | {firstName: "Peter", lastName: "Parker"},
23 | {firstName: "Sandra", lastName: "Parker"},
24 | {firstName: "John", lastName: "Doe"}
25 | ];
26 |
27 | var result = Stream(data)
28 | .partitionBy({lastName: 'Parker'});
29 |
30 | assert.equal(result[true].length, 2);
31 | assert.equal(result[false].length, 1);
32 | assert.equal(result[true][0], data[0]);
33 | assert.equal(result[true][1], data[1]);
34 | assert.equal(result[false][0], data[2]);
35 | });
36 |
37 | QUnit.test("partitionBy regexp", function (assert) {
38 | var result = Stream(["a1", "a2", "b1"])
39 | .partitionBy(/a.*/);
40 |
41 | assert.equal(result[true].length, 2);
42 | assert.equal(result[false].length, 1);
43 | assert.equal(result[true][0], "a1");
44 | assert.equal(result[true][1], "a2");
45 | assert.equal(result[false][0], "b1");
46 | });
47 |
48 | QUnit.test("partitionBy predicate empty", function (assert) {
49 | var result = Stream([])
50 | .partitionBy(function (person) {
51 | return person.lastName === 'Parker';
52 | });
53 |
54 | assert.equal(result[true].length, 0);
55 | assert.equal(result[false].length, 0);
56 | });
57 |
58 | QUnit.test("partitionBy size", function (assert) {
59 | var data = Stream
60 | .range(0, 25)
61 | .toArray();
62 |
63 | var result = Stream(data)
64 | .partitionBy(10);
65 |
66 | assert.equal(result.length, 3);
67 | assert.equal(result[0].length, 10);
68 | assert.equal(result[1].length, 10);
69 | assert.equal(result[2].length, 5);
70 |
71 | for (var i = 0; i < result.length; i++) {
72 | var partition = result[i];
73 | for (var j = 0; j < partition.length; j++) {
74 | var obj = partition[j];
75 | assert.equal(obj, j + (i * 10));
76 | }
77 | }
78 | });
79 |
80 | QUnit.test("partitionBy size empty", function (assert) {
81 | var result = Stream([])
82 | .partitionBy(10);
83 |
84 | assert.equal(Object.keys(result).length, 0);
85 | });
--------------------------------------------------------------------------------
/test/test-peek.js:
--------------------------------------------------------------------------------
1 | QUnit.test("peek", function (assert) {
2 | var poke = [];
3 | var result = Stream([1, 2, 3, 4])
4 | .peek(function (num) {
5 | poke.push(num);
6 | })
7 | .toArray();
8 |
9 | assert.equal(result.length, poke.length);
10 | assert.equal(result[0], poke[0]);
11 | assert.equal(result[1], poke[1]);
12 | assert.equal(result[2], poke[2]);
13 | assert.equal(result[3], poke[3]);
14 | });
15 |
16 | QUnit.test("peek empty", function (assert) {
17 | var poke = [];
18 | var result = Stream([])
19 | .peek(function (num) {
20 | poke.push(num);
21 | })
22 | .toArray();
23 |
24 | assert.equal(poke.length, 0);
25 | assert.equal(result.length, 0);
26 | });
27 |
28 | QUnit.test("peek console.log", function (assert) {
29 | Stream(["peek"])
30 | .peek(console.log)
31 | .toArray();
32 |
33 | assert.ok(true); // assert no error
34 | });
--------------------------------------------------------------------------------
/test/test-reduce.js:
--------------------------------------------------------------------------------
1 | QUnit.test("reduce", function (assert) {
2 | var result = Stream([1, 2, 3, 4])
3 | .reduce(1000, function (identity, num) {
4 | return identity + num;
5 | });
6 | assert.equal(result, 1010);
7 | });
8 |
9 | QUnit.test("reduce empty", function (assert) {
10 | var result = Stream([])
11 | .reduce(1000, function (identity, num) {
12 | return identity + num;
13 | });
14 | assert.equal(result, 1000);
15 | });
16 |
17 | QUnit.test("reduce first", function (assert) {
18 | var result = Stream([1, 2, 3, 4])
19 | .reduce(function (identity, num) {
20 | return identity * num;
21 | });
22 | assert.equal(result, "[object Optional]");
23 | assert.equal(result.get(), 24);
24 | });
25 |
26 | QUnit.test("reduce first empty", function (assert) {
27 | var result = Stream([])
28 | .reduce(function (identity, num) {
29 | return identity * num;
30 | })
31 | .orElse("NOTHING");
32 | assert.equal(result, "NOTHING");
33 | });
--------------------------------------------------------------------------------
/test/test-reverse.js:
--------------------------------------------------------------------------------
1 | QUnit.test("reverse", function (assert) {
2 | var data = [1, 2, 3, 4];
3 |
4 | var result = Stream(data)
5 | .reverse()
6 | .toArray();
7 |
8 | assert.equal(result.length, 4);
9 | assert.equal(result[0], 4);
10 | assert.equal(result[1], 3);
11 | assert.equal(result[2], 2);
12 | assert.equal(result[3], 1);
13 |
14 | // assert original data is untouched
15 | assert.equal(data.length, 4);
16 | assert.equal(data[0], 1);
17 | assert.equal(data[1], 2);
18 | assert.equal(data[2], 3);
19 | assert.equal(data[3], 4);
20 | });
21 |
--------------------------------------------------------------------------------
/test/test-shuffle.js:
--------------------------------------------------------------------------------
1 | QUnit.test("shuffle num array", function (assert) {
2 | var data = [1, 2, 3, 4, 5];
3 |
4 | var result = Stream(data)
5 | .shuffle()
6 | .toArray();
7 |
8 | assert.equal(result.length, data.length);
9 | assert.ok(result.indexOf(1) > -1);
10 | assert.ok(result.indexOf(2) > -1);
11 | assert.ok(result.indexOf(3) > -1);
12 | assert.ok(result.indexOf(4) > -1);
13 | assert.ok(result.indexOf(5) > -1);
14 |
15 | // assert original data is untouched
16 | assert.equal(data.length, 5);
17 | assert.equal(data[0], 1);
18 | assert.equal(data[1], 2);
19 | assert.equal(data[2], 3);
20 | assert.equal(data[3], 4);
21 | assert.equal(data[4], 5);
22 | });
23 |
--------------------------------------------------------------------------------
/test/test-skip.js:
--------------------------------------------------------------------------------
1 | QUnit.test("skip", function (assert) {
2 | var result = Stream([1, 2, 3, 4])
3 | .skip(2)
4 | .toArray();
5 |
6 | assert.equal(result.length, 2);
7 | assert.equal(result[0], 3);
8 | assert.equal(result[1], 4);
9 | });
10 |
11 | QUnit.test("skip empty", function (assert) {
12 | var result = Stream([])
13 | .skip(1)
14 | .toArray();
15 |
16 | assert.equal(result.length, 0);
17 | });
18 |
19 | QUnit.test("skip high", function (assert) {
20 | var result = Stream([1, 2, 3, 4])
21 | .skip(10)
22 | .toArray();
23 |
24 | assert.equal(result.length, 0);
25 | });
26 |
27 | QUnit.test("skip zero", function (assert) {
28 | var result = Stream([1, 2, 3, 4])
29 | .skip(0)
30 | .toArray();
31 |
32 | assert.equal(result.length, 4);
33 | assert.equal(result[0], 1);
34 | assert.equal(result[1], 2);
35 | assert.equal(result[2], 3);
36 | assert.equal(result[3], 4);
37 | });
38 |
39 | QUnit.test("skip negative", function (assert) {
40 | var result = Stream([1, 2, 3, 4])
41 | .skip(-1)
42 | .toArray();
43 |
44 | assert.equal(result.length, 4);
45 | assert.equal(result[0], 1);
46 | assert.equal(result[1], 2);
47 | assert.equal(result[2], 3);
48 | assert.equal(result[3], 4);
49 | });
--------------------------------------------------------------------------------
/test/test-slice.js:
--------------------------------------------------------------------------------
1 | QUnit.test("slice", function (assert) {
2 | var result = Stream([1, 2, 3, 4])
3 | .slice(1, 3)
4 | .toArray();
5 |
6 | assert.equal(result.length, 2);
7 | assert.equal(result[0], 2);
8 | assert.equal(result[1], 3);
9 | });
10 |
11 | QUnit.test("slice empty", function (assert) {
12 | var result = Stream([])
13 | .slice(1, 2)
14 | .toArray();
15 |
16 | assert.equal(result.length, 0);
17 | });
18 |
19 | QUnit.test("slice high", function (assert) {
20 | var result = Stream([1, 2, 3, 4])
21 | .skip(10, 20)
22 | .toArray();
23 |
24 | assert.equal(result.length, 0);
25 | });
26 |
27 | QUnit.test("slice wrong args", function (assert) {
28 | assert.throws(function () {
29 | Stream.of(1, 2).slice(2, 1).toArray();
30 | });
31 | });
--------------------------------------------------------------------------------
/test/test-sorted.js:
--------------------------------------------------------------------------------
1 | QUnit.test("sorted", function (assert) {
2 | var result = Stream([4, 1, 3, 2])
3 | .sorted()
4 | .toArray();
5 |
6 | assert.equal(result.length, 4);
7 | assert.equal(result[0], 1);
8 | assert.equal(result[1], 2);
9 | assert.equal(result[2], 3);
10 | assert.equal(result[3], 4);
11 | });
12 |
13 | QUnit.test("sorted (comparator)", function (assert) {
14 | var result = Stream([4, 1, 3, 2])
15 | .sorted(function (num1, num2) {
16 | if (num1 === num2) return 0;
17 | return num1 < num2 ? 1 : -1;
18 | })
19 | .toArray();
20 |
21 | assert.equal(result.length, 4);
22 | assert.equal(result[0], 4);
23 | assert.equal(result[1], 3);
24 | assert.equal(result[2], 2);
25 | assert.equal(result[3], 1);
26 | });
27 |
28 | QUnit.test("sorted empty", function (assert) {
29 | var result = Stream([])
30 | .sorted()
31 | .toArray();
32 |
33 | assert.equal(result.length, 0);
34 | });
35 |
36 | QUnit.test("sorted by path", function (assert) {
37 | var data = [{a: 4}, {a: 1}, {a: 3}, {a: 2}];
38 | var result = Stream(data)
39 | .sorted("a")
40 | .toArray();
41 |
42 | assert.equal(result.length, 4);
43 | assert.equal(result[0].a, 1);
44 | assert.equal(result[1].a, 2);
45 | assert.equal(result[2].a, 3);
46 | assert.equal(result[3].a, 4);
47 |
48 | // assert input data is untouched
49 | assert.equal(data.length, 4);
50 | assert.equal(data[0].a, 4);
51 | assert.equal(data[1].a, 1);
52 | assert.equal(data[2].a, 3);
53 | assert.equal(data[3].a, 2);
54 | });
--------------------------------------------------------------------------------
/test/test-sum.js:
--------------------------------------------------------------------------------
1 | QUnit.test("sum", function (assert) {
2 | var result = Stream([1, 2, 3, 4]).sum();
3 | assert.equal(result, 10);
4 | });
5 |
6 | QUnit.test("sum empty", function (assert) {
7 | var result = Stream([]).sum();
8 | assert.equal(result, 0);
9 | });
10 |
11 | QUnit.test("sum via path", function (assert) {
12 | var result = Stream.of({a: 1}, {a: 2}, {a: 3}).sum("a");
13 | assert.equal(result, 6);
14 | });
--------------------------------------------------------------------------------
/test/test-takeWhile.js:
--------------------------------------------------------------------------------
1 | QUnit.test("takeWhile num array", function (assert) {
2 | var data = [1, 2, 3, 2, 1];
3 |
4 | var result = Stream(data)
5 | .takeWhile(function (num) {
6 | return num < 3;
7 | })
8 | .toArray();
9 |
10 | assert.equal(result.length, 2);
11 | assert.equal(result[0], 1);
12 | assert.equal(result[1], 2);
13 |
14 | // assert original data is untouched
15 | assert.equal(data.length, 5);
16 | assert.equal(data[0], 1);
17 | assert.equal(data[1], 2);
18 | assert.equal(data[2], 3);
19 | assert.equal(data[3], 2);
20 | assert.equal(data[4], 1);
21 | });
22 |
23 | QUnit.test("takeWhile object", function (assert) {
24 | var data = {a: 1, b: 2, c: 3, d: 2};
25 |
26 | var result = Stream(data)
27 | .takeWhile(function (num) {
28 | return num < 3;
29 | })
30 | .toArray();
31 |
32 | assert.equal(result.length, 2);
33 | assert.equal(result[0], 1);
34 | assert.equal(result[1], 2);
35 |
36 | // assert original data is untouched
37 | assert.equal(data.a, 1);
38 | assert.equal(data.b, 2);
39 | assert.equal(data.c, 3);
40 | assert.equal(data.d, 2);
41 | });
42 |
43 | QUnit.test("takeWhile empty", function (assert) {
44 | var result = Stream([])
45 | .takeWhile(function () {
46 | return true;
47 | })
48 | .toArray();
49 |
50 | assert.equal(result.length, 0);
51 | });
52 |
53 | QUnit.test("takeWhile via regexp literal", function (assert) {
54 | var data = ["a1", "a2", "b3", "a4"];
55 |
56 | var result = Stream(data)
57 | .takeWhile(/a.*/)
58 | .toArray();
59 |
60 | assert.equal(result.length, 2);
61 | assert.equal(result[0], "a1");
62 | assert.equal(result[1], "a2");
63 |
64 | // assert original data is untouched
65 | assert.equal(data.length, 4);
66 | assert.equal(data[0], "a1");
67 | assert.equal(data[1], "a2");
68 | assert.equal(data[2], "b3");
69 | assert.equal(data[3], "a4");
70 | });
71 |
72 | QUnit.test("takeWhile via regexp object", function (assert) {
73 | var data = ["a1", "a2", "b3", "a4"];
74 |
75 | var result = Stream(data)
76 | .takeWhile(new RegExp("a.*"))
77 | .toArray();
78 |
79 | assert.equal(result.length, 2);
80 | assert.equal(result[0], "a1");
81 | assert.equal(result[1], "a2");
82 |
83 | // assert original data is untouched
84 | assert.equal(data.length, 4);
85 | assert.equal(data[0], "a1");
86 | assert.equal(data[1], "a2");
87 | assert.equal(data[2], "b3");
88 | assert.equal(data[3], "a4");
89 | });
90 |
91 | QUnit.test("takeWhile via sample object (depth=1)", function (assert) {
92 | var data = [
93 | {a: 1, b: 1},
94 | {a: 1, b: 2},
95 | {a: 2, b: 3},
96 | {a: 1, b: 4}
97 | ];
98 |
99 | var result = Stream(data)
100 | .takeWhile({a: 1})
101 | .toArray();
102 |
103 | assert.equal(result.length, 2);
104 | assert.equal(result[0].a, 1);
105 | assert.equal(result[0].b, 1);
106 | assert.equal(result[1].a, 1);
107 | assert.equal(result[1].b, 2);
108 | });
109 |
110 | QUnit.test("takeWhile via sample object (depth=2)", function (assert) {
111 | var data = [
112 | {a: 1, b: 1, c: {x: "x1"}},
113 | {a: 1, b: 2, c: {x: "x1"}},
114 | {a: 2, b: 3, c: {x: "x3"}},
115 | {a: 1, b: 4, c: {x: "x1"}}
116 | ];
117 |
118 | var result = Stream(data)
119 | .takeWhile({a: 1, c: {x: "x1"}})
120 | .toArray();
121 |
122 | assert.equal(result.length, 2);
123 | assert.equal(result[0].a, 1);
124 | assert.equal(result[0].b, 1);
125 | assert.equal(result[0].c.x, "x1");
126 | assert.equal(result[1].a, 1);
127 | assert.equal(result[1].b, 2);
128 | assert.equal(result[1].c.x, "x1");
129 | });
--------------------------------------------------------------------------------
/test/test-toMap.js:
--------------------------------------------------------------------------------
1 | QUnit.test("toMap", function (assert) {
2 | var data = [
3 | {firstName: "Peter", lastName: "Parker"},
4 | {firstName: "John", lastName: "Doe"}
5 | ];
6 |
7 | var map = Stream(data)
8 | .toMap(function (obj) {
9 | return obj["lastName"];
10 | });
11 |
12 | assert.equal(map.hasOwnProperty("Parker"), true);
13 | assert.equal(map.hasOwnProperty("Doe"), true);
14 | assert.equal(map["Parker"], data[0]);
15 | assert.equal(map["Doe"], data[1]);
16 | });
17 |
18 | QUnit.test("toMap path", function (assert) {
19 | var data = [
20 | {firstName: "Peter", lastName: "Parker"},
21 | {firstName: "John", lastName: "Doe"}
22 | ];
23 |
24 | var map = Stream(data)
25 | .toMap("lastName");
26 |
27 | assert.equal(map.hasOwnProperty("Parker"), true);
28 | assert.equal(map.hasOwnProperty("Doe"), true);
29 | assert.equal(map["Parker"], data[0]);
30 | assert.equal(map["Doe"], data[1]);
31 | });
32 |
33 | QUnit.test("toMap empty", function (assert) {
34 | var map = Stream([])
35 | .toMap(function (obj) {
36 | return obj["lastName"];
37 | });
38 |
39 | assert.equal(Object.keys(map).length, 0);
40 | });
41 |
42 | QUnit.test("toMap duplicate key", function (assert) {
43 | var data = [
44 | {firstName: "Peter", lastName: "Parker"},
45 | {firstName: "Sandra", lastName: "Parker"},
46 | {firstName: "John", lastName: "Doe"}
47 | ];
48 |
49 | assert.throws(function () {
50 | Stream(data)
51 | .toMap(function (obj) {
52 | return obj["lastName"];
53 | });
54 | });
55 | });
56 |
57 | QUnit.test("toMap duplicate key merge", function (assert) {
58 | var data = [
59 | {firstName: "Peter", lastName: "Parker"},
60 | {firstName: "Sandra", lastName: "Parker"},
61 | {firstName: "John", lastName: "Doe"}
62 | ];
63 |
64 | var map = Stream(data)
65 | .indexBy(function (obj) {
66 | return obj["lastName"];
67 | }, function (val1) {
68 | return val1;
69 | });
70 |
71 | assert.equal(map.hasOwnProperty("Parker"), true);
72 | assert.equal(map.hasOwnProperty("Doe"), true);
73 | assert.equal(map["Parker"], data[0]);
74 | assert.equal(map["Doe"], data[2]);
75 | });
--------------------------------------------------------------------------------