Skip to content

Commit

Permalink
✨ Allow assertion functions to return an assertion object
Browse files Browse the repository at this point in the history
  • Loading branch information
wwilsman committed May 14, 2024
1 parent fdbd966 commit a3898d5
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 5 deletions.
12 changes: 7 additions & 5 deletions lib/assertion.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,14 @@ import Context from './context.js';
*/

/**
* @param {AssertSubject} assertion
* @param {(AssertObject | AssertSubject)} assertion
* @param {AssertMessage} [failureMessage]
* @param {AssertMessage} [negatedMessage]
* @returns {import('./context').ContextGenerator<{ assert?: boolean }>}
*/
export function* assert(assertion, failureMessage, negatedMessage) {
if (typeof assertion === 'object' && Object.getPrototypeOf(assertion) === Object.prototype)
({ assertion, failureMessage = failureMessage, negatedMessage = negatedMessage } = assertion);
let expected = yield ({ assert }) => assert?.expected;
let error, pass;

Expand All @@ -37,6 +39,10 @@ export function* assert(assertion, failureMessage, negatedMessage) {
pass = false;
}

if (typeof pass === 'object' &&
Object.getPrototypeOf(pass) === Object.prototype && 'assertion' in pass
) pass = yield assert(pass, failureMessage, negatedMessage);

if (!!pass !== expected) {
throw (error ?? new Error((expected
? (yield failureMessage) || 'Assertion failed'
Expand Down Expand Up @@ -68,10 +74,6 @@ export class Assertion {
* @param {AssertMessage} [negatedMessage]
*/
constructor(assertion, failureMessage, negatedMessage) {
if (typeof assertion === 'object' &&
Object.getPrototypeOf(assertion) === Object.prototype)
({ assertion, failureMessage, negatedMessage } = assertion);

Object.defineProperty(this, Assertion.Symbol, {
// @ts-ignore
value: () => assert(assertion, failureMessage, negatedMessage),
Expand Down
17 changes: 17 additions & 0 deletions tests/interactor.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -571,6 +571,23 @@ describe('Assert', () => {
'Negated message');
});

it('accepts an assertion that returns an assertion object', async () => {
TestAssert.defineAssertion('test', (expected, msg) => ({
assertion: expected === true,
failureMessage: `Failure message (${msg})`,
negatedMessage: `Negated message (${msg})`
}));

await assert(typeof T.assert.test === 'function',
'Expected test to be a function');
await assert(T.assert.test(true) instanceof Assertion,
'Expected test to return an Interaction instance');
await assert.throws(T.assert.test(false, 'foo'),
'Failure message (foo)');
await assert.throws(T.assert.not.test(true, 'bar'),
'Negated message (bar)');
});

it('accepts an assertion class', async () => {
let pass = false;

Expand Down

0 comments on commit a3898d5

Please sign in to comment.