jam 0.6.0 → 0.7.0
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/README.md +27 -232
- package/bin/jam.js +31 -0
- package/install.js +108 -0
- package/lib/platform.js +72 -0
- package/lib/resolve-binary.js +37 -0
- package/package.json +24 -27
- package/.npmignore +0 -6
- package/.travis.yml +0 -3
- package/Makefile +0 -67
- package/example/file1.txt +0 -1
- package/example/file2.txt +0 -1
- package/example/file3.txt +0 -1
- package/example/map.js +0 -29
- package/index.js +0 -6
- package/lib/jam.js +0 -295
- package/test/helpers.js +0 -271
- package/test/jam.js +0 -121
package/example/map.js
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
var FILES = 'file1.txt,file2.txt,file3.txt'.split(',')
|
|
3
|
-
, jam = require('../lib/jam')
|
|
4
|
-
, fs = require('fs');
|
|
5
|
-
|
|
6
|
-
// normal form
|
|
7
|
-
var readFile = function(next, filename) { fs.readFile(filename, next); }
|
|
8
|
-
, catResult = function(next, result) {
|
|
9
|
-
process.stdout.write(result.join(''));
|
|
10
|
-
next();
|
|
11
|
-
};
|
|
12
|
-
|
|
13
|
-
function normal(next) {
|
|
14
|
-
console.log("NORMAL FORM ::");
|
|
15
|
-
jam(jam.map(FILES, readFile))
|
|
16
|
-
(catResult)
|
|
17
|
-
(next);
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
function monad(next) {
|
|
21
|
-
console.log("MONAD FORM ::");
|
|
22
|
-
jam(jam.return(FILES))
|
|
23
|
-
(jam.map(readFile))
|
|
24
|
-
(catResult)
|
|
25
|
-
(next);
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
jam(normal)(monad)(function(e) { if (e) console.error(e); });
|
|
29
|
-
|
package/index.js
DELETED
package/lib/jam.js
DELETED
|
@@ -1,295 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
// lib/jam.js - Main JAM entrypoint
|
|
3
|
-
module.exports = (function() {
|
|
4
|
-
|
|
5
|
-
var assert = require('assert'), tick = null;
|
|
6
|
-
|
|
7
|
-
// Find out if we have setImmediate and fallback to setTimeout if necessary.
|
|
8
|
-
tick = typeof setImmediate === 'function' ?
|
|
9
|
-
setImmediate :
|
|
10
|
-
function(func) { setTimeout(func, 0); };
|
|
11
|
-
|
|
12
|
-
// # INTERNAL HELPERS
|
|
13
|
-
|
|
14
|
-
// Function and arguments helpers.
|
|
15
|
-
var toArgs = function(args) { return Array.prototype.slice.call(args); };
|
|
16
|
-
|
|
17
|
-
function replaceHead(args, newHead) {
|
|
18
|
-
args = toArgs(args);
|
|
19
|
-
if (!args.length) return [newHead];
|
|
20
|
-
|
|
21
|
-
args[0] = newHead;
|
|
22
|
-
return args;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
function bind(func, context) {
|
|
26
|
-
return function() { return func.apply(context, arguments); };
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
// Common assertions
|
|
30
|
-
function ensureFunc(func, argName) {
|
|
31
|
-
assert(typeof func === 'function', argName + ' argument missing or not a function');
|
|
32
|
-
};
|
|
33
|
-
|
|
34
|
-
function ensureNum(num, argName) {
|
|
35
|
-
assert(typeof num === 'number', argName + ' argument missing or not a number');
|
|
36
|
-
};
|
|
37
|
-
|
|
38
|
-
function ensureArray(arr, argName) {
|
|
39
|
-
assert(arr && typeof arr === 'object' && typeof arr.length === 'number',
|
|
40
|
-
argName + ' argument missing or does not looks like an array');
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
// ---
|
|
44
|
-
|
|
45
|
-
// # HELPERS
|
|
46
|
-
|
|
47
|
-
// Additional functions that adds to the original jam function.
|
|
48
|
-
function includeHelpers(func) {
|
|
49
|
-
|
|
50
|
-
// ## jam.identity()
|
|
51
|
-
|
|
52
|
-
// Simple function that passes the values it receives to the next function.
|
|
53
|
-
// Useful if you need a `process.nextTick` inserted in-between your call chain.
|
|
54
|
-
func.identity = function(next) {
|
|
55
|
-
function _identity(next) {
|
|
56
|
-
var args = arguments;
|
|
57
|
-
tick(function() {
|
|
58
|
-
next.apply(this, replaceHead(args, null));
|
|
59
|
-
});
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
// This function can also be passed to jam verbatim.
|
|
63
|
-
return (typeof next === 'function') ?
|
|
64
|
-
_identity.apply(this, arguments) :
|
|
65
|
-
_identity;
|
|
66
|
-
};
|
|
67
|
-
|
|
68
|
-
// ## jam.nextTick()
|
|
69
|
-
|
|
70
|
-
// Alias for `.identity`. Use when you need a `process.nextTick` inserted in-between
|
|
71
|
-
// your call chain.
|
|
72
|
-
func.nextTick = func.identity
|
|
73
|
-
|
|
74
|
-
// ## jam.return( [args...] )
|
|
75
|
-
|
|
76
|
-
// Returns a set of values to the next function in the chain. Useful when you want to
|
|
77
|
-
// pass in the next function verbatim without wrapping it in a `function() { }` just
|
|
78
|
-
// to pass values into it.
|
|
79
|
-
func.return = function() {
|
|
80
|
-
var args = toArgs(arguments);
|
|
81
|
-
return function(next) {
|
|
82
|
-
args.unshift(null);
|
|
83
|
-
next.apply(this, args);
|
|
84
|
-
};
|
|
85
|
-
};
|
|
86
|
-
|
|
87
|
-
// ## jam.null()
|
|
88
|
-
|
|
89
|
-
// Similar to `.identity` but absorbs all arguments that has been passed to it and
|
|
90
|
-
// forward nothing to the next function. Effectively nullifying any arguments passed
|
|
91
|
-
// from previous jam call.
|
|
92
|
-
//
|
|
93
|
-
// Like `jam.identity`, this function can be passed to the jam chain verbatim.
|
|
94
|
-
func.null = function(next) {
|
|
95
|
-
function _null(next) { next(); }
|
|
96
|
-
|
|
97
|
-
return (typeof next === 'function') ? _null.call(this, next) : _null;
|
|
98
|
-
};
|
|
99
|
-
|
|
100
|
-
// ## jam.call( function, [args...] )
|
|
101
|
-
|
|
102
|
-
// Convenience for calling functions that accepts arguments in standard node.js
|
|
103
|
-
// convention. Since jam insert `next` as first argument, most functions cannot be
|
|
104
|
-
// passed directly into the jam chain, thus this helper function.
|
|
105
|
-
//
|
|
106
|
-
// If no `args` is given, this function passes arguments given to `next()` call from
|
|
107
|
-
// previous function directly to the function (with proper callback) placement).
|
|
108
|
-
//
|
|
109
|
-
// Use this in combination with `jam.return` or `jam.null` if you want to control the
|
|
110
|
-
// arguments that are passed to the function.
|
|
111
|
-
func.call = function(func) {
|
|
112
|
-
ensureFunc(func, 'function');
|
|
113
|
-
|
|
114
|
-
var args = toArgs(arguments);
|
|
115
|
-
args.shift(); // func
|
|
116
|
-
|
|
117
|
-
if (args.length) { // use provided arguments
|
|
118
|
-
return function(next) {
|
|
119
|
-
args.push(next);
|
|
120
|
-
func.apply(this, args);
|
|
121
|
-
};
|
|
122
|
-
|
|
123
|
-
} else { // use passed-in arguments during chain resolution
|
|
124
|
-
return function(next) {
|
|
125
|
-
args = toArgs(arguments);
|
|
126
|
-
args.shift(); // move next to last position
|
|
127
|
-
args.push(next);
|
|
128
|
-
|
|
129
|
-
func.apply(this, args);
|
|
130
|
-
};
|
|
131
|
-
}
|
|
132
|
-
};
|
|
133
|
-
|
|
134
|
-
// ## jam.each( array, iterator( next, element, index ) )
|
|
135
|
-
|
|
136
|
-
// Execute the given `iterator` function for each element given in the `array`. The
|
|
137
|
-
// iterator is given a `next` function and the element to act on. The next step in the
|
|
138
|
-
// chain will receive the original array passed verbatim so you can chain multiple
|
|
139
|
-
// `.each` calls to act on the same array.
|
|
140
|
-
//
|
|
141
|
-
// You can also pass `arguments` and `"strings"` as an array or you can omit the array
|
|
142
|
-
// entirely, in which case this method will assume that the previous chain step
|
|
143
|
-
// returns something that looks like an array as its first result.
|
|
144
|
-
//
|
|
145
|
-
// Under the hood, a JAM step is added for each element. So the iterator will be
|
|
146
|
-
// called serially, one after another finish. A parallel version maybe added in the
|
|
147
|
-
// future.
|
|
148
|
-
func.each = function(array, iterator) {
|
|
149
|
-
if (typeof array === 'function') {
|
|
150
|
-
iterator = array;
|
|
151
|
-
array = null
|
|
152
|
-
} else {
|
|
153
|
-
ensureArray(array, 'array');
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
ensureFunc(iterator, 'iterator');
|
|
157
|
-
|
|
158
|
-
return function(next, array_) {
|
|
159
|
-
var arr = array || array_;
|
|
160
|
-
|
|
161
|
-
// Builds another JAM chain internally
|
|
162
|
-
var chain = jam(jam.identity)
|
|
163
|
-
, count = arr.length;
|
|
164
|
-
|
|
165
|
-
for (var i = 0; i < count; i++) (function(element, i) {
|
|
166
|
-
chain = chain(function(next) { iterator(next, element, i); });
|
|
167
|
-
})(arr[i], i);
|
|
168
|
-
|
|
169
|
-
chain = chain(function(next) { next(null, arr); });
|
|
170
|
-
return chain(next);
|
|
171
|
-
};
|
|
172
|
-
};
|
|
173
|
-
|
|
174
|
-
// ## jam.map( array, iterator( next, element, index ) )
|
|
175
|
-
|
|
176
|
-
// Works exactly like the `each` helper but if a value is passed to the iterator's
|
|
177
|
-
// `next` function, it is collected into a new array which will be passed to the next
|
|
178
|
-
// function in the JAM chain after `map`.
|
|
179
|
-
//
|
|
180
|
-
// Like with `each`, you can omit the `array` input, in which case this method will
|
|
181
|
-
// assume that the previous chain step returns something that looks like an array as
|
|
182
|
-
// its first result.
|
|
183
|
-
func.map = function(array, iterator) {
|
|
184
|
-
if (typeof array === 'function') {
|
|
185
|
-
iterator = array;
|
|
186
|
-
array = null;
|
|
187
|
-
} else {
|
|
188
|
-
ensureArray(array, 'array');
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
ensureFunc(iterator, 'iterator');
|
|
192
|
-
|
|
193
|
-
return function(next, array_) {
|
|
194
|
-
var arr = array || array_;
|
|
195
|
-
|
|
196
|
-
// Builds another JAM chain internally and collect results.
|
|
197
|
-
// TODO: Dry with .each?
|
|
198
|
-
var chain = jam(jam.identity)
|
|
199
|
-
, count = arr.length
|
|
200
|
-
, result = [];
|
|
201
|
-
|
|
202
|
-
for (var i = 0; i < count; i++) (function(element, i) {
|
|
203
|
-
chain = chain(function(next, previous) {
|
|
204
|
-
result.push(previous);
|
|
205
|
-
iterator(next, element, i);
|
|
206
|
-
});
|
|
207
|
-
})(arr[i], i);
|
|
208
|
-
|
|
209
|
-
chain = chain(function(next, last) {
|
|
210
|
-
result.push(last);
|
|
211
|
-
result.shift(); // discard first undefined element
|
|
212
|
-
next(null, result);
|
|
213
|
-
});
|
|
214
|
-
|
|
215
|
-
return chain(next);
|
|
216
|
-
};
|
|
217
|
-
};
|
|
218
|
-
|
|
219
|
-
// ## jam.timeout( timeout )
|
|
220
|
-
|
|
221
|
-
// Pauses the chain for the specified `timeout` using `setTimeout`. Useful for
|
|
222
|
-
// inserting a delay in-between a long jam chain.
|
|
223
|
-
func.timeout = function(timeout) {
|
|
224
|
-
ensureNum(timeout, 'timeout');
|
|
225
|
-
|
|
226
|
-
return function(next) {
|
|
227
|
-
var args = replaceHead(arguments, null);
|
|
228
|
-
setTimeout(function() { next.apply(this, args); }, timeout);
|
|
229
|
-
};
|
|
230
|
-
};
|
|
231
|
-
|
|
232
|
-
// TODO: noError() ? or absorbError()
|
|
233
|
-
return func;
|
|
234
|
-
};
|
|
235
|
-
|
|
236
|
-
// ---
|
|
237
|
-
|
|
238
|
-
// # JAM function
|
|
239
|
-
|
|
240
|
-
// Exported function starts the asynchronous call chain.
|
|
241
|
-
function jam(func, context) {
|
|
242
|
-
ensureFunc(func, 'function');
|
|
243
|
-
|
|
244
|
-
var steps = [];
|
|
245
|
-
|
|
246
|
-
// ##### Chain resolver.
|
|
247
|
-
|
|
248
|
-
// The resolver will execute all functions passed to the chain as soon as `nextTick`.
|
|
249
|
-
// Thus jam will not works across async context where the chain is not built all at
|
|
250
|
-
// once in a single event loop, which is not really a problem from my personal
|
|
251
|
-
// experience.
|
|
252
|
-
tick(function resolve(e) {
|
|
253
|
-
var args = Array.prototype.slice.call(arguments);
|
|
254
|
-
|
|
255
|
-
// Any errors passed to next() are (fast-)forwarded to the last function in the
|
|
256
|
-
// chain skipping any functions that's left to be executed.
|
|
257
|
-
if (e) return steps[steps.length - 1].apply(this, args);
|
|
258
|
-
|
|
259
|
-
// Any parameters given to next() are passed as arguments to the next function in
|
|
260
|
-
// the chain (except for errors, of course.)
|
|
261
|
-
var next = steps.shift()
|
|
262
|
-
, args = Array.prototype.slice.call(arguments)
|
|
263
|
-
|
|
264
|
-
if (steps.length) {
|
|
265
|
-
args.shift(); // error arg
|
|
266
|
-
args.unshift(resolve); // next() function
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
return next.apply(this, args);
|
|
270
|
-
});
|
|
271
|
-
|
|
272
|
-
// ##### Chain context continuation.
|
|
273
|
-
|
|
274
|
-
// Subsequent invocation of the function returned from the `jam` function simply adds
|
|
275
|
-
// the given function to the chain.
|
|
276
|
-
function continuable(func, context) {
|
|
277
|
-
ensureFunc(func, 'function');
|
|
278
|
-
|
|
279
|
-
if (context) { // TODO: Handle falsy things?
|
|
280
|
-
func = bind(func, context);
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
steps.push(func);
|
|
284
|
-
return continuable;
|
|
285
|
-
};
|
|
286
|
-
|
|
287
|
-
return includeHelpers(continuable(func, context));
|
|
288
|
-
};
|
|
289
|
-
|
|
290
|
-
// ---
|
|
291
|
-
|
|
292
|
-
return includeHelpers(jam);
|
|
293
|
-
|
|
294
|
-
})();
|
|
295
|
-
|
package/test/helpers.js
DELETED
|
@@ -1,271 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
// test/helpers.js - Test JAM helper functions
|
|
3
|
-
(function() {
|
|
4
|
-
|
|
5
|
-
var assert = require('chai').assert
|
|
6
|
-
, stub = require('sinon').stub;
|
|
7
|
-
|
|
8
|
-
var NON_ARR_OR_FUNCS = [undefined, null, 123, 'string', { }]
|
|
9
|
-
, NON_FUNCTIONS = NON_ARR_OR_FUNCS.concat([[]])
|
|
10
|
-
, NON_ARRAYS = NON_ARR_OR_FUNCS.concat([function() { }])
|
|
11
|
-
, NON_NUMS = [undefined, null, 'string', { }, function() { }, []];
|
|
12
|
-
|
|
13
|
-
var ITERABLES = ['each', 'map'];
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
// functions with multiple usage modes
|
|
17
|
-
describeModes = function(modes, tests) {
|
|
18
|
-
for (var mode in modes) (function(mode, code) {
|
|
19
|
-
var factory = new Function('return ' + code + ';');
|
|
20
|
-
|
|
21
|
-
describe(mode, function() {
|
|
22
|
-
before(function() { this.factory = factory; });
|
|
23
|
-
after(function() { delete this.factory; });
|
|
24
|
-
|
|
25
|
-
tests()
|
|
26
|
-
});
|
|
27
|
-
})(mode, modes[mode]);
|
|
28
|
-
};
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
describe('Helpers', function() {
|
|
32
|
-
before(function() { this.jam = require('../index'); });
|
|
33
|
-
|
|
34
|
-
describe('.identity function', function() {
|
|
35
|
-
describe('.nextTick alias', function() {
|
|
36
|
-
it('should be exported', function() {
|
|
37
|
-
assert.typeOf(this.jam.nextTick, 'function');
|
|
38
|
-
assert.equal(this.jam.nextTick, this.jam.identity);
|
|
39
|
-
});
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
it('should be exported', function() {
|
|
43
|
-
assert.typeOf(this.jam.identity, 'function');
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
var MODES =
|
|
47
|
-
{ 'normal form' : 'this.jam.identity'
|
|
48
|
-
, 'invoked form' : 'this.jam.identity()' };
|
|
49
|
-
|
|
50
|
-
describeModes(MODES, function() {
|
|
51
|
-
it('should calls the next function without any args when used standalone', function(done) {
|
|
52
|
-
this.jam(this.factory())
|
|
53
|
-
(function(next) { assert.lengthOf(arguments, 1); next(); })
|
|
54
|
-
(done);
|
|
55
|
-
});
|
|
56
|
-
|
|
57
|
-
it('should pass all the args to the next function when used in chain', function(done) {
|
|
58
|
-
this.jam(function(next) { next(null, 'one', 'two'); })
|
|
59
|
-
(this.factory())
|
|
60
|
-
(function(next, arg0, arg1) {
|
|
61
|
-
assert.equal(arg0, 'one');
|
|
62
|
-
assert.equal(arg1, 'two');
|
|
63
|
-
next();
|
|
64
|
-
})
|
|
65
|
-
(done);
|
|
66
|
-
});
|
|
67
|
-
});
|
|
68
|
-
|
|
69
|
-
}); // .identity
|
|
70
|
-
|
|
71
|
-
describe('.return function', function() {
|
|
72
|
-
it('should be exported', function() {
|
|
73
|
-
assert.typeOf(this.jam.return, 'function');
|
|
74
|
-
});
|
|
75
|
-
|
|
76
|
-
it('should calls the next function with the supplied values', function(done) {
|
|
77
|
-
this.jam(this.jam.return('one', 'two'))
|
|
78
|
-
(function(next, arg0, arg1) {
|
|
79
|
-
assert.equal(arg0, 'one');
|
|
80
|
-
assert.equal(arg1, 'two');
|
|
81
|
-
next();
|
|
82
|
-
})
|
|
83
|
-
(done);
|
|
84
|
-
});
|
|
85
|
-
}); // .return
|
|
86
|
-
|
|
87
|
-
describe('.null function', function() {
|
|
88
|
-
it('should be exported', function() {
|
|
89
|
-
assert.typeOf(this.jam.null, 'function');
|
|
90
|
-
});
|
|
91
|
-
|
|
92
|
-
var MODES =
|
|
93
|
-
{ 'normal form' : 'this.jam.null'
|
|
94
|
-
, 'invoked form' : 'this.jam.null()' };
|
|
95
|
-
|
|
96
|
-
describeModes(MODES, function() {
|
|
97
|
-
it('should calls the next function in the chain with no arguments', function(done) {
|
|
98
|
-
this.jam(function(next) { next(null, 1, 2, 3); })
|
|
99
|
-
(this.factory())
|
|
100
|
-
(function(next, arg) {
|
|
101
|
-
assert.isUndefined(arg);
|
|
102
|
-
next();
|
|
103
|
-
})
|
|
104
|
-
(done);
|
|
105
|
-
});
|
|
106
|
-
});
|
|
107
|
-
}); // .null
|
|
108
|
-
|
|
109
|
-
describe('.call function', function() {
|
|
110
|
-
it('should be exported', function() {
|
|
111
|
-
assert.typeOf(this.jam.call, 'function');
|
|
112
|
-
});
|
|
113
|
-
|
|
114
|
-
it('should throws if function argument missing or not a function', function() {
|
|
115
|
-
var me = this;
|
|
116
|
-
|
|
117
|
-
NON_FUNCTIONS.forEach(function(thing) {
|
|
118
|
-
assert.throws(function() { me.jam.call(thing); }, /func/i);
|
|
119
|
-
});
|
|
120
|
-
});
|
|
121
|
-
|
|
122
|
-
it('should calls the given function when no arguments given', function(done) {
|
|
123
|
-
var spy = stub().callsArg(0);
|
|
124
|
-
this.jam(this.jam.call(spy))
|
|
125
|
-
(function(next) { assert(spy.called); next(); })
|
|
126
|
-
(done);
|
|
127
|
-
});
|
|
128
|
-
|
|
129
|
-
it('should passes arguments to the function if arguments given', function(done) {
|
|
130
|
-
var spy = stub().callsArg(1);
|
|
131
|
-
this.jam(this.jam.call(spy, 'one'))
|
|
132
|
-
(function(next) { assert(spy.calledWith('one')); next(); })
|
|
133
|
-
(done);
|
|
134
|
-
});
|
|
135
|
-
|
|
136
|
-
it('should forwards arguments to `next()` from previous function if no arguments given', function(done) {
|
|
137
|
-
var spy = stub().callsArg(2);
|
|
138
|
-
|
|
139
|
-
this.jam(function(next) { next(null, 'one', 'two'); })
|
|
140
|
-
(this.jam.call(spy))
|
|
141
|
-
(function(next) { assert(spy.calledWith('one', 'two')); next(); })
|
|
142
|
-
(done);
|
|
143
|
-
});
|
|
144
|
-
}); // .call
|
|
145
|
-
|
|
146
|
-
describe('.timeout function', function() {
|
|
147
|
-
it('should be exported', function() {
|
|
148
|
-
assert.typeOf(this.jam.timeout, 'function');
|
|
149
|
-
});
|
|
150
|
-
|
|
151
|
-
it('should throws if timeout argument missing or not a number', function() {
|
|
152
|
-
var me = this;
|
|
153
|
-
|
|
154
|
-
NON_NUMS.forEach(function(thing) {
|
|
155
|
-
assert.throws(function() { me.jam.timeout(thing); }, /timeout/i);
|
|
156
|
-
});
|
|
157
|
-
});
|
|
158
|
-
|
|
159
|
-
it('should calls the next function after the specified timeout', function(done) {
|
|
160
|
-
this.jam(this.jam.timeout(1))(done);
|
|
161
|
-
});
|
|
162
|
-
|
|
163
|
-
it('should forwards arguments to `next()` from previous function', function(done) {
|
|
164
|
-
this.jam(this.jam.return('hello'))
|
|
165
|
-
(this.jam.timeout(1))
|
|
166
|
-
(function(e, hello) {
|
|
167
|
-
assert(hello === 'hello');
|
|
168
|
-
done()
|
|
169
|
-
});
|
|
170
|
-
});
|
|
171
|
-
});
|
|
172
|
-
|
|
173
|
-
describe('iterable functions', function() {
|
|
174
|
-
|
|
175
|
-
ITERABLES.forEach(function(func) {
|
|
176
|
-
describe('.' + func + ' function', function() {
|
|
177
|
-
it('should be exported', function() {
|
|
178
|
-
assert.typeOf(this.jam[func], 'function');
|
|
179
|
-
});
|
|
180
|
-
|
|
181
|
-
it('should throws if array argument not an array or function', function() {
|
|
182
|
-
var me = this;
|
|
183
|
-
NON_ARR_OR_FUNCS.forEach(function(thing) {
|
|
184
|
-
assert.throws(function() { me.jam[func](thing); }, /array/i);
|
|
185
|
-
});
|
|
186
|
-
});
|
|
187
|
-
|
|
188
|
-
it('should throws if iterator argument missing or not a function', function() {
|
|
189
|
-
var me = this;
|
|
190
|
-
NON_FUNCTIONS.forEach(function(thing) {
|
|
191
|
-
assert.throws(function() { me.jam[func]([1,2,3], thing); }, /iterator/i);
|
|
192
|
-
});
|
|
193
|
-
});
|
|
194
|
-
});
|
|
195
|
-
}); // iterables
|
|
196
|
-
|
|
197
|
-
var MODES =
|
|
198
|
-
{ 'normal form':
|
|
199
|
-
'this.jam[arguments[0]].call(this.jam, arguments[2])'
|
|
200
|
-
, 'invoked form':
|
|
201
|
-
'this.jam[arguments[0]].call(this.jam, arguments[1], arguments[2])'
|
|
202
|
-
};
|
|
203
|
-
|
|
204
|
-
describeModes(MODES, function() {
|
|
205
|
-
ITERABLES.forEach(function(func) {
|
|
206
|
-
it('should calls iterator for each element in the given array serially', function(done) {
|
|
207
|
-
var elements = ['one', 'two', 'three']
|
|
208
|
-
, index = 0;
|
|
209
|
-
|
|
210
|
-
var check = function(next, element, index_) {
|
|
211
|
-
assert.equal(index_, index);
|
|
212
|
-
assert.equal(element, elements[index]);
|
|
213
|
-
index++;
|
|
214
|
-
next()
|
|
215
|
-
};
|
|
216
|
-
|
|
217
|
-
this.jam(this.jam.return(elements))
|
|
218
|
-
(this.factory(func, elements, check))
|
|
219
|
-
(done);
|
|
220
|
-
});
|
|
221
|
-
|
|
222
|
-
it('should forwards error properly when an iterator calls `next()` with an Error`', function(done) {
|
|
223
|
-
var err = new Error('test error')
|
|
224
|
-
, elements = ['one', 'two', 'three']
|
|
225
|
-
, index = 0;
|
|
226
|
-
|
|
227
|
-
var err = function(next, element, index_) {
|
|
228
|
-
next(index_ < 2 ? undefined : err);
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
this.jam(this.jam.return(elements))
|
|
232
|
-
(this.factory(func, elements, err))
|
|
233
|
-
(function(e) {
|
|
234
|
-
assert.equal(e, err); // should be forwarded here
|
|
235
|
-
done()
|
|
236
|
-
});
|
|
237
|
-
});
|
|
238
|
-
});
|
|
239
|
-
}); // describeModes
|
|
240
|
-
|
|
241
|
-
}); // iterables
|
|
242
|
-
|
|
243
|
-
describe('.each function', function() {
|
|
244
|
-
it('should pass original array to next() when done', function(done) {
|
|
245
|
-
var elements = [1, 2, 3];
|
|
246
|
-
|
|
247
|
-
this.jam(this.jam.each(elements, this.jam.identity))(function(next, result) {
|
|
248
|
-
assert.equal(elements, result);
|
|
249
|
-
next()
|
|
250
|
-
})(done);
|
|
251
|
-
});
|
|
252
|
-
}); // .each
|
|
253
|
-
|
|
254
|
-
describe('.map function', function() {
|
|
255
|
-
it('should collects iterator result and pass to next()', function(done) {
|
|
256
|
-
var elements = [1, 2, 3];
|
|
257
|
-
|
|
258
|
-
this.jam(this.jam.map(elements, function(next, element, index) {
|
|
259
|
-
return next(null, element * 2);
|
|
260
|
-
}))(function(next, result) {
|
|
261
|
-
for (var i = 0; i < elements.length; i++) {
|
|
262
|
-
assert.equal(elements[i] * 2, result[i]);
|
|
263
|
-
}
|
|
264
|
-
next()
|
|
265
|
-
})(done);
|
|
266
|
-
});
|
|
267
|
-
}); // .map
|
|
268
|
-
|
|
269
|
-
});
|
|
270
|
-
|
|
271
|
-
})();
|