blob: a77c6d1c2aa4bd0c89cf5123da7b0955e2141615 [file] [log] [blame]
<!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>