1 var Q = require('../kew')
2 var originalQ = require('q')
4 // test that fin() works with a synchronous resolve
5 exports.testSynchronousThenAndFin = function (test) {
9 var promise1 = Q.resolve(vals[0])
10 var promise2 = promise1.fin(function () {
13 var promise3 = promise2.then(function (data) {
14 if (data === vals[0]) return vals[1]
16 var promise4 = promise3.fin(function () {
20 Q.all([promise2, promise4])
21 .then(function (data) {
22 test.equal(counter, 2, "fin() should have been called twice")
23 test.equal(data[0], vals[0], "first fin() should return the first val")
24 test.equal(data[1], vals[1], "second fin() should return the second val")
29 // test that fin() works with a synchronous reject
30 exports.testSynchronousFailAndFin = function (test) {
32 errs.push(new Error('nope 1'))
33 errs.push(new Error('nope 2'))
36 var promise1 = Q.reject(errs[0])
37 var promise2 = promise1.fin(function () {
40 var promise3 = promise2.fail(function (e) {
41 if (e === errs[0]) throw errs[1]
43 var promise4 = promise3.fin(function () {
48 promise2.fail(function (e) {
51 promise4.fail(function (e) {
55 .then(function (data) {
56 test.equal(counter, 2, "fin() should have been called twice")
57 test.equal(data[0] && data[1], true, "all promises should return true")
62 // test that fin() works with an asynchrnous resolve
63 exports.testAsynchronousThenAndFin = function (test) {
68 setTimeout(function () {
69 defer.resolve(vals[0])
71 var promise1 = defer.promise
72 var promise2 = promise1.fin(function () {
75 var promise3 = promise2.then(function (data) {
76 if (data !== vals[0]) return
79 setTimeout(function () {
80 defer.resolve(vals[1])
84 var promise4 = promise3.fin(function () {
88 Q.all([promise2, promise4])
89 .then(function (data) {
90 test.equal(counter, 2, "fin() should have been called twice")
91 test.equal(data[0], vals[0], "first fin() should return the first val")
92 test.equal(data[1], vals[1], "second fin() should return the second val")
97 // test that fin() works with an asynchronous reject
98 exports.testAsynchronousFailAndFin = function (test) {
100 errs.push(new Error('nope 1'))
101 errs.push(new Error('nope 2'))
104 var defer = Q.defer()
105 setTimeout(function () {
106 defer.reject(errs[0])
108 var promise1 = defer.promise
109 var promise2 = promise1.fin(function () {
112 var promise3 = promise2.fail(function (e) {
113 if (e !== errs[0]) return
115 var defer = Q.defer()
116 setTimeout(function () {
117 defer.reject(errs[1])
122 var promise4 = promise3.fin(function () {
127 promise2.fail(function (e) {
130 promise4.fail(function (e) {
134 .then(function (data) {
135 test.equal(counter, 2, "fin() should have been called twice")
136 test.equal(data[0] && data[1], true, "all promises should return true")
141 // test several thens chaining
142 exports.testChainedThens = function (test) {
143 var promise1 = Q.resolve('a')
144 var promise2 = promise1.then(function(data) {
147 var promise3 = promise2.then(function (data) {
150 // testing the same promise again to make sure they can run side by side
151 var promise4 = promise2.then(function (data) {
155 Q.all([promise1, promise2, promise3, promise4])
156 .then(function (data) {
157 test.equal(data[0], 'a')
158 test.equal(data[1], 'ab')
159 test.equal(data[2], 'abc')
160 test.equal(data[3], 'abc')
165 // test several fails chaining
166 exports.testChainedFails = function (test) {
168 errs.push(new Error("first err"))
169 errs.push(new Error("second err"))
170 errs.push(new Error("third err"))
172 var promise1 = Q.reject(errs[0])
173 var promise2 = promise1.fail(function (e) {
174 if (e === errs[0]) throw errs[1]
176 var promise3 = promise2.fail(function (e) {
177 if (e === errs[1]) throw errs[2]
179 var promise4 = promise2.fail(function (e) {
180 if (e === errs[1]) throw errs[2]
184 promise1.fail(function (e) {
187 promise2.fail(function (e) {
190 promise3.fail(function (e) {
193 promise4.fail(function (e) {
197 .then(function (data) {
198 test.equal(data[0] && data[1] && data[2] && data[3], true)
203 // test that we can call end without callbacks and not fail
204 exports.testEndNoCallbacks = function (test) {
205 Q.resolve(true).end()
206 test.ok("Ended successfully")
210 // test that we can call end with callbacks and fail
211 exports.testEndNoCallbacksThrows = function (test) {
212 var testError = new Error('Testing')
214 Q.reject(testError).end()
215 test.fail("Should throw an error")
217 test.equal(e, testError, "Should throw the correct error")
222 // test chaining when a promise returns a promise
223 exports.testChainedPromises = function (test) {
224 var err = new Error('nope')
227 var shouldFail = Q.reject(err)
228 var shouldSucceed = Q.resolve(val)
235 if (e === err) return shouldSucceed
238 .then(function (data) {
239 test.equal(data, val, "val should be returned")
244 // test .end() is called with no parent scope (causing an uncaught exception)
245 exports.testChainedEndUncaught = function (test) {
246 var uncaughtErrors = 0
248 errs.push(new Error('nope 1'))
249 errs.push(new Error('nope 2'))
250 errs.push(new Error('nope 3'))
252 var cb = function (e) {
255 test.equal(uncaughtErrors, 3, "Errors should be uncaught")
256 process.removeListener('uncaughtException', cb)
260 process.on('uncaughtException', cb)
262 var defer = Q.defer()
265 var promise1 = defer.promise
266 var promise2 = promise1.fail(function (e) {
267 if (e === errs[0]) throw errs[1]
269 var promise3 = promise2.fail(function (e) {
270 if (e === errs[1]) throw errs[2]
277 setTimeout(function () {
278 defer.reject(errs[0])
282 // test .end() is called with a parent scope and is caught
283 exports.testChainedCaught = function (test) {
284 var err = new Error('nope')
289 test.equal(e, err, "Error should be caught")
294 // test a mix of fails and thens
295 exports.testChainedMixed = function (test) {
297 errs.push(new Error('nope 1'))
298 errs.push(new Error('nope 2'))
299 errs.push(new Error('nope 3'))
303 var promise1 = Q.reject(errs[0])
304 var promise2 = promise1.fail(function (e) {
305 if (e === errs[0]) return vals[0]
307 var promise3 = promise2.then(function (data) {
308 if (data === vals[0]) throw errs[1]
310 var promise4 = promise3.fail(function (e) {
311 if (e === errs[1]) return vals[1]
313 var promise5 = promise4.then(function (data) {
314 if (data === vals[1]) throw errs[2]
316 var promise6 = promise5.fail(function (e) {
317 if (e === errs[2]) return vals[2]
321 promise1.fail(function (e) {
324 promise2.then(function (data) {
325 return data === vals[0]
327 promise3.fail(function (e) {
330 promise4.then(function (data) {
331 return data === vals[1]
333 promise5.fail(function (e) {
336 promise6.then(function (data) {
337 return data === vals[2]
340 .then(function (data) {
341 test.equal(data[0] && data[1] && data[2] && data[3] && data[4] && data[5], true, "All values should return true")
346 exports.testInteroperabilityWithOtherPromises = function(test) {
347 var promise1 = Q.defer()
348 promise1.then(function(value) {
349 return originalQ(1 + value)
350 }).then(function(result) {
351 test.equal(result, 11)
354 var promise2 = Q.defer(),
355 errToThrow = new Error('error')
356 promise2.then(function() {
357 return originalQ.reject(errToThrow)
358 }).fail(function(err) {
359 test.equal(err, errToThrow)
365 Q.all([promise1, promise2]).then(function() {
370 exports.testAllSettled = function(test) {
371 var promise1 = Q.resolve('woot')
372 var promise2 = Q.reject(new Error('oops'))
374 Q.allSettled([promise1, promise2, 'just a string'])
375 .then(function (data) {
376 test.equals('fulfilled', data[0].state)
377 test.equals('woot', data[0].value)
378 test.equals('rejected', data[1].state)
379 test.equals('oops', data[1].reason.message)
380 test.equals('fulfilled', data[2].state)
381 test.equals('just a string', data[2].value)
385 .then(function (data) {
386 test.equals(0, data.length)
391 exports.testTimeout = function(test) {
392 var promise = Q.delay(50).timeout(45, 'Timeout message')
393 promise.then(function () {
394 test.fail('The promise is supposed to be timeout')
397 test.equals('Timeout message', e.message, 'The error message should be the one passed into timeout()')
402 exports.testNotTimeout = function(test) {
403 var promise = Q.delay('expected data', 40).timeout(45, 'Timeout message')
404 promise.then(function (data) {
405 test.equals('expected data', data, 'The data should be the data from the original promise')
408 test.fail('The promise is supposed to be resolved before the timeout')
413 exports.testNotTimeoutButReject = function(test) {
414 var promise = Q.delay(40).then(function() {throw new Error('Reject message')}).timeout(45, 'Timeout message')
415 promise.then(function (data) {
416 test.fail('The promise is supposed to be rejected')
419 test.equals('Reject message', e.message, 'The error message should be from the original promise')
424 exports.testDelay = function (test) {
425 var timePassed = false
426 setTimeout(function () {
429 Q.resolve('expected').delay(20).then(function (result) {
430 test.equal('expected', result)