UNPKG

7.54 kBJavaScriptView Raw
1const { identity, isEven, isGreaterThan, modulus, digitize, not, compose,
2 transduceArray, transduceAsyncIterator, transduceAsyncHasNextIterator, transduceGenerator,
3 take, skip, mapping, filtering, eventing, sampling, passthrough, split, randomFilter, neighbors,
4 makeAsyncRangeIterator, makeAsyncHasNextRangeIterator } = require('../dist/funprog.umd')
5const { nums, add1, sub1, concat, useNew, delay } = require('./utility.js')
6
7var assert = require('assert')
8
9const xform = compose(
10mapping(isGreaterThan(6)),
11mapping(add1),
12filtering(isEven)
13// mapping(doubleIt),
14// mapping(add1),
15)
16describe('Given the functional programming library', function () {
17 it('Then compose not and operation', async function () {
18 var f = compose(not, sub1)
19 assert.equal(true, await f(1))
20 assert.equal(false, await f(0))
21 })
22})
23
24describe('Given the transform functions', function () {
25 it('Then mapping identity is a no-op', async function () {
26 var f = mapping(identity)
27 var rf = await f(concat)
28 var val = await rf([1], [])
29 assert.equal(1, val[0])
30 })
31 it('Then passthrough is a no-op', async function () {
32 var f = passthrough()
33 var rf = await f(concat)
34 var val = await rf([1], [])
35 assert.equal(1, val[0])
36 })
37 it('Then randomFilter(1) is always includes', async function () {
38 var f = randomFilter(1)
39 var rf = await f(concat)
40 var val = await rf([], 1)
41 assert.equal(1, val.length)
42 })
43 it('Then randomFilter(0) is always eliminates', async function () {
44 var f = randomFilter(-1)
45 var rf = await f(concat)
46 var val = await rf([], 1)
47 assert.ok(val.reduced === null)
48 })
49})
50
51describe('Given the functional programming library', function () {
52 it('Then able to synchronously transduce from an array', async function () {
53 const tform = compose(
54 mapping(compose(not, sub1)),
55 take(1))
56 const result = await transduceArray(tform, concat, [], nums)
57 assert.equal(result.toString(), [true].toString())
58 })
59 it('Then able to synchronously transduce from an array', async function () {
60 const result = await transduceArray(xform, concat, [], nums)
61 assert.equal(result.toString(), [8, 10].toString())
62 })
63 it('Then able to asynchronously transduce from an interator', async function () {
64 const deltaxform = compose(
65 mapping(identity)
66 )
67 const numsIt = makeAsyncRangeIterator(1, 10)
68 var result = await transduceAsyncIterator(deltaxform, concat, [], numsIt)
69 assert.equal(result.toString(), [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ].toString())
70 })
71 it('Then able to asynchronously transduce from an hasNext interator', async function () {
72 const deltaxform = compose(
73 mapping(identity)
74 )
75 const numsIt = makeAsyncHasNextRangeIterator(1, 10)
76 var result = await transduceAsyncHasNextIterator(deltaxform, concat, [], numsIt)
77 assert.equal(result.toString(), [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ].toString())
78 })
79 it('Then able to asynchronously take from hasNext interator', async function () {
80 const deltaxform = compose(
81 take(3),
82 mapping(identity)
83 )
84 const numsIt = makeAsyncHasNextRangeIterator(1, 10)
85 var result = await transduceAsyncHasNextIterator(deltaxform, concat, [], numsIt)
86 assert.equal(result.toString(), [1, 2, 3].toString())
87 })
88 it('Then able to asynchronously skip from hasNext interator', async function () {
89 const deltaxform = compose(
90 skip(6),
91 mapping(identity)
92 )
93 const numsIt = makeAsyncHasNextRangeIterator(1, 10)
94 var result = await transduceAsyncHasNextIterator(deltaxform, concat, [], numsIt)
95 assert.equal(result.toString(), [7, 8, 9].toString())
96 })
97 it('Then able to asynchronously detect events from a stream', async function () {
98 const deltaxform = compose(
99 mapping(modulus(3)),
100 eventing(digitize) // 3 events [1-2,4-5,7-8]
101 )
102 const numsIt = makeAsyncHasNextRangeIterator(1, 10)
103 var result = await transduceAsyncHasNextIterator(deltaxform, concat, [], numsIt)
104 assert.equal(result[1].start, 3)
105 assert.equal(result[1].end, 4)
106 })
107 it('Then able build a transformed generator', async function () {
108 const deltaxform = compose(
109 skip(3),
110 mapping(modulus(3))
111 )
112 const generator = makeAsyncRangeIterator(1, 10)
113 var newgenerator = await transduceGenerator(deltaxform, useNew, null, generator)
114 for await (const value of newgenerator) {
115 assert.equal(value, 1)
116 break
117 }
118 })
119 it('Then able sample from generator', async function () {
120 const deltaxform = sampling(300) // emit a value every 300 milliseconds if available
121 const generator = makeAsyncRangeIterator(1, 10, 1, 100) // generator 1 through 10 by ones every 100 milliseconds
122 var newgenerator = await transduceGenerator(deltaxform, useNew, null, generator)
123 var cnt = 0
124 var last = null
125 // the values here will be 1,4,7
126 for await (const value of newgenerator) {
127 cnt++
128 if (cnt >= 3) {
129 last = value
130 break
131 }
132 }
133 assert.equal(last, 7)
134 })
135 it('Then able to split from generator', async function () {
136 var duplicate = function (x) {
137 return [x, x] // a function which maps a value to an array.
138 }
139 var deltaxform = compose(
140 mapping(identity),
141 split(duplicate), // replicate each value
142 filtering(isEven),
143 take(5)
144 )
145
146 const generator = makeAsyncRangeIterator(1, 10) // generator 1 through 10 by ones every 100 milliseconds
147 var newgenerator = await transduceGenerator(deltaxform, useNew, null, generator)
148 var stream = []
149 for await (const value of newgenerator) {
150 stream.push(value)
151 }
152 // stream should be [ 2,2,4,4,6 ]
153 assert.equal(stream[0], 2)
154 assert.equal(stream[1], 2)
155 assert.equal(stream[2], 4)
156 assert.equal(stream[4], 6)
157 })
158 it('Then use neighbors to get average of n to n+5 records inclusive of itself as n record is processed', async function () {
159 var enrich = function (x) {
160 let sum = x.neighbors.reduce((x, y) => x + y, 0)
161 let avg = sum / x.neighbors.length
162 let diff = x.data - avg
163 return {
164 data: x.data,
165 diff: diff
166 }
167 }
168 var deltaxform = compose(
169 mapping(identity),
170 neighbors(5),
171 mapping(enrich)
172 )
173 const generator = makeAsyncRangeIterator(1, 10) // generator 1 through 10 by ones every 100 milliseconds
174 var newgenerator = await transduceGenerator(deltaxform, useNew, null, generator)
175 var stream = []
176 for await (const value of newgenerator) {
177 stream.push(value)
178 }
179 assert.equal(stream[0].data, 1)
180 assert.equal(stream[0].diff, -2)
181 assert.equal(stream[1].data, 2)
182 assert.equal(stream[1].diff, -2)
183 assert.equal(stream[2].data, 3)
184 assert.equal(stream[2].diff, -2)
185 assert.equal(stream[3].data, 4)
186 assert.equal(stream[3].diff, -2)
187 })
188})