Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Recognize typical assertion errors and use their formatting #3187

Merged
merged 13 commits into from
May 24, 2023
52 changes: 42 additions & 10 deletions lib/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,22 @@ import concordanceOptions from './concordance-options.js';
import nowAndTimers from './now-and-timers.cjs';
import parseTestArgs from './parse-test-args.js';

const hasOwnProperty = (object, prop) => Object.prototype.hasOwnProperty.call(object, prop);

function isExternalAssertError(error) {
if (typeof error !== 'object' || error === null) {
return false;
}

// Match errors thrown by <https://www.npmjs.com/package/expect>.
if (hasOwnProperty(error, 'matcherResult')) {
return true;
}

// Match errors thrown by <https://www.npmjs.com/package/chai> and <https://nodejs.org/api/assert.html>.
return hasOwnProperty(error, 'actual') && hasOwnProperty(error, 'expected');
}

function formatErrorValue(label, error) {
const formatted = concordance.format(error, concordanceOptions);
return {label, formatted};
Expand Down Expand Up @@ -519,11 +535,19 @@ export default class Test {

const result = this.callFn();
if (!result.ok) {
this.saveFirstError(new AssertionError({
message: 'Error thrown in test',
savedError: result.error instanceof Error && result.error,
values: [formatErrorValue('Error thrown in test:', result.error)],
}));
if (isExternalAssertError(result.error)) {
this.saveFirstError(new AssertionError({
message: 'Assertion failed',
savedError: result.error instanceof Error && result.error,
values: [{label: 'Assertion failed: ', formatted: result.error.message}],
}));
} else {
this.saveFirstError(new AssertionError({
message: 'Error thrown in test',
savedError: result.error instanceof Error && result.error,
values: [formatErrorValue('Error thrown in test:', result.error)],
}));
}

return this.finish();
}
Expand Down Expand Up @@ -564,11 +588,19 @@ export default class Test {

promise
.catch(error => {
this.saveFirstError(new AssertionError({
message: 'Rejected promise returned by test',
savedError: error instanceof Error && error,
values: [formatErrorValue('Rejected promise returned by test. Reason:', error)],
}));
if (isExternalAssertError(error)) {
this.saveFirstError(new AssertionError({
message: 'Assertion failed',
savedError: error instanceof Error && error,
values: [{label: 'Assertion failed: ', formatted: error.message}],
}));
} else {
this.saveFirstError(new AssertionError({
message: 'Rejected promise returned by test',
savedError: error instanceof Error && error,
values: [formatErrorValue('Rejected promise returned by test. Reason:', error)],
}));
}
})
.then(() => resolve(this.finish()));
});
Expand Down
Loading