Merge remote-tracking branch 'origin/5.0' into parallel
This commit is contained in:
@@ -1291,20 +1291,14 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
|
||||
if (!options.suppressLoadErrors) {
|
||||
installGlobalErrors();
|
||||
globalErrors.pushListener(function loadtimeErrorHandler(
|
||||
message,
|
||||
filename,
|
||||
lineno,
|
||||
colNo,
|
||||
err
|
||||
) {
|
||||
globalErrors.pushListener(function loadtimeErrorHandler(error, event) {
|
||||
topSuite.result.failedExpectations.push({
|
||||
passed: false,
|
||||
globalErrorType: 'load',
|
||||
message: message,
|
||||
stack: err && err.stack,
|
||||
filename: filename,
|
||||
lineno: lineno
|
||||
message: error ? error.message : event.message,
|
||||
stack: error && error.stack,
|
||||
filename: event && event.filename,
|
||||
lineno: event && event.lineno
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -1648,18 +1642,12 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
/**
|
||||
* Executes the specs.
|
||||
*
|
||||
* If called with no parameters or with a falsy value as the first parameter,
|
||||
* If called with no parameter or with a falsy parameter,
|
||||
* all specs will be executed except those that are excluded by a
|
||||
* [spec filter]{@link Configuration#specFilter} or other mechanism. If the
|
||||
* first parameter is a list of spec/suite IDs, only those specs/suites will
|
||||
* parameter is a list of spec/suite IDs, only those specs/suites will
|
||||
* be run.
|
||||
*
|
||||
* Both parameters are optional, but a completion callback is only valid as
|
||||
* the second parameter. To specify a completion callback but not a list of
|
||||
* specs/suites to run, pass null or undefined as the first parameter. The
|
||||
* completion callback is supported for backward compatibility. In most
|
||||
* cases it will be more convenient to use the returned promise instead.
|
||||
*
|
||||
* execute should not be called more than once unless the env has been
|
||||
* configured with `{autoCleanClosures: false}`.
|
||||
*
|
||||
@@ -1667,25 +1655,19 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
* {@link JasmineDoneInfo|overall result} that's passed to a reporter's
|
||||
* `jasmineDone` method, even if the suite did not pass. To determine
|
||||
* whether the suite passed, check the value that the promise resolves to
|
||||
* or use a {@link Reporter}.
|
||||
* or use a {@link Reporter}. The promise will be rejected in the case of
|
||||
* certain serious errors that prevent execution from starting.
|
||||
*
|
||||
* @name Env#execute
|
||||
* @since 2.0.0
|
||||
* @function
|
||||
* @async
|
||||
* @param {(string[])=} runablesToRun IDs of suites and/or specs to run
|
||||
* @param {Function=} onComplete Function that will be called after all specs have run
|
||||
* @return {Promise<JasmineDoneInfo>}
|
||||
*/
|
||||
this.execute = function(runablesToRun, onComplete) {
|
||||
this.execute = async function(runablesToRun) {
|
||||
installGlobalErrors();
|
||||
|
||||
return runner.execute(runablesToRun).then(function(jasmineDoneInfo) {
|
||||
if (onComplete) {
|
||||
onComplete();
|
||||
}
|
||||
|
||||
return jasmineDoneInfo;
|
||||
});
|
||||
return runner.execute(runablesToRun);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -3982,18 +3964,22 @@ getJasmineRequireObj().GlobalErrors = function(j$) {
|
||||
let overrideHandler = null,
|
||||
onRemoveOverrideHandler = null;
|
||||
|
||||
function onerror(message, source, lineno, colno, error) {
|
||||
function onBrowserError(event) {
|
||||
dispatchBrowserError(event.error, event);
|
||||
}
|
||||
|
||||
function dispatchBrowserError(error, event) {
|
||||
if (overrideHandler) {
|
||||
overrideHandler(error || message);
|
||||
overrideHandler(error);
|
||||
return;
|
||||
}
|
||||
|
||||
const handler = handlers[handlers.length - 1];
|
||||
|
||||
if (handler) {
|
||||
handler.apply(null, Array.prototype.slice.call(arguments, 0));
|
||||
handler(error, event);
|
||||
} else {
|
||||
throw arguments[0];
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4070,8 +4056,7 @@ getJasmineRequireObj().GlobalErrors = function(j$) {
|
||||
this.installOne_('uncaughtException', 'Uncaught exception');
|
||||
this.installOne_('unhandledRejection', 'Unhandled promise rejection');
|
||||
} else {
|
||||
const originalHandler = global.onerror;
|
||||
global.onerror = onerror;
|
||||
global.addEventListener('error', onBrowserError);
|
||||
|
||||
const browserRejectionHandler = function browserRejectionHandler(
|
||||
event
|
||||
@@ -4079,16 +4064,19 @@ getJasmineRequireObj().GlobalErrors = function(j$) {
|
||||
if (j$.isError_(event.reason)) {
|
||||
event.reason.jasmineMessage =
|
||||
'Unhandled promise rejection: ' + event.reason;
|
||||
global.onerror(event.reason);
|
||||
dispatchBrowserError(event.reason, event);
|
||||
} else {
|
||||
global.onerror('Unhandled promise rejection: ' + event.reason);
|
||||
dispatchBrowserError(
|
||||
'Unhandled promise rejection: ' + event.reason,
|
||||
event
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
global.addEventListener('unhandledrejection', browserRejectionHandler);
|
||||
|
||||
this.uninstall = function uninstall() {
|
||||
global.onerror = originalHandler;
|
||||
global.removeEventListener('error', onBrowserError);
|
||||
global.removeEventListener(
|
||||
'unhandledrejection',
|
||||
browserRejectionHandler
|
||||
@@ -4097,6 +4085,13 @@ getJasmineRequireObj().GlobalErrors = function(j$) {
|
||||
}
|
||||
};
|
||||
|
||||
// The listener at the top of the stack will be called with two arguments:
|
||||
// the error and the event. Either of them may be falsy.
|
||||
// The error will normally be provided, but will be falsy in the case of
|
||||
// some browser load-time errors. The event will normally be provided in
|
||||
// browsers but will be falsy in Node.
|
||||
// Listeners that are pushed after spec files have been loaded should be
|
||||
// able to just use the error parameter.
|
||||
this.pushListener = function pushListener(listener) {
|
||||
handlers.push(listener);
|
||||
};
|
||||
@@ -7502,11 +7497,8 @@ getJasmineRequireObj().QueueRunner = function(j$) {
|
||||
}
|
||||
|
||||
QueueRunner.prototype.execute = function() {
|
||||
this.handleFinalError = (message, source, lineno, colno, error) => {
|
||||
// Older browsers would send the error as the first parameter. HTML5
|
||||
// specifies the the five parameters above. The error instance should
|
||||
// be preffered, otherwise the call stack would get lost.
|
||||
this.onException(error || message);
|
||||
this.handleFinalError = error => {
|
||||
this.onException(error);
|
||||
};
|
||||
this.globalErrors.pushListener(this.handleFinalError);
|
||||
this.run(0);
|
||||
@@ -8430,11 +8422,7 @@ getJasmineRequireObj().Runner = function(j$) {
|
||||
];
|
||||
}
|
||||
|
||||
// Although execute returns a promise, it isn't async for backwards
|
||||
// compatibility: The "Invalid order" exception needs to be propagated
|
||||
// synchronously from Env#execute.
|
||||
// TODO: make this and Env#execute async in the next major release
|
||||
execute(runablesToRun) {
|
||||
async execute(runablesToRun) {
|
||||
if (this.executedBefore_) {
|
||||
this.topSuite_.reset();
|
||||
}
|
||||
|
||||
@@ -1,56 +1,42 @@
|
||||
describe('GlobalErrors', function() {
|
||||
it('calls the added handler on error', function() {
|
||||
const fakeGlobal = minimalBrowserGlobal();
|
||||
const fakeGlobal = browserGlobal();
|
||||
const handler = jasmine.createSpy('errorHandler');
|
||||
const errors = new jasmineUnderTest.GlobalErrors(fakeGlobal);
|
||||
|
||||
errors.install();
|
||||
errors.pushListener(handler);
|
||||
|
||||
fakeGlobal.onerror('foo');
|
||||
|
||||
expect(handler).toHaveBeenCalledWith('foo');
|
||||
});
|
||||
|
||||
it('enables external interception of error by overriding global.onerror', function() {
|
||||
const fakeGlobal = minimalBrowserGlobal();
|
||||
const handler = jasmine.createSpy('errorHandler');
|
||||
const hijackHandler = jasmine.createSpy('hijackErrorHandler');
|
||||
const errors = new jasmineUnderTest.GlobalErrors(fakeGlobal);
|
||||
|
||||
errors.install();
|
||||
errors.pushListener(handler);
|
||||
|
||||
fakeGlobal.onerror = hijackHandler;
|
||||
|
||||
fakeGlobal.onerror('foo');
|
||||
|
||||
expect(hijackHandler).toHaveBeenCalledWith('foo');
|
||||
expect(handler).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('calls the global error handler with all parameters', function() {
|
||||
const fakeGlobal = minimalBrowserGlobal();
|
||||
const handler = jasmine.createSpy('errorHandler');
|
||||
const errors = new jasmineUnderTest.GlobalErrors(fakeGlobal);
|
||||
const fooError = new Error('foo');
|
||||
|
||||
errors.install();
|
||||
errors.pushListener(handler);
|
||||
|
||||
fakeGlobal.onerror(fooError.message, 'foo.js', 1, 1, fooError);
|
||||
const error = new Error('nope');
|
||||
dispatchErrorEvent(fakeGlobal, { error });
|
||||
|
||||
expect(handler).toHaveBeenCalledWith(
|
||||
fooError.message,
|
||||
'foo.js',
|
||||
1,
|
||||
1,
|
||||
fooError
|
||||
jasmine.is(error),
|
||||
jasmine.objectContaining({ error: jasmine.is(error) })
|
||||
);
|
||||
});
|
||||
|
||||
it('is not affected by overriding global.onerror', function() {
|
||||
const fakeGlobal = browserGlobal();
|
||||
const handler = jasmine.createSpy('errorHandler');
|
||||
const errors = new jasmineUnderTest.GlobalErrors(fakeGlobal);
|
||||
|
||||
errors.install();
|
||||
errors.pushListener(handler);
|
||||
|
||||
fakeGlobal.onerror = () => {};
|
||||
|
||||
const error = new Error('nope');
|
||||
dispatchErrorEvent(fakeGlobal, { error });
|
||||
|
||||
expect(handler).toHaveBeenCalledWith(
|
||||
jasmine.is(error),
|
||||
jasmine.objectContaining({ error: jasmine.is(error) })
|
||||
);
|
||||
});
|
||||
|
||||
it('only calls the most recent handler', function() {
|
||||
const fakeGlobal = minimalBrowserGlobal();
|
||||
const fakeGlobal = browserGlobal();
|
||||
const handler1 = jasmine.createSpy('errorHandler1');
|
||||
const handler2 = jasmine.createSpy('errorHandler2');
|
||||
const errors = new jasmineUnderTest.GlobalErrors(fakeGlobal);
|
||||
@@ -59,14 +45,18 @@ describe('GlobalErrors', function() {
|
||||
errors.pushListener(handler1);
|
||||
errors.pushListener(handler2);
|
||||
|
||||
fakeGlobal.onerror('foo');
|
||||
const error = new Error('nope');
|
||||
dispatchErrorEvent(fakeGlobal, { error });
|
||||
|
||||
expect(handler1).not.toHaveBeenCalled();
|
||||
expect(handler2).toHaveBeenCalledWith('foo');
|
||||
expect(handler2).toHaveBeenCalledWith(
|
||||
jasmine.is(error),
|
||||
jasmine.objectContaining({ error: jasmine.is(error) })
|
||||
);
|
||||
});
|
||||
|
||||
it('calls previous handlers when one is removed', function() {
|
||||
const fakeGlobal = minimalBrowserGlobal();
|
||||
const fakeGlobal = browserGlobal();
|
||||
const handler1 = jasmine.createSpy('errorHandler1');
|
||||
const handler2 = jasmine.createSpy('errorHandler2');
|
||||
const errors = new jasmineUnderTest.GlobalErrors(fakeGlobal);
|
||||
@@ -77,9 +67,13 @@ describe('GlobalErrors', function() {
|
||||
|
||||
errors.popListener(handler2);
|
||||
|
||||
fakeGlobal.onerror('foo');
|
||||
const error = new Error('nope');
|
||||
dispatchErrorEvent(fakeGlobal, { error });
|
||||
|
||||
expect(handler1).toHaveBeenCalledWith('foo');
|
||||
expect(handler1).toHaveBeenCalledWith(
|
||||
jasmine.is(error),
|
||||
jasmine.objectContaining({ error: jasmine.is(error) })
|
||||
);
|
||||
expect(handler2).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
@@ -90,34 +84,27 @@ describe('GlobalErrors', function() {
|
||||
}).toThrowError('popListener expects a listener');
|
||||
});
|
||||
|
||||
it('uninstalls itself, putting back a previous callback', function() {
|
||||
const originalCallback = jasmine.createSpy('error');
|
||||
const fakeGlobal = {
|
||||
...minimalBrowserGlobal(),
|
||||
onerror: originalCallback
|
||||
};
|
||||
it('uninstalls itself', function() {
|
||||
const fakeGlobal = browserGlobal();
|
||||
const errors = new jasmineUnderTest.GlobalErrors(fakeGlobal);
|
||||
|
||||
expect(fakeGlobal.onerror).toBe(originalCallback);
|
||||
function unrelatedListener() {}
|
||||
|
||||
errors.install();
|
||||
|
||||
expect(fakeGlobal.onerror).not.toBe(originalCallback);
|
||||
|
||||
fakeGlobal.addEventListener('error', unrelatedListener);
|
||||
errors.uninstall();
|
||||
|
||||
expect(fakeGlobal.onerror).toBe(originalCallback);
|
||||
expect(fakeGlobal.listeners_.error).toEqual([unrelatedListener]);
|
||||
});
|
||||
|
||||
it('rethrows the original error when there is no handler', function() {
|
||||
const fakeGlobal = minimalBrowserGlobal();
|
||||
const fakeGlobal = browserGlobal();
|
||||
const errors = new jasmineUnderTest.GlobalErrors(fakeGlobal);
|
||||
const originalError = new Error('nope');
|
||||
|
||||
errors.install();
|
||||
|
||||
try {
|
||||
fakeGlobal.onerror(originalError);
|
||||
dispatchErrorEvent(fakeGlobal, { error: originalError });
|
||||
} catch (e) {
|
||||
expect(e).toBe(originalError);
|
||||
}
|
||||
@@ -289,128 +276,61 @@ describe('GlobalErrors', function() {
|
||||
|
||||
describe('Reporting unhandled promise rejections in the browser', function() {
|
||||
it('subscribes and unsubscribes from the unhandledrejection event', function() {
|
||||
const fakeGlobal = jasmine.createSpyObj('globalErrors', [
|
||||
'addEventListener',
|
||||
'removeEventListener',
|
||||
'onerror'
|
||||
]),
|
||||
errors = new jasmineUnderTest.GlobalErrors(fakeGlobal);
|
||||
const fakeGlobal = browserGlobal();
|
||||
const errors = new jasmineUnderTest.GlobalErrors(fakeGlobal);
|
||||
|
||||
errors.install();
|
||||
expect(fakeGlobal.addEventListener).toHaveBeenCalledWith(
|
||||
'unhandledrejection',
|
||||
expect(fakeGlobal.listeners_.unhandledrejection).toEqual([
|
||||
jasmine.any(Function)
|
||||
);
|
||||
]);
|
||||
|
||||
const addedListener = fakeGlobal.addEventListener.calls.argsFor(0)[1];
|
||||
errors.uninstall();
|
||||
|
||||
expect(fakeGlobal.removeEventListener).toHaveBeenCalledWith(
|
||||
'unhandledrejection',
|
||||
addedListener
|
||||
);
|
||||
expect(fakeGlobal.listeners_.unhandledrejection).toEqual([]);
|
||||
});
|
||||
|
||||
it('reports rejections whose reason is a string', function() {
|
||||
const fakeGlobal = jasmine.createSpyObj('globalErrors', [
|
||||
'addEventListener',
|
||||
'removeEventListener',
|
||||
'onerror'
|
||||
]),
|
||||
handler = jasmine.createSpy('errorHandler'),
|
||||
errors = new jasmineUnderTest.GlobalErrors(fakeGlobal);
|
||||
const fakeGlobal = browserGlobal();
|
||||
const handler = jasmine.createSpy('errorHandler');
|
||||
const errors = new jasmineUnderTest.GlobalErrors(fakeGlobal);
|
||||
|
||||
errors.install();
|
||||
errors.pushListener(handler);
|
||||
|
||||
const addedListener = fakeGlobal.addEventListener.calls.argsFor(0)[1];
|
||||
addedListener({ reason: 'nope' });
|
||||
const event = { reason: 'nope' };
|
||||
dispatchUnhandledRejectionEvent(fakeGlobal, event);
|
||||
|
||||
expect(handler).toHaveBeenCalledWith('Unhandled promise rejection: nope');
|
||||
expect(handler).toHaveBeenCalledWith(
|
||||
'Unhandled promise rejection: nope',
|
||||
event
|
||||
);
|
||||
});
|
||||
|
||||
it('reports rejections whose reason is an Error', function() {
|
||||
const fakeGlobal = jasmine.createSpyObj('globalErrors', [
|
||||
'addEventListener',
|
||||
'removeEventListener',
|
||||
'onerror'
|
||||
]),
|
||||
handler = jasmine.createSpy('errorHandler'),
|
||||
errors = new jasmineUnderTest.GlobalErrors(fakeGlobal);
|
||||
const fakeGlobal = browserGlobal();
|
||||
const handler = jasmine.createSpy('errorHandler');
|
||||
const errors = new jasmineUnderTest.GlobalErrors(fakeGlobal);
|
||||
|
||||
errors.install();
|
||||
errors.pushListener(handler);
|
||||
|
||||
const addedListener = fakeGlobal.addEventListener.calls.argsFor(0)[1];
|
||||
const reason = new Error('bar');
|
||||
|
||||
addedListener({ reason: reason });
|
||||
const event = { reason };
|
||||
dispatchUnhandledRejectionEvent(fakeGlobal, event);
|
||||
|
||||
expect(handler).toHaveBeenCalledWith(
|
||||
jasmine.objectContaining({
|
||||
jasmineMessage: 'Unhandled promise rejection: Error: bar',
|
||||
message: reason.message,
|
||||
stack: reason.stack
|
||||
})
|
||||
}),
|
||||
event
|
||||
);
|
||||
});
|
||||
|
||||
describe('Enabling external interception of reported rejections by overriding global.onerror', function() {
|
||||
it('overriding global.onerror intercepts rejections whose reason is a string', function() {
|
||||
const fakeGlobal = jasmine.createSpyObj('globalErrors', [
|
||||
'addEventListener'
|
||||
]),
|
||||
handler = jasmine.createSpy('errorHandler'),
|
||||
hijackHandler = jasmine.createSpy('hijackErrorHandler'),
|
||||
errors = new jasmineUnderTest.GlobalErrors(fakeGlobal);
|
||||
|
||||
errors.install();
|
||||
errors.pushListener(handler);
|
||||
|
||||
fakeGlobal.onerror = hijackHandler;
|
||||
|
||||
const addedListener = fakeGlobal.addEventListener.calls.argsFor(0)[1];
|
||||
addedListener({ reason: 'nope' });
|
||||
|
||||
expect(hijackHandler).toHaveBeenCalledWith(
|
||||
'Unhandled promise rejection: nope'
|
||||
);
|
||||
expect(handler).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('overriding global.onerror intercepts rejections whose reason is an Error', function() {
|
||||
const fakeGlobal = jasmine.createSpyObj('globalErrors', [
|
||||
'addEventListener'
|
||||
]),
|
||||
handler = jasmine.createSpy('errorHandler'),
|
||||
hijackHandler = jasmine.createSpy('hijackErrorHandler'),
|
||||
errors = new jasmineUnderTest.GlobalErrors(fakeGlobal);
|
||||
|
||||
errors.install();
|
||||
errors.pushListener(handler);
|
||||
|
||||
fakeGlobal.onerror = hijackHandler;
|
||||
|
||||
const addedListener = fakeGlobal.addEventListener.calls.argsFor(0)[1];
|
||||
const reason = new Error('bar');
|
||||
|
||||
addedListener({ reason: reason });
|
||||
|
||||
expect(hijackHandler).toHaveBeenCalledWith(
|
||||
jasmine.objectContaining({
|
||||
jasmineMessage: 'Unhandled promise rejection: Error: bar',
|
||||
message: reason.message,
|
||||
stack: reason.stack
|
||||
})
|
||||
);
|
||||
expect(handler).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('#setOverrideListener', function() {
|
||||
it('overrides the existing handlers in browsers until removed', function() {
|
||||
const fakeGlobal = minimalBrowserGlobal();
|
||||
const fakeGlobal = browserGlobal();
|
||||
const handler0 = jasmine.createSpy('handler0');
|
||||
const handler1 = jasmine.createSpy('handler1');
|
||||
const overrideHandler = jasmine.createSpy('overrideHandler');
|
||||
@@ -420,19 +340,18 @@ describe('GlobalErrors', function() {
|
||||
errors.pushListener(handler0);
|
||||
errors.setOverrideListener(overrideHandler, () => {});
|
||||
errors.pushListener(handler1);
|
||||
fakeGlobal.onerror('foo');
|
||||
fakeGlobal.onerror(null, null, null, null, new Error('bar'));
|
||||
dispatchErrorEvent(fakeGlobal, { error: 'foo' });
|
||||
|
||||
expect(overrideHandler).toHaveBeenCalledWith('foo');
|
||||
expect(overrideHandler).toHaveBeenCalledWith(new Error('bar'));
|
||||
expect(handler0).not.toHaveBeenCalled();
|
||||
expect(handler1).not.toHaveBeenCalled();
|
||||
|
||||
errors.removeOverrideListener();
|
||||
|
||||
fakeGlobal.onerror('baz');
|
||||
const event = { error: 'baz' };
|
||||
dispatchErrorEvent(fakeGlobal, event);
|
||||
expect(overrideHandler).not.toHaveBeenCalledWith('baz');
|
||||
expect(handler1).toHaveBeenCalledWith('baz');
|
||||
expect(handler1).toHaveBeenCalledWith('baz', event);
|
||||
});
|
||||
|
||||
it('overrides the existing handlers in Node until removed', function() {
|
||||
@@ -532,7 +451,7 @@ describe('GlobalErrors', function() {
|
||||
});
|
||||
|
||||
it('throws if there is already an override handler', function() {
|
||||
const errors = new jasmineUnderTest.GlobalErrors(minimalBrowserGlobal());
|
||||
const errors = new jasmineUnderTest.GlobalErrors(browserGlobal());
|
||||
|
||||
errors.setOverrideListener(() => {}, () => {});
|
||||
expect(function() {
|
||||
@@ -544,7 +463,7 @@ describe('GlobalErrors', function() {
|
||||
describe('#removeOverrideListener', function() {
|
||||
it("calls the handler's onRemove callback", function() {
|
||||
const onRemove = jasmine.createSpy('onRemove');
|
||||
const errors = new jasmineUnderTest.GlobalErrors(minimalBrowserGlobal());
|
||||
const errors = new jasmineUnderTest.GlobalErrors(browserGlobal());
|
||||
|
||||
errors.setOverrideListener(() => {}, onRemove);
|
||||
errors.removeOverrideListener();
|
||||
@@ -553,17 +472,43 @@ describe('GlobalErrors', function() {
|
||||
});
|
||||
|
||||
it('does not throw if there is no handler', function() {
|
||||
const errors = new jasmineUnderTest.GlobalErrors(minimalBrowserGlobal());
|
||||
const errors = new jasmineUnderTest.GlobalErrors(browserGlobal());
|
||||
|
||||
expect(() => errors.removeOverrideListener()).not.toThrow();
|
||||
});
|
||||
});
|
||||
|
||||
function minimalBrowserGlobal() {
|
||||
function browserGlobal() {
|
||||
return {
|
||||
addEventListener() {},
|
||||
removeEventListener() {},
|
||||
onerror: null
|
||||
listeners_: { error: [], unhandledrejection: [] },
|
||||
addEventListener(eventName, listener) {
|
||||
this.listeners_[eventName].push(listener);
|
||||
},
|
||||
removeEventListener(eventName, listener) {
|
||||
this.listeners_[eventName] = this.listeners_[eventName].filter(
|
||||
l => l !== listener
|
||||
);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function dispatchErrorEvent(global, event) {
|
||||
expect(global.listeners_.error.length)
|
||||
.withContext('number of error listeners')
|
||||
.toBeGreaterThan(0);
|
||||
|
||||
for (const l of global.listeners_.error) {
|
||||
l(event);
|
||||
}
|
||||
}
|
||||
|
||||
function dispatchUnhandledRejectionEvent(global, event) {
|
||||
expect(global.listeners_.unhandledrejection.length)
|
||||
.withContext('number of unhandledrejection listeners')
|
||||
.toBeGreaterThan(0);
|
||||
|
||||
for (const l of global.listeners_.unhandledrejection) {
|
||||
l(event);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -623,7 +623,7 @@ describe('QueueRunner', function() {
|
||||
});
|
||||
});
|
||||
|
||||
it('passes the error instance to exception handlers in HTML browsers', function() {
|
||||
it('passes final errors to exception handlers', function() {
|
||||
const error = new Error('fake error'),
|
||||
onExceptionCallback = jasmine.createSpy('on exception callback'),
|
||||
queueRunner = new jasmineUnderTest.QueueRunner({
|
||||
@@ -631,24 +631,11 @@ describe('QueueRunner', function() {
|
||||
});
|
||||
|
||||
queueRunner.execute();
|
||||
queueRunner.handleFinalError(error.message, 'fake.js', 1, 1, error);
|
||||
queueRunner.handleFinalError(error);
|
||||
|
||||
expect(onExceptionCallback).toHaveBeenCalledWith(error);
|
||||
});
|
||||
|
||||
it('passes the first argument to exception handlers for compatibility', function() {
|
||||
const error = new Error('fake error'),
|
||||
onExceptionCallback = jasmine.createSpy('on exception callback'),
|
||||
queueRunner = new jasmineUnderTest.QueueRunner({
|
||||
onException: onExceptionCallback
|
||||
});
|
||||
|
||||
queueRunner.execute();
|
||||
queueRunner.handleFinalError(error.message);
|
||||
|
||||
expect(onExceptionCallback).toHaveBeenCalledWith(error.message);
|
||||
});
|
||||
|
||||
it('calls exception handlers when an exception is thrown in a fn', function() {
|
||||
const queueableFn = {
|
||||
type: 'queueable',
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
describe('Env integration', function() {
|
||||
let env;
|
||||
const isBrowser = typeof window !== 'undefined';
|
||||
|
||||
beforeEach(function() {
|
||||
jasmine.getEnv().registerIntegrationMatchers();
|
||||
@@ -455,7 +456,7 @@ describe('Env integration', function() {
|
||||
env.describe('A suite', function() {
|
||||
env.it('fails', function(specDone) {
|
||||
setTimeout(function() {
|
||||
global.onerror('fail');
|
||||
dispatchErrorEvent(global, { error: 'fail' });
|
||||
specDone();
|
||||
});
|
||||
});
|
||||
@@ -509,10 +510,14 @@ describe('Env integration', function() {
|
||||
},
|
||||
specDone: function() {
|
||||
clearStackCallbacks[clearStackCallCount + 1] = function() {
|
||||
global.onerror('fail at the end of the reporter queue');
|
||||
dispatchErrorEvent(global, {
|
||||
error: 'fail at the end of the reporter queue'
|
||||
});
|
||||
};
|
||||
clearStackCallbacks[clearStackCallCount + 2] = function() {
|
||||
global.onerror('fail at the end of the spec queue');
|
||||
dispatchErrorEvent(global, {
|
||||
error: 'fail at the end of the spec queue'
|
||||
});
|
||||
};
|
||||
}
|
||||
});
|
||||
@@ -559,7 +564,7 @@ describe('Env integration', function() {
|
||||
specDone();
|
||||
queueMicrotask(function() {
|
||||
queueMicrotask(function() {
|
||||
global.onerror('fail');
|
||||
dispatchErrorEvent(global, { error: 'fail' });
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -622,10 +627,14 @@ describe('Env integration', function() {
|
||||
|
||||
if (result.description === 'A nested suite') {
|
||||
clearStackCallbacks[clearStackCallCount + 1] = function() {
|
||||
global.onerror('fail at the end of the reporter queue');
|
||||
dispatchErrorEvent(global, {
|
||||
error: 'fail at the end of the reporter queue'
|
||||
});
|
||||
};
|
||||
clearStackCallbacks[clearStackCallCount + 2] = function() {
|
||||
global.onerror('fail at the end of the suite queue');
|
||||
dispatchErrorEvent(global, {
|
||||
error: 'fail at the end of the suite queue'
|
||||
});
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -668,7 +677,7 @@ describe('Env integration', function() {
|
||||
|
||||
env.addReporter({
|
||||
jasmineDone: function() {
|
||||
global.onerror('a very late error');
|
||||
dispatchErrorEvent(global, { error: 'a very late error' });
|
||||
}
|
||||
});
|
||||
|
||||
@@ -720,7 +729,7 @@ describe('Env integration', function() {
|
||||
expectedErrors.push(`${msg} thrown`);
|
||||
}
|
||||
|
||||
global.onerror(msg);
|
||||
dispatchErrorEvent(global, { error: msg });
|
||||
realClearStack(fn);
|
||||
});
|
||||
spyOn(console, 'error');
|
||||
@@ -2547,15 +2556,24 @@ describe('Env integration', function() {
|
||||
);
|
||||
});
|
||||
|
||||
await env.execute();
|
||||
await jasmine.spyOnGlobalErrorsAsync(async function(globalErrorSpy) {
|
||||
await env.execute();
|
||||
|
||||
if (isBrowser) {
|
||||
// Verify that there were no unexpected errors
|
||||
expect(globalErrorSpy).toHaveBeenCalledTimes(2);
|
||||
expect(globalErrorSpy).toHaveBeenCalledWith(new Error('suite'));
|
||||
expect(globalErrorSpy).toHaveBeenCalledWith(new Error('spec'));
|
||||
}
|
||||
});
|
||||
|
||||
expect(reporter.suiteDone).toHaveFailedExpectationsForRunnable(
|
||||
'async suite',
|
||||
[/^(((Uncaught )?(exception: )?Error: suite( thrown)?)|(suite thrown))$/]
|
||||
[/Error: suite/]
|
||||
);
|
||||
expect(reporter.specDone).toHaveFailedExpectationsForRunnable(
|
||||
'suite async spec',
|
||||
[/^(((Uncaught )?(exception: )?Error: spec( thrown)?)|(spec thrown))$/]
|
||||
[/Error: spec/]
|
||||
);
|
||||
});
|
||||
|
||||
@@ -2689,14 +2707,14 @@ describe('Env integration', function() {
|
||||
]);
|
||||
|
||||
env.addReporter(reporter);
|
||||
global.onerror(
|
||||
'Uncaught SyntaxError: Unexpected end of input',
|
||||
'borkenSpec.js',
|
||||
42,
|
||||
undefined,
|
||||
{ stack: 'a stack' }
|
||||
);
|
||||
global.onerror('Uncaught Error: ENOCHEESE');
|
||||
dispatchErrorEvent(global, {
|
||||
message: 'Uncaught SyntaxError: Unexpected end of input',
|
||||
error: undefined,
|
||||
filename: 'borkenSpec.js',
|
||||
lineno: 42
|
||||
});
|
||||
const error = new Error('ENOCHEESE');
|
||||
dispatchErrorEvent(global, { error });
|
||||
|
||||
await env.execute();
|
||||
|
||||
@@ -2706,15 +2724,15 @@ describe('Env integration', function() {
|
||||
passed: false,
|
||||
globalErrorType: 'load',
|
||||
message: 'Uncaught SyntaxError: Unexpected end of input',
|
||||
stack: 'a stack',
|
||||
stack: undefined,
|
||||
filename: 'borkenSpec.js',
|
||||
lineno: 42
|
||||
},
|
||||
{
|
||||
passed: false,
|
||||
globalErrorType: 'load',
|
||||
message: 'Uncaught Error: ENOCHEESE',
|
||||
stack: undefined,
|
||||
message: 'ENOCHEESE',
|
||||
stack: error.stack,
|
||||
filename: undefined,
|
||||
lineno: undefined
|
||||
}
|
||||
@@ -2946,7 +2964,7 @@ describe('Env integration', function() {
|
||||
|
||||
env.addReporter(reporter);
|
||||
env.it('passes', function() {});
|
||||
global.onerror('Uncaught Error: ENOCHEESE');
|
||||
dispatchErrorEvent(global, { error: 'ENOCHEESE' });
|
||||
await env.execute();
|
||||
|
||||
expect(reporter.jasmineDone).toHaveBeenCalled();
|
||||
@@ -3679,16 +3697,6 @@ describe('Env integration', function() {
|
||||
expect(failedExpectations).toEqual([]);
|
||||
});
|
||||
|
||||
it('calls the optional done callback when finished', function(done) {
|
||||
const reporter = jasmine.createSpyObj('reporter', ['jasmineDone']);
|
||||
env.addReporter(reporter);
|
||||
|
||||
env.execute(null, function() {
|
||||
expect(reporter.jasmineDone).toHaveBeenCalled();
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
describe('#spyOnGlobalErrorsAsync', function() {
|
||||
const leftInstalledMessage =
|
||||
'Global error spy was not uninstalled. ' +
|
||||
@@ -3729,7 +3737,16 @@ describe('Env integration', function() {
|
||||
|
||||
const reporter = jasmine.createSpyObj('reporter', ['specDone']);
|
||||
env.addReporter(reporter);
|
||||
await env.execute();
|
||||
await jasmine.spyOnGlobalErrorsAsync(async function(globalErrorSpy) {
|
||||
await env.execute();
|
||||
|
||||
if (isBrowser) {
|
||||
// Verify that there were no unexpected errors
|
||||
expect(globalErrorSpy).toHaveBeenCalledTimes(2);
|
||||
expect(globalErrorSpy).toHaveBeenCalledWith(new Error('nope'));
|
||||
expect(globalErrorSpy).toHaveBeenCalledWith(new Error('yep'));
|
||||
}
|
||||
});
|
||||
|
||||
const passingResult = resultForRunable(
|
||||
reporter.specDone,
|
||||
@@ -3776,7 +3793,17 @@ describe('Env integration', function() {
|
||||
'suiteDone'
|
||||
]);
|
||||
env.addReporter(reporter);
|
||||
await env.execute();
|
||||
await jasmine.spyOnGlobalErrorsAsync(async function(globalErrorSpy) {
|
||||
await env.execute();
|
||||
|
||||
if (isBrowser) {
|
||||
// Verify that there were no unexpected errors
|
||||
expect(globalErrorSpy).toHaveBeenCalledTimes(1);
|
||||
expect(globalErrorSpy).toHaveBeenCalledWith(
|
||||
new Error('should fail the spec')
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
const suiteResult = resultForRunable(reporter.suiteDone, 'Suite 1');
|
||||
expect(suiteResult.status).toEqual('failed');
|
||||
@@ -3821,7 +3848,17 @@ describe('Env integration', function() {
|
||||
'suiteDone'
|
||||
]);
|
||||
env.addReporter(reporter);
|
||||
await env.execute();
|
||||
await jasmine.spyOnGlobalErrorsAsync(async function(globalErrorSpy) {
|
||||
await env.execute();
|
||||
|
||||
if (isBrowser) {
|
||||
// Verify that there were no unexpected errors
|
||||
expect(globalErrorSpy).toHaveBeenCalledTimes(1);
|
||||
expect(globalErrorSpy).toHaveBeenCalledWith(
|
||||
new Error('should fail the spec')
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
expect(reporter.suiteDone).toHaveFailedExpectationsForRunnable(
|
||||
'Suite 1',
|
||||
@@ -3871,7 +3908,18 @@ describe('Env integration', function() {
|
||||
'suiteDone'
|
||||
]);
|
||||
env.addReporter(reporter);
|
||||
await env.execute();
|
||||
|
||||
await jasmine.spyOnGlobalErrorsAsync(async function(globalErrorSpy) {
|
||||
await env.execute();
|
||||
|
||||
if (isBrowser) {
|
||||
// Verify that there were no unexpected errors
|
||||
expect(globalErrorSpy).toHaveBeenCalledTimes(1);
|
||||
expect(globalErrorSpy).toHaveBeenCalledWith(
|
||||
new Error('should fail the spec')
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
const spec1Result = resultForRunable(reporter.specDone, 'Suite 1 a spec');
|
||||
expect(spec1Result.status).toEqual('failed');
|
||||
@@ -3907,7 +3955,17 @@ describe('Env integration', function() {
|
||||
|
||||
const reporter = jasmine.createSpyObj('reporter', ['specDone']);
|
||||
env.addReporter(reporter);
|
||||
await env.execute();
|
||||
await jasmine.spyOnGlobalErrorsAsync(async function(globalErrorSpy) {
|
||||
await env.execute();
|
||||
|
||||
if (isBrowser) {
|
||||
// Verify that there were no unexpected errors
|
||||
expect(globalErrorSpy).toHaveBeenCalledTimes(1);
|
||||
expect(globalErrorSpy).toHaveBeenCalledWith(
|
||||
new Error('should fail the spec')
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
const spec1Result = resultForRunable(reporter.specDone, 'spec 1');
|
||||
expect(spec1Result.status).toEqual('failed');
|
||||
@@ -3952,7 +4010,17 @@ describe('Env integration', function() {
|
||||
'suiteDone'
|
||||
]);
|
||||
env.addReporter(reporter);
|
||||
await env.execute();
|
||||
await jasmine.spyOnGlobalErrorsAsync(async function(globalErrorSpy) {
|
||||
await env.execute();
|
||||
|
||||
if (isBrowser) {
|
||||
// Verify that there were no unexpected errors
|
||||
expect(globalErrorSpy).toHaveBeenCalledTimes(1);
|
||||
expect(globalErrorSpy).toHaveBeenCalledWith(
|
||||
new Error('should fail the spec')
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
const spec1Result = resultForRunable(reporter.specDone, 'Suite 1 a spec');
|
||||
expect(spec1Result.status).toEqual('failed');
|
||||
@@ -4010,8 +4078,25 @@ describe('Env integration', function() {
|
||||
|
||||
function browserEventMethods() {
|
||||
return {
|
||||
addEventListener() {},
|
||||
removeEventListener() {}
|
||||
listeners_: { error: [], unhandledrejection: [] },
|
||||
addEventListener(eventName, listener) {
|
||||
this.listeners_[eventName].push(listener);
|
||||
},
|
||||
removeEventListener(eventName, listener) {
|
||||
this.listeners_[eventName] = this.listeners_[eventName].filter(
|
||||
l => l !== listener
|
||||
);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function dispatchErrorEvent(global, event) {
|
||||
expect(global.listeners_.error.length)
|
||||
.withContext('number of error listeners')
|
||||
.toBeGreaterThan(0);
|
||||
|
||||
for (const l of global.listeners_.error) {
|
||||
l(event);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -626,7 +626,7 @@ describe('spec running', function() {
|
||||
expect(actions).toEqual(['spec2', 'spec3', 'spec1']);
|
||||
});
|
||||
|
||||
it('refuses to re-enter suites with a beforeAll', function() {
|
||||
it('refuses to re-enter suites with a beforeAll', async function() {
|
||||
const actions = [];
|
||||
let spec1;
|
||||
let spec2;
|
||||
@@ -648,13 +648,12 @@ describe('spec running', function() {
|
||||
actions.push('spec3');
|
||||
});
|
||||
|
||||
expect(function() {
|
||||
env.execute([spec2.id, spec3.id, spec1.id]);
|
||||
}).toThrowError(/beforeAll/);
|
||||
const promise = env.execute([spec2.id, spec3.id, spec1.id]);
|
||||
await expectAsync(promise).toBeRejectedWithError(/beforeAll/);
|
||||
expect(actions).toEqual([]);
|
||||
});
|
||||
|
||||
it('refuses to re-enter suites with a afterAll', function() {
|
||||
it('refuses to re-enter suites with a afterAll', async function() {
|
||||
const actions = [];
|
||||
let spec1;
|
||||
let spec2;
|
||||
@@ -676,9 +675,8 @@ describe('spec running', function() {
|
||||
actions.push('spec3');
|
||||
});
|
||||
|
||||
expect(function() {
|
||||
env.execute([spec2.id, spec3.id, spec1.id]);
|
||||
}).toThrowError(/afterAll/);
|
||||
const promise = env.execute([spec2.id, spec3.id, spec1.id]);
|
||||
await expectAsync(promise).toBeRejectedWithError(/afterAll/);
|
||||
expect(actions).toEqual([]);
|
||||
});
|
||||
|
||||
|
||||
@@ -149,20 +149,14 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
|
||||
if (!options.suppressLoadErrors) {
|
||||
installGlobalErrors();
|
||||
globalErrors.pushListener(function loadtimeErrorHandler(
|
||||
message,
|
||||
filename,
|
||||
lineno,
|
||||
colNo,
|
||||
err
|
||||
) {
|
||||
globalErrors.pushListener(function loadtimeErrorHandler(error, event) {
|
||||
topSuite.result.failedExpectations.push({
|
||||
passed: false,
|
||||
globalErrorType: 'load',
|
||||
message: message,
|
||||
stack: err && err.stack,
|
||||
filename: filename,
|
||||
lineno: lineno
|
||||
message: error ? error.message : event.message,
|
||||
stack: error && error.stack,
|
||||
filename: event && event.filename,
|
||||
lineno: event && event.lineno
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -506,18 +500,12 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
/**
|
||||
* Executes the specs.
|
||||
*
|
||||
* If called with no parameters or with a falsy value as the first parameter,
|
||||
* If called with no parameter or with a falsy parameter,
|
||||
* all specs will be executed except those that are excluded by a
|
||||
* [spec filter]{@link Configuration#specFilter} or other mechanism. If the
|
||||
* first parameter is a list of spec/suite IDs, only those specs/suites will
|
||||
* parameter is a list of spec/suite IDs, only those specs/suites will
|
||||
* be run.
|
||||
*
|
||||
* Both parameters are optional, but a completion callback is only valid as
|
||||
* the second parameter. To specify a completion callback but not a list of
|
||||
* specs/suites to run, pass null or undefined as the first parameter. The
|
||||
* completion callback is supported for backward compatibility. In most
|
||||
* cases it will be more convenient to use the returned promise instead.
|
||||
*
|
||||
* execute should not be called more than once unless the env has been
|
||||
* configured with `{autoCleanClosures: false}`.
|
||||
*
|
||||
@@ -525,25 +513,19 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
* {@link JasmineDoneInfo|overall result} that's passed to a reporter's
|
||||
* `jasmineDone` method, even if the suite did not pass. To determine
|
||||
* whether the suite passed, check the value that the promise resolves to
|
||||
* or use a {@link Reporter}.
|
||||
* or use a {@link Reporter}. The promise will be rejected in the case of
|
||||
* certain serious errors that prevent execution from starting.
|
||||
*
|
||||
* @name Env#execute
|
||||
* @since 2.0.0
|
||||
* @function
|
||||
* @async
|
||||
* @param {(string[])=} runablesToRun IDs of suites and/or specs to run
|
||||
* @param {Function=} onComplete Function that will be called after all specs have run
|
||||
* @return {Promise<JasmineDoneInfo>}
|
||||
*/
|
||||
this.execute = function(runablesToRun, onComplete) {
|
||||
this.execute = async function(runablesToRun) {
|
||||
installGlobalErrors();
|
||||
|
||||
return runner.execute(runablesToRun).then(function(jasmineDoneInfo) {
|
||||
if (onComplete) {
|
||||
onComplete();
|
||||
}
|
||||
|
||||
return jasmineDoneInfo;
|
||||
});
|
||||
return runner.execute(runablesToRun);
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -6,18 +6,22 @@ getJasmineRequireObj().GlobalErrors = function(j$) {
|
||||
let overrideHandler = null,
|
||||
onRemoveOverrideHandler = null;
|
||||
|
||||
function onerror(message, source, lineno, colno, error) {
|
||||
function onBrowserError(event) {
|
||||
dispatchBrowserError(event.error, event);
|
||||
}
|
||||
|
||||
function dispatchBrowserError(error, event) {
|
||||
if (overrideHandler) {
|
||||
overrideHandler(error || message);
|
||||
overrideHandler(error);
|
||||
return;
|
||||
}
|
||||
|
||||
const handler = handlers[handlers.length - 1];
|
||||
|
||||
if (handler) {
|
||||
handler.apply(null, Array.prototype.slice.call(arguments, 0));
|
||||
handler(error, event);
|
||||
} else {
|
||||
throw arguments[0];
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -94,8 +98,7 @@ getJasmineRequireObj().GlobalErrors = function(j$) {
|
||||
this.installOne_('uncaughtException', 'Uncaught exception');
|
||||
this.installOne_('unhandledRejection', 'Unhandled promise rejection');
|
||||
} else {
|
||||
const originalHandler = global.onerror;
|
||||
global.onerror = onerror;
|
||||
global.addEventListener('error', onBrowserError);
|
||||
|
||||
const browserRejectionHandler = function browserRejectionHandler(
|
||||
event
|
||||
@@ -103,16 +106,19 @@ getJasmineRequireObj().GlobalErrors = function(j$) {
|
||||
if (j$.isError_(event.reason)) {
|
||||
event.reason.jasmineMessage =
|
||||
'Unhandled promise rejection: ' + event.reason;
|
||||
global.onerror(event.reason);
|
||||
dispatchBrowserError(event.reason, event);
|
||||
} else {
|
||||
global.onerror('Unhandled promise rejection: ' + event.reason);
|
||||
dispatchBrowserError(
|
||||
'Unhandled promise rejection: ' + event.reason,
|
||||
event
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
global.addEventListener('unhandledrejection', browserRejectionHandler);
|
||||
|
||||
this.uninstall = function uninstall() {
|
||||
global.onerror = originalHandler;
|
||||
global.removeEventListener('error', onBrowserError);
|
||||
global.removeEventListener(
|
||||
'unhandledrejection',
|
||||
browserRejectionHandler
|
||||
@@ -121,6 +127,13 @@ getJasmineRequireObj().GlobalErrors = function(j$) {
|
||||
}
|
||||
};
|
||||
|
||||
// The listener at the top of the stack will be called with two arguments:
|
||||
// the error and the event. Either of them may be falsy.
|
||||
// The error will normally be provided, but will be falsy in the case of
|
||||
// some browser load-time errors. The event will normally be provided in
|
||||
// browsers but will be falsy in Node.
|
||||
// Listeners that are pushed after spec files have been loaded should be
|
||||
// able to just use the error parameter.
|
||||
this.pushListener = function pushListener(listener) {
|
||||
handlers.push(listener);
|
||||
};
|
||||
|
||||
@@ -74,11 +74,8 @@ getJasmineRequireObj().QueueRunner = function(j$) {
|
||||
}
|
||||
|
||||
QueueRunner.prototype.execute = function() {
|
||||
this.handleFinalError = (message, source, lineno, colno, error) => {
|
||||
// Older browsers would send the error as the first parameter. HTML5
|
||||
// specifies the the five parameters above. The error instance should
|
||||
// be preffered, otherwise the call stack would get lost.
|
||||
this.onException(error || message);
|
||||
this.handleFinalError = error => {
|
||||
this.onException(error);
|
||||
};
|
||||
this.globalErrors.pushListener(this.handleFinalError);
|
||||
this.run(0);
|
||||
|
||||
@@ -27,11 +27,7 @@ getJasmineRequireObj().Runner = function(j$) {
|
||||
];
|
||||
}
|
||||
|
||||
// Although execute returns a promise, it isn't async for backwards
|
||||
// compatibility: The "Invalid order" exception needs to be propagated
|
||||
// synchronously from Env#execute.
|
||||
// TODO: make this and Env#execute async in the next major release
|
||||
execute(runablesToRun) {
|
||||
async execute(runablesToRun) {
|
||||
if (this.executedBefore_) {
|
||||
this.topSuite_.reset();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user