Skip to content

Commit

Permalink
fix: improved error messages
Browse files Browse the repository at this point in the history
  • Loading branch information
microcood committed Jun 6, 2018
1 parent 6f28c1c commit e03132e
Show file tree
Hide file tree
Showing 10 changed files with 288 additions and 67 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
"css": "^2.2.3",
"jest-diff": "^22.4.3",
"jest-matcher-utils": "^22.4.3",
"pretty-format": "^23.0.1",
"redent": "^2.0.0"
},
"devDependencies": {
Expand Down
198 changes: 198 additions & 0 deletions src/__tests__/__snapshots__/index.js.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,198 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`.toBeInTheDOM 1`] = `
"<dim>expect(</><red>element</><dim>).not.toBeInTheDOM(</><dim>)</>
Received:
<red><span data-testid=\\"count-value\\" /></>"
`;
exports[`.toBeInTheDOM 2`] = `
"<dim>expect(</><red>element</><dim>).toBeInTheDOM(</><dim>)</>
Received:
<red>null</>"
`;
exports[`.toBeInTheDOM 3`] = `
"<dim>expect(</><red>received</><dim>).toBeInTheDOM(</><dim>)</>
<red>received</> value must be an HTMLElement.
Received:
object: <red>{\\"thisIsNot\\": \\"an html element\\"}</>"
`;
exports[`.toBeVisible 1`] = `
"<dim>expect(</><red>element</><dim>).not.toBeVisible(</><dim>)</>
Received element is visible:
<red><header /></>"
`;
exports[`.toBeVisible 2`] = `
"<dim>expect(</><red>element</><dim>).toBeVisible(</><dim>)</>
Received element is not visible:
<red><p /></>"
`;
exports[`.toHaveAttribute 1`] = `
"<dim>expect(</><red>element</><dim>).not.toHaveAttribute(</><green><green>\\"disabled\\"<green></><dim>) // element.hasAttribute(\\"disabled\\")</>
Expected the element not to have attribute:
<green>disabled</>
Received:
<red>disabled=\\"\\"</>"
`;
exports[`.toHaveAttribute 2`] = `
"<dim>expect(</><red>element</><dim>).not.toHaveAttribute(</><green><green>\\"type\\"<green></><dim>) // element.hasAttribute(\\"type\\")</>
Expected the element not to have attribute:
<green>type</>
Received:
<red>type=\\"submit\\"</>"
`;
exports[`.toHaveAttribute 3`] = `
"<dim>expect(</><red>element</><dim>).toHaveAttribute(</><green><green>\\"class\\"<green></><dim>) // element.hasAttribute(\\"class\\")</>
Expected the element to have attribute:
<green>class</>
Received:
<red>null</>"
`;
exports[`.toHaveAttribute 4`] = `
"<dim>expect(</><red>element</><dim>).not.toHaveAttribute(</><green><green>\\"type\\"<green></><dim>, </><green><green>\\"submit\\"<green></><dim>) // element.getAttribute(\\"type\\") === \\"submit\\"</>
Expected the element not to have attribute:
<green>type=\\"submit\\"</>
Received:
<red>type=\\"submit\\"</>"
`;
exports[`.toHaveAttribute 5`] = `
"<dim>expect(</><red>element</><dim>).toHaveAttribute(</><green><green>\\"type\\"<green></><dim>, </><green><green>\\"button\\"<green></><dim>) // element.getAttribute(\\"type\\") === \\"button\\"</>
Expected the element to have attribute:
<green>type=\\"button\\"</>
Received:
<red>type=\\"submit\\"</>"
`;
exports[`.toHaveAttribute 6`] = `
"<dim>expect(</><red>received</><dim>).not.toHaveAttribute(</><dim>)</>
<red>received</> value must be an HTMLElement.
Received:
object: <red>{\\"thisIsNot\\": \\"an html element\\"}</>"
`;
exports[`.toHaveClass 1`] = `
"<dim>expect(</><red>element</><dim>).not.toHaveClass(</><green><green>\\"btn\\"<green></><dim>)</>
Expected the element not to have class:
<green> btn</>
Received:
<red> btn extra btn-danger</>"
`;
exports[`.toHaveClass 2`] = `
"<dim>expect(</><red>element</><dim>).not.toHaveClass(</><green><green>\\"btn-danger\\"<green></><dim>)</>
Expected the element not to have class:
<green> btn-danger</>
Received:
<red> btn extra btn-danger</>"
`;
exports[`.toHaveClass 3`] = `
"<dim>expect(</><red>element</><dim>).not.toHaveClass(</><green><green>\\"extra\\"<green></><dim>)</>
Expected the element not to have class:
<green> extra</>
Received:
<red> btn extra btn-danger</>"
`;
exports[`.toHaveClass 4`] = `
"<dim>expect(</><red>element</><dim>).toHaveClass(</><green><green>\\"xtra\\"<green></><dim>)</>
Expected the element to have class:
<green> xtra</>
Received:
<red> btn extra btn-danger</>"
`;
exports[`.toHaveClass 5`] = `
"<dim>expect(</><red>element</><dim>).not.toHaveClass(</><green><green>\\"btn btn-danger\\"<green></><dim>)</>
Expected the element not to have class:
<green> btn btn-danger</>
Received:
<red> btn extra btn-danger</>"
`;
exports[`.toHaveClass 6`] = `
"<dim>expect(</><red>element</><dim>).toHaveClass(</><green><green>\\"btn-link\\"<green></><dim>)</>
Expected the element to have class:
<green> btn-link</>
Received:
<red> btn extra btn-danger</>"
`;
exports[`.toHaveClass 7`] = `
"<dim>expect(</><red>element</><dim>).toHaveClass(</><green><green>\\"btn-danger\\"<green></><dim>)</>
Expected the element to have class:
<green> btn-danger</>
Received:
"
`;
exports[`.toHaveStyle 1`] = `
"<dim>expect(</><red>element</><dim>).toHaveStyle(</><dim>)</>
<green>- Expected</>
<green>- font-weight: bold;</>
<dim> </>
<red>+ </>"
`;
exports[`.toHaveStyle 2`] = `
"<dim>expect(</><red>element</><dim>).not.toHaveStyle(</><dim>)</>
<dim>Compared values have no visual difference.</>"
`;
exports[`.toHaveStyle 3`] = `"Syntax error parsing expected css: property missing ':' in 1:24"`;
exports[`.toHaveStyle 4`] = `"Syntax error parsing expected css: property missing ':' in 1:18"`;
exports[`.toHaveTextContent 1`] = `
"<dim>expect(</><red>received</><dim>).toHaveTextContent(</><dim>)</>
<red>received</> value must be an HTMLElement.
Received: <red>null</>"
`;
exports[`.toHaveTextContent 2`] = `
"<dim>expect(</><red>element</><dim>).toHaveTextContent(</><dim>)</>
Expected element to have text content:
<green> 3</>
Received:
<red> 2</>"
`;
exports[`.toHaveTextContent 3`] = `
"<dim>expect(</><red>element</><dim>).not.toHaveTextContent(</><dim>)</>
Expected element not to have text content:
<green> 2</>
Received:
<red> 2</>"
`;
54 changes: 30 additions & 24 deletions src/__tests__/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import '../extend-expect'
import {plugins} from 'pretty-format'
import {render} from './helpers/test-utils'

