Skip to content

Commit

Permalink
Add support for nested matchers on .not/.rejects/.resolves
Browse files Browse the repository at this point in the history
  • Loading branch information
mattphillips committed Aug 7, 2018
1 parent 264a3c7 commit 0fd13a0
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 17 deletions.
7 changes: 7 additions & 0 deletions src/__snapshots__/withMessage.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,10 @@ exports[`withMessage() throws error with custom message when matcher fails 1`] =
expected ACTUAL to be 1"
`;

exports[`withMessage() throws error with custom message when not matcher fails 1`] = `
"Custom message:
should fail
expected ACTUAL to not be ACTUAL"
`;
36 changes: 22 additions & 14 deletions src/withMessage.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,23 +10,31 @@ class JestAssertionError extends Error {
}

const wrapMatchers = (matchers, customMessage) => {
return Object.keys(matchers).reduce((acc, key) => {
const matcher = matchers[key];
const newMatcher = (...args) => {
try {
matcher(...args);
} catch (error) {
if (typeof customMessage !== 'string' || customMessage.length < 1 || !error.matcherResult) {
throw error;
}
return Object.keys(matchers).reduce((acc, name) => {
const matcher = matchers[name];

if (typeof matcher === 'function') {
const newMatcher = (...args) => {
try {
matcher(...args);
} catch (error) {
if (typeof customMessage !== 'string' || customMessage.length < 1 || !error.matcherResult) {
throw error;
}

const { matcherResult } = error;
const message = () => 'Custom message:\n ' + customMessage + '\n\n' + matcherResult.message();

const { matcherResult } = error;
const message = () => 'Custom message:\n ' + customMessage + '\n\n' + matcherResult.message();
throw new JestAssertionError(Object.assign({}, matcherResult, { message }), newMatcher);
}
};
return { ...acc, [name]: newMatcher };
}

throw new JestAssertionError(Object.assign({}, matcherResult, { message }), newMatcher);
}
return {
...acc,
[name]: wrapMatchers(matcher, customMessage) // recurse on .not/.resolves/.rejects
};
return Object.assign({}, acc, { [key]: newMatcher });
}, {});
};

Expand Down
45 changes: 42 additions & 3 deletions src/withMessage.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,28 @@ describe('withMessage()', () => {
expectMock.extend = 'extend';

const newExpect = withMessage(expectMock);
newExpect(ACTUAL, 'should fail').toBe(1);
newExpect(ACTUAL, 'should fail').toBe(ACTUAL);
expect(newExpect.extend).toBe('extend');
expect(expectMock).toHaveBeenCalledWith(ACTUAL);
expect(toBeMock).toHaveBeenCalledWith(1);
expect(toBeMock).toHaveBeenCalledWith(ACTUAL);
});

test('does not throw when matcher passes', () => {
expect.assertions(2);
const toBeMock = jest.fn();
const expectMock = jest.fn(() => ({ toBe: toBeMock }));

withMessage(expectMock)(ACTUAL, 'should fail').toBe(1);
withMessage(expectMock)(ACTUAL, 'should fail').toBe(ACTUAL);
expect(expectMock).toHaveBeenCalledWith(ACTUAL);
expect(toBeMock).toHaveBeenCalledWith(ACTUAL);
});

test('does not throw when matcher passes when using not', () => {
expect.assertions(2);
const toBeMock = jest.fn();
const expectMock = jest.fn(() => ({ not: { toBe: toBeMock } }));

withMessage(expectMock)(ACTUAL, 'should fail').not.toBe(1);
expect(expectMock).toHaveBeenCalledWith(ACTUAL);
expect(toBeMock).toHaveBeenCalledWith(1);
});
Expand Down Expand Up @@ -88,4 +98,33 @@ describe('withMessage()', () => {
expect(toBeMock).toHaveBeenCalledWith(1);
}
});

test('throws error with custom message when not matcher fails', () => {
expect.assertions(4);
const originalError = new Error('Boo');
originalError.matcherResult = {
actual: ACTUAL,
expected: 1,
message: () => 'expected ACTUAL to not be ACTUAL',
pass: false
};

const toBeMock = jest.fn(() => {
throw originalError;
});
const expectMock = jest.fn(() => ({ not: { toBe: toBeMock } }));

try {
withMessage(expectMock)(ACTUAL, 'should fail').not.toBe(ACTUAL);
} catch (e) {
expect(e.matcherResult).toMatchObject({
actual: ACTUAL,
expected: 1,
pass: false
});
expect(e.message).toMatchSnapshot();
expect(expectMock).toHaveBeenCalledWith(ACTUAL);
expect(toBeMock).toHaveBeenCalledWith(ACTUAL);
}
});
});

0 comments on commit 0fd13a0

Please sign in to comment.