Merge remote-tracking branch 'origin/5.0' into parallel

This commit is contained in:
Steve Gravrock
2022-09-18 09:43:31 -07:00
9 changed files with 312 additions and 321 deletions

View File

@@ -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);
};
/**

View File

@@ -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);
};

View File

@@ -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);

View File

@@ -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();
}