-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Improving api #13
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
Improving api #13
Changes from 7 commits
5a2c05f
dd727d0
485e8fb
96a1a9e
cc2a1c3
3931a69
3ae81f6
987c4f3
57fd424
d1157a2
0cdb02b
74d8205
8348852
492645b
e222206
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
const expect = require('expect') //eslint-disable-line import/no-extraneous-dependencies | ||
const extensions = require('./dist/jest-extensions') | ||
|
||
const {toBeInTheDOM, toHaveTextContent, toSatisfyDOM} = extensions.default | ||
expect.extend({toBeInTheDOM, toHaveTextContent, toSatisfyDOM}) | ||
|
||
module.exports = expect |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,6 @@ | ||
import React from 'react' | ||
import {render} from '../' | ||
import '../../extend-expect' | ||
|
||
test('query can return null', () => { | ||
const { | ||
|
@@ -66,4 +67,18 @@ test('totally empty label', () => { | |
expect(() => getByLabelText('')).toThrowErrorMatchingSnapshot() | ||
}) | ||
|
||
test('using jest helpers to assert element states', () => { | ||
const {queryByTestId, getByTestId} = render( | ||
<span data-testid="count-value">2</span>, | ||
) | ||
|
||
//other ways to assert your test cases, but you don't need all of them. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not sure why prettier didn't add a space here, but please add a space before the |
||
expect(queryByTestId('count-value')).toBeInTheDOM() | ||
expect(queryByTestId('count-value')).toHaveTextContent('2') | ||
expect(getByTestId('count-value')).toSatisfyDOM(el => el.textContent === '2') | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm starting to question the value of this matcher. Maybe instead we should just recommend people use jest-extend instead. This is basically the same as The other matchers are still very valuable though! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @kentcdodds There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I agree that this matcher can be useful, but I'd much rather be very selective about what we include in this library. It's much easier to exclude something and add it later than add something and remove it later. So I lean on the side of excluding things. I'm thinking most people wont need this and those who do will be happy to include jest-extend I think. |
||
expect(queryByTestId('count-value')).not.toHaveTextContent( | ||
'you are not there', | ||
) | ||
}) | ||
|
||
/* eslint jsx-a11y/label-has-for:0 */ |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
import {matcherHint, printReceived, printExpected} from 'jest-matcher-utils' //eslint-disable-line import/no-extraneous-dependencies | ||
|
||
function getDisplayName(subject) { | ||
if (subject && subject.constructor) { | ||
return subject.constructor.name | ||
} else { | ||
return typeof subject | ||
} | ||
} | ||
|
||
const assertMessage = (assertionName, message, received, expected) => () => | ||
`${matcherHint(`${assertionName}`, 'received', '')} \n${message}: ` + | ||
`${printExpected(expected)} \nReceived: ${printReceived(received)}` | ||
|
||
const extensions = { | ||
toBeInTheDOM(received) { | ||
getDisplayName(received) | ||
if (received) { | ||
return { | ||
message: () => | ||
`${matcherHint( | ||
'.not.toBeInTheDOM', | ||
'received', | ||
'', | ||
)} Expected the element not to be present` + | ||
`\nReceived : ${printReceived(received)}`, | ||
pass: true, | ||
} | ||
} else { | ||
return { | ||
message: () => | ||
`${matcherHint( | ||
'.toBeInTheDOM', | ||
'received', | ||
'', | ||
)} Expected the element to be present` + | ||
`\nReceived : ${printReceived(received)}`, | ||
pass: false, | ||
} | ||
} | ||
}, | ||
|
||
toHaveTextContent(htmlElement, checkWith) { | ||
if (!(htmlElement instanceof HTMLElement)) | ||
throw new Error( | ||
`The given subject is a ${getDisplayName( | ||
htmlElement, | ||
)}, not an HTMLElement`, | ||
) | ||
|
||
const textContent = htmlElement.textContent | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could we add an extra check here that throw new Error(`The given subject is a ${getDisplayName(htmlElement)}, not an HTMLElement`) Or return an object, but this should probably fail regardless of whether people use The function getDisplayName(subject) {
if (subject && subject.constructor) {
return subject.constructor.name
} else {
return typeof subject
}
} Or, maybe there's a better thing for this available on npm... There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I guess the code that you had mentioned |
||
const pass = textContent === checkWith | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could we extend this to use the Using the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, thats a good idea. Can take care of that, will move
|
||
if (pass) { | ||
return { | ||
message: assertMessage( | ||
'.not.toHaveTextContent', | ||
'Expected value not equals to', | ||
htmlElement, | ||
checkWith, | ||
), | ||
pass: true, | ||
} | ||
} else { | ||
return { | ||
message: assertMessage( | ||
'.toHaveTextContent', | ||
'Expected value equals to', | ||
htmlElement, | ||
checkWith, | ||
), | ||
pass: false, | ||
} | ||
} | ||
}, | ||
|
||
toSatisfyDOM(actual, predicate) { | ||
const pass = predicate(actual) | ||
if (pass) { | ||
return { | ||
message: assertMessage( | ||
'.not.toSatisfyDOM()', | ||
'Expected predicate not equals to true', | ||
actual, | ||
predicate, | ||
), | ||
pass: true, | ||
} | ||
} else { | ||
return { | ||
message: assertMessage( | ||
'.not.toSatisfyDOM()', | ||
'Expected predicate equals to true', | ||
actual, | ||
predicate, | ||
), | ||
pass: false, | ||
} | ||
} | ||
}, | ||
} | ||
|
||
export default extensions |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The problem with this is it means you have to run the build before you can run the tests (because on a fresh clone the
dist
directory doesn't work). It also means that any changes tojest-extensions.js
wont be picked up by tests until the next build.Instead, you'll basically need to duplicate the code.
Alternatively... You could put the code that's currently in
extend-expect.js
intosrc/extend-expect.js
and then change the contents of:extend-expect.js
to be simply:require('./dist/extend-expect')
. Then you could update this import to simply:'../extend-expect'
👍