2023-10-03 11:14:36 +08:00
|
|
|
'use strict';
|
|
|
|
|
|
|
|
var expect = require('expect.js');
|
|
|
|
var promiseRetry = require('../');
|
|
|
|
var promiseDelay = require('sleep-promise');
|
|
|
|
|
|
|
|
describe('promise-retry', function () {
|
|
|
|
it('should call fn again if retry was called', function () {
|
|
|
|
var count = 0;
|
|
|
|
|
|
|
|
return promiseRetry(function (retry) {
|
|
|
|
count += 1;
|
|
|
|
|
|
|
|
return promiseDelay(10)
|
|
|
|
.then(function () {
|
|
|
|
if (count <= 2) {
|
|
|
|
retry(new Error('foo'));
|
|
|
|
}
|
|
|
|
|
|
|
|
return 'final';
|
|
|
|
});
|
|
|
|
}, { factor: 1 })
|
|
|
|
.then(function (value) {
|
|
|
|
expect(value).to.be('final');
|
|
|
|
expect(count).to.be(3);
|
|
|
|
}, function () {
|
|
|
|
throw new Error('should not fail');
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should call fn with the attempt number', function () {
|
|
|
|
var count = 0;
|
|
|
|
|
|
|
|
return promiseRetry(function (retry, number) {
|
|
|
|
count += 1;
|
|
|
|
expect(count).to.equal(number);
|
|
|
|
|
|
|
|
return promiseDelay(10)
|
|
|
|
.then(function () {
|
|
|
|
if (count <= 2) {
|
|
|
|
retry(new Error('foo'));
|
|
|
|
}
|
|
|
|
|
|
|
|
return 'final';
|
|
|
|
});
|
|
|
|
}, { factor: 1 })
|
|
|
|
.then(function (value) {
|
|
|
|
expect(value).to.be('final');
|
|
|
|
expect(count).to.be(3);
|
|
|
|
}, function () {
|
|
|
|
throw new Error('should not fail');
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should not retry on fulfillment if retry was not called', function () {
|
|
|
|
var count = 0;
|
|
|
|
|
|
|
|
return promiseRetry(function () {
|
|
|
|
count += 1;
|
|
|
|
|
|
|
|
return promiseDelay(10)
|
|
|
|
.then(function () {
|
|
|
|
return 'final';
|
|
|
|
});
|
|
|
|
})
|
|
|
|
.then(function (value) {
|
|
|
|
expect(value).to.be('final');
|
|
|
|
expect(count).to.be(1);
|
|
|
|
}, function () {
|
|
|
|
throw new Error('should not fail');
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should not retry on rejection if retry was not called', function () {
|
|
|
|
var count = 0;
|
|
|
|
|
|
|
|
return promiseRetry(function () {
|
|
|
|
count += 1;
|
|
|
|
|
|
|
|
return promiseDelay(10)
|
|
|
|
.then(function () {
|
|
|
|
throw new Error('foo');
|
|
|
|
});
|
|
|
|
})
|
|
|
|
.then(function () {
|
|
|
|
throw new Error('should not succeed');
|
|
|
|
}, function (err) {
|
|
|
|
expect(err.message).to.be('foo');
|
|
|
|
expect(count).to.be(1);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should not retry on rejection if nr of retries is 0', function () {
|
|
|
|
var count = 0;
|
|
|
|
|
|
|
|
return promiseRetry(function (retry) {
|
|
|
|
count += 1;
|
|
|
|
|
|
|
|
return promiseDelay(10)
|
|
|
|
.then(function () {
|
|
|
|
throw new Error('foo');
|
|
|
|
})
|
|
|
|
.catch(retry);
|
|
|
|
}, { retries : 0 })
|
|
|
|
.then(function () {
|
|
|
|
throw new Error('should not succeed');
|
|
|
|
}, function (err) {
|
|
|
|
expect(err.message).to.be('foo');
|
|
|
|
expect(count).to.be(1);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should reject the promise if the retries were exceeded', function () {
|
|
|
|
var count = 0;
|
|
|
|
|
|
|
|
return promiseRetry(function (retry) {
|
|
|
|
count += 1;
|
|
|
|
|
|
|
|
return promiseDelay(10)
|
|
|
|
.then(function () {
|
|
|
|
throw new Error('foo');
|
|
|
|
})
|
|
|
|
.catch(retry);
|
|
|
|
}, { retries: 2, factor: 1 })
|
|
|
|
.then(function () {
|
|
|
|
throw new Error('should not succeed');
|
|
|
|
}, function (err) {
|
|
|
|
expect(err.message).to.be('foo');
|
|
|
|
expect(count).to.be(3);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should pass options to the underlying retry module', function () {
|
|
|
|
var count = 0;
|
|
|
|
|
|
|
|
return promiseRetry(function (retry) {
|
|
|
|
return promiseDelay(10)
|
|
|
|
.then(function () {
|
|
|
|
if (count < 2) {
|
|
|
|
count += 1;
|
|
|
|
retry(new Error('foo'));
|
|
|
|
}
|
|
|
|
|
|
|
|
return 'final';
|
|
|
|
});
|
|
|
|
}, { retries: 1, factor: 1 })
|
|
|
|
.then(function () {
|
|
|
|
throw new Error('should not succeed');
|
|
|
|
}, function (err) {
|
|
|
|
expect(err.message).to.be('foo');
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should convert direct fulfillments into promises', function () {
|
|
|
|
return promiseRetry(function () {
|
|
|
|
return 'final';
|
|
|
|
}, { factor: 1 })
|
|
|
|
.then(function (value) {
|
|
|
|
expect(value).to.be('final');
|
|
|
|
}, function () {
|
|
|
|
throw new Error('should not fail');
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should convert direct rejections into promises', function () {
|
|
|
|
promiseRetry(function () {
|
|
|
|
throw new Error('foo');
|
|
|
|
}, { retries: 1, factor: 1 })
|
|
|
|
.then(function () {
|
|
|
|
throw new Error('should not succeed');
|
|
|
|
}, function (err) {
|
|
|
|
expect(err.message).to.be('foo');
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should not crash on undefined rejections', function () {
|
|
|
|
return promiseRetry(function () {
|
|
|
|
throw undefined;
|
|
|
|
}, { retries: 1, factor: 1 })
|
|
|
|
.then(function () {
|
|
|
|
throw new Error('should not succeed');
|
|
|
|
}, function (err) {
|
|
|
|
expect(err).to.be(undefined);
|
|
|
|
})
|
|
|
|
.then(function () {
|
|
|
|
return promiseRetry(function (retry) {
|
|
|
|
retry();
|
|
|
|
}, { retries: 1, factor: 1 });
|
|
|
|
})
|
|
|
|
.then(function () {
|
|
|
|
throw new Error('should not succeed');
|
|
|
|
}, function (err) {
|
|
|
|
expect(err).to.be(undefined);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should retry if retry() was called with undefined', function () {
|
|
|
|
var count = 0;
|
|
|
|
|
|
|
|
return promiseRetry(function (retry) {
|
|
|
|
count += 1;
|
|
|
|
|
|
|
|
return promiseDelay(10)
|
|
|
|
.then(function () {
|
|
|
|
if (count <= 2) {
|
|
|
|
retry();
|
|
|
|
}
|
|
|
|
|
|
|
|
return 'final';
|
|
|
|
});
|
|
|
|
}, { factor: 1 })
|
|
|
|
.then(function (value) {
|
|
|
|
expect(value).to.be('final');
|
|
|
|
expect(count).to.be(3);
|
|
|
|
}, function () {
|
|
|
|
throw new Error('should not fail');
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should work with several retries in the same chain', function () {
|
|
|
|
var count = 0;
|
|
|
|
|
|
|
|
return promiseRetry(function (retry) {
|
|
|
|
count += 1;
|
|
|
|
|
|
|
|
return promiseDelay(10)
|
|
|
|
.then(function () {
|
|
|
|
retry(new Error('foo'));
|
|
|
|
})
|
|
|
|
.catch(function (err) {
|
|
|
|
retry(err);
|
|
|
|
});
|
|
|
|
}, { retries: 1, factor: 1 })
|
|
|
|
.then(function () {
|
|
|
|
throw new Error('should not succeed');
|
|
|
|
}, function (err) {
|
|
|
|
expect(err.message).to.be('foo');
|
|
|
|
expect(count).to.be(2);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should allow options to be passed first', function () {
|
|
|
|
var count = 0;
|
|
|
|
|
|
|
|
return promiseRetry({ factor: 1 }, function (retry) {
|
|
|
|
count += 1;
|
|
|
|
|
|
|
|
return promiseDelay(10)
|
|
|
|
.then(function () {
|
|
|
|
if (count <= 2) {
|
|
|
|
retry(new Error('foo'));
|
|
|
|
}
|
|
|
|
|
|
|
|
return 'final';
|
|
|
|
});
|
|
|
|
}).then(function (value) {
|
|
|
|
expect(value).to.be('final');
|
|
|
|
expect(count).to.be(3);
|
|
|
|
}, function () {
|
|
|
|
throw new Error('should not fail');
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|