ppipe 2.6.3 → 2.6.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc.js +212 -8
- package/.github/CONTRIBUTING.md +13 -13
- package/.github/ISSUE_TEMPLATE.md +17 -17
- package/.github/PULL_REQUEST_TEMPLATE.md +30 -30
- package/.travis.yml +3 -3
- package/CODE_OF_CONDUCT.md +46 -46
- package/LICENSE +13 -13
- package/README.md +329 -322
- package/package.json +36 -32
- package/prettier.config.js +8 -0
- package/src/getPropertyByPath.js +8 -6
- package/src/index.js +49 -41
- package/src/lib/isFunction.js +1 -1
- package/src/lib/isPromise.js +1 -1
- package/test/examples.js +175 -175
- package/test/test.js +603 -603
- package/.idea/codeStyles/Project.xml +0 -16
- package/.idea/codeStyles/codeStyleConfig.xml +0 -5
- package/.idea/inspectionProfiles/Project_Default.xml +0 -6
- package/.idea/misc.xml +0 -6
- package/.idea/modules.xml +0 -8
- package/.idea/ppipe.iml +0 -8
- package/.idea/vcs.xml +0 -6
package/test/test.js
CHANGED
|
@@ -1,603 +1,603 @@
|
|
|
1
|
-
/* eslint quotes: "off" */
|
|
2
|
-
|
|
3
|
-
let assert = require("chai").assert;
|
|
4
|
-
let ppipe = require("../src/index.js");
|
|
5
|
-
|
|
6
|
-
function doubleSay(str) {
|
|
7
|
-
return str + ", " + str;
|
|
8
|
-
}
|
|
9
|
-
function capitalize(str) {
|
|
10
|
-
return str[0].toUpperCase() + str.substring(1);
|
|
11
|
-
}
|
|
12
|
-
function delay(fn) {
|
|
13
|
-
return function() {
|
|
14
|
-
let args = arguments;
|
|
15
|
-
return new Promise(resolve =>
|
|
16
|
-
setTimeout(() => resolve(fn.apply(null, args)), 10)
|
|
17
|
-
);
|
|
18
|
-
};
|
|
19
|
-
}
|
|
20
|
-
function exclaim(str) {
|
|
21
|
-
return str + "!";
|
|
22
|
-
}
|
|
23
|
-
function join() {
|
|
24
|
-
let arr = Array.from(arguments);
|
|
25
|
-
return arr.join(", ");
|
|
26
|
-
}
|
|
27
|
-
function quote(str) {
|
|
28
|
-
return '"' + str + '"';
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
let _ = ppipe._;
|
|
32
|
-
|
|
33
|
-
describe("ppipe", function() {
|
|
34
|
-
let message = "hello";
|
|
35
|
-
it("should correctly pass the params to the first fn", function() {
|
|
36
|
-
assert.equal(ppipe(message)(doubleSay).val, doubleSay(message));
|
|
37
|
-
});
|
|
38
|
-
|
|
39
|
-
it("should throw if accessing val from a pipe that contains an error", function() {
|
|
40
|
-
let caught = false;
|
|
41
|
-
try {
|
|
42
|
-
ppipe(message)(() => {
|
|
43
|
-
throw new Error("foo");
|
|
44
|
-
})(doubleSay).val;
|
|
45
|
-
} catch (error) {
|
|
46
|
-
caught = error.message === "foo";
|
|
47
|
-
}
|
|
48
|
-
assert.equal(caught, true);
|
|
49
|
-
});
|
|
50
|
-
|
|
51
|
-
it("should throw if ending a pipe that contains an error", function() {
|
|
52
|
-
let caught = false;
|
|
53
|
-
try {
|
|
54
|
-
ppipe(message)(() => {
|
|
55
|
-
throw new Error("foo");
|
|
56
|
-
})(doubleSay)();
|
|
57
|
-
} catch (error) {
|
|
58
|
-
caught = error.message === "foo";
|
|
59
|
-
}
|
|
60
|
-
assert.equal(caught, true);
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
it("should fail promise if ending an async pipe that contains an error even when the deferred value comes later", async function() {
|
|
64
|
-
let caught = false;
|
|
65
|
-
try {
|
|
66
|
-
await ppipe(message)(() => {
|
|
67
|
-
throw new Error("foo");
|
|
68
|
-
})(() => Promise.resolve(message))(doubleSay).then(x => x);
|
|
69
|
-
} catch (error) {
|
|
70
|
-
caught = error.message === "foo";
|
|
71
|
-
}
|
|
72
|
-
assert.equal(caught, true);
|
|
73
|
-
});
|
|
74
|
-
|
|
75
|
-
it("should not touch the error as long as it exists when an undefined prop is called", async function() {
|
|
76
|
-
let caught = false;
|
|
77
|
-
try {
|
|
78
|
-
var error = new Error("oh noes");
|
|
79
|
-
await ppipe()(() => Promise.reject(error)).weCantKnowIfThisMethodExists();
|
|
80
|
-
} catch (error) {
|
|
81
|
-
caught = error.message === "oh noes";
|
|
82
|
-
}
|
|
83
|
-
assert.equal(caught, true);
|
|
84
|
-
});
|
|
85
|
-
|
|
86
|
-
it("should not continue a sync chain if a method is missing", function() {
|
|
87
|
-
let caught = false;
|
|
88
|
-
try {
|
|
89
|
-
ppipe("foo")(x => x).weKnowThisMethodIsMissing();
|
|
90
|
-
} catch (error) {
|
|
91
|
-
caught = true;
|
|
92
|
-
}
|
|
93
|
-
assert.equal(caught, true);
|
|
94
|
-
});
|
|
95
|
-
|
|
96
|
-
it("should error with missing method if no errors exist in ctx and missing method is called", async function() {
|
|
97
|
-
let caught = false;
|
|
98
|
-
try {
|
|
99
|
-
await ppipe("foo")(x => Promise.resolve(x)).weKnowThisMethodIsMissing();
|
|
100
|
-
} catch (error) {
|
|
101
|
-
caught = true;
|
|
102
|
-
}
|
|
103
|
-
assert.equal(caught, true);
|
|
104
|
-
});
|
|
105
|
-
|
|
106
|
-
it("should throw if a non-function is passed as the first argument", function() {
|
|
107
|
-
let caught = false;
|
|
108
|
-
try {
|
|
109
|
-
ppipe(message)({})(doubleSay)();
|
|
110
|
-
} catch (error) {
|
|
111
|
-
const expectedErrorMessage =
|
|
112
|
-
"first parameter to a pipe should be a function or a single placeholder";
|
|
113
|
-
caught = error.message === expectedErrorMessage;
|
|
114
|
-
}
|
|
115
|
-
assert.equal(caught, true);
|
|
116
|
-
});
|
|
117
|
-
|
|
118
|
-
it("should correctly pass the params to the second fn", function() {
|
|
119
|
-
assert.equal(
|
|
120
|
-
ppipe(message)(doubleSay)(exclaim).val,
|
|
121
|
-
exclaim(doubleSay(message))
|
|
122
|
-
);
|
|
123
|
-
});
|
|
124
|
-
|
|
125
|
-
it("should correctly insert parameters", function() {
|
|
126
|
-
assert.equal(
|
|
127
|
-
ppipe(message)(doubleSay)(join, _, "I said")(exclaim).val,
|
|
128
|
-
exclaim(join(doubleSay(message), "I said"))
|
|
129
|
-
);
|
|
130
|
-
});
|
|
131
|
-
|
|
132
|
-
it("should insert parameters at the end when no placeholder exists", function() {
|
|
133
|
-
assert.equal(
|
|
134
|
-
ppipe(message)(doubleSay)(join, "I said")(exclaim).val,
|
|
135
|
-
exclaim(join("I said", doubleSay(message)))
|
|
136
|
-
);
|
|
137
|
-
});
|
|
138
|
-
|
|
139
|
-
it("should correctly insert parameters on multiple functions", function() {
|
|
140
|
-
assert.equal(
|
|
141
|
-
ppipe(message)(doubleSay)(join, _, "I said")(exclaim)(
|
|
142
|
-
join,
|
|
143
|
-
"and suddenly",
|
|
144
|
-
_,
|
|
145
|
-
"without thinking"
|
|
146
|
-
).val,
|
|
147
|
-
join(
|
|
148
|
-
"and suddenly",
|
|
149
|
-
exclaim(join(doubleSay(message), "I said")),
|
|
150
|
-
"without thinking"
|
|
151
|
-
)
|
|
152
|
-
);
|
|
153
|
-
});
|
|
154
|
-
|
|
155
|
-
it("should return the value when no function is passed", function() {
|
|
156
|
-
assert.equal(
|
|
157
|
-
ppipe(message)(doubleSay)(join, _, "I said")(exclaim)(
|
|
158
|
-
join,
|
|
159
|
-
"and suddenly",
|
|
160
|
-
_,
|
|
161
|
-
"without thinking"
|
|
162
|
-
)(),
|
|
163
|
-
join(
|
|
164
|
-
"and suddenly",
|
|
165
|
-
exclaim(join(doubleSay(message), "I said")),
|
|
166
|
-
"without thinking"
|
|
167
|
-
)
|
|
168
|
-
);
|
|
169
|
-
});
|
|
170
|
-
|
|
171
|
-
let result = "Hello!";
|
|
172
|
-
|
|
173
|
-
it("should wrap promise factories in the middle of the chain", function() {
|
|
174
|
-
return ppipe(message)(Promise.resolve.bind(Promise))(delay(capitalize))(
|
|
175
|
-
exclaim
|
|
176
|
-
).then(res => {
|
|
177
|
-
return assert.equal(result, res);
|
|
178
|
-
});
|
|
179
|
-
});
|
|
180
|
-
|
|
181
|
-
it("should wrap promise factories at the end of the chain", function() {
|
|
182
|
-
return ppipe(message)(capitalize)(delay(exclaim)).then(res => {
|
|
183
|
-
return assert.equal(result, res);
|
|
184
|
-
});
|
|
185
|
-
});
|
|
186
|
-
|
|
187
|
-
it("should wrap promises in the beginning of the chain", function() {
|
|
188
|
-
return ppipe(Promise.resolve(message))(capitalize)(exclaim).then(res => {
|
|
189
|
-
return assert.equal(result, res);
|
|
190
|
-
});
|
|
191
|
-
});
|
|
192
|
-
|
|
193
|
-
it("should wrap multiple promise factories and promises in chain", function() {
|
|
194
|
-
return ppipe(Promise.resolve(message))(delay(capitalize))(
|
|
195
|
-
delay(exclaim)
|
|
196
|
-
).then(res => {
|
|
197
|
-
return assert.equal(result, res);
|
|
198
|
-
});
|
|
199
|
-
});
|
|
200
|
-
|
|
201
|
-
it("should simulate promises even when value is not delayed", function() {
|
|
202
|
-
return ppipe(message)(capitalize)(exclaim).then(res => {
|
|
203
|
-
return assert.equal(result, res);
|
|
204
|
-
});
|
|
205
|
-
});
|
|
206
|
-
|
|
207
|
-
it("should be able to insert promise values as parameters", function() {
|
|
208
|
-
return ppipe(message)(doubleSay)(delay(quote))(delay(join), _, "I said")(
|
|
209
|
-
join,
|
|
210
|
-
"and suddenly",
|
|
211
|
-
_,
|
|
212
|
-
"without thinking"
|
|
213
|
-
)(delay(exclaim))(exclaim).then(res =>
|
|
214
|
-
assert.equal(
|
|
215
|
-
'and suddenly, "hello, hello", I said, without thinking!!',
|
|
216
|
-
res
|
|
217
|
-
)
|
|
218
|
-
);
|
|
219
|
-
});
|
|
220
|
-
|
|
221
|
-
it("should be able to insert promise values more than once", function() {
|
|
222
|
-
return ppipe(message)(doubleSay)(delay(quote))(
|
|
223
|
-
delay(join),
|
|
224
|
-
_,
|
|
225
|
-
"test",
|
|
226
|
-
_,
|
|
227
|
-
_,
|
|
228
|
-
_,
|
|
229
|
-
"test"
|
|
230
|
-
)(delay(exclaim))(exclaim).then(res =>
|
|
231
|
-
assert.equal(
|
|
232
|
-
'"hello, hello", test, "hello, hello", "hello, hello", "hello, hello", test!!',
|
|
233
|
-
res
|
|
234
|
-
)
|
|
235
|
-
);
|
|
236
|
-
});
|
|
237
|
-
|
|
238
|
-
it("should be able to insert selected properties from promise values more than once", function() {
|
|
239
|
-
return ppipe(message)
|
|
240
|
-
.pipe(doubleSay)
|
|
241
|
-
.pipe(delay(quote))
|
|
242
|
-
.pipe(x => ({ foo: x, bar: x.toUpperCase() }))
|
|
243
|
-
.pipe(delay(join), _.foo, _.foo, _.foo, _.bar)
|
|
244
|
-
.pipe(delay(exclaim))
|
|
245
|
-
.pipe(exclaim)
|
|
246
|
-
.then(res =>
|
|
247
|
-
assert.equal(
|
|
248
|
-
'"hello, hello", "hello, hello", "hello, hello", "HELLO, HELLO"!!',
|
|
249
|
-
res
|
|
250
|
-
)
|
|
251
|
-
);
|
|
252
|
-
});
|
|
253
|
-
|
|
254
|
-
it("should be awaitable", async function() {
|
|
255
|
-
const res = await ppipe(message)
|
|
256
|
-
.pipe(doubleSay)
|
|
257
|
-
.pipe(delay(quote))
|
|
258
|
-
.pipe(x => ({ foo: x, bar: x.toUpperCase() }))
|
|
259
|
-
.pipe(delay(join), _.foo, _.foo, _.foo, _.bar)
|
|
260
|
-
.pipe(delay(exclaim))
|
|
261
|
-
.pipe(exclaim);
|
|
262
|
-
assert.equal(
|
|
263
|
-
'"hello, hello", "hello, hello", "hello, hello", "HELLO, HELLO"!!',
|
|
264
|
-
res
|
|
265
|
-
);
|
|
266
|
-
});
|
|
267
|
-
|
|
268
|
-
it("should pass the errors when rejected", function() {
|
|
269
|
-
let caught = false;
|
|
270
|
-
return ppipe(message)
|
|
271
|
-
.pipe(doubleSay)
|
|
272
|
-
.pipe(delay(quote))
|
|
273
|
-
.pipe(x => ({ foo: x, bar: x.toUpperCase() }))
|
|
274
|
-
.pipe(delay(join), _.foo, _.foo, _.foo, _.bar)
|
|
275
|
-
.pipe(() => Promise.reject(new Error("oh noes")))
|
|
276
|
-
.pipe(delay(exclaim))
|
|
277
|
-
.pipe(exclaim)
|
|
278
|
-
.catch(() => {
|
|
279
|
-
caught = true;
|
|
280
|
-
})
|
|
281
|
-
.then(() => assert(caught, true));
|
|
282
|
-
});
|
|
283
|
-
|
|
284
|
-
it("should pass the errors when thrown", function() {
|
|
285
|
-
let caught = false;
|
|
286
|
-
return ppipe(message)
|
|
287
|
-
.pipe(doubleSay)
|
|
288
|
-
.pipe(delay(quote))
|
|
289
|
-
.pipe(x => ({ foo: x, bar: x.toUpperCase() }))
|
|
290
|
-
.pipe(delay(join), _.foo, _.foo, _.foo, _.bar)
|
|
291
|
-
.pipe(() => {
|
|
292
|
-
throw new Error("oh noes");
|
|
293
|
-
})
|
|
294
|
-
.someMethodOfThePotentialResultIWantedToCallIfThereWasntAnError()
|
|
295
|
-
.pipe(delay(exclaim))
|
|
296
|
-
.pipe(exclaim)
|
|
297
|
-
.catch(() => {
|
|
298
|
-
caught = true;
|
|
299
|
-
})
|
|
300
|
-
.then(() => assert(caught, true));
|
|
301
|
-
});
|
|
302
|
-
|
|
303
|
-
it("should have catchable async errors", function() {
|
|
304
|
-
let caught = false;
|
|
305
|
-
try {
|
|
306
|
-
ppipe(message)
|
|
307
|
-
.pipe(doubleSay)
|
|
308
|
-
.pipe(() => {
|
|
309
|
-
throw new Error("oh noes");
|
|
310
|
-
})
|
|
311
|
-
.someMethodOfThePotentialResultIWantedToCallIfThereWasntAnError()
|
|
312
|
-
.pipe(delay(exclaim));
|
|
313
|
-
} catch (error) {
|
|
314
|
-
caught = true;
|
|
315
|
-
}
|
|
316
|
-
assert(caught, true);
|
|
317
|
-
});
|
|
318
|
-
|
|
319
|
-
it("should be able to access result prototype methods", function() {
|
|
320
|
-
return ppipe([1, 2, 3])
|
|
321
|
-
.map(i => i + 1)
|
|
322
|
-
.pipe(x => x.reduce((x, y) => x + y, 0))
|
|
323
|
-
.then(res => {
|
|
324
|
-
return assert.equal(9, res);
|
|
325
|
-
});
|
|
326
|
-
});
|
|
327
|
-
|
|
328
|
-
it("should be able to revert to chaining and back from prototype methods", function() {
|
|
329
|
-
const divide = (x, y) => x / y;
|
|
330
|
-
return (
|
|
331
|
-
ppipe("dummy")(() => [1, 2, 3])
|
|
332
|
-
.map(i => i + 1)
|
|
333
|
-
/*reduce: 9, divide: 9/3 == 3*/
|
|
334
|
-
.reduce((x, y) => x + y, 0)
|
|
335
|
-
.pipe(divide, _, 3)
|
|
336
|
-
.then(x => assert.equal(3, x))
|
|
337
|
-
);
|
|
338
|
-
});
|
|
339
|
-
|
|
340
|
-
it("should be able to access properties of the result", function() {
|
|
341
|
-
const divide = (x, y) => x / y;
|
|
342
|
-
return ppipe("dummy")(() => [1, 2, 3])
|
|
343
|
-
.map(i => i + 1)
|
|
344
|
-
.length()
|
|
345
|
-
.pipe(divide, _, 3)
|
|
346
|
-
.then(x => assert.equal(1, x));
|
|
347
|
-
});
|
|
348
|
-
|
|
349
|
-
it("should return itself via .pipe", function() {
|
|
350
|
-
const divide = (x, y) => x / y;
|
|
351
|
-
return (
|
|
352
|
-
ppipe("dummy")(() => [1, 2, 3])
|
|
353
|
-
.map(i => i + 1)
|
|
354
|
-
/*reduce: 9, divide: 9/3 == 3*/
|
|
355
|
-
.reduce((x, y) => x + y, 0)
|
|
356
|
-
.pipe(divide, _, 3)
|
|
357
|
-
.then(x => assert.equal(3, x))
|
|
358
|
-
);
|
|
359
|
-
});
|
|
360
|
-
|
|
361
|
-
class Test {
|
|
362
|
-
constructor(initial) {
|
|
363
|
-
this.value = initial;
|
|
364
|
-
}
|
|
365
|
-
increment() {
|
|
366
|
-
this.value = this.value + 1;
|
|
367
|
-
return this;
|
|
368
|
-
}
|
|
369
|
-
square() {
|
|
370
|
-
this.value = this.value * this.value;
|
|
371
|
-
return this;
|
|
372
|
-
}
|
|
373
|
-
add(x) {
|
|
374
|
-
this.value = this.value + x.value;
|
|
375
|
-
return this;
|
|
376
|
-
}
|
|
377
|
-
doWeirdStuff(x, y) {
|
|
378
|
-
return this.value * 100 + x * 10 + y;
|
|
379
|
-
}
|
|
380
|
-
}
|
|
381
|
-
|
|
382
|
-
it("should be able to switch context by using 'with'", () => {
|
|
383
|
-
const startVal = new Test(5);
|
|
384
|
-
ppipe(startVal)
|
|
385
|
-
.square()
|
|
386
|
-
.increment()
|
|
387
|
-
.with(new Test(9))
|
|
388
|
-
.add()
|
|
389
|
-
.with(new Test(1))
|
|
390
|
-
.doWeirdStuff(_.value, _.value)
|
|
391
|
-
.with(assert)
|
|
392
|
-
.equal(_, 485);
|
|
393
|
-
const secondStartVal = new Test(5);
|
|
394
|
-
const res = ppipe(secondStartVal)
|
|
395
|
-
.square()
|
|
396
|
-
.increment()
|
|
397
|
-
.with(new Test(9))
|
|
398
|
-
.add()
|
|
399
|
-
.with(new Test(1))
|
|
400
|
-
.doWeirdStuff(_.value, _.value);
|
|
401
|
-
assert.equal(res.val, 485);
|
|
402
|
-
});
|
|
403
|
-
|
|
404
|
-
it("should keep the context gained with 'with' after a 'pipe'", () => {
|
|
405
|
-
const startVal = new Test(5);
|
|
406
|
-
const res = ppipe(startVal)
|
|
407
|
-
.square()
|
|
408
|
-
.increment()
|
|
409
|
-
.with(new Test(9))
|
|
410
|
-
.add()
|
|
411
|
-
.with(new Test(1))
|
|
412
|
-
.pipe(Test.prototype.doWeirdStuff, _.value, _.value).val;
|
|
413
|
-
assert.equal(res, 485);
|
|
414
|
-
|
|
415
|
-
const secondStartVal = new Test(5);
|
|
416
|
-
const res2 = ppipe(secondStartVal)
|
|
417
|
-
.square()
|
|
418
|
-
.increment()
|
|
419
|
-
.with(new Test(9))
|
|
420
|
-
.add()
|
|
421
|
-
.with(new Test(1))
|
|
422
|
-
.pipe(secondStartVal.doWeirdStuff, _.value, _.value).val;
|
|
423
|
-
assert.equal(res2, 485);
|
|
424
|
-
});
|
|
425
|
-
|
|
426
|
-
it("should not mess with the promises", async () => {
|
|
427
|
-
const startVal = new Test(5);
|
|
428
|
-
const res = await ppipe(startVal)
|
|
429
|
-
.square()
|
|
430
|
-
.increment()
|
|
431
|
-
.with(new Test(9))
|
|
432
|
-
.then(x => 10 * x.value)
|
|
433
|
-
.catch(() => {
|
|
434
|
-
throw new Error("should not be reachable");
|
|
435
|
-
});
|
|
436
|
-
const res2 = await ppipe(res).pipe((x, y) => x + y, 1);
|
|
437
|
-
assert.equal(res2, 261);
|
|
438
|
-
});
|
|
439
|
-
|
|
440
|
-
it("should support binding, applying and calling", async () => {
|
|
441
|
-
const res = await ppipe(10)
|
|
442
|
-
.call(null, x => x + 1)
|
|
443
|
-
.apply(null, [x => Promise.resolve(x)])
|
|
444
|
-
.bind(null, (x, y) => x / y)(_, 10);
|
|
445
|
-
assert.equal(res, 1.1);
|
|
446
|
-
});
|
|
447
|
-
|
|
448
|
-
it("should support extensions", async () => {
|
|
449
|
-
const newPipe = ppipe.extend({
|
|
450
|
-
assertEqAndIncrement: (x, y) => {
|
|
451
|
-
assert.equal(x, y);
|
|
452
|
-
return x + 1;
|
|
453
|
-
}
|
|
454
|
-
});
|
|
455
|
-
const res = await newPipe(10)
|
|
456
|
-
.pipe(x => x + 1)
|
|
457
|
-
.assertEqAndIncrement(_, 11);
|
|
458
|
-
assert.equal(res, 12);
|
|
459
|
-
});
|
|
460
|
-
|
|
461
|
-
it("should support re-extending an extended ppipe", async () => {
|
|
462
|
-
const newPipe = ppipe.extend({
|
|
463
|
-
assertEqAndIncrement: (x, y) => {
|
|
464
|
-
assert.equal(x, y);
|
|
465
|
-
return x + 1;
|
|
466
|
-
}
|
|
467
|
-
});
|
|
468
|
-
const newerPipe = newPipe.extend({
|
|
469
|
-
divide: (x, y) => {
|
|
470
|
-
return x / y;
|
|
471
|
-
}
|
|
472
|
-
});
|
|
473
|
-
const res = await newerPipe(10)
|
|
474
|
-
.pipe(x => x + 1)
|
|
475
|
-
.assertEqAndIncrement(_, 11)
|
|
476
|
-
.divide(_, 12);
|
|
477
|
-
assert.equal(res, 1);
|
|
478
|
-
});
|
|
479
|
-
|
|
480
|
-
it("should support expanding the array result", async () => {
|
|
481
|
-
const addAll = (...params) => {
|
|
482
|
-
return params.reduce((a, b) => a + b, 0);
|
|
483
|
-
};
|
|
484
|
-
const res = await ppipe(1)
|
|
485
|
-
.pipe(x => [x, 2, 3])
|
|
486
|
-
.pipe(addAll, ..._, 4);
|
|
487
|
-
assert.equal(res, 10);
|
|
488
|
-
});
|
|
489
|
-
|
|
490
|
-
it("should support expanding the array property of result", async () => {
|
|
491
|
-
const addAll = (...params) => {
|
|
492
|
-
return params.reduce((a, b) => a + b, 0);
|
|
493
|
-
};
|
|
494
|
-
const res = await ppipe(1)
|
|
495
|
-
.pipe(x => ({ test: [x, 2, 3] }))
|
|
496
|
-
.pipe(addAll, ..._.test, 4);
|
|
497
|
-
assert.equal(res, 10);
|
|
498
|
-
});
|
|
499
|
-
|
|
500
|
-
it("should support expanding the deep array property of result", async () => {
|
|
501
|
-
const addAll = (...params) => {
|
|
502
|
-
return params.reduce((a, b) => a + b, 0);
|
|
503
|
-
};
|
|
504
|
-
const res = await ppipe(1)
|
|
505
|
-
.pipe(x => ({ test: { test: [x, 2, 3] } }))
|
|
506
|
-
.pipe(addAll, ..._.test.test, 4);
|
|
507
|
-
assert.equal(res, 10);
|
|
508
|
-
});
|
|
509
|
-
|
|
510
|
-
it("should return undefined when getting not existing deep properties", async () => {
|
|
511
|
-
const res = await ppipe(1)
|
|
512
|
-
.pipe(x => ({ test: { test: [x, 2, 3] } }))
|
|
513
|
-
.pipe(x => x, _.test.test.foo.bar);
|
|
514
|
-
assert.equal(res, undefined);
|
|
515
|
-
});
|
|
516
|
-
|
|
517
|
-
it("should use unit fn with no defined and a single param", async () => {
|
|
518
|
-
const res = await ppipe(1)
|
|
519
|
-
.pipe(x => ({ test: { test: [x, 2, 3] } }))
|
|
520
|
-
.pipe(_.test.test.foo.bar);
|
|
521
|
-
assert.equal(res, undefined);
|
|
522
|
-
const res2 = await ppipe(1)
|
|
523
|
-
.pipe(x => ({ test: { test: [x, 2, 3] } }))
|
|
524
|
-
.pipe(_.test.test[0]);
|
|
525
|
-
assert.equal(res2, 1);
|
|
526
|
-
});
|
|
527
|
-
|
|
528
|
-
it("should be able to extract array members", async () => {
|
|
529
|
-
async function asyncComplexDoubleArray(x) {
|
|
530
|
-
const result = x * 2;
|
|
531
|
-
const input = x;
|
|
532
|
-
return [await Promise.resolve(0), result, input, 20]; //some API designed by a mad scientist
|
|
533
|
-
}
|
|
534
|
-
const addAll = (...params) => {
|
|
535
|
-
return params.reduce((a, b) => a + b, 0);
|
|
536
|
-
};
|
|
537
|
-
const res = await ppipe(5)
|
|
538
|
-
.pipe(asyncComplexDoubleArray)
|
|
539
|
-
.pipe(addAll, _[1], _[2]);
|
|
540
|
-
assert.equal(res, 15);
|
|
541
|
-
const res2 = await ppipe(5)
|
|
542
|
-
.pipe(asyncComplexDoubleArray)
|
|
543
|
-
.pipe(addAll, _["[1]"], _["[2]"]);
|
|
544
|
-
assert.equal(res2, 15);
|
|
545
|
-
const res3 = await ppipe(5)
|
|
546
|
-
.pipe(asyncComplexDoubleArray)
|
|
547
|
-
.pipe(x => ({ test: x, foo: "bar" }))
|
|
548
|
-
.pipe(addAll, _["test[1]"], _.test[2], _.test["3"]);
|
|
549
|
-
assert.equal(res3, 35);
|
|
550
|
-
const res4 = await ppipe(5)
|
|
551
|
-
.pipe(asyncComplexDoubleArray)
|
|
552
|
-
.pipe(x => ({ test: () => ({ innerTest: x }), foo: "bar" }))
|
|
553
|
-
.pipe(
|
|
554
|
-
addAll,
|
|
555
|
-
_["test().innerTest[1]"],
|
|
556
|
-
_["test().innerTest"][2],
|
|
557
|
-
..._["test()"].innerTest
|
|
558
|
-
);
|
|
559
|
-
assert.equal(res4, 50);
|
|
560
|
-
const res5 = await ppipe(5)
|
|
561
|
-
.pipe(asyncComplexDoubleArray)
|
|
562
|
-
.pipe(x => ({ test: () => ({ innerTest: x }), foo: "bar" }))
|
|
563
|
-
.test()
|
|
564
|
-
.innerTest()
|
|
565
|
-
.pipe(addAll, _[1], _[2]);
|
|
566
|
-
assert.equal(res5, 15);
|
|
567
|
-
});
|
|
568
|
-
it("should be able to extract promised values", async () => {
|
|
569
|
-
const getXAsync = x =>
|
|
570
|
-
new Promise(res => setTimeout(() => res({ result: x }), 1));
|
|
571
|
-
const aComplexResult = { a: { complex: getXAsync.bind(null, 2) } };
|
|
572
|
-
const res = await ppipe(aComplexResult)
|
|
573
|
-
.pipe(_.a["complex()"].result)
|
|
574
|
-
.pipe(x => x * x);
|
|
575
|
-
assert.equal(res, 4);
|
|
576
|
-
const res2 = await ppipe(aComplexResult)
|
|
577
|
-
.pipe(_.a["complex().result"])
|
|
578
|
-
.pipe(x => x * x);
|
|
579
|
-
assert.equal(res2, 4);
|
|
580
|
-
const res3 = await ppipe(aComplexResult)
|
|
581
|
-
.a()
|
|
582
|
-
.complex()
|
|
583
|
-
.result()
|
|
584
|
-
.pipe(x => x * x);
|
|
585
|
-
assert.equal(res3, 4);
|
|
586
|
-
const plainCrazyResult = {
|
|
587
|
-
a: { complex: getXAsync.bind(null, aComplexResult) }
|
|
588
|
-
};
|
|
589
|
-
const res4 = await ppipe(plainCrazyResult)
|
|
590
|
-
.a()
|
|
591
|
-
.complex()
|
|
592
|
-
.result()
|
|
593
|
-
.a()
|
|
594
|
-
.complex()
|
|
595
|
-
.result()
|
|
596
|
-
.pipe(x => x * x);
|
|
597
|
-
assert.equal(res4, 4);
|
|
598
|
-
const res5 = await ppipe(plainCrazyResult)
|
|
599
|
-
.pipe(_.a["complex()"].result.a["complex()"].result)
|
|
600
|
-
.pipe(x => x * x);
|
|
601
|
-
assert.equal(res5, 4);
|
|
602
|
-
});
|
|
603
|
-
});
|
|
1
|
+
/* eslint quotes: "off" */
|
|
2
|
+
|
|
3
|
+
let assert = require("chai").assert;
|
|
4
|
+
let ppipe = require("../src/index.js");
|
|
5
|
+
|
|
6
|
+
function doubleSay(str) {
|
|
7
|
+
return str + ", " + str;
|
|
8
|
+
}
|
|
9
|
+
function capitalize(str) {
|
|
10
|
+
return str[0].toUpperCase() + str.substring(1);
|
|
11
|
+
}
|
|
12
|
+
function delay(fn) {
|
|
13
|
+
return function() {
|
|
14
|
+
let args = arguments;
|
|
15
|
+
return new Promise(resolve =>
|
|
16
|
+
setTimeout(() => resolve(fn.apply(null, args)), 10)
|
|
17
|
+
);
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
function exclaim(str) {
|
|
21
|
+
return str + "!";
|
|
22
|
+
}
|
|
23
|
+
function join() {
|
|
24
|
+
let arr = Array.from(arguments);
|
|
25
|
+
return arr.join(", ");
|
|
26
|
+
}
|
|
27
|
+
function quote(str) {
|
|
28
|
+
return '"' + str + '"';
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
let _ = ppipe._;
|
|
32
|
+
|
|
33
|
+
describe("ppipe", function() {
|
|
34
|
+
let message = "hello";
|
|
35
|
+
it("should correctly pass the params to the first fn", function() {
|
|
36
|
+
assert.equal(ppipe(message)(doubleSay).val, doubleSay(message));
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
it("should throw if accessing val from a pipe that contains an error", function() {
|
|
40
|
+
let caught = false;
|
|
41
|
+
try {
|
|
42
|
+
ppipe(message)(() => {
|
|
43
|
+
throw new Error("foo");
|
|
44
|
+
})(doubleSay).val;
|
|
45
|
+
} catch (error) {
|
|
46
|
+
caught = error.message === "foo";
|
|
47
|
+
}
|
|
48
|
+
assert.equal(caught, true);
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
it("should throw if ending a pipe that contains an error", function() {
|
|
52
|
+
let caught = false;
|
|
53
|
+
try {
|
|
54
|
+
ppipe(message)(() => {
|
|
55
|
+
throw new Error("foo");
|
|
56
|
+
})(doubleSay)();
|
|
57
|
+
} catch (error) {
|
|
58
|
+
caught = error.message === "foo";
|
|
59
|
+
}
|
|
60
|
+
assert.equal(caught, true);
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
it("should fail promise if ending an async pipe that contains an error even when the deferred value comes later", async function() {
|
|
64
|
+
let caught = false;
|
|
65
|
+
try {
|
|
66
|
+
await ppipe(message)(() => {
|
|
67
|
+
throw new Error("foo");
|
|
68
|
+
})(() => Promise.resolve(message))(doubleSay).then(x => x);
|
|
69
|
+
} catch (error) {
|
|
70
|
+
caught = error.message === "foo";
|
|
71
|
+
}
|
|
72
|
+
assert.equal(caught, true);
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
it("should not touch the error as long as it exists when an undefined prop is called", async function() {
|
|
76
|
+
let caught = false;
|
|
77
|
+
try {
|
|
78
|
+
var error = new Error("oh noes");
|
|
79
|
+
await ppipe()(() => Promise.reject(error)).weCantKnowIfThisMethodExists();
|
|
80
|
+
} catch (error) {
|
|
81
|
+
caught = error.message === "oh noes";
|
|
82
|
+
}
|
|
83
|
+
assert.equal(caught, true);
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
it("should not continue a sync chain if a method is missing", function() {
|
|
87
|
+
let caught = false;
|
|
88
|
+
try {
|
|
89
|
+
ppipe("foo")(x => x).weKnowThisMethodIsMissing();
|
|
90
|
+
} catch (error) {
|
|
91
|
+
caught = true;
|
|
92
|
+
}
|
|
93
|
+
assert.equal(caught, true);
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
it("should error with missing method if no errors exist in ctx and missing method is called", async function() {
|
|
97
|
+
let caught = false;
|
|
98
|
+
try {
|
|
99
|
+
await ppipe("foo")(x => Promise.resolve(x)).weKnowThisMethodIsMissing();
|
|
100
|
+
} catch (error) {
|
|
101
|
+
caught = true;
|
|
102
|
+
}
|
|
103
|
+
assert.equal(caught, true);
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
it("should throw if a non-function is passed as the first argument", function() {
|
|
107
|
+
let caught = false;
|
|
108
|
+
try {
|
|
109
|
+
ppipe(message)({})(doubleSay)();
|
|
110
|
+
} catch (error) {
|
|
111
|
+
const expectedErrorMessage =
|
|
112
|
+
"first parameter to a pipe should be a function or a single placeholder";
|
|
113
|
+
caught = error.message === expectedErrorMessage;
|
|
114
|
+
}
|
|
115
|
+
assert.equal(caught, true);
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
it("should correctly pass the params to the second fn", function() {
|
|
119
|
+
assert.equal(
|
|
120
|
+
ppipe(message)(doubleSay)(exclaim).val,
|
|
121
|
+
exclaim(doubleSay(message))
|
|
122
|
+
);
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
it("should correctly insert parameters", function() {
|
|
126
|
+
assert.equal(
|
|
127
|
+
ppipe(message)(doubleSay)(join, _, "I said")(exclaim).val,
|
|
128
|
+
exclaim(join(doubleSay(message), "I said"))
|
|
129
|
+
);
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
it("should insert parameters at the end when no placeholder exists", function() {
|
|
133
|
+
assert.equal(
|
|
134
|
+
ppipe(message)(doubleSay)(join, "I said")(exclaim).val,
|
|
135
|
+
exclaim(join("I said", doubleSay(message)))
|
|
136
|
+
);
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
it("should correctly insert parameters on multiple functions", function() {
|
|
140
|
+
assert.equal(
|
|
141
|
+
ppipe(message)(doubleSay)(join, _, "I said")(exclaim)(
|
|
142
|
+
join,
|
|
143
|
+
"and suddenly",
|
|
144
|
+
_,
|
|
145
|
+
"without thinking"
|
|
146
|
+
).val,
|
|
147
|
+
join(
|
|
148
|
+
"and suddenly",
|
|
149
|
+
exclaim(join(doubleSay(message), "I said")),
|
|
150
|
+
"without thinking"
|
|
151
|
+
)
|
|
152
|
+
);
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
it("should return the value when no function is passed", function() {
|
|
156
|
+
assert.equal(
|
|
157
|
+
ppipe(message)(doubleSay)(join, _, "I said")(exclaim)(
|
|
158
|
+
join,
|
|
159
|
+
"and suddenly",
|
|
160
|
+
_,
|
|
161
|
+
"without thinking"
|
|
162
|
+
)(),
|
|
163
|
+
join(
|
|
164
|
+
"and suddenly",
|
|
165
|
+
exclaim(join(doubleSay(message), "I said")),
|
|
166
|
+
"without thinking"
|
|
167
|
+
)
|
|
168
|
+
);
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
let result = "Hello!";
|
|
172
|
+
|
|
173
|
+
it("should wrap promise factories in the middle of the chain", function() {
|
|
174
|
+
return ppipe(message)(Promise.resolve.bind(Promise))(delay(capitalize))(
|
|
175
|
+
exclaim
|
|
176
|
+
).then(res => {
|
|
177
|
+
return assert.equal(result, res);
|
|
178
|
+
});
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
it("should wrap promise factories at the end of the chain", function() {
|
|
182
|
+
return ppipe(message)(capitalize)(delay(exclaim)).then(res => {
|
|
183
|
+
return assert.equal(result, res);
|
|
184
|
+
});
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
it("should wrap promises in the beginning of the chain", function() {
|
|
188
|
+
return ppipe(Promise.resolve(message))(capitalize)(exclaim).then(res => {
|
|
189
|
+
return assert.equal(result, res);
|
|
190
|
+
});
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
it("should wrap multiple promise factories and promises in chain", function() {
|
|
194
|
+
return ppipe(Promise.resolve(message))(delay(capitalize))(
|
|
195
|
+
delay(exclaim)
|
|
196
|
+
).then(res => {
|
|
197
|
+
return assert.equal(result, res);
|
|
198
|
+
});
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
it("should simulate promises even when value is not delayed", function() {
|
|
202
|
+
return ppipe(message)(capitalize)(exclaim).then(res => {
|
|
203
|
+
return assert.equal(result, res);
|
|
204
|
+
});
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
it("should be able to insert promise values as parameters", function() {
|
|
208
|
+
return ppipe(message)(doubleSay)(delay(quote))(delay(join), _, "I said")(
|
|
209
|
+
join,
|
|
210
|
+
"and suddenly",
|
|
211
|
+
_,
|
|
212
|
+
"without thinking"
|
|
213
|
+
)(delay(exclaim))(exclaim).then(res =>
|
|
214
|
+
assert.equal(
|
|
215
|
+
'and suddenly, "hello, hello", I said, without thinking!!',
|
|
216
|
+
res
|
|
217
|
+
)
|
|
218
|
+
);
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
it("should be able to insert promise values more than once", function() {
|
|
222
|
+
return ppipe(message)(doubleSay)(delay(quote))(
|
|
223
|
+
delay(join),
|
|
224
|
+
_,
|
|
225
|
+
"test",
|
|
226
|
+
_,
|
|
227
|
+
_,
|
|
228
|
+
_,
|
|
229
|
+
"test"
|
|
230
|
+
)(delay(exclaim))(exclaim).then(res =>
|
|
231
|
+
assert.equal(
|
|
232
|
+
'"hello, hello", test, "hello, hello", "hello, hello", "hello, hello", test!!',
|
|
233
|
+
res
|
|
234
|
+
)
|
|
235
|
+
);
|
|
236
|
+
});
|
|
237
|
+
|
|
238
|
+
it("should be able to insert selected properties from promise values more than once", function() {
|
|
239
|
+
return ppipe(message)
|
|
240
|
+
.pipe(doubleSay)
|
|
241
|
+
.pipe(delay(quote))
|
|
242
|
+
.pipe(x => ({ foo: x, bar: x.toUpperCase() }))
|
|
243
|
+
.pipe(delay(join), _.foo, _.foo, _.foo, _.bar)
|
|
244
|
+
.pipe(delay(exclaim))
|
|
245
|
+
.pipe(exclaim)
|
|
246
|
+
.then(res =>
|
|
247
|
+
assert.equal(
|
|
248
|
+
'"hello, hello", "hello, hello", "hello, hello", "HELLO, HELLO"!!',
|
|
249
|
+
res
|
|
250
|
+
)
|
|
251
|
+
);
|
|
252
|
+
});
|
|
253
|
+
|
|
254
|
+
it("should be awaitable", async function() {
|
|
255
|
+
const res = await ppipe(message)
|
|
256
|
+
.pipe(doubleSay)
|
|
257
|
+
.pipe(delay(quote))
|
|
258
|
+
.pipe(x => ({ foo: x, bar: x.toUpperCase() }))
|
|
259
|
+
.pipe(delay(join), _.foo, _.foo, _.foo, _.bar)
|
|
260
|
+
.pipe(delay(exclaim))
|
|
261
|
+
.pipe(exclaim);
|
|
262
|
+
assert.equal(
|
|
263
|
+
'"hello, hello", "hello, hello", "hello, hello", "HELLO, HELLO"!!',
|
|
264
|
+
res
|
|
265
|
+
);
|
|
266
|
+
});
|
|
267
|
+
|
|
268
|
+
it("should pass the errors when rejected", function() {
|
|
269
|
+
let caught = false;
|
|
270
|
+
return ppipe(message)
|
|
271
|
+
.pipe(doubleSay)
|
|
272
|
+
.pipe(delay(quote))
|
|
273
|
+
.pipe(x => ({ foo: x, bar: x.toUpperCase() }))
|
|
274
|
+
.pipe(delay(join), _.foo, _.foo, _.foo, _.bar)
|
|
275
|
+
.pipe(() => Promise.reject(new Error("oh noes")))
|
|
276
|
+
.pipe(delay(exclaim))
|
|
277
|
+
.pipe(exclaim)
|
|
278
|
+
.catch(() => {
|
|
279
|
+
caught = true;
|
|
280
|
+
})
|
|
281
|
+
.then(() => assert(caught, true));
|
|
282
|
+
});
|
|
283
|
+
|
|
284
|
+
it("should pass the errors when thrown", function() {
|
|
285
|
+
let caught = false;
|
|
286
|
+
return ppipe(message)
|
|
287
|
+
.pipe(doubleSay)
|
|
288
|
+
.pipe(delay(quote))
|
|
289
|
+
.pipe(x => ({ foo: x, bar: x.toUpperCase() }))
|
|
290
|
+
.pipe(delay(join), _.foo, _.foo, _.foo, _.bar)
|
|
291
|
+
.pipe(() => {
|
|
292
|
+
throw new Error("oh noes");
|
|
293
|
+
})
|
|
294
|
+
.someMethodOfThePotentialResultIWantedToCallIfThereWasntAnError()
|
|
295
|
+
.pipe(delay(exclaim))
|
|
296
|
+
.pipe(exclaim)
|
|
297
|
+
.catch(() => {
|
|
298
|
+
caught = true;
|
|
299
|
+
})
|
|
300
|
+
.then(() => assert(caught, true));
|
|
301
|
+
});
|
|
302
|
+
|
|
303
|
+
it("should have catchable async errors", function() {
|
|
304
|
+
let caught = false;
|
|
305
|
+
try {
|
|
306
|
+
ppipe(message)
|
|
307
|
+
.pipe(doubleSay)
|
|
308
|
+
.pipe(() => {
|
|
309
|
+
throw new Error("oh noes");
|
|
310
|
+
})
|
|
311
|
+
.someMethodOfThePotentialResultIWantedToCallIfThereWasntAnError()
|
|
312
|
+
.pipe(delay(exclaim));
|
|
313
|
+
} catch (error) {
|
|
314
|
+
caught = true;
|
|
315
|
+
}
|
|
316
|
+
assert(caught, true);
|
|
317
|
+
});
|
|
318
|
+
|
|
319
|
+
it("should be able to access result prototype methods", function() {
|
|
320
|
+
return ppipe([1, 2, 3])
|
|
321
|
+
.map(i => i + 1)
|
|
322
|
+
.pipe(x => x.reduce((x, y) => x + y, 0))
|
|
323
|
+
.then(res => {
|
|
324
|
+
return assert.equal(9, res);
|
|
325
|
+
});
|
|
326
|
+
});
|
|
327
|
+
|
|
328
|
+
it("should be able to revert to chaining and back from prototype methods", function() {
|
|
329
|
+
const divide = (x, y) => x / y;
|
|
330
|
+
return (
|
|
331
|
+
ppipe("dummy")(() => [1, 2, 3])
|
|
332
|
+
.map(i => i + 1)
|
|
333
|
+
/*reduce: 9, divide: 9/3 == 3*/
|
|
334
|
+
.reduce((x, y) => x + y, 0)
|
|
335
|
+
.pipe(divide, _, 3)
|
|
336
|
+
.then(x => assert.equal(3, x))
|
|
337
|
+
);
|
|
338
|
+
});
|
|
339
|
+
|
|
340
|
+
it("should be able to access properties of the result", function() {
|
|
341
|
+
const divide = (x, y) => x / y;
|
|
342
|
+
return ppipe("dummy")(() => [1, 2, 3])
|
|
343
|
+
.map(i => i + 1)
|
|
344
|
+
.length()
|
|
345
|
+
.pipe(divide, _, 3)
|
|
346
|
+
.then(x => assert.equal(1, x));
|
|
347
|
+
});
|
|
348
|
+
|
|
349
|
+
it("should return itself via .pipe", function() {
|
|
350
|
+
const divide = (x, y) => x / y;
|
|
351
|
+
return (
|
|
352
|
+
ppipe("dummy")(() => [1, 2, 3])
|
|
353
|
+
.map(i => i + 1)
|
|
354
|
+
/*reduce: 9, divide: 9/3 == 3*/
|
|
355
|
+
.reduce((x, y) => x + y, 0)
|
|
356
|
+
.pipe(divide, _, 3)
|
|
357
|
+
.then(x => assert.equal(3, x))
|
|
358
|
+
);
|
|
359
|
+
});
|
|
360
|
+
|
|
361
|
+
class Test {
|
|
362
|
+
constructor(initial) {
|
|
363
|
+
this.value = initial;
|
|
364
|
+
}
|
|
365
|
+
increment() {
|
|
366
|
+
this.value = this.value + 1;
|
|
367
|
+
return this;
|
|
368
|
+
}
|
|
369
|
+
square() {
|
|
370
|
+
this.value = this.value * this.value;
|
|
371
|
+
return this;
|
|
372
|
+
}
|
|
373
|
+
add(x) {
|
|
374
|
+
this.value = this.value + x.value;
|
|
375
|
+
return this;
|
|
376
|
+
}
|
|
377
|
+
doWeirdStuff(x, y) {
|
|
378
|
+
return this.value * 100 + x * 10 + y;
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
it("should be able to switch context by using 'with'", () => {
|
|
383
|
+
const startVal = new Test(5);
|
|
384
|
+
ppipe(startVal)
|
|
385
|
+
.square()
|
|
386
|
+
.increment()
|
|
387
|
+
.with(new Test(9))
|
|
388
|
+
.add()
|
|
389
|
+
.with(new Test(1))
|
|
390
|
+
.doWeirdStuff(_.value, _.value)
|
|
391
|
+
.with(assert)
|
|
392
|
+
.equal(_, 485);
|
|
393
|
+
const secondStartVal = new Test(5);
|
|
394
|
+
const res = ppipe(secondStartVal)
|
|
395
|
+
.square()
|
|
396
|
+
.increment()
|
|
397
|
+
.with(new Test(9))
|
|
398
|
+
.add()
|
|
399
|
+
.with(new Test(1))
|
|
400
|
+
.doWeirdStuff(_.value, _.value);
|
|
401
|
+
assert.equal(res.val, 485);
|
|
402
|
+
});
|
|
403
|
+
|
|
404
|
+
it("should keep the context gained with 'with' after a 'pipe'", () => {
|
|
405
|
+
const startVal = new Test(5);
|
|
406
|
+
const res = ppipe(startVal)
|
|
407
|
+
.square()
|
|
408
|
+
.increment()
|
|
409
|
+
.with(new Test(9))
|
|
410
|
+
.add()
|
|
411
|
+
.with(new Test(1))
|
|
412
|
+
.pipe(Test.prototype.doWeirdStuff, _.value, _.value).val;
|
|
413
|
+
assert.equal(res, 485);
|
|
414
|
+
|
|
415
|
+
const secondStartVal = new Test(5);
|
|
416
|
+
const res2 = ppipe(secondStartVal)
|
|
417
|
+
.square()
|
|
418
|
+
.increment()
|
|
419
|
+
.with(new Test(9))
|
|
420
|
+
.add()
|
|
421
|
+
.with(new Test(1))
|
|
422
|
+
.pipe(secondStartVal.doWeirdStuff, _.value, _.value).val;
|
|
423
|
+
assert.equal(res2, 485);
|
|
424
|
+
});
|
|
425
|
+
|
|
426
|
+
it("should not mess with the promises", async () => {
|
|
427
|
+
const startVal = new Test(5);
|
|
428
|
+
const res = await ppipe(startVal)
|
|
429
|
+
.square()
|
|
430
|
+
.increment()
|
|
431
|
+
.with(new Test(9))
|
|
432
|
+
.then(x => 10 * x.value)
|
|
433
|
+
.catch(() => {
|
|
434
|
+
throw new Error("should not be reachable");
|
|
435
|
+
});
|
|
436
|
+
const res2 = await ppipe(res).pipe((x, y) => x + y, 1);
|
|
437
|
+
assert.equal(res2, 261);
|
|
438
|
+
});
|
|
439
|
+
|
|
440
|
+
it("should support binding, applying and calling", async () => {
|
|
441
|
+
const res = await ppipe(10)
|
|
442
|
+
.call(null, x => x + 1)
|
|
443
|
+
.apply(null, [x => Promise.resolve(x)])
|
|
444
|
+
.bind(null, (x, y) => x / y)(_, 10);
|
|
445
|
+
assert.equal(res, 1.1);
|
|
446
|
+
});
|
|
447
|
+
|
|
448
|
+
it("should support extensions", async () => {
|
|
449
|
+
const newPipe = ppipe.extend({
|
|
450
|
+
assertEqAndIncrement: (x, y) => {
|
|
451
|
+
assert.equal(x, y);
|
|
452
|
+
return x + 1;
|
|
453
|
+
}
|
|
454
|
+
});
|
|
455
|
+
const res = await newPipe(10)
|
|
456
|
+
.pipe(x => x + 1)
|
|
457
|
+
.assertEqAndIncrement(_, 11);
|
|
458
|
+
assert.equal(res, 12);
|
|
459
|
+
});
|
|
460
|
+
|
|
461
|
+
it("should support re-extending an extended ppipe", async () => {
|
|
462
|
+
const newPipe = ppipe.extend({
|
|
463
|
+
assertEqAndIncrement: (x, y) => {
|
|
464
|
+
assert.equal(x, y);
|
|
465
|
+
return x + 1;
|
|
466
|
+
}
|
|
467
|
+
});
|
|
468
|
+
const newerPipe = newPipe.extend({
|
|
469
|
+
divide: (x, y) => {
|
|
470
|
+
return x / y;
|
|
471
|
+
}
|
|
472
|
+
});
|
|
473
|
+
const res = await newerPipe(10)
|
|
474
|
+
.pipe(x => x + 1)
|
|
475
|
+
.assertEqAndIncrement(_, 11)
|
|
476
|
+
.divide(_, 12);
|
|
477
|
+
assert.equal(res, 1);
|
|
478
|
+
});
|
|
479
|
+
|
|
480
|
+
it("should support expanding the array result", async () => {
|
|
481
|
+
const addAll = (...params) => {
|
|
482
|
+
return params.reduce((a, b) => a + b, 0);
|
|
483
|
+
};
|
|
484
|
+
const res = await ppipe(1)
|
|
485
|
+
.pipe(x => [x, 2, 3])
|
|
486
|
+
.pipe(addAll, ..._, 4);
|
|
487
|
+
assert.equal(res, 10);
|
|
488
|
+
});
|
|
489
|
+
|
|
490
|
+
it("should support expanding the array property of result", async () => {
|
|
491
|
+
const addAll = (...params) => {
|
|
492
|
+
return params.reduce((a, b) => a + b, 0);
|
|
493
|
+
};
|
|
494
|
+
const res = await ppipe(1)
|
|
495
|
+
.pipe(x => ({ test: [x, 2, 3] }))
|
|
496
|
+
.pipe(addAll, ..._.test, 4);
|
|
497
|
+
assert.equal(res, 10);
|
|
498
|
+
});
|
|
499
|
+
|
|
500
|
+
it("should support expanding the deep array property of result", async () => {
|
|
501
|
+
const addAll = (...params) => {
|
|
502
|
+
return params.reduce((a, b) => a + b, 0);
|
|
503
|
+
};
|
|
504
|
+
const res = await ppipe(1)
|
|
505
|
+
.pipe(x => ({ test: { test: [x, 2, 3] } }))
|
|
506
|
+
.pipe(addAll, ..._.test.test, 4);
|
|
507
|
+
assert.equal(res, 10);
|
|
508
|
+
});
|
|
509
|
+
|
|
510
|
+
it("should return undefined when getting not existing deep properties", async () => {
|
|
511
|
+
const res = await ppipe(1)
|
|
512
|
+
.pipe(x => ({ test: { test: [x, 2, 3] } }))
|
|
513
|
+
.pipe(x => x, _.test.test.foo.bar);
|
|
514
|
+
assert.equal(res, undefined);
|
|
515
|
+
});
|
|
516
|
+
|
|
517
|
+
it("should use unit fn with no defined and a single param", async () => {
|
|
518
|
+
const res = await ppipe(1)
|
|
519
|
+
.pipe(x => ({ test: { test: [x, 2, 3] } }))
|
|
520
|
+
.pipe(_.test.test.foo.bar);
|
|
521
|
+
assert.equal(res, undefined);
|
|
522
|
+
const res2 = await ppipe(1)
|
|
523
|
+
.pipe(x => ({ test: { test: [x, 2, 3] } }))
|
|
524
|
+
.pipe(_.test.test[0]);
|
|
525
|
+
assert.equal(res2, 1);
|
|
526
|
+
});
|
|
527
|
+
|
|
528
|
+
it("should be able to extract array members", async () => {
|
|
529
|
+
async function asyncComplexDoubleArray(x) {
|
|
530
|
+
const result = x * 2;
|
|
531
|
+
const input = x;
|
|
532
|
+
return [await Promise.resolve(0), result, input, 20]; //some API designed by a mad scientist
|
|
533
|
+
}
|
|
534
|
+
const addAll = (...params) => {
|
|
535
|
+
return params.reduce((a, b) => a + b, 0);
|
|
536
|
+
};
|
|
537
|
+
const res = await ppipe(5)
|
|
538
|
+
.pipe(asyncComplexDoubleArray)
|
|
539
|
+
.pipe(addAll, _[1], _[2]);
|
|
540
|
+
assert.equal(res, 15);
|
|
541
|
+
const res2 = await ppipe(5)
|
|
542
|
+
.pipe(asyncComplexDoubleArray)
|
|
543
|
+
.pipe(addAll, _["[1]"], _["[2]"]);
|
|
544
|
+
assert.equal(res2, 15);
|
|
545
|
+
const res3 = await ppipe(5)
|
|
546
|
+
.pipe(asyncComplexDoubleArray)
|
|
547
|
+
.pipe(x => ({ test: x, foo: "bar" }))
|
|
548
|
+
.pipe(addAll, _["test[1]"], _.test[2], _.test["3"]);
|
|
549
|
+
assert.equal(res3, 35);
|
|
550
|
+
const res4 = await ppipe(5)
|
|
551
|
+
.pipe(asyncComplexDoubleArray)
|
|
552
|
+
.pipe(x => ({ test: () => ({ innerTest: x }), foo: "bar" }))
|
|
553
|
+
.pipe(
|
|
554
|
+
addAll,
|
|
555
|
+
_["test().innerTest[1]"],
|
|
556
|
+
_["test().innerTest"][2],
|
|
557
|
+
..._["test()"].innerTest
|
|
558
|
+
);
|
|
559
|
+
assert.equal(res4, 50);
|
|
560
|
+
const res5 = await ppipe(5)
|
|
561
|
+
.pipe(asyncComplexDoubleArray)
|
|
562
|
+
.pipe(x => ({ test: () => ({ innerTest: x }), foo: "bar" }))
|
|
563
|
+
.test()
|
|
564
|
+
.innerTest()
|
|
565
|
+
.pipe(addAll, _[1], _[2]);
|
|
566
|
+
assert.equal(res5, 15);
|
|
567
|
+
});
|
|
568
|
+
it("should be able to extract promised values", async () => {
|
|
569
|
+
const getXAsync = x =>
|
|
570
|
+
new Promise(res => setTimeout(() => res({ result: x }), 1));
|
|
571
|
+
const aComplexResult = { a: { complex: getXAsync.bind(null, 2) } };
|
|
572
|
+
const res = await ppipe(aComplexResult)
|
|
573
|
+
.pipe(_.a["complex()"].result)
|
|
574
|
+
.pipe(x => x * x);
|
|
575
|
+
assert.equal(res, 4);
|
|
576
|
+
const res2 = await ppipe(aComplexResult)
|
|
577
|
+
.pipe(_.a["complex().result"])
|
|
578
|
+
.pipe(x => x * x);
|
|
579
|
+
assert.equal(res2, 4);
|
|
580
|
+
const res3 = await ppipe(aComplexResult)
|
|
581
|
+
.a()
|
|
582
|
+
.complex()
|
|
583
|
+
.result()
|
|
584
|
+
.pipe(x => x * x);
|
|
585
|
+
assert.equal(res3, 4);
|
|
586
|
+
const plainCrazyResult = {
|
|
587
|
+
a: { complex: getXAsync.bind(null, aComplexResult) }
|
|
588
|
+
};
|
|
589
|
+
const res4 = await ppipe(plainCrazyResult)
|
|
590
|
+
.a()
|
|
591
|
+
.complex()
|
|
592
|
+
.result()
|
|
593
|
+
.a()
|
|
594
|
+
.complex()
|
|
595
|
+
.result()
|
|
596
|
+
.pipe(x => x * x);
|
|
597
|
+
assert.equal(res4, 4);
|
|
598
|
+
const res5 = await ppipe(plainCrazyResult)
|
|
599
|
+
.pipe(_.a["complex()"].result.a["complex()"].result)
|
|
600
|
+
.pipe(x => x * x);
|
|
601
|
+
assert.equal(res5, 4);
|
|
602
|
+
});
|
|
603
|
+
});
|