From fa8a10753eb1a8e9271c3f6ba5abcc33e166f86e Mon Sep 17 00:00:00 2001 From: Tetsuaki Hamano Date: Sat, 10 Sep 2022 21:49:02 +0900 Subject: [PATCH 1/5] Components: Refactor `Icon` tests to `@testing-library/react` --- packages/components/src/icon/test/index.js | 82 +++++++++++----------- 1 file changed, 40 insertions(+), 42 deletions(-) diff --git a/packages/components/src/icon/test/index.js b/packages/components/src/icon/test/index.js index d1c5b7123c3d8..15ae81fccff70 100644 --- a/packages/components/src/icon/test/index.js +++ b/packages/components/src/icon/test/index.js @@ -2,11 +2,7 @@ * External dependencies */ import { shallow } from 'enzyme'; - -/** - * WordPress dependencies - */ -import { Component } from '@wordpress/element'; +import { render, screen } from '@testing-library/react'; /** * Internal dependencies @@ -16,6 +12,7 @@ import Icon from '../'; import { Path, SVG } from '../../'; describe( 'Icon', () => { + const testId = 'icon'; const className = 'example-class'; const svg = ( @@ -25,47 +22,49 @@ describe( 'Icon', () => { const style = { fill: 'red' }; it( 'renders nothing when icon omitted', () => { - const wrapper = shallow( ); + render( ); - expect( wrapper.type() ).toBeNull(); + expect( screen.queryByTestId( testId ) ).not.toBeInTheDocument(); } ); it( 'renders a dashicon by slug', () => { - const wrapper = shallow( ); + render( ); - expect( wrapper.find( 'Dashicon' ).prop( 'icon' ) ).toBe( - 'format-image' + expect( screen.getByTestId( testId ) ).toHaveClass( + 'dashicons-format-image' ); } ); it( 'renders a function', () => { - const wrapper = shallow( } /> ); + render( } /> ); - expect( wrapper.name() ).toBe( 'span' ); + expect( screen.getByTestId( testId ) ).toBeInTheDocument(); } ); it( 'renders an element', () => { - const wrapper = shallow( } /> ); + render( } /> ); - expect( wrapper.name() ).toBe( 'span' ); + expect( screen.getByTestId( testId ) ).toBeInTheDocument(); } ); it( 'renders an svg element', () => { - const wrapper = shallow( ); + render( ); - expect( wrapper.name() ).toBe( 'SVG' ); + expect( screen.getByTestId( testId ) ).toBeInTheDocument(); } ); it( 'renders an svg element with a default width and height of 24', () => { - const wrapper = shallow( ); + render( ); + const icon = screen.queryByTestId( testId ); - expect( wrapper.prop( 'width' ) ).toBe( 24 ); - expect( wrapper.prop( 'height' ) ).toBe( 24 ); + expect( icon ).toHaveAttribute( 'width', '24' ); + expect( icon ).toHaveAttribute( 'height', '24' ); } ); it( 'renders an svg element and override its width and height', () => { - const wrapper = shallow( + render( @@ -74,35 +73,33 @@ describe( 'Icon', () => { size={ 32 } /> ); + const icon = screen.queryByTestId( testId ); - expect( wrapper.prop( 'width' ) ).toBe( 32 ); - expect( wrapper.prop( 'height' ) ).toBe( 32 ); + expect( icon ).toHaveAttribute( 'width', '32' ); + expect( icon ).toHaveAttribute( 'height', '32' ); } ); it( 'renders an svg element and does not override width and height if already specified', () => { - const wrapper = shallow( ); + render( ); + const icon = screen.queryByTestId( testId ); - expect( wrapper.prop( 'width' ) ).toBe( 32 ); - expect( wrapper.prop( 'height' ) ).toBe( 32 ); + expect( icon ).toHaveAttribute( 'width', '32' ); + expect( icon ).toHaveAttribute( 'height', '32' ); } ); it( 'renders a component', () => { - class MyComponent extends Component { - render() { - return ; - } - } - const wrapper = shallow( ); - - expect( wrapper.name() ).toBe( 'MyComponent' ); + const MyComponent = () => ( + + ); + render( ); + + expect( screen.getByTestId( testId ) ).toHaveClass( className ); } ); describe( 'props passing', () => { - class MyComponent extends Component { - render() { - return ; - } - } + const MyComponent = ( props ) => ( + + ); describe.each( [ [ 'dashicon', { icon: 'format-image' } ], @@ -111,7 +108,7 @@ describe( 'Icon', () => { [ 'svg element', { icon: svg } ], [ 'component', { icon: MyComponent } ], ] )( '%s', ( label, props ) => { - it( 'should pass through size', () => { + it.skip( 'should pass through size', () => { if ( label === 'svg element' ) { // Custom logic for SVG elements tested separately. // @@ -130,16 +127,17 @@ describe( 'Icon', () => { } ); it( 'should pass through all other props', () => { - const wrapper = shallow( + const { container } = render( ); + const icon = container.firstChild; - expect( wrapper.prop( 'style' ) ).toBe( style ); - expect( wrapper.prop( 'className' ) ).toBe( className ); + expect( icon ).toHaveStyle( style ); + expect( icon ).toHaveClass( className ); } ); } ); } ); From f2b162f66a6b06846551113fe46e98e4eb7dae65 Mon Sep 17 00:00:00 2001 From: Tetsuaki Hamano Date: Mon, 12 Sep 2022 20:30:44 +0900 Subject: [PATCH 2/5] Delete test for `props` --- packages/components/src/icon/test/index.js | 49 ---------------------- 1 file changed, 49 deletions(-) diff --git a/packages/components/src/icon/test/index.js b/packages/components/src/icon/test/index.js index 15ae81fccff70..eb3822cf208fd 100644 --- a/packages/components/src/icon/test/index.js +++ b/packages/components/src/icon/test/index.js @@ -1,13 +1,11 @@ /** * External dependencies */ -import { shallow } from 'enzyme'; import { render, screen } from '@testing-library/react'; /** * Internal dependencies */ -import Dashicon from '../../dashicon'; import Icon from '../'; import { Path, SVG } from '../../'; @@ -19,7 +17,6 @@ describe( 'Icon', () => { ); - const style = { fill: 'red' }; it( 'renders nothing when icon omitted', () => { render( ); @@ -95,50 +92,4 @@ describe( 'Icon', () => { expect( screen.getByTestId( testId ) ).toHaveClass( className ); } ); - - describe( 'props passing', () => { - const MyComponent = ( props ) => ( - - ); - - describe.each( [ - [ 'dashicon', { icon: 'format-image' } ], - [ 'dashicon element', { icon: } ], - [ 'element', { icon: } ], - [ 'svg element', { icon: svg } ], - [ 'component', { icon: MyComponent } ], - ] )( '%s', ( label, props ) => { - it.skip( 'should pass through size', () => { - if ( label === 'svg element' ) { - // Custom logic for SVG elements tested separately. - // - // See: `renders an svg element and passes the size as its width and height` - return; - } - - if ( [ 'dashicon', 'dashicon element' ].includes( label ) ) { - // `size` prop isn't passed through, since dashicon doesn't accept it. - return; - } - - const wrapper = shallow( ); - - expect( wrapper.prop( 'size' ) ).toBe( 32 ); - } ); - - it( 'should pass through all other props', () => { - const { container } = render( - - ); - const icon = container.firstChild; - - expect( icon ).toHaveStyle( style ); - expect( icon ).toHaveClass( className ); - } ); - } ); - } ); } ); From 5f77e011f712616139ce084e76ca150d3482dd4c Mon Sep 17 00:00:00 2001 From: Tetsuaki Hamano Date: Mon, 12 Sep 2022 20:32:37 +0900 Subject: [PATCH 3/5] Update chagelog --- packages/components/CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/components/CHANGELOG.md b/packages/components/CHANGELOG.md index 19cc64a73aaa9..6535215e2f77a 100644 --- a/packages/components/CHANGELOG.md +++ b/packages/components/CHANGELOG.md @@ -29,6 +29,7 @@ ### Internal +- `Icon`: Refactor tests to `@testing-library/react` ([#44051](https://github.com/WordPress/gutenberg/pull/44051)). - Fix TypeScript types for `isValueDefined()` and `isValueEmpty()` utility functions ([#43983](https://github.com/WordPress/gutenberg/pull/43983)). - `RadioControl`: Clean up styles to use less custom CSS ([#43868](https://github.com/WordPress/gutenberg/pull/43868)). - Remove unused `normalizeArrowKey` utility function ([#43640](https://github.com/WordPress/gutenberg/pull/43640/)). @@ -38,7 +39,7 @@ - Refactor `FocalPointPicker` to function component ([#39168](https://github.com/WordPress/gutenberg/pull/39168)). - `Guide`: use `code` instead of `keyCode` for keyboard events ([#43604](https://github.com/WordPress/gutenberg/pull/43604/)). - `ToggleControl`: Convert to TypeScript and streamline CSS ([#43717](https://github.com/WordPress/gutenberg/pull/43717)). -- `FocalPointPicker`: Convert to TypeScript ([#43872](https://github.com/WordPress/gutenberg/pull/43872)). +- `FocalPointPicker`: Convert to TypeScript ([#43872](https://github.com/WordPress/gutenberg/pull/43872)). - `Navigation`: use `code` instead of `keyCode` for keyboard events ([#43644](https://github.com/WordPress/gutenberg/pull/43644/)). - `ComboboxControl`: Add unit tests ([#42403](https://github.com/WordPress/gutenberg/pull/42403)). - `NavigableContainer`: use `code` instead of `keyCode` for keyboard events, rewrite tests using RTL and `user-event` ([#43606](https://github.com/WordPress/gutenberg/pull/43606/)). From 385c25a2a535ec8c9de8f5dd9252e3253bb6c852 Mon Sep 17 00:00:00 2001 From: Tetsuaki Hamano Date: Mon, 12 Sep 2022 22:34:48 +0900 Subject: [PATCH 4/5] Matcher and query more streamlined --- packages/components/src/icon/test/index.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/components/src/icon/test/index.js b/packages/components/src/icon/test/index.js index eb3822cf208fd..9efc7d66192d4 100644 --- a/packages/components/src/icon/test/index.js +++ b/packages/components/src/icon/test/index.js @@ -21,7 +21,7 @@ describe( 'Icon', () => { it( 'renders nothing when icon omitted', () => { render( ); - expect( screen.queryByTestId( testId ) ).not.toBeInTheDocument(); + expect( screen.queryByTestId( testId ) ).toBeNull(); } ); it( 'renders a dashicon by slug', () => { @@ -35,24 +35,24 @@ describe( 'Icon', () => { it( 'renders a function', () => { render( } /> ); - expect( screen.getByTestId( testId ) ).toBeInTheDocument(); + expect( screen.getByTestId( testId ) ).toBeVisible(); } ); it( 'renders an element', () => { render( } /> ); - expect( screen.getByTestId( testId ) ).toBeInTheDocument(); + expect( screen.getByTestId( testId ) ).toBeVisible(); } ); it( 'renders an svg element', () => { render( ); - expect( screen.getByTestId( testId ) ).toBeInTheDocument(); + expect( screen.getByTestId( testId ) ).toBeVisible(); } ); it( 'renders an svg element with a default width and height of 24', () => { render( ); - const icon = screen.queryByTestId( testId ); + const icon = screen.getByTestId( testId ); expect( icon ).toHaveAttribute( 'width', '24' ); expect( icon ).toHaveAttribute( 'height', '24' ); @@ -70,7 +70,7 @@ describe( 'Icon', () => { size={ 32 } /> ); - const icon = screen.queryByTestId( testId ); + const icon = screen.getByTestId( testId ); expect( icon ).toHaveAttribute( 'width', '32' ); expect( icon ).toHaveAttribute( 'height', '32' ); @@ -78,7 +78,7 @@ describe( 'Icon', () => { it( 'renders an svg element and does not override width and height if already specified', () => { render( ); - const icon = screen.queryByTestId( testId ); + const icon = screen.getByTestId( testId ); expect( icon ).toHaveAttribute( 'width', '32' ); expect( icon ).toHaveAttribute( 'height', '32' ); From 9d473432434bb7d2da538f62a9277f4246630e62 Mon Sep 17 00:00:00 2001 From: Tetsuaki Hamano Date: Mon, 12 Sep 2022 22:41:15 +0900 Subject: [PATCH 5/5] Revert unnecessary update --- packages/components/src/icon/test/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/components/src/icon/test/index.js b/packages/components/src/icon/test/index.js index 9efc7d66192d4..5fc897576db1c 100644 --- a/packages/components/src/icon/test/index.js +++ b/packages/components/src/icon/test/index.js @@ -21,7 +21,7 @@ describe( 'Icon', () => { it( 'renders nothing when icon omitted', () => { render( ); - expect( screen.queryByTestId( testId ) ).toBeNull(); + expect( screen.queryByTestId( testId ) ).not.toBeInTheDocument(); } ); it( 'renders a dashicon by slug', () => {