Skip to content

Commit

Permalink
Components: Refactor Icon tests to @testing-library/react (#44051)
Browse files Browse the repository at this point in the history
* Components: Refactor `Icon` tests to `@testing-library/react`

* Delete test for `props`

* Update chagelog

* Matcher and query more streamlined

* Revert unnecessary update
  • Loading branch information
t-hamano authored Sep 12, 2022
1 parent 64b1f90 commit 9ccd2d3
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 83 deletions.
3 changes: 2 additions & 1 deletion packages/components/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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/)).
Expand All @@ -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/)).
Expand Down
113 changes: 31 additions & 82 deletions packages/components/src/icon/test/index.js
Original file line number Diff line number Diff line change
@@ -1,71 +1,67 @@
/**
* External dependencies
*/
import { shallow } from 'enzyme';

/**
* WordPress dependencies
*/
import { Component } from '@wordpress/element';
import { render, screen } from '@testing-library/react';

/**
* Internal dependencies
*/
import Dashicon from '../../dashicon';
import Icon from '../';
import { Path, SVG } from '../../';

describe( 'Icon', () => {
const testId = 'icon';
const className = 'example-class';
const svg = (
<SVG>
<Path d="M5 4v3h5.5v12h3V7H19V4z" />
</SVG>
);
const style = { fill: 'red' };

it( 'renders nothing when icon omitted', () => {
const wrapper = shallow( <Icon /> );
render( <Icon data-testid={ testId } /> );

expect( wrapper.type() ).toBeNull();
expect( screen.queryByTestId( testId ) ).not.toBeInTheDocument();
} );

it( 'renders a dashicon by slug', () => {
const wrapper = shallow( <Icon icon="format-image" /> );
render( <Icon data-testid={ testId } icon="format-image" /> );

expect( wrapper.find( 'Dashicon' ).prop( 'icon' ) ).toBe(
'format-image'
expect( screen.getByTestId( testId ) ).toHaveClass(
'dashicons-format-image'
);
} );

it( 'renders a function', () => {
const wrapper = shallow( <Icon icon={ () => <span /> } /> );
render( <Icon icon={ () => <span data-testid={ testId } /> } /> );

expect( wrapper.name() ).toBe( 'span' );
expect( screen.getByTestId( testId ) ).toBeVisible();
} );

it( 'renders an element', () => {
const wrapper = shallow( <Icon icon={ <span /> } /> );
render( <Icon icon={ <span data-testid={ testId } /> } /> );

expect( wrapper.name() ).toBe( 'span' );
expect( screen.getByTestId( testId ) ).toBeVisible();
} );

it( 'renders an svg element', () => {
const wrapper = shallow( <Icon icon={ svg } /> );
render( <Icon data-testid={ testId } icon={ svg } /> );

expect( wrapper.name() ).toBe( 'SVG' );
expect( screen.getByTestId( testId ) ).toBeVisible();
} );

it( 'renders an svg element with a default width and height of 24', () => {
const wrapper = shallow( <Icon icon={ svg } /> );
render( <Icon data-testid={ testId } icon={ svg } /> );
const icon = screen.getByTestId( 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(
<Icon
data-testid={ testId }
icon={
<SVG width={ 64 } height={ 64 }>
<Path d="M5 4v3h5.5v12h3V7H19V4z" />
Expand All @@ -74,73 +70,26 @@ describe( 'Icon', () => {
size={ 32 }
/>
);
const icon = screen.getByTestId( 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( <Icon icon={ svg } size={ 32 } /> );
render( <Icon data-testid={ testId } icon={ svg } size={ 32 } /> );
const icon = screen.getByTestId( 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 <span />;
}
}
const wrapper = shallow( <Icon icon={ MyComponent } /> );

expect( wrapper.name() ).toBe( 'MyComponent' );
} );

describe( 'props passing', () => {
class MyComponent extends Component {
render() {
return <span className={ this.props.className } />;
}
}

describe.each( [
[ 'dashicon', { icon: 'format-image' } ],
[ 'dashicon element', { icon: <Dashicon icon="format-image" /> } ],
[ 'element', { icon: <span /> } ],
[ 'svg element', { icon: svg } ],
[ 'component', { icon: MyComponent } ],
] )( '%s', ( label, props ) => {
it( '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( <Icon { ...props } size={ 32 } /> );

expect( wrapper.prop( 'size' ) ).toBe( 32 );
} );

it( 'should pass through all other props', () => {
const wrapper = shallow(
<Icon
{ ...props }
style={ style }
className={ className }
/>
);
const MyComponent = () => (
<span data-testid={ testId } className={ className } />
);
render( <Icon icon={ MyComponent } /> );

expect( wrapper.prop( 'style' ) ).toBe( style );
expect( wrapper.prop( 'className' ) ).toBe( className );
} );
} );
expect( screen.getByTestId( testId ) ).toHaveClass( className );
} );
} );

0 comments on commit 9ccd2d3

Please sign in to comment.