expect.addSnapshotSerializer(plugins.ConvertAnsi)

test('.toBeInTheDOM', () => {
const {queryByTestId} = render(`<span data-testid="count-value">2</span>`)

Expand All @@ -10,13 +13,13 @@ test('.toBeInTheDOM', () => {
// negative test cases wrapped in throwError assertions for coverage.
expect(() =>
expect(queryByTestId('count-value')).not.toBeInTheDOM(),
).toThrowError()
).toThrowErrorMatchingSnapshot()
expect(() =>
expect(queryByTestId('count-value1')).toBeInTheDOM(),
).toThrowError()
).toThrowErrorMatchingSnapshot()
expect(() =>
expect({thisIsNot: 'an html element'}).toBeInTheDOM(),
).toThrowError()
).toThrowErrorMatchingSnapshot()
})

test('.toHaveTextContent', () => {
Expand All @@ -27,14 +30,14 @@ test('.toHaveTextContent', () => {
expect(queryByTestId('count-value')).not.toHaveTextContent('21')
expect(() =>
expect(queryByTestId('count-value2')).toHaveTextContent('2'),
).toThrowError()
).toThrowErrorMatchingSnapshot()

expect(() =>
expect(queryByTestId('count-value')).toHaveTextContent('3'),
).toThrowError()
).toThrowErrorMatchingSnapshot()
expect(() =>
expect(queryByTestId('count-value')).not.toHaveTextContent('2'),
).toThrowError()
).toThrowErrorMatchingSnapshot()
})

