| <!DOCTYPE html> |
| <html> |
| <!-- |
| Copyright 2013 The Closure Library Authors. All Rights Reserved. |
| --> |
| <head> |
| <title>Closure Unit Tests - goog.async.Deferred</title> |
| <script src="../../../../../closure/goog/base.js"></script> |
| <script> |
| |
| goog.require('goog.async.Deferred'); |
| goog.require('goog.testing.AsyncTestCase'); |
| goog.require('goog.testing.MockClock'); |
| goog.require('goog.testing.jsunit'); |
| |
| </script> |
| </head> |
| <body> |
| <script> |
| |
| var asyncTestCase = goog.testing.AsyncTestCase.createAndInstall(); |
| var realSetTimeout = window.setTimeout; |
| var mockClock = new goog.testing.MockClock(); |
| |
| function setUp() { |
| mockClock.install(); |
| goog.async.Deferred.LONG_STACK_TRACES = true; |
| } |
| |
| function tearDown() { |
| // Advance the mockClock to fire any unhandled exception timeouts. |
| mockClock.tick(); |
| mockClock.uninstall(); |
| } |
| |
| function testErrorStack() { |
| if (!Error.captureStackTrace) { |
| return; |
| } |
| var d; |
| // Get the deferred from somewhere deep in the callstack. |
| (function immediate() { |
| (function immediate2() { |
| d = new goog.async.Deferred(); |
| d.addCallback(function actuallyThrows() { |
| throw new Error('Foo'); |
| }); |
| })(); |
| })(); |
| d.addCallback(function actuallyThrows() { |
| throw new Error('Foo'); |
| }); |
| asyncTestCase.waitForAsync('Wait for timeout'); |
| realSetTimeout(function willThrow() { |
| var error = assertThrows(function callbackCaller() { |
| d.callback(); |
| mockClock.tick(); |
| }); |
| assertContains('Foo', error.stack); |
| assertContains('testErrorStack', error.stack); |
| assertContains('callbackCaller', error.stack); |
| assertContains('willThrow', error.stack); |
| assertContains('actuallyThrows', error.stack); |
| assertContains('DEFERRED OPERATION', error.stack); |
| assertContains('immediate', error.stack); |
| assertContains('immediate2', error.stack); |
| |
| asyncTestCase.continueTesting(); |
| }, 0); |
| } |
| |
| function testErrorStack_forErrback() { |
| if (!Error.captureStackTrace) { |
| return; |
| } |
| var d = new goog.async.Deferred(); |
| asyncTestCase.waitForAsync('Wait for timeout'); |
| realSetTimeout(function willThrow() { |
| d.errback(new Error('Foo')); |
| asyncTestCase.continueTesting(); |
| }, 0); |
| |
| d.addErrback(function(error) { |
| assertContains('Foo', error.stack); |
| assertContains('testErrorStack_forErrback', error.stack); |
| assertContains('willThrow', error.stack); |
| assertContains('DEFERRED OPERATION', error.stack); |
| }); |
| } |
| |
| function testErrorStack_nested() { |
| if (!Error.captureStackTrace) { |
| return; |
| } |
| var d = new goog.async.Deferred(); |
| d.addErrback(function(error) { |
| assertContains('Foo', error.stack); |
| assertContains('testErrorStack_nested', error.stack); |
| assertContains('async1', error.stack); |
| assertContains('async2', error.stack); |
| assertContains('immediate', error.stack); |
| assertContains('DEFERRED OPERATION', error.stack); |
| }); |
| asyncTestCase.waitForAsync('Wait for timeout'); |
| realSetTimeout(function async1() { |
| var nested = new goog.async.Deferred(); |
| nested.addErrback(function nestedErrback(error) { |
| d.errback(error); |
| mockClock.tick(); |
| }); |
| realSetTimeout(function async2() { |
| (function immediate() { |
| nested.errback(new Error('Foo')); |
| mockClock.tick(); |
| })(); |
| |
| asyncTestCase.continueTesting(); |
| }); |
| }, 0); |
| } |
| |
| function testErrorStack_doesNotTouchCustomStack() { |
| if (!Error.captureStackTrace) { |
| return; |
| } |
| var d = new goog.async.Deferred(); |
| d.addCallback(function actuallyThrows() { |
| var e = new Error('Foo'); |
| e.stack = 'STACK'; |
| throw e; |
| }); |
| asyncTestCase.waitForAsync('Wait for timeout'); |
| realSetTimeout(function willThrow() { |
| var error = assertThrows(function callbackCaller() { |
| d.callback(); |
| mockClock.tick(); |
| }); |
| assertContains('STACK', error.stack); |
| asyncTestCase.continueTesting(); |
| }, 0); |
| } |
| |
| </script> |
| </body> |
| </html> |