Skip to content

Commit

Permalink
Merge branch 'feature/delays' into dev
Browse files Browse the repository at this point in the history
  • Loading branch information
etki committed Aug 14, 2017
2 parents da89dca + 2fd4791 commit b218b7e
Show file tree
Hide file tree
Showing 6 changed files with 149 additions and 3 deletions.
4 changes: 3 additions & 1 deletion lib/concurrent/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,7 @@ module.exports = {
TimeoutException: timeout.TimeoutException,
TaskQueue: TaskQueue.TaskQueue,
RejectionException: TaskQueue.RejectionException,
timeout: timeout.timeout
timeout: timeout.timeout,
delay: timeout.delay,
throttle: timeout.throttle
}
40 changes: 40 additions & 0 deletions lib/concurrent/timeout.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,47 @@ function timeout (promise, timeout, message) {
})
}

/**
* Delays processing of callback for specified time. If no callback is
* given, returns empty promise that will resolve in specified time
*
* @param {int} time
* @param {Function} [callback]
*
* @return {Thenable.<*>}
*/
function delay (time, callback) {
callback = callback || function () {}
return new Promise(function (resolve, reject) {
setTimeout(function () {
try {
resolve(callback())
} catch (e) {
reject(e)
}
}, time)
})
}

/**
* Wraps given promise with another one which won't resolve earlier
* than specified time.
*
* @param {Thenable.<*>} promise
* @param {int} time Throttle time in milliseconds
* @return {Thenable.<*>}
*/
function throttle (promise, time) {
return new Promise(function (resolve) {
setTimeout(resolve, time)
}).then(function () {
return promise
})
}

module.exports = {
timeout: timeout,
delay: delay,
throttle: throttle,
TimeoutException: TimeoutException
}
3 changes: 1 addition & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,7 @@
"npm-cli-login": "0.0.10",
"npm-utils": "^1.11.0",
"promise": "^7.1.1",
"sinon": "^1.17.6",
"sinon-as-promised": "^4.0.2",
"sinon": "^3.2.0",
"standard": "^9.0.0",
"uglify-js": "^3.0.27"
},
Expand Down
41 changes: 41 additions & 0 deletions test/suites/integration/concurrent/timeout.delay.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/* eslint-env mocha */

var Sinon = require('sinon')
var Chai = require('chai')
var expect = Chai.expect
var delay = require('../../../../lib').Concurrent.delay

describe('Integration', function () {
describe('/concurrent', function () {
describe('/timeout.js', function () {
describe('.delay', function () {
var clock

beforeEach(function () {
clock = Sinon.useFakeTimers()
})

afterEach(function () {
clock.restore()
})

it('delays processing of specified code', function () {
var callback = Sinon.stub()
var delayed = delay(10, callback)
expect(callback.callCount).to.eq(0)
clock.next()
return delayed
.then(function () {
expect(callback.callCount).to.eq(1)
})
})

it('creates delayed promise if no callback is specified', function () {
var promise = delay(1)
clock.next()
return promise
})
})
})
})
})
50 changes: 50 additions & 0 deletions test/suites/integration/concurrent/timeout.throttle.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/* eslint-env mocha */

var Sinon = require('sinon')
var Chai = require('chai')
var expect = Chai.expect
var throttle = require('../../../../lib').Concurrent.throttle

describe('Integration', function () {
describe('/concurrent', function () {
describe('/timeout.js', function () {
describe('.throttle', function () {
var clock

beforeEach(function () {
clock = Sinon.useFakeTimers()
})

afterEach(function () {
clock.restore()
})

it('creates promise that resolves after passed time if it resolved too fast', function () {
var promise = Promise.resolve()
var stub = Sinon.stub()
var throttled = throttle(promise, 10).then(stub)
expect(stub.callCount).to.eq(0)
clock.next()
return throttled
.then(function () {
expect(stub.callCount).to.eq(1)
})
})

it('doesn\'t slow down promise that takes longer that throttle time', function () {
var promise = new Promise(function (resolve) {
setTimeout(resolve, 30)
})
var stub = Sinon.stub()
var throttled = throttle(promise, 10).then(stub)
expect(stub.callCount).to.eq(0)
clock.tick(30)
return throttled
.then(function () {
expect(stub.callCount).to.eq(1)
})
})
})
})
})
})
14 changes: 14 additions & 0 deletions test/suites/integration/concurrent/timeout.timeout.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
var Concurrent = require('../../../../lib').Concurrent
var timeout = Concurrent.timeout
var TimeoutException = Concurrent.TimeoutException
var Sinon = require('sinon')
var Chai = require('chai')
var expect = Chai.expect

Expand All @@ -16,6 +17,16 @@ describe('Integration', function () {
describe('/concurrent', function () {
describe('/timeout.js', function () {
describe('.timeout', function () {
var clock

beforeEach(function () {
clock = Sinon.useFakeTimers()
})

afterEach(function () {
clock.restore()
})

it('returns promise if timeout is negative', function () {
var promise = new Promise(function () {})
return expect(timeout(promise, -1)).to.equal(promise)
Expand All @@ -34,13 +45,15 @@ describe('Integration', function () {
it('wraps promise in timed out one', function () {
var promise = new Promise(function () {})
var wrapped = timeout(promise, 0)
clock.next()
return expect(wrapped).to.eventually.be.rejectedWith(TimeoutException)
})

it('passes provided message to exception', function () {
var message = 'foo'
var promise = new Promise(function () {})
var wrapped = timeout(promise, 0, message)
clock.next()
return wrapped
.then(branchStopper, function (error) {
expect(error).to.be.instanceOf(TimeoutException)
Expand All @@ -55,6 +68,7 @@ describe('Integration', function () {
.then(function () {
return timeout(promise, 0)
})
clock.next()
return expect(wrapped).to.eventually.eq(value)
})
})
Expand Down

0 comments on commit b218b7e

Please sign in to comment.