-
Notifications
You must be signed in to change notification settings - Fork 3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add tests and small syntactic improvements #2
base: latest
Are you sure you want to change the base?
Changes from all commits
79656bd
d22f27e
1eb2b41
ea0cef1
b15f561
5c2cf27
1638ae4
3c25e3a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
[*] | ||
indent_size = 2 | ||
indent_style = space | ||
end_of_line = lf |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,5 @@ | ||
node_modules/ | ||
.vscode/ | ||
*~ | ||
.#* | ||
coverage | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,36 +1,34 @@ | ||
'use strict' | ||
module.exports = inflight | ||
|
||
let Bluebird | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why remove this? Why not let people use bluebird if they have bluebird? Bluebird is more than a ponyfill, it also adds additional really handy APIs. Also it's often faster than native Promises. |
||
try { | ||
Bluebird = require('bluebird') | ||
} catch (_) { | ||
Bluebird = Promise | ||
const active = {} | ||
|
||
function cleanup() { | ||
delete active[unique] | ||
} | ||
|
||
function _inflight (unique, doFly) { | ||
if (!active[unique]) { | ||
active[unique] = (new Promise(function (resolve) { | ||
return resolve(doFly()) | ||
})) | ||
active[unique].then(cleanup, cleanup) | ||
function cleanup() { delete active[unique] } | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The other copy of |
||
} | ||
return active[unique] | ||
} | ||
|
||
const active = {} | ||
inflight.active = active | ||
function inflight (unique, doFly) { | ||
return Bluebird.all([unique, doFly]).then(function (args) { | ||
return Promise.all([unique, doFly]).then(function (args) { | ||
const unique = args[0] | ||
const doFly = args[1] | ||
if (Array.isArray(unique)) { | ||
return Bluebird.all(unique).then(function (uniqueArr) { | ||
return Promise.all(unique).then(function (uniqueArr) { | ||
return _inflight(uniqueArr.join(''), doFly) | ||
}) | ||
} else { | ||
return _inflight(unique, doFly) | ||
} | ||
}) | ||
|
||
function _inflight (unique, doFly) { | ||
if (!active[unique]) { | ||
active[unique] = (new Bluebird(function (resolve) { | ||
return resolve(doFly()) | ||
})) | ||
active[unique].then(cleanup, cleanup) | ||
function cleanup() { delete active[unique] } | ||
} | ||
return active[unique] | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
const inflight = require('./inflight') | ||
|
||
describe('inflight()', () => { | ||
it('calls a single doFly()', async () => { | ||
const doFly = jest.fn() | ||
await inflight('unique-key', doFly) | ||
expect(doFly).toHaveBeenCalled() | ||
}) | ||
|
||
it('calls multiple doFly()', async () => { | ||
const req = jest.fn((key) => { | ||
return inflight(key, () => { | ||
return new Promise(resolve => { | ||
setTimeout(resolve(key), 50) | ||
}) | ||
}) | ||
}) | ||
|
||
const result = await Promise.all([ | ||
req('hello'), | ||
req('hello'), | ||
]) | ||
expect(result).toEqual(['hello', 'hello']) | ||
}) | ||
|
||
it('calls doFly() only once if it is in progress', async () => { | ||
let calls = 0 | ||
const req = jest.fn((key) => { | ||
return inflight(key, () => { | ||
return new Promise(resolve => { | ||
calls++ | ||
setTimeout(resolve(42), 10000) | ||
}) | ||
}) | ||
}) | ||
|
||
const result = await Promise.all([ | ||
req('hello'), | ||
req('hello'), | ||
]) | ||
expect(result).toEqual([42, 42]) | ||
expect(calls).toEqual(1) | ||
}) | ||
|
||
it('calls doFly() again after it is settled', async () => { | ||
let calls = 0 | ||
const req = jest.fn((key) => { | ||
return inflight(key, () => { | ||
return new Promise(resolve => { | ||
calls++ | ||
setTimeout(resolve(calls + 100), 10000) | ||
}) | ||
}) | ||
}) | ||
|
||
const firstResult = await req('hello') | ||
expect(firstResult).toEqual(101) | ||
const secondResult = await req('hello') | ||
expect(secondResult).toEqual(102) | ||
}) | ||
|
||
it('can handle `unique` that is a promise', async () => { | ||
const doFly = jest.fn() | ||
await inflight(Promise.resolve('unique-key'), doFly) | ||
expect(doFly).toHaveBeenCalled() | ||
}) | ||
|
||
it('can handle `unique` that is an array', async () => { | ||
const doFly = jest.fn() | ||
await inflight(Promise.resolve(['unique', 'key']), doFly) | ||
expect(doFly).toHaveBeenCalled() | ||
}) | ||
|
||
it('can handle `unique` that is an array of promises', async () => { | ||
const doFly = jest.fn() | ||
await inflight([Promise.resolve('unique'), Promise.resolve('key')], doFly) | ||
expect(doFly).toHaveBeenCalled() | ||
}) | ||
}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like the tests, but as a rule I use
tap
for my tests, notjest
. Ordinarily I'm not that picky, but as I'll have to maintain this going forward, I would like to see them in tap format before landing.