Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

Commit 56dae6f

Browse files
jurko-gospodneticgkalpak
authored andcommitted
fix(ngMock): fix collecting stack trace in inject() on IE10+, PhantomJS
Add support for collecting current stack trace information in browsers (e.g. IE10+, PhantomJS) that do not automatically store the current stack trace information in a newly created `Error` object's `stack` property, but only add it there once the `Error` gets thrown. The original implementation works fine in Firefox & Chrome, but fails on IE10+ and PhantomJS where it, for example, breaks Karma's error reporting in cases when an exception is thrown in a test like the following: ``` it('the holy crusade', inject(function() { var x = {}; x.holyGrail(); })); ``` In this case, the ngMock `inject()` implementation would incorrectly add the word `undefined` at the end of the collected error stack trace information, thus causing the main error description to be reported back to Karma as `undefined`. The added test makes sure this functionality: - works as expected in browsers supporting JavaScript stack trace collection, e.g. Chrome, Firefox, IE10+, Opera & PhantomJS - does not add any bogus stack track information in browsers that do not support JavaScript stack trace collection, e.g. IE9 Fixes #13591 Closes #13592 Closes #13593
1 parent 611dcbc commit 56dae6f

File tree

2 files changed

+51
-0
lines changed

2 files changed

+51
-0
lines changed

src/ngMock/angular-mocks.js

+6
Original file line numberDiff line numberDiff line change
@@ -2480,6 +2480,12 @@ if (window.jasmine || window.mocha) {
24802480
window.inject = angular.mock.inject = function() {
24812481
var blockFns = Array.prototype.slice.call(arguments, 0);
24822482
var errorForStack = new Error('Declaration Location');
2483+
// IE10+ and PhanthomJS do not set stack trace information, until the error is thrown
2484+
if (!errorForStack.stack) {
2485+
try {
2486+
throw errorForStack;
2487+
} catch (e) {}
2488+
}
24832489
return isSpecRunning() ? workFn.call(currentSpec) : workFn;
24842490
/////////////////////
24852491
function workFn() {

test/ngMock/angular-mocksSpec.js

+45
Original file line numberDiff line numberDiff line change
@@ -919,6 +919,51 @@ describe('ngMock', function() {
919919
});
920920
}).toThrow('test message');
921921
}));
922+
923+
describe('error stack trace when called outside of spec context', function() {
924+
// - Chrome, Firefox, Edge, Opera give us the stack trace as soon as an Error is created
925+
// - IE10+, PhantomJS give us the stack trace only once the error is thrown
926+
// - IE9 does not provide stack traces
927+
var stackTraceSupported = (function() {
928+
var error = new Error();
929+
if (!error.stack) {
930+
try {
931+
throw error;
932+
} catch (e) {}
933+
}
934+
935+
return !!error.stack;
936+
})();
937+
938+
function testCaller() {
939+
return inject(function() {
940+
throw new Error();
941+
});
942+
}
943+
var throwErrorFromInjectCallback = testCaller();
944+
945+
if (stackTraceSupported) {
946+
describe('on browsers supporting stack traces', function() {
947+
it('should update thrown Error stack trace with inject call location', function() {
948+
try {
949+
throwErrorFromInjectCallback();
950+
} catch (e) {
951+
expect(e.stack).toMatch('testCaller');
952+
}
953+
});
954+
});
955+
} else {
956+
describe('on browsers not supporting stack traces', function() {
957+
it('should not add stack trace information to thrown Error', function() {
958+
try {
959+
throwErrorFromInjectCallback();
960+
} catch (e) {
961+
expect(e.stack).toBeUndefined();
962+
}
963+
});
964+
});
965+
}
966+
});
922967
});
923968
});
924969

0 commit comments

Comments
 (0)