From f4f41738e1a9c506e329abd36068386e137bb27a Mon Sep 17 00:00:00 2001 From: Leandro Lourenci Date: Wed, 6 May 2020 16:58:29 -0300 Subject: [PATCH 1/9] Allow to use regex on non-multiple value on toHaveDisplayValue --- src/__tests__/to-have-display-value.js | 1 + src/to-have-display-value.js | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/__tests__/to-have-display-value.js b/src/__tests__/to-have-display-value.js index e49749a9..32e051c4 100644 --- a/src/__tests__/to-have-display-value.js +++ b/src/__tests__/to-have-display-value.js @@ -21,6 +21,7 @@ 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', () => { diff --git a/src/to-have-display-value.js b/src/to-have-display-value.js index c59d7181..33b9997a 100644 --- a/src/to-have-display-value.js +++ b/src/to-have-display-value.js @@ -1,6 +1,7 @@ import {matcherHint} from 'jest-matcher-utils' +import {matches,checkHtmlElement, getMessage} from './utils' + -import {checkHtmlElement, getMessage} from './utils' export function toHaveDisplayValue(htmlElement, expectedValue) { checkHtmlElement(htmlElement, toHaveDisplayValue, this) @@ -27,7 +28,7 @@ export function toHaveDisplayValue(htmlElement, expectedValue) { : htmlElement.value return { - pass: value === expectedValue.toString(), + pass: matches(value, expectedValue), message: () => getMessage( matcherHint( From 26c6e7126bf64afad9aa7baf08f477ab37003ef5 Mon Sep 17 00:00:00 2001 From: Leandro Lourenci Date: Wed, 6 May 2020 17:16:28 -0300 Subject: [PATCH 2/9] Allow to use regex on multiple value on toHaveDisplayValue --- src/__tests__/to-have-display-value.js | 7 +++++-- src/to-have-display-value.js | 8 +++++--- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/__tests__/to-have-display-value.js b/src/__tests__/to-have-display-value.js index 32e051c4..468f5fc7 100644 --- a/src/__tests__/to-have-display-value.js +++ b/src/__tests__/to-have-display-value.js @@ -1,6 +1,6 @@ import {render} from './helpers/test-utils' -test('it should work as expected', () => { +test.only('it should work as expected', () => { const {queryByTestId} = render(` @@ -35,12 +35,15 @@ test('it should work with select multiple', () => { `) expect(queryByTestId('select')).toHaveDisplayValue(['Ananas', 'Avocado']) + expect(queryByTestId('select')).toHaveDisplayValue(['Avocado', 'Ananas']) + expect(queryByTestId('select')).toHaveDisplayValue([/[Aa]nanas/, 'Avocado']) expect(() => expect(queryByTestId('select')).not.toHaveDisplayValue([ 'Ananas', 'Avocado', ]), ).toThrow() + expect(queryByTestId('select')).not.toHaveDisplayValue(['Ananas', 'Avocado', 'Orange']) expect(queryByTestId('select')).not.toHaveDisplayValue('Ananas') expect(() => diff --git a/src/to-have-display-value.js b/src/to-have-display-value.js index 33b9997a..1dfae2e3 100644 --- a/src/to-have-display-value.js +++ b/src/to-have-display-value.js @@ -24,11 +24,13 @@ export function toHaveDisplayValue(htmlElement, expectedValue) { ? Array.from(htmlElement) .filter(option => option.selected) .map(option => option.textContent) - .toString() - : htmlElement.value + : [htmlElement.value] + + const expectedValueArray = expectedValue instanceof Array ? expectedValue : [expectedValue] + const matchess = expectedValueArray.filter(expected => value.filter(valueFilter => matches(valueFilter, expected)).length).length return { - pass: matches(value, expectedValue), + pass: matchess === value.length && matchess === expectedValueArray.length, message: () => getMessage( matcherHint( From c717de783a2f44920f87595e8336f0ff55009508 Mon Sep 17 00:00:00 2001 From: Leandro Lourenci Date: Wed, 6 May 2020 17:17:45 -0300 Subject: [PATCH 3/9] Allow to use regex on multiple value on toHaveDisplayValue --- src/__tests__/to-have-display-value.js | 10 +++++++--- src/to-have-display-value.js | 12 +++++++----- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/src/__tests__/to-have-display-value.js b/src/__tests__/to-have-display-value.js index 468f5fc7..f1ca3857 100644 --- a/src/__tests__/to-have-display-value.js +++ b/src/__tests__/to-have-display-value.js @@ -1,6 +1,6 @@ import {render} from './helpers/test-utils' -test.only('it should work as expected', () => { +test('it should work as expected', () => { const {queryByTestId} = render(` @@ -43,7 +43,11 @@ test.only('it should work with select multiple', () => { 'Avocado', ]), ).toThrow() - expect(queryByTestId('select')).not.toHaveDisplayValue(['Ananas', 'Avocado', 'Orange']) + expect(queryByTestId('select')).not.toHaveDisplayValue([ + 'Ananas', + 'Avocado', + 'Orange', + ]) expect(queryByTestId('select')).not.toHaveDisplayValue('Ananas') expect(() => diff --git a/src/to-have-display-value.js b/src/to-have-display-value.js index 1dfae2e3..07314453 100644 --- a/src/to-have-display-value.js +++ b/src/to-have-display-value.js @@ -1,7 +1,5 @@ import {matcherHint} from 'jest-matcher-utils' -import {matches,checkHtmlElement, getMessage} from './utils' - - +import {matches, checkHtmlElement, getMessage} from './utils' export function toHaveDisplayValue(htmlElement, expectedValue) { checkHtmlElement(htmlElement, toHaveDisplayValue, this) @@ -26,8 +24,12 @@ export function toHaveDisplayValue(htmlElement, expectedValue) { .map(option => option.textContent) : [htmlElement.value] - const expectedValueArray = expectedValue instanceof Array ? expectedValue : [expectedValue] - const matchess = expectedValueArray.filter(expected => value.filter(valueFilter => matches(valueFilter, expected)).length).length + const expectedValueArray = + expectedValue instanceof Array ? expectedValue : [expectedValue] + const matchess = expectedValueArray.filter( + expected => + value.filter(valueFilter => matches(valueFilter, expected)).length, + ).length return { pass: matchess === value.length && matchess === expectedValueArray.length, From b713864deaf6b1254ef546c594ca34ff691c541b Mon Sep 17 00:00:00 2001 From: Leandro Lourenci Date: Wed, 6 May 2020 17:45:18 -0300 Subject: [PATCH 4/9] Do some refactor --- src/to-have-display-value.js | 45 ++++++++++++++++++++++++------------ 1 file changed, 30 insertions(+), 15 deletions(-) diff --git a/src/to-have-display-value.js b/src/to-have-display-value.js index 07314453..8de80d25 100644 --- a/src/to-have-display-value.js +++ b/src/to-have-display-value.js @@ -17,22 +17,19 @@ export function toHaveDisplayValue(htmlElement, expectedValue) { ) } - const value = - tagName === 'select' - ? Array.from(htmlElement) - .filter(option => option.selected) - .map(option => option.textContent) - : [htmlElement.value] - - const expectedValueArray = - expectedValue instanceof Array ? expectedValue : [expectedValue] - const matchess = expectedValueArray.filter( - expected => - value.filter(valueFilter => matches(valueFilter, expected)).length, - ).length + const values = getValues(tagName, htmlElement) + const expectedValues = getExpectedValues(expectedValue) + const qtyOfMatchesWithValues = getQtyOfMatchesBetweenArrays( + values, + expectedValues, + ) + + const matchedWithAllValues = qtyOfMatchesWithValues === values.length + const matchedWithAllExpectedValues = + qtyOfMatchesWithValues === expectedValues.length return { - pass: matchess === value.length && matchess === expectedValueArray.length, + pass: matchedWithAllValues && matchedWithAllExpectedValues, message: () => getMessage( matcherHint( @@ -43,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 getQtyOfMatchesBetweenArrays(arrayBase, array) { + return array.filter( + expected => arrayBase.filter(value => matches(value, expected)).length, + ).length +} From cc3ebdc18c3410f5d8b253ae6e5a3767b1a694d5 Mon Sep 17 00:00:00 2001 From: Leandro Lourenci Date: Wed, 6 May 2020 20:11:12 -0300 Subject: [PATCH 5/9] Split specs in contexts --- src/__tests__/to-have-display-value.js | 85 +++++++++++++++++--------- 1 file changed, 56 insertions(+), 29 deletions(-) diff --git a/src/__tests__/to-have-display-value.js b/src/__tests__/to-have-display-value.js index f1ca3857..6e26199f 100644 --- a/src/__tests__/to-have-display-value.js +++ b/src/__tests__/to-have-display-value.js @@ -24,41 +24,68 @@ test('it should work as expected', () => { expect(queryByTestId('select')).toHaveDisplayValue(/[bB]ana/) }) -test('it should work with select multiple', () => { - const {queryByTestId} = render(` - - `) +describe('with multiple select', () => { + let subject - expect(queryByTestId('select')).toHaveDisplayValue(['Ananas', 'Avocado']) - expect(queryByTestId('select')).toHaveDisplayValue(['Avocado', 'Ananas']) - expect(queryByTestId('select')).toHaveDisplayValue([/[Aa]nanas/, 'Avocado']) - expect(() => - expect(queryByTestId('select')).not.toHaveDisplayValue([ + afterEach(() => { + subject = undefined + }) + + beforeEach(() => { + subject = render(` + + `) + }) + + it('matches only when all the multiple selected values are equal to all the expected values', () => { + expect(subject.queryByTestId('select')).toHaveDisplayValue([ 'Ananas', 'Avocado', - ]), - ).toThrow() - expect(queryByTestId('select')).not.toHaveDisplayValue([ - 'Ananas', - 'Avocado', - 'Orange', - ]) - - 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', () => { + expect(subject.queryByTestId('select')).toHaveDisplayValue([ + 'Avocado', + 'Ananas', + ]) }) - expect(queryByTestId('select')).toHaveDisplayValue(['Ananas', 'Banana']) + it('matches with regex expected values', () => { + expect(subject.queryByTestId('select')).toHaveDisplayValue([ + /[Aa]nanas/, + 'Avocado', + ]) + }) }) test('it should work with input elements', () => { From 259552b114ed3d4a9807ec9a9bf0b76c47202653 Mon Sep 17 00:00:00 2001 From: Leandro Lourenci Date: Wed, 6 May 2020 20:17:46 -0300 Subject: [PATCH 6/9] Add to README.md --- README.md | 12 +++++++++--- src/__tests__/to-have-display-value.js | 2 ++ 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 4e2361ee..60fdba52 100644 --- a/README.md +++ b/README.md @@ -86,9 +86,11 @@ should be installed as one of your project's `devDependencies`: ``` npm install --save-dev @testing-library/jest-dom ``` -or + +or for installation with [yarn](https://yarnpkg.com/) package manager. + ``` yarn add --dev @testing-library/jest-dom ``` @@ -778,7 +780,7 @@ expect(selectInput).not.toHaveValue(['second', 'third']) ### `toHaveDisplayValue` ```typescript -toHaveDisplayValue(value: string | string[]) +toHaveDisplayValue(value: string | (string|RegExp)[]) ``` This allows you to check whether the given form element has the specified @@ -823,9 +825,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(['Banana', /Avocado/]) ```
@@ -1026,6 +1031,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 6e26199f..c87e2384 100644 --- a/src/__tests__/to-have-display-value.js +++ b/src/__tests__/to-have-display-value.js @@ -94,6 +94,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') @@ -107,6 +108,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( From d014eecb49f3a0153277d77b78618dfd9351f71f Mon Sep 17 00:00:00 2001 From: Leandro Lourenci Date: Wed, 6 May 2020 20:20:30 -0300 Subject: [PATCH 7/9] Add to README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 60fdba52..062745c9 100644 --- a/README.md +++ b/README.md @@ -780,7 +780,7 @@ expect(selectInput).not.toHaveValue(['second', 'third']) ### `toHaveDisplayValue` ```typescript -toHaveDisplayValue(value: string | (string|RegExp)[]) +toHaveDisplayValue(value: string | RegExp | (string|RegExp)[]) ``` This allows you to check whether the given form element has the specified From ca2c16d43ad2a60ef5baabd79501c2a02eaba6c8 Mon Sep 17 00:00:00 2001 From: Leandro Lourenci Date: Wed, 6 May 2020 20:32:43 -0300 Subject: [PATCH 8/9] Update docs to describe the unordered multiple match --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 062745c9..19fc0be4 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) @@ -830,7 +831,7 @@ expect(textarea).toHaveDisplayValue('An example description here.') expect(textarea).toHaveDisplayValue(/example/) expect(selectSingle).toHaveDisplayValue('Select a fruit...') expect(selectSingle).toHaveDisplayValue(/Select/) -expect(selectMultiple).toHaveDisplayValue(['Banana', /Avocado/]) +expect(selectMultiple).toHaveDisplayValue([/Avocado/, 'Banana']) ```
From 1e638548ea52f83d3d6e5147c0598e0264acb5f3 Mon Sep 17 00:00:00 2001 From: Leandro Lourenci Date: Thu, 7 May 2020 17:41:05 -0300 Subject: [PATCH 9/9] Add review --- src/__tests__/to-have-display-value.js | 15 ++++++--------- src/to-have-display-value.js | 8 ++++---- 2 files changed, 10 insertions(+), 13 deletions(-) diff --git a/src/__tests__/to-have-display-value.js b/src/__tests__/to-have-display-value.js index c87e2384..8cae8734 100644 --- a/src/__tests__/to-have-display-value.js +++ b/src/__tests__/to-have-display-value.js @@ -25,14 +25,8 @@ test('it should work as expected', () => { }) describe('with multiple select', () => { - let subject - - afterEach(() => { - subject = undefined - }) - - beforeEach(() => { - subject = render(` + function mount() { + return render(` `) - }) + } 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', @@ -74,6 +69,7 @@ describe('with multiple select', () => { }) it('matches even when the expected values are unordered', () => { + const subject = mount() expect(subject.queryByTestId('select')).toHaveDisplayValue([ 'Avocado', 'Ananas', @@ -81,6 +77,7 @@ describe('with multiple select', () => { }) it('matches with regex expected values', () => { + const subject = mount() expect(subject.queryByTestId('select')).toHaveDisplayValue([ /[Aa]nanas/, 'Avocado', diff --git a/src/to-have-display-value.js b/src/to-have-display-value.js index 8de80d25..11d35c5c 100644 --- a/src/to-have-display-value.js +++ b/src/to-have-display-value.js @@ -19,14 +19,14 @@ export function toHaveDisplayValue(htmlElement, expectedValue) { const values = getValues(tagName, htmlElement) const expectedValues = getExpectedValues(expectedValue) - const qtyOfMatchesWithValues = getQtyOfMatchesBetweenArrays( + const numberOfMatchesWithValues = getNumberOfMatchesBetweenArrays( values, expectedValues, ) - const matchedWithAllValues = qtyOfMatchesWithValues === values.length + const matchedWithAllValues = numberOfMatchesWithValues === values.length const matchedWithAllExpectedValues = - qtyOfMatchesWithValues === expectedValues.length + numberOfMatchesWithValues === expectedValues.length return { pass: matchedWithAllValues && matchedWithAllExpectedValues, @@ -57,7 +57,7 @@ function getExpectedValues(expectedValue) { return expectedValue instanceof Array ? expectedValue : [expectedValue] } -function getQtyOfMatchesBetweenArrays(arrayBase, array) { +function getNumberOfMatchesBetweenArrays(arrayBase, array) { return array.filter( expected => arrayBase.filter(value => matches(value, expected)).length, ).length