diff --git a/README.md b/README.md
index c9461bcb..b21a10d9 100644
--- a/README.md
+++ b/README.md
@@ -46,6 +46,7 @@ clear to read and to maintain.
+
- [Installation](#installation)
- [Usage](#usage)
- [Custom matchers](#custom-matchers)
@@ -781,7 +782,7 @@ expect(selectInput).not.toHaveValue(['second', 'third'])
### `toHaveDisplayValue`
```typescript
-toHaveDisplayValue(value: string | string[])
+toHaveDisplayValue(value: string | RegExp | (string|RegExp)[])
```
This allows you to check whether the given form element has the specified
@@ -826,9 +827,12 @@ const selectSingle = screen.getByLabelText('Fruit')
const selectMultiple = screen.getByLabelText('Fruits')
expect(input).toHaveDisplayValue('Luca')
+expect(input).toHaveDisplayValue(/Luc/)
expect(textarea).toHaveDisplayValue('An example description here.')
+expect(textarea).toHaveDisplayValue(/example/)
expect(selectSingle).toHaveDisplayValue('Select a fruit...')
-expect(selectMultiple).toHaveDisplayValue(['Banana', 'Avocado'])
+expect(selectSingle).toHaveDisplayValue(/Select/)
+expect(selectMultiple).toHaveDisplayValue([/Avocado/, 'Banana'])
```
@@ -1084,6 +1088,7 @@ Thanks goes to these people ([emoji key][emojis]):
+
This project follows the [all-contributors][all-contributors] specification.
diff --git a/src/__tests__/to-have-display-value.js b/src/__tests__/to-have-display-value.js
index e49749a9..8cae8734 100644
--- a/src/__tests__/to-have-display-value.js
+++ b/src/__tests__/to-have-display-value.js
@@ -21,36 +21,68 @@ test('it should work as expected', () => {
queryByTestId('select').value = 'banana'
expect(queryByTestId('select')).toHaveDisplayValue('Banana')
+ expect(queryByTestId('select')).toHaveDisplayValue(/[bB]ana/)
})
-test('it should work with select multiple', () => {
- const {queryByTestId} = render(`
-
- `)
+describe('with multiple select', () => {
+ function mount() {
+ return render(`
+
+ `)
+ }
- expect(queryByTestId('select')).toHaveDisplayValue(['Ananas', 'Avocado'])
- expect(() =>
- expect(queryByTestId('select')).not.toHaveDisplayValue([
+ it('matches only when all the multiple selected values are equal to all the expected values', () => {
+ const subject = mount()
+ expect(subject.queryByTestId('select')).toHaveDisplayValue([
'Ananas',
'Avocado',
- ]),
- ).toThrow()
-
- expect(queryByTestId('select')).not.toHaveDisplayValue('Ananas')
- expect(() =>
- expect(queryByTestId('select')).toHaveDisplayValue('Ananas'),
- ).toThrow()
+ ])
+ expect(() =>
+ expect(subject.queryByTestId('select')).not.toHaveDisplayValue([
+ 'Ananas',
+ 'Avocado',
+ ]),
+ ).toThrow()
+ expect(subject.queryByTestId('select')).not.toHaveDisplayValue([
+ 'Ananas',
+ 'Avocado',
+ 'Orange',
+ ])
+ expect(subject.queryByTestId('select')).not.toHaveDisplayValue('Ananas')
+ expect(() =>
+ expect(subject.queryByTestId('select')).toHaveDisplayValue('Ananas'),
+ ).toThrow()
+
+ Array.from(subject.queryByTestId('select').options).forEach(option => {
+ option.selected = ['ananas', 'banana'].includes(option.value)
+ })
+
+ expect(subject.queryByTestId('select')).toHaveDisplayValue([
+ 'Ananas',
+ 'Banana',
+ ])
+ })
- Array.from(queryByTestId('select').options).forEach(option => {
- option.selected = ['ananas', 'banana'].includes(option.value)
+ it('matches even when the expected values are unordered', () => {
+ const subject = mount()
+ expect(subject.queryByTestId('select')).toHaveDisplayValue([
+ 'Avocado',
+ 'Ananas',
+ ])
})
- expect(queryByTestId('select')).toHaveDisplayValue(['Ananas', 'Banana'])
+ it('matches with regex expected values', () => {
+ const subject = mount()
+ expect(subject.queryByTestId('select')).toHaveDisplayValue([
+ /[Aa]nanas/,
+ 'Avocado',
+ ])
+ })
})
test('it should work with input elements', () => {
@@ -59,6 +91,7 @@ test('it should work with input elements', () => {
`)
expect(queryByTestId('input')).toHaveDisplayValue('Luca')
+ expect(queryByTestId('input')).toHaveDisplayValue(/Luc/)
queryByTestId('input').value = 'Piero'
expect(queryByTestId('input')).toHaveDisplayValue('Piero')
@@ -72,6 +105,7 @@ test('it should work with textarea elements', () => {
expect(queryByTestId('textarea-example')).toHaveDisplayValue(
'An example description here.',
)
+ expect(queryByTestId('textarea-example')).toHaveDisplayValue(/example/)
queryByTestId('textarea-example').value = 'Another example'
expect(queryByTestId('textarea-example')).toHaveDisplayValue(
diff --git a/src/to-have-display-value.js b/src/to-have-display-value.js
index c59d7181..11d35c5c 100644
--- a/src/to-have-display-value.js
+++ b/src/to-have-display-value.js
@@ -1,6 +1,5 @@
import {matcherHint} from 'jest-matcher-utils'
-
-import {checkHtmlElement, getMessage} from './utils'
+import {matches, checkHtmlElement, getMessage} from './utils'
export function toHaveDisplayValue(htmlElement, expectedValue) {
checkHtmlElement(htmlElement, toHaveDisplayValue, this)
@@ -18,16 +17,19 @@ export function toHaveDisplayValue(htmlElement, expectedValue) {
)
}
- const value =
- tagName === 'select'
- ? Array.from(htmlElement)
- .filter(option => option.selected)
- .map(option => option.textContent)
- .toString()
- : htmlElement.value
+ const values = getValues(tagName, htmlElement)
+ const expectedValues = getExpectedValues(expectedValue)
+ const numberOfMatchesWithValues = getNumberOfMatchesBetweenArrays(
+ values,
+ expectedValues,
+ )
+
+ const matchedWithAllValues = numberOfMatchesWithValues === values.length
+ const matchedWithAllExpectedValues =
+ numberOfMatchesWithValues === expectedValues.length
return {
- pass: value === expectedValue.toString(),
+ pass: matchedWithAllValues && matchedWithAllExpectedValues,
message: () =>
getMessage(
matcherHint(
@@ -38,7 +40,25 @@ export function toHaveDisplayValue(htmlElement, expectedValue) {
`Expected element ${this.isNot ? 'not ' : ''}to have display value`,
expectedValue,
'Received',
- value,
+ values,
),
}
}
+
+function getValues(tagName, htmlElement) {
+ return tagName === 'select'
+ ? Array.from(htmlElement)
+ .filter(option => option.selected)
+ .map(option => option.textContent)
+ : [htmlElement.value]
+}
+
+function getExpectedValues(expectedValue) {
+ return expectedValue instanceof Array ? expectedValue : [expectedValue]
+}
+
+function getNumberOfMatchesBetweenArrays(arrayBase, array) {
+ return array.filter(
+ expected => arrayBase.filter(value => matches(value, expected)).length,
+ ).length
+}