Skip to content

Commit

Permalink
Recognize typical assertion errors and use their formatting
Browse files Browse the repository at this point in the history
Co-authored-by: Mark Wubben <mark@novemberborn.net>
  • Loading branch information
Irvenae and novemberborn authored May 24, 2023
1 parent faa9654 commit 5558367
Show file tree
Hide file tree
Showing 10 changed files with 653 additions and 14 deletions.
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

0 comments on commit 5558367

Please sign in to comment.