首次提交
This commit is contained in:
+43
@@ -0,0 +1,43 @@
|
||||
name: ci
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [10.x, 12.x, 13.x]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Use Node.js
|
||||
uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
|
||||
- name: Install
|
||||
run: |
|
||||
npm install
|
||||
|
||||
- name: Run tests
|
||||
run: |
|
||||
npm run test
|
||||
|
||||
- name: Coveralls Parallel
|
||||
uses: coverallsapp/github-action@master
|
||||
with:
|
||||
github-token: ${{ secrets.github_token }}
|
||||
parallel: true
|
||||
|
||||
coverage:
|
||||
needs: test
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Coveralls Finished
|
||||
uses: coverallsapp/github-action@master
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
parallel-finished: true
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
Copyright (c) 2015, Matteo Collina <matteo.collina@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
+115
@@ -0,0 +1,115 @@
|
||||
# fastseries
|
||||
|
||||
![ci][ci-url]
|
||||
[![npm version][npm-badge]][npm-url]
|
||||
[![Coverage Status][coveralls-badge]][coveralls-url]
|
||||
[![Dependency Status][david-badge]][david-url]
|
||||
|
||||
Zero-overhead series function call for node.js.
|
||||
Also supports `each` and `map`!
|
||||
|
||||
If you need zero-overhead parallel function call, check out
|
||||
[fastparallel](http://npm.im/fastparallel).
|
||||
|
||||
[](https://github.com/feross/standard)
|
||||
|
||||
## Example for series call
|
||||
|
||||
```js
|
||||
var series = require('fastseries')({
|
||||
// if you want the results, then here you are
|
||||
results: true
|
||||
})
|
||||
|
||||
series(
|
||||
{}, // what will be this in the functions
|
||||
[something, something, something], // functions to call
|
||||
42, // the first argument of the functions
|
||||
done // the function to be called when the series ends
|
||||
)
|
||||
|
||||
function late (arg, cb) {
|
||||
console.log('finishing', arg)
|
||||
cb(null, 'myresult-' + arg)
|
||||
}
|
||||
|
||||
function something (arg, cb) {
|
||||
setTimeout(late, 1000, arg, cb)
|
||||
}
|
||||
|
||||
function done (err, results) {
|
||||
console.log('series completed, results:', results)
|
||||
}
|
||||
```
|
||||
|
||||
## Example for each and map calls
|
||||
|
||||
```js
|
||||
var series = require('fastseries')({
|
||||
// if you want the results, then here you are
|
||||
// passing false disables map
|
||||
results: true
|
||||
})
|
||||
|
||||
series(
|
||||
{}, // what will be this in the functions
|
||||
something, // functions to call
|
||||
[1, 2, 3], // the first argument of the functions
|
||||
done // the function to be called when the series ends
|
||||
)
|
||||
|
||||
function late (arg, cb) {
|
||||
console.log('finishing', arg)
|
||||
cb(null, 'myresult-' + arg)
|
||||
}
|
||||
|
||||
function something (arg, cb) {
|
||||
setTimeout(late, 1000, arg, cb)
|
||||
}
|
||||
|
||||
function done (err, results) {
|
||||
console.log('series completed, results:', results)
|
||||
}
|
||||
```
|
||||
|
||||
## Caveats
|
||||
|
||||
The `done` function will be called only once, even if more than one error happen.
|
||||
|
||||
This library works by caching the latest used function, so that running a new series
|
||||
does not cause **any memory allocations**.
|
||||
|
||||
## Benchmarks
|
||||
|
||||
Benchmark for doing 3 calls `setImmediate` 1 million times:
|
||||
|
||||
```
|
||||
benchSetImmediate*1000000: 2460.623ms
|
||||
benchAsyncSeries*1000000: 3064.569ms
|
||||
benchAsyncEachSeries*1000000: 2913.525ms
|
||||
benchAsyncMapSeries*1000000: 3020.794ms
|
||||
benchNeoSeries*1000000: 2617.064ms
|
||||
benchNeoEachSeries*1000000: 2621.672ms
|
||||
benchNeoMapSeries*1000000: 2611.294ms
|
||||
benchTinyEachAsync*1000000: 2706.457ms
|
||||
benchFastSeries*1000000: 2540.653ms
|
||||
benchFastSeriesNoResults*1000000: 2538.674ms
|
||||
benchFastSeriesEach*1000000: 2534.856ms
|
||||
benchFastSeriesEachResults*1000000: 2545.394ms
|
||||
```
|
||||
|
||||
Benchmarks taken on Node 12.16.1 on a dedicated server.
|
||||
|
||||
See [bench.js](./bench.js) for mode details.
|
||||
|
||||
## License
|
||||
|
||||
ISC
|
||||
|
||||
[ci-url]: https://github.com/mcollina/fastseries/workflows/ci/badge.svg
|
||||
[npm-badge]: https://badge.fury.io/js/fastseries.svg
|
||||
[npm-url]: https://badge.fury.io/js/fastseries
|
||||
[coveralls-badge]:https://coveralls.io/repos/mcollina/fastseries/badge.svg?branch=master&service=github
|
||||
[coveralls-url]: https://coveralls.io/github/mcollina/fastseries?branch=master
|
||||
[david-badge]: https://david-dm.org/mcollina/fastseries.svg
|
||||
[david-url]: https://david-dm.org/mcollina/fastseries
|
||||
+94
@@ -0,0 +1,94 @@
|
||||
var max = 1000000
|
||||
var series = require('./')()
|
||||
var seriesNoResults = require('./')({ results: false })
|
||||
var async = require('async')
|
||||
var neo = require('neo-async')
|
||||
var bench = require('fastbench')
|
||||
var tinyEachAsync = require('tiny-each-async')
|
||||
|
||||
function benchFastSeries (done) {
|
||||
series(null, [somethingP, somethingP, somethingP], 42, done)
|
||||
}
|
||||
|
||||
function benchFastSeriesNoResults (done) {
|
||||
seriesNoResults(null, [somethingP, somethingP, somethingP], 42, done)
|
||||
}
|
||||
|
||||
function benchFastSeriesEach (done) {
|
||||
seriesNoResults(null, somethingP, [1, 2, 3], done)
|
||||
}
|
||||
|
||||
function benchFastSeriesEachResults (done) {
|
||||
series(null, somethingP, [1, 2, 3], done)
|
||||
}
|
||||
|
||||
function benchAsyncSeries (done) {
|
||||
async.series([somethingA, somethingA, somethingA], done)
|
||||
}
|
||||
|
||||
function benchAsyncEachSeries (done) {
|
||||
async.eachSeries([1, 2, 3], somethingP, done)
|
||||
}
|
||||
|
||||
function benchAsyncMapSeries (done) {
|
||||
async.mapSeries([1, 2, 3], somethingP, done)
|
||||
}
|
||||
|
||||
function benchNeoSeries (done) {
|
||||
neo.series([somethingA, somethingA, somethingA], done)
|
||||
}
|
||||
|
||||
function benchNeoEachSeries (done) {
|
||||
neo.eachSeries([1, 2, 3], somethingP, done)
|
||||
}
|
||||
|
||||
function benchNeoMapSeries (done) {
|
||||
neo.mapSeries([1, 2, 3], somethingP, done)
|
||||
}
|
||||
|
||||
function benchTinyEachAsync (done) {
|
||||
tinyEachAsync([1, 2, 3], 1, somethingP, done)
|
||||
}
|
||||
|
||||
var nextDone
|
||||
var nextCount
|
||||
|
||||
function benchSetImmediate (done) {
|
||||
nextCount = 3
|
||||
nextDone = done
|
||||
setImmediate(somethingImmediate)
|
||||
}
|
||||
|
||||
function somethingImmediate () {
|
||||
nextCount--
|
||||
if (nextCount === 0) {
|
||||
nextDone()
|
||||
} else {
|
||||
setImmediate(somethingImmediate)
|
||||
}
|
||||
}
|
||||
|
||||
function somethingP (arg, cb) {
|
||||
setImmediate(cb)
|
||||
}
|
||||
|
||||
function somethingA (cb) {
|
||||
setImmediate(cb)
|
||||
}
|
||||
|
||||
var run = bench([
|
||||
benchSetImmediate,
|
||||
benchAsyncSeries,
|
||||
benchAsyncEachSeries,
|
||||
benchAsyncMapSeries,
|
||||
benchNeoSeries,
|
||||
benchNeoEachSeries,
|
||||
benchNeoMapSeries,
|
||||
benchTinyEachAsync,
|
||||
benchFastSeries,
|
||||
benchFastSeriesNoResults,
|
||||
benchFastSeriesEach,
|
||||
benchFastSeriesEachResults
|
||||
], max)
|
||||
|
||||
run(run)
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
var series = require('./')({
|
||||
// this is a function that will be called
|
||||
// when a series completes
|
||||
released: completed,
|
||||
|
||||
// we want results and errors
|
||||
// passing false will make it faster!
|
||||
results: true
|
||||
})
|
||||
|
||||
series(
|
||||
{}, // what will be this in the functions
|
||||
[something, something, something], // functions to call
|
||||
42, // the first argument of the functions
|
||||
next // the function to be called when the series ends
|
||||
)
|
||||
|
||||
function late (arg, cb) {
|
||||
console.log('finishing', arg)
|
||||
cb(null, 'myresult-' + arg)
|
||||
}
|
||||
|
||||
function something (arg, cb) {
|
||||
setTimeout(late, 1000, arg, cb)
|
||||
}
|
||||
|
||||
function next (err, results) {
|
||||
if (err) {
|
||||
// do something here!
|
||||
}
|
||||
console.log('series completed, results:', results)
|
||||
|
||||
series({}, something, [1, 2, 3], done)
|
||||
}
|
||||
|
||||
function done (err, results) {
|
||||
if (err) {
|
||||
// do something here!
|
||||
}
|
||||
console.log('series completed, results:', results)
|
||||
}
|
||||
|
||||
function completed () {
|
||||
console.log('series completed!')
|
||||
}
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
{
|
||||
"name": "fastseries",
|
||||
"version": "2.0.0",
|
||||
"description": "Zero-overhead asynchronous series/each/map function calls",
|
||||
"main": "series.js",
|
||||
"scripts": {
|
||||
"lint": "standard --verbose | snazzy",
|
||||
"unit": "tape test.js",
|
||||
"unit:report": "nyc --reporter=html --reporter=cobertura --reporter=text tape test.js",
|
||||
"unit:cov": "nyc --reporter=lcovonly tape test.js",
|
||||
"cov": "nyc --reporter=text tape test.js",
|
||||
"test:report": "npm run lint && npm run unit:report",
|
||||
"test": "npm run lint && npm run unit:cov"
|
||||
},
|
||||
"pre-commit": [
|
||||
"test"
|
||||
],
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/mcollina/fastseries.git"
|
||||
},
|
||||
"keywords": [
|
||||
"series",
|
||||
"fast",
|
||||
"async"
|
||||
],
|
||||
"author": "Matteo Collina <hello@matteocollina.com>",
|
||||
"license": "ISC",
|
||||
"bugs": {
|
||||
"url": "https://github.com/mcollina/fastseries/issues"
|
||||
},
|
||||
"homepage": "https://github.com/mcollina/fastseries",
|
||||
"devDependencies": {
|
||||
"async": "^3.2.0",
|
||||
"fastbench": "^1.0.1",
|
||||
"neo-async": "^2.6.1",
|
||||
"nyc": "^15.0.0",
|
||||
"pre-commit": "^1.2.2",
|
||||
"snazzy": "^8.0.0",
|
||||
"standard": "^14.3.1",
|
||||
"tape": "^4.13.0",
|
||||
"tiny-each-async": "^2.0.3"
|
||||
}
|
||||
}
|
||||
+155
@@ -0,0 +1,155 @@
|
||||
'use strict'
|
||||
|
||||
var defaults = {
|
||||
results: true
|
||||
}
|
||||
|
||||
function fastseries (options) {
|
||||
options = Object.assign({}, defaults, options)
|
||||
|
||||
var seriesEach
|
||||
var seriesList
|
||||
|
||||
if (options.results) {
|
||||
seriesEach = resultEach
|
||||
seriesList = resultList
|
||||
} else {
|
||||
seriesEach = noResultEach
|
||||
seriesList = noResultList
|
||||
}
|
||||
|
||||
return series
|
||||
|
||||
function series (that, toCall, arg, done) {
|
||||
done = (done || nop).bind(that)
|
||||
|
||||
if (toCall.length === 0) {
|
||||
done.call(that)
|
||||
} else if (toCall.bind) {
|
||||
if (that) {
|
||||
toCall = toCall.bind(that)
|
||||
}
|
||||
seriesEach(toCall, arg, done)
|
||||
} else {
|
||||
var _list
|
||||
if (that) {
|
||||
var length = toCall.length
|
||||
_list = new Array(length)
|
||||
for (var i = 0; i < length; i++) {
|
||||
_list[i] = toCall[i].bind(that)
|
||||
}
|
||||
} else {
|
||||
_list = toCall
|
||||
}
|
||||
|
||||
seriesList(_list, arg, done)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function noResultEach (each, list, cb) {
|
||||
var i = 0
|
||||
var length = list.length
|
||||
|
||||
release()
|
||||
|
||||
function release () {
|
||||
if (i < length) {
|
||||
makeCallTwo(each, list[i++], release)
|
||||
} else {
|
||||
cb()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function noResultList (list, arg, cb) {
|
||||
var i = 0
|
||||
var length = list.length
|
||||
var makeCall
|
||||
|
||||
if (list[0].length === 1) {
|
||||
makeCall = makeCallOne
|
||||
} else {
|
||||
makeCall = makeCallTwo
|
||||
}
|
||||
|
||||
release()
|
||||
|
||||
function release () {
|
||||
if (i < length) {
|
||||
makeCall(list[i++], arg, release)
|
||||
} else {
|
||||
cb()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function resultEach (each, list, cb) {
|
||||
var i = 0
|
||||
var length = list.length
|
||||
var results = new Array(length)
|
||||
|
||||
release(null, null)
|
||||
|
||||
function release (err, result) {
|
||||
if (err) {
|
||||
cb(err)
|
||||
return
|
||||
}
|
||||
|
||||
if (i > 0) {
|
||||
results[i - 1] = result
|
||||
}
|
||||
|
||||
if (i < length) {
|
||||
makeCallTwo(each, list[i++], release)
|
||||
} else {
|
||||
cb(null, results)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function resultList (list, arg, cb) {
|
||||
var i = 0
|
||||
var length = list.length
|
||||
var makeCall
|
||||
|
||||
if (list[0].length === 1) {
|
||||
makeCall = makeCallOne
|
||||
} else {
|
||||
makeCall = makeCallTwo
|
||||
}
|
||||
|
||||
var results = new Array(length)
|
||||
|
||||
release(null, null)
|
||||
|
||||
function release (err, result) {
|
||||
if (err) {
|
||||
cb(err)
|
||||
return
|
||||
}
|
||||
|
||||
if (i > 0) {
|
||||
results[i - 1] = result
|
||||
}
|
||||
|
||||
if (i < length) {
|
||||
makeCall(list[i++], arg, release)
|
||||
} else {
|
||||
cb(null, results)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function makeCallOne (cb, arg, release) {
|
||||
cb(release)
|
||||
}
|
||||
|
||||
function makeCallTwo (cb, arg, release) {
|
||||
cb(arg, release)
|
||||
}
|
||||
|
||||
function nop () { }
|
||||
|
||||
module.exports = fastseries
|
||||
+368
@@ -0,0 +1,368 @@
|
||||
'use strict'
|
||||
|
||||
var test = require('tape')
|
||||
var series = require('./')
|
||||
|
||||
test('basically works', function (t) {
|
||||
t.plan(7)
|
||||
|
||||
var instance = series()
|
||||
var count = 0
|
||||
var obj = {}
|
||||
|
||||
instance(obj, [build(0), build(1)], 42, function done () {
|
||||
t.equal(count, 2, 'all functions must have completed')
|
||||
})
|
||||
|
||||
function build (expected) {
|
||||
return function something (arg, cb) {
|
||||
t.equal(obj, this)
|
||||
t.equal(arg, 42)
|
||||
t.equal(expected, count)
|
||||
setImmediate(function () {
|
||||
count++
|
||||
cb()
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
test('without this', function (t) {
|
||||
t.plan(7)
|
||||
|
||||
var instance = series()
|
||||
var count = 0
|
||||
|
||||
instance(null, [build(0), build(1)], 42, function done () {
|
||||
t.equal(count, 2, 'all functions must have completed')
|
||||
})
|
||||
|
||||
function build (expected) {
|
||||
return function something (arg, cb) {
|
||||
t.equal(undefined, this)
|
||||
t.equal(arg, 42)
|
||||
t.equal(expected, count)
|
||||
setImmediate(function () {
|
||||
count++
|
||||
cb()
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
test('accumulates results', function (t) {
|
||||
t.plan(7)
|
||||
|
||||
var instance = series()
|
||||
var count = 0
|
||||
var obj = {}
|
||||
|
||||
instance(obj, [something, something], 42, function done (err, results) {
|
||||
t.notOk(err, 'no error')
|
||||
t.equal(count, 2, 'all functions must have completed')
|
||||
t.deepEqual(results, [1, 2])
|
||||
})
|
||||
|
||||
function something (arg, cb) {
|
||||
t.equal(obj, this)
|
||||
t.equal(arg, 42)
|
||||
setImmediate(function () {
|
||||
count++
|
||||
cb(null, count)
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
test('fowards errs', function (t) {
|
||||
t.plan(3)
|
||||
|
||||
var instance = series()
|
||||
var count = 0
|
||||
var obj = {}
|
||||
|
||||
instance(obj, [somethingErr, something], 42, function done (err, results) {
|
||||
t.ok(err, 'error exists')
|
||||
t.equal(err.message, 'this is an err!')
|
||||
t.equal(count, 1, 'only the first function must have completed')
|
||||
})
|
||||
|
||||
function something (arg, cb) {
|
||||
setImmediate(function () {
|
||||
count++
|
||||
cb(null, count)
|
||||
})
|
||||
}
|
||||
|
||||
function somethingErr (arg, cb) {
|
||||
setImmediate(function () {
|
||||
count++
|
||||
cb(new Error('this is an err!'))
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
test('does not forward errors or result with results:false flag', function (t) {
|
||||
t.plan(7)
|
||||
|
||||
var instance = series({
|
||||
results: false
|
||||
})
|
||||
var count = 0
|
||||
var obj = {}
|
||||
|
||||
instance(obj, [something, something], 42, function done (err, results) {
|
||||
t.equal(err, undefined, 'no err')
|
||||
t.equal(results, undefined, 'no err')
|
||||
t.equal(count, 2, 'all functions must have completed')
|
||||
})
|
||||
|
||||
function something (arg, cb) {
|
||||
t.equal(obj, this)
|
||||
t.equal(arg, 42)
|
||||
setImmediate(function () {
|
||||
count++
|
||||
cb()
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
test('should call done iff an empty is passed', function (t) {
|
||||
t.plan(1)
|
||||
|
||||
var instance = series()
|
||||
var obj = {}
|
||||
|
||||
instance(obj, [], 42, function done () {
|
||||
t.pass()
|
||||
})
|
||||
})
|
||||
|
||||
test('each support', function (t) {
|
||||
t.plan(7)
|
||||
|
||||
var instance = series()
|
||||
var count = 0
|
||||
var obj = {}
|
||||
var args = [1, 2, 3]
|
||||
var i = 0
|
||||
|
||||
instance(obj, something, [].concat(args), function done () {
|
||||
t.equal(count, 3, 'all functions must have completed')
|
||||
})
|
||||
|
||||
function something (arg, cb) {
|
||||
t.equal(obj, this, 'this matches')
|
||||
t.equal(args[i++], arg, 'the arg is correct')
|
||||
setImmediate(function () {
|
||||
count++
|
||||
cb()
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
test('each errors', function (t) {
|
||||
t.plan(2)
|
||||
|
||||
var instance = series()
|
||||
var obj = {}
|
||||
var args = [1, 2, 3]
|
||||
var err = new Error('kaboom')
|
||||
|
||||
instance(obj, something, [].concat(args), function done (_err) {
|
||||
t.equal(err, _err)
|
||||
})
|
||||
|
||||
function something (arg, cb) {
|
||||
t.pass('something called')
|
||||
cb(err)
|
||||
}
|
||||
})
|
||||
|
||||
test('each without this', function (t) {
|
||||
t.plan(7)
|
||||
|
||||
var instance = series()
|
||||
var count = 0
|
||||
var args = [1, 2, 3]
|
||||
var i = 0
|
||||
|
||||
instance(null, something, [].concat(args), function done () {
|
||||
t.equal(count, 3, 'all functions must have completed')
|
||||
})
|
||||
|
||||
function something (arg, cb) {
|
||||
t.equal(undefined, this, 'this matches')
|
||||
t.equal(args[i++], arg, 'the arg is correct')
|
||||
setImmediate(function () {
|
||||
count++
|
||||
cb()
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
test('call the callback with the given this', function (t) {
|
||||
t.plan(1)
|
||||
|
||||
var instance = series()
|
||||
var obj = {}
|
||||
|
||||
instance(obj, [build(), build()], 42, function done () {
|
||||
t.equal(obj, this, 'this matches')
|
||||
})
|
||||
|
||||
function build () {
|
||||
return function something (arg, cb) {
|
||||
setImmediate(cb)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
test('call the callback with the given this with no results', function (t) {
|
||||
t.plan(1)
|
||||
|
||||
var instance = series({ results: false })
|
||||
var obj = {}
|
||||
|
||||
instance(obj, [build(), build()], 42, function done () {
|
||||
t.equal(obj, this, 'this matches')
|
||||
})
|
||||
|
||||
function build () {
|
||||
return function something (arg, cb) {
|
||||
setImmediate(cb)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
test('call the callback with the given this with no data', function (t) {
|
||||
t.plan(1)
|
||||
|
||||
var instance = series()
|
||||
var obj = {}
|
||||
|
||||
instance(obj, [], 42, function done () {
|
||||
t.equal(obj, this, 'this matches')
|
||||
})
|
||||
})
|
||||
|
||||
test('support no final callback', function (t) {
|
||||
t.plan(6)
|
||||
|
||||
var instance = series()
|
||||
var count = 0
|
||||
var obj = {}
|
||||
|
||||
instance(obj, [build(0), build(1)], 42)
|
||||
|
||||
function build (expected) {
|
||||
return function something (arg, cb) {
|
||||
t.equal(obj, this)
|
||||
t.equal(arg, 42)
|
||||
t.equal(expected, count)
|
||||
setImmediate(function () {
|
||||
count++
|
||||
cb()
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
test('call without arg if there is no arg with no results', function (t) {
|
||||
t.plan(3)
|
||||
|
||||
var instance = series({
|
||||
results: false
|
||||
})
|
||||
var count = 0
|
||||
var obj = {}
|
||||
|
||||
instance(obj, [something, something], 42, function done () {
|
||||
t.equal(count, 2, 'all functions must have completed')
|
||||
})
|
||||
|
||||
function something (cb) {
|
||||
t.equal(obj, this)
|
||||
setImmediate(function () {
|
||||
count++
|
||||
cb()
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
test('call without arg if there is no arg with results', function (t) {
|
||||
t.plan(3)
|
||||
|
||||
var instance = series()
|
||||
var count = 0
|
||||
var obj = {}
|
||||
|
||||
instance(obj, [something, something], 42, function done () {
|
||||
t.equal(count, 2, 'all functions must have completed')
|
||||
})
|
||||
|
||||
function something (cb) {
|
||||
t.equal(obj, this)
|
||||
setImmediate(function () {
|
||||
count++
|
||||
cb()
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
test('each support with nothing to process', function (t) {
|
||||
t.plan(2)
|
||||
|
||||
var instance = series()
|
||||
var obj = {}
|
||||
var args = []
|
||||
|
||||
instance(obj, something, args, function done (err, results) {
|
||||
t.error(err)
|
||||
t.deepEqual(results, [], 'empty results')
|
||||
})
|
||||
|
||||
function something (arg, cb) {
|
||||
t.fail('this should never happen')
|
||||
}
|
||||
})
|
||||
|
||||
test('each without results support with nothing to process', function (t) {
|
||||
t.plan(1)
|
||||
|
||||
var instance = series({ results: false })
|
||||
var obj = {}
|
||||
var args = []
|
||||
|
||||
instance(obj, something, args, function done () {
|
||||
t.pass('done called')
|
||||
})
|
||||
|
||||
function something (arg, cb) {
|
||||
t.fail('this should never happen')
|
||||
}
|
||||
})
|
||||
|
||||
test('each without results', function (t) {
|
||||
t.plan(7)
|
||||
|
||||
var instance = series({
|
||||
results: false
|
||||
})
|
||||
var count = 0
|
||||
var obj = {}
|
||||
var args = [1, 2, 3]
|
||||
var i = 0
|
||||
|
||||
instance(obj, something, [].concat(args), function done () {
|
||||
t.equal(count, 3, 'all functions must have completed')
|
||||
})
|
||||
|
||||
function something (arg, cb) {
|
||||
t.equal(obj, this, 'this matches')
|
||||
t.equal(args[i++], arg, 'the arg is correct')
|
||||
setImmediate(function () {
|
||||
count++
|
||||
cb()
|
||||
})
|
||||
}
|
||||
})
|
||||
Reference in New Issue
Block a user