1'use strict'; 2 3var expect = require('expect.js'); 4var promiseRetry = require('../'); 5var promiseDelay = require('sleep-promise'); 6 7describe('promise-retry', function () { 8 it('should call fn again if retry was called', function () { 9 var count = 0; 10 11 return promiseRetry(function (retry) { 12 count += 1; 13 14 return promiseDelay(10) 15 .then(function () { 16 if (count <= 2) { 17 retry(new Error('foo')); 18 } 19 20 return 'final'; 21 }); 22 }, { factor: 1 }) 23 .then(function (value) { 24 expect(value).to.be('final'); 25 expect(count).to.be(3); 26 }, function () { 27 throw new Error('should not fail'); 28 }); 29 }); 30 31 it('should call fn with the attempt number', function () { 32 var count = 0; 33 34 return promiseRetry(function (retry, number) { 35 count += 1; 36 expect(count).to.equal(number); 37 38 return promiseDelay(10) 39 .then(function () { 40 if (count <= 2) { 41 retry(new Error('foo')); 42 } 43 44 return 'final'; 45 }); 46 }, { factor: 1 }) 47 .then(function (value) { 48 expect(value).to.be('final'); 49 expect(count).to.be(3); 50 }, function () { 51 throw new Error('should not fail'); 52 }); 53 }); 54 55 it('should not retry on fulfillment if retry was not called', function () { 56 var count = 0; 57 58 return promiseRetry(function () { 59 count += 1; 60 61 return promiseDelay(10) 62 .then(function () { 63 return 'final'; 64 }); 65 }) 66 .then(function (value) { 67 expect(value).to.be('final'); 68 expect(count).to.be(1); 69 }, function () { 70 throw new Error('should not fail'); 71 }); 72 }); 73 74 it('should not retry on rejection if retry was not called', function () { 75 var count = 0; 76 77 return promiseRetry(function () { 78 count += 1; 79 80 return promiseDelay(10) 81 .then(function () { 82 throw new Error('foo'); 83 }); 84 }) 85 .then(function () { 86 throw new Error('should not succeed'); 87 }, function (err) { 88 expect(err.message).to.be('foo'); 89 expect(count).to.be(1); 90 }); 91 }); 92 93 it('should not retry on rejection if nr of retries is 0', function () { 94 var count = 0; 95 96 return promiseRetry(function (retry) { 97 count += 1; 98 99 return promiseDelay(10) 100 .then(function () { 101 throw new Error('foo'); 102 }) 103 .catch(retry); 104 }, { retries : 0 }) 105 .then(function () { 106 throw new Error('should not succeed'); 107 }, function (err) { 108 expect(err.message).to.be('foo'); 109 expect(count).to.be(1); 110 }); 111 }); 112 113 it('should reject the promise if the retries were exceeded', function () { 114 var count = 0; 115 116 return promiseRetry(function (retry) { 117 count += 1; 118 119 return promiseDelay(10) 120 .then(function () { 121 throw new Error('foo'); 122 }) 123 .catch(retry); 124 }, { retries: 2, factor: 1 }) 125 .then(function () { 126 throw new Error('should not succeed'); 127 }, function (err) { 128 expect(err.message).to.be('foo'); 129 expect(count).to.be(3); 130 }); 131 }); 132 133 it('should pass options to the underlying retry module', function () { 134 var count = 0; 135 136 return promiseRetry(function (retry) { 137 return promiseDelay(10) 138 .then(function () { 139 if (count < 2) { 140 count += 1; 141 retry(new Error('foo')); 142 } 143 144 return 'final'; 145 }); 146 }, { retries: 1, factor: 1 }) 147 .then(function () { 148 throw new Error('should not succeed'); 149 }, function (err) { 150 expect(err.message).to.be('foo'); 151 }); 152 }); 153 154 it('should convert direct fulfillments into promises', function () { 155 return promiseRetry(function () { 156 return 'final'; 157 }, { factor: 1 }) 158 .then(function (value) { 159 expect(value).to.be('final'); 160 }, function () { 161 throw new Error('should not fail'); 162 }); 163 }); 164 165 it('should convert direct rejections into promises', function () { 166 promiseRetry(function () { 167 throw new Error('foo'); 168 }, { retries: 1, factor: 1 }) 169 .then(function () { 170 throw new Error('should not succeed'); 171 }, function (err) { 172 expect(err.message).to.be('foo'); 173 }); 174 }); 175 176 it('should not crash on undefined rejections', function () { 177 return promiseRetry(function () { 178 throw undefined; 179 }, { retries: 1, factor: 1 }) 180 .then(function () { 181 throw new Error('should not succeed'); 182 }, function (err) { 183 expect(err).to.be(undefined); 184 }) 185 .then(function () { 186 return promiseRetry(function (retry) { 187 retry(); 188 }, { retries: 1, factor: 1 }); 189 }) 190 .then(function () { 191 throw new Error('should not succeed'); 192 }, function (err) { 193 expect(err).to.be(undefined); 194 }); 195 }); 196 197 it('should retry if retry() was called with undefined', function () { 198 var count = 0; 199 200 return promiseRetry(function (retry) { 201 count += 1; 202 203 return promiseDelay(10) 204 .then(function () { 205 if (count <= 2) { 206 retry(); 207 } 208 209 return 'final'; 210 }); 211 }, { factor: 1 }) 212 .then(function (value) { 213 expect(value).to.be('final'); 214 expect(count).to.be(3); 215 }, function () { 216 throw new Error('should not fail'); 217 }); 218 }); 219 220 it('should work with several retries in the same chain', function () { 221 var count = 0; 222 223 return promiseRetry(function (retry) { 224 count += 1; 225 226 return promiseDelay(10) 227 .then(function () { 228 retry(new Error('foo')); 229 }) 230 .catch(function (err) { 231 retry(err); 232 }); 233 }, { retries: 1, factor: 1 }) 234 .then(function () { 235 throw new Error('should not succeed'); 236 }, function (err) { 237 expect(err.message).to.be('foo'); 238 expect(count).to.be(2); 239 }); 240 }); 241 242 it('should allow options to be passed first', function () { 243 var count = 0; 244 245 return promiseRetry({ factor: 1 }, function (retry) { 246 count += 1; 247 248 return promiseDelay(10) 249 .then(function () { 250 if (count <= 2) { 251 retry(new Error('foo')); 252 } 253 254 return 'final'; 255 }); 256 }).then(function (value) { 257 expect(value).to.be('final'); 258 expect(count).to.be(3); 259 }, function () { 260 throw new Error('should not fail'); 261 }); 262 }); 263}); 264