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
This commit is contained in:
committed by
Georgios Kalpakas
parent
611dcbc035
commit
56dae6fa1b
Vendored
+6
@@ -2480,6 +2480,12 @@ if (window.jasmine || window.mocha) {
|
||||
window.inject = angular.mock.inject = function() {
|
||||
var blockFns = Array.prototype.slice.call(arguments, 0);
|
||||
var errorForStack = new Error('Declaration Location');
|
||||
// IE10+ and PhanthomJS do not set stack trace information, until the error is thrown
|
||||
if (!errorForStack.stack) {
|
||||
try {
|
||||
throw errorForStack;
|
||||
} catch (e) {}
|
||||
}
|
||||
return isSpecRunning() ? workFn.call(currentSpec) : workFn;
|
||||
/////////////////////
|
||||
function workFn() {
|
||||
|
||||
Vendored
+45
@@ -919,6 +919,51 @@ describe('ngMock', function() {
|
||||
});
|
||||
}).toThrow('test message');
|
||||
}));
|
||||
|
||||
describe('error stack trace when called outside of spec context', function() {
|
||||
// - Chrome, Firefox, Edge, Opera give us the stack trace as soon as an Error is created
|
||||
// - IE10+, PhantomJS give us the stack trace only once the error is thrown
|
||||
// - IE9 does not provide stack traces
|
||||
var stackTraceSupported = (function() {
|
||||
var error = new Error();
|
||||
if (!error.stack) {
|
||||
try {
|
||||
throw error;
|
||||
} catch (e) {}
|
||||
}
|
||||
|
||||
return !!error.stack;
|
||||
})();
|
||||
|
||||
function testCaller() {
|
||||
return inject(function() {
|
||||
throw new Error();
|
||||
});
|
||||
}
|
||||
var throwErrorFromInjectCallback = testCaller();
|
||||
|
||||
if (stackTraceSupported) {
|
||||
describe('on browsers supporting stack traces', function() {
|
||||
it('should update thrown Error stack trace with inject call location', function() {
|
||||
try {
|
||||
throwErrorFromInjectCallback();
|
||||
} catch (e) {
|
||||
expect(e.stack).toMatch('testCaller');
|
||||
}
|
||||
});
|
||||
});
|
||||
} else {
|
||||
describe('on browsers not supporting stack traces', function() {
|
||||
it('should not add stack trace information to thrown Error', function() {
|
||||
try {
|
||||
throwErrorFromInjectCallback();
|
||||
} catch (e) {
|
||||
expect(e.stack).toBeUndefined();
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user