Skip to content

Commit

Permalink
feat: use regex based TextMatch for suggestions (#617)
Browse files Browse the repository at this point in the history
Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
  • Loading branch information
smeijer and kentcdodds committed Jun 11, 2020
1 parent 281eb8b commit b23a2bc
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 22 deletions.
40 changes: 22 additions & 18 deletions src/__tests__/suggestions.js
Expand Up @@ -72,7 +72,9 @@ test(`should not suggest if the suggestion would give different results`, () =>
test('should suggest by label over title', () => {
renderIntoDocument(`<label><span>bar</span><input title="foo" /></label>`)

expect(() => screen.getByTitle('foo')).toThrowError(/getByLabelText\('bar'\)/)
expect(() => screen.getByTitle('foo')).toThrowError(
/getByLabelText\(\/bar\/i\)/,
)
})

test('should not suggest if there would be mixed suggestions', () => {
Expand Down Expand Up @@ -178,7 +180,7 @@ test('should suggest getByLabelText when no role available', () => {
`<label for="foo">Username</label><input data-testid="foo" id="foo" />`,
)
expect(() => screen.getByTestId('foo')).toThrowError(
/getByLabelText\('Username'\)/,
/getByLabelText\(\/username\/i\)/,
)
})

Expand All @@ -191,7 +193,7 @@ test(`should suggest getByLabel on non form elements`, () => {
`)

expect(() => screen.getByTestId('foo')).toThrowError(
/getByLabelText\('Section One'\)/,
/getByLabelText\(\/section one\/i\)/,
)
})

Expand Down Expand Up @@ -230,23 +232,23 @@ test(`should suggest label over placeholder text`, () => {
)

expect(() => screen.getByPlaceholderText('Username')).toThrowError(
/getByLabelText\('Username'\)/,
/getByLabelText\(\/username\/i\)/,
)
})

test(`should suggest getByPlaceholderText`, () => {
renderIntoDocument(`<input data-testid="foo" placeholder="Username" />`)

expect(() => screen.getByTestId('foo')).toThrowError(
/getByPlaceholderText\('Username'\)/,
/getByPlaceholderText\(\/username\/i\)/,
)
})

test(`should suggest getByText for simple elements`, () => {
renderIntoDocument(`<div data-testid="foo">hello there</div>`)

expect(() => screen.getByTestId('foo')).toThrowError(
/getByText\('hello there'\)/,
/getByText\(\/hello there\/i\)/,
)
})

Expand All @@ -256,7 +258,7 @@ test(`should suggest getByDisplayValue`, () => {
document.getElementById('lastName').value = 'Prine' // RIP John Prine

expect(() => screen.getByTestId('lastName')).toThrowError(
/getByDisplayValue\('Prine'\)/,
/getByDisplayValue\(\/prine\/i\)/,
)
})

Expand All @@ -269,10 +271,10 @@ test(`should suggest getByAltText`, () => {
`)

expect(() => screen.getByTestId('input')).toThrowError(
/getByAltText\('last name'\)/,
/getByAltText\(\/last name\/i\)/,
)
expect(() => screen.getByTestId('area')).toThrowError(
/getByAltText\('Computer'\)/,
/getByAltText\(\/computer\/i\)/,
)
})

Expand All @@ -285,27 +287,29 @@ test(`should suggest getByTitle`, () => {
</svg>`)

expect(() => screen.getByTestId('delete')).toThrowError(
/getByTitle\('Delete'\)/,
/getByTitle\(\/delete\/i\)/,
)
expect(() => screen.getAllByTestId('delete')).toThrowError(
/getAllByTitle\('Delete'\)/,
/getAllByTitle\(\/delete\/i\)/,
)
expect(() => screen.queryByTestId('delete')).toThrowError(
/queryByTitle\('Delete'\)/,
/queryByTitle\(\/delete\/i\)/,
)
expect(() => screen.queryAllByTestId('delete')).toThrowError(
/queryAllByTitle\('Delete'\)/,
/queryAllByTitle\(\/delete\/i\)/,
)
expect(() => screen.queryAllByTestId('delete')).toThrowError(
/queryAllByTitle\('Delete'\)/,
/queryAllByTitle\(\/delete\/i\)/,
)
expect(() => screen.queryAllByTestId('delete')).toThrowError(
/queryAllByTitle\('Delete'\)/,
/queryAllByTitle\(\/delete\/i\)/,
)

// Since `ByTitle` and `ByText` will both return the <title> element
// `getByText` will always be the suggested query as it is higher up the list.
expect(() => screen.getByTestId('svg')).toThrowError(/getByText\('Close'\)/)
expect(() => screen.getByTestId('svg')).toThrowError(
/getByText\(\/close\/i\)/,
)
})

test('getSuggestedQuery handles `variant` and defaults to `get`', () => {
Expand Down Expand Up @@ -343,9 +347,9 @@ test('getSuggestedQuery returns rich data for tooling', () => {
expect(getSuggestedQuery(div)).toMatchObject({
queryName: 'Text',
queryMethod: 'getByText',
queryArgs: ['cancel'],
queryArgs: [/cancel/i],
variant: 'get',
})

expect(getSuggestedQuery(div).toString()).toEqual(`getByText('cancel')`)
expect(getSuggestedQuery(div).toString()).toEqual(`getByText(/cancel/i)`)
})
17 changes: 13 additions & 4 deletions src/suggestions.js
Expand Up @@ -30,8 +30,12 @@ function escapeRegExp(string) {
return string.replace(/[.*+\-?^${}()|[\]\\]/g, '\\$&') // $& means the whole matched string
}

function getRegExpMatcher(string) {
return new RegExp(string.toLowerCase(), 'i')
}

function makeSuggestion(queryName, content, {variant = 'get', name}) {
const queryArgs = [content]
const queryArgs = [queryName === 'Role' ? content : getRegExpMatcher(content)]

if (name) {
queryArgs.push({name: new RegExp(escapeRegExp(name.toLowerCase()), 'i')})
Expand All @@ -45,12 +49,17 @@ function makeSuggestion(queryName, content, {variant = 'get', name}) {
queryArgs,
variant,
toString() {
const options = queryArgs[1]
? `, { ${Object.entries(queryArgs[1])
let [text, options] = queryArgs

text = typeof text === 'string' ? `'${text}'` : text

options = options
? `, { ${Object.entries(options)
.map(([k, v]) => `${k}: ${v}`)
.join(', ')} }`
: ''
return `${queryMethod}('${content}'${options})`

return `${queryMethod}(${text}${options})`
},
}
}
Expand Down

0 comments on commit b23a2bc

Please sign in to comment.