test('.toHaveAttribute', () => {
Expand All @@ -52,19 +55,22 @@ test('.toHaveAttribute', () => {

expect(() =>
expect(queryByTestId('ok-button')).not.toHaveAttribute('disabled'),
).toThrowError()
).toThrowErrorMatchingSnapshot()
expect(() =>
expect(queryByTestId('ok-button')).not.toHaveAttribute('type'),
).toThrowError()
).toThrowErrorMatchingSnapshot()
expect(() =>
expect(queryByTestId('ok-button')).toHaveAttribute('class'),
).toThrowError()
).toThrowErrorMatchingSnapshot()
expect(() =>
expect(queryByTestId('ok-button')).not.toHaveAttribute('type', 'submit'),
).toThrowError()
).toThrowErrorMatchingSnapshot()
expect(() =>
expect(queryByTestId('ok-button')).toHaveAttribute('type', 'button'),
).toThrowError()
).toThrowErrorMatchingSnapshot()
expect(() =>
expect({thisIsNot: 'an html element'}).not.toHaveAttribute(),
).toThrowErrorMatchingSnapshot()
})

test('.toHaveClass', () => {
Expand All @@ -89,25 +95,25 @@ test('.toHaveClass', () => {

expect(() =>
expect(queryByTestId('delete-button')).not.toHaveClass('btn'),
).toThrowError()
).toThrowErrorMatchingSnapshot()
expect(() =>
expect(queryByTestId('delete-button')).not.toHaveClass('btn-danger'),
).toThrowError()
).toThrowErrorMatchingSnapshot()
expect(() =>
expect(queryByTestId('delete-button')).not.toHaveClass('extra'),
).toThrowError()
).toThrowErrorMatchingSnapshot()
expect(() =>
expect(queryByTestId('delete-button')).toHaveClass('xtra'),
).toThrowError()
).toThrowErrorMatchingSnapshot()
expect(() =>
expect(queryByTestId('delete-button')).not.toHaveClass('btn btn-danger'),
).toThrowError()
).toThrowErrorMatchingSnapshot()
expect(() =>
expect(queryByTestId('delete-button')).toHaveClass('btn-link'),
).toThrowError()
).toThrowErrorMatchingSnapshot()
expect(() =>
expect(queryByTestId('cancel-button')).toHaveClass('btn-danger'),
).toThrowError()
).toThrowErrorMatchingSnapshot()
})

test('.toHaveStyle', () => {
Expand Down Expand Up @@ -149,20 +155,20 @@ test('.toHaveStyle', () => {

expect(() =>
expect(container.querySelector('.label')).toHaveStyle('font-weight: bold'),
).toThrowError()
).toThrowErrorMatchingSnapshot()
expect(() =>
expect(container.querySelector('.label')).not.toHaveStyle('color: white'),
).toThrowError()
).toThrowErrorMatchingSnapshot()

// Make sure the test fails if the css syntax is not valid
expect(() =>
expect(container.querySelector('.label')).not.toHaveStyle(
'font-weight bold',
),
).toThrowError()
).toThrowErrorMatchingSnapshot()
expect(() =>
expect(container.querySelector('.label')).toHaveStyle('color white'),
).toThrowError()
).toThrowErrorMatchingSnapshot()

document.body.removeChild(style)
document.body.removeChild(container)
Expand Down Expand Up @@ -194,8 +200,8 @@ test('.toBeVisible', () => {

expect(() =>
expect(container.querySelector('header')).not.toBeVisible(),
).toThrowError()
).toThrowErrorMatchingSnapshot()
expect(() =>
expect(container.querySelector('p')).toBeVisible(),
).toThrowError()
).toThrowErrorMatchingSnapshot()
})
18 changes: 8 additions & 10 deletions src/to-be-in-the-dom.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,19 @@
import {matcherHint} from 'jest-matcher-utils'
import {checkHtmlElement, getMessage} from './utils'
import {matcherHint, printReceived} from 'jest-matcher-utils'
import {checkHtmlElement} from './utils'

export function toBeInTheDOM(received) {
if (received) {
checkHtmlElement(received)
checkHtmlElement(received, toBeInTheDOM, this)
}
return {
pass: !!received,
message: () => {
const to = this.isNot ? 'not to' : 'to'
return getMessage(
return [
matcherHint(`${this.isNot ? '.not' : ''}.toBeInTheDOM`, 'element', ''),
'Expected',
`element ${to} be present`,
'Received',
received,
)
'',
'Received:',
` ${printReceived(received ? received.cloneNode(false) : received)}`,
].join('\n')
},
}
}
Loading

0 comments on commit e03132e

Please sign in to comment.