Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
fix(getBy*): throw an error if more than one element is found (#229)
Closes #202

BREAKING CHANGE: All `getBy` and `findBy` query variants now will throw an error if more than one element is returned. If this is expected, then use `getAllBy` (or `findAllBy`) instead.
  • Loading branch information
Kent C. Dodds authored and Kent C. Dodds committed Apr 25, 2019
1 parent 253d677 commit 7f8c100
Show file tree
Hide file tree
Showing 16 changed files with 567 additions and 407 deletions.
2 changes: 1 addition & 1 deletion src/__tests__/element-queries.js
Expand Up @@ -86,7 +86,7 @@ test('get throws a useful error message', () => {
</div>"
`)
expect(() => getByRole('LucyRicardo')).toThrowErrorMatchingInlineSnapshot(`
"Unable to find an element by role=LucyRicardo
"Unable to find an element by [role=LucyRicardo]
<div>
<div />
Expand Down
86 changes: 86 additions & 0 deletions src/__tests__/get-by-errors.js
@@ -0,0 +1,86 @@
import cases from 'jest-in-case'
import {render} from './helpers/test-utils'

cases(
'getBy* queries throw an error when there are multiple elements returned',
({name, query, html}) => {
const utils = render(html)
expect(() => utils[name](query)).toThrow(/multiple elements/i)
},
{
getByLabelText: {
query: /his/,
html: `<div aria-label="his"></div><div aria-label="history"></div>`,
},
getByPlaceholderText: {
query: /his/,
html: `<input placeholder="his" /><input placeholder="history" />`,
},
getByText: {
query: /his/,
html: `<div>his</div><div>history</div>`,
},
getByAltText: {
query: /his/,
html: `<img alt="his" src="his.png" /><img alt="history" src="history.png" />`,
},
getByTitle: {
query: /his/,
html: `<div title="his"></div><div title="history"></div>`,
},
getByDisplayValue: {
query: /his/,
html: `<input value="his" /><select><option value="history">history</option></select>`,
},
getByRole: {
query: /his/,
html: `<div role="his"></div><div role="history"></div>`,
},
getByTestId: {
query: /his/,
html: `<div data-testid="his"></div><div data-testid="history"></div>`,
},
},
)

cases(
'queryBy* queries throw an error when there are multiple elements returned',
({name, query, html}) => {
const utils = render(html)
expect(() => utils[name](query)).toThrow(/multiple elements/i)
},
{
queryByLabelText: {
query: /his/,
html: `<div aria-label="his"></div><div aria-label="history"></div>`,
},
queryByPlaceholderText: {
query: /his/,
html: `<input placeholder="his" /><input placeholder="history" />`,
},
queryByText: {
query: /his/,
html: `<div>his</div><div>history</div>`,
},
queryByAltText: {
query: /his/,
html: `<img alt="his" src="his.png" /><img alt="history" src="history.png" />`,
},
queryByTitle: {
query: /his/,
html: `<div title="his"></div><div title="history"></div>`,
},
queryByDisplayValue: {
query: /his/,
html: `<input value="his" /><select><option value="history">history</option></select>`,
},
queryByRole: {
query: /his/,
html: `<div role="his"></div><div role="history"></div>`,
},
queryByTestId: {
query: /his/,
html: `<div data-testid="his"></div><div data-testid="history"></div>`,
},
},
)
15 changes: 15 additions & 0 deletions src/__tests__/misc.js
@@ -0,0 +1,15 @@
import {render} from './helpers/test-utils'
import {queryByAttribute} from '..'

// we used to use queryByAttribute internally, but we don't anymore. Some people
// use it as an undocumented part of the API, so we'll keep it around.
test('queryByAttribute', () => {
const {container} = render(
'<div data-foo="bar"></div><div data-foo="rubar"></div>',
)
expect(queryByAttribute('data-foo', container, 'bar')).not.toBeNull()
expect(queryByAttribute('blah', container, 'sup')).toBeNull()
expect(() => queryByAttribute('data-foo', container, /bar/)).toThrow(
/multiple/,
)
})

0 comments on commit 7f8c100

Please sign in to comment.