Skip to content

Commit

Permalink
Add unit test
Browse files Browse the repository at this point in the history
  • Loading branch information
ciampo committed Jan 10, 2024
1 parent d4c34dc commit 3c6a860
Showing 1 changed file with 124 additions and 17 deletions.
141 changes: 124 additions & 17 deletions packages/components/src/color-picker/test/index.tsx
@@ -1,9 +1,14 @@
/**
* External dependencies
*/
import { screen, render } from '@testing-library/react';
import { fireEvent, screen, render, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';

/**
* WordPress dependencies
*/
import { useState } from '@wordpress/element';

/**
* Internal dependencies
*/
Expand Down Expand Up @@ -133,20 +138,34 @@ describe( 'ColorPicker', () => {
} );
} );

describe.each( [
[ 'hue', 'Hue', '#aad52a' ],
[ 'saturation', 'Saturation', '#20dfdf' ],
[ 'lightness', 'Lightness', '#95eaea' ],
] )( 'HSL inputs', ( colorInput, inputLabel, expected ) => {
it( `should fire onChange with the correct value when the ${ colorInput } value is updated`, async () => {
describe( 'HSL inputs', () => {
it( 'sliders', async () => {
const user = userEvent.setup();
const onChange = jest.fn();
const color = '#2ad5d5';

const ControlledColorPicker = ( {
onChange: onChangeProp,
...restProps
}: React.ComponentProps< typeof ColorPicker > ) => {
const [ colorState, setColorState ] = useState( '#000000' );

const internalOnChange: typeof onChangeProp = ( newColor ) => {
onChangeProp?.( newColor );
setColorState( newColor );
};

return (
<ColorPicker
{ ...restProps }
onChange={ internalOnChange }
color={ colorState }
/>
);
};

render(
<ColorPicker
<ControlledColorPicker
onChange={ onChange }
color={ color }
enableAlpha={ false }
/>
);
Expand All @@ -156,16 +175,104 @@ describe( 'ColorPicker', () => {

await user.selectOptions( formatSelector, 'hsl' );

const inputElement = screen.getByRole( 'spinbutton', {
name: inputLabel,
const hueSliders = screen.getAllByRole( 'slider', {
name: 'Hue',
} );
expect( inputElement ).toBeVisible();
expect( hueSliders ).toHaveLength( 2 );

await user.clear( inputElement );
await user.type( inputElement, '75' );
// Reason for the `!` post-fix expression operator: if the check above
// doesn't fail, we're guaranteed that `hueSlider` is not undefined.
const hueSlider = hueSliders.at( -1 )!;
const saturationSlider = screen.getByRole( 'slider', {
name: 'Saturation',
} );
const lightnessSlider = screen.getByRole( 'slider', {
name: 'Lightness',
} );
const hueNumberInput = screen.getByRole( 'spinbutton', {
name: 'Hue',
} );
const saturationNumberInput = screen.getByRole( 'spinbutton', {
name: 'Saturation',
} );
const lightnessNumberInput = screen.getByRole( 'spinbutton', {
name: 'Lightness',
} );

expect( onChange ).toHaveBeenCalledTimes( 3 );
expect( onChange ).toHaveBeenLastCalledWith( expected );
// All initial inputs should have a value of `0` since the color is black.
expect( hueSlider ).toHaveValue( '0' );
expect( saturationSlider ).toHaveValue( '0' );
expect( lightnessSlider ).toHaveValue( '0' );
expect( hueNumberInput ).toHaveValue( 0 );
expect( saturationNumberInput ).toHaveValue( 0 );
expect( lightnessNumberInput ).toHaveValue( 0 );

// Interact with the Hue slider, it should change its value (and the
// value of the associated number input), but it shouldn't cause the
// `onChange` callback to fire, since the resulting color is still black.
fireEvent.change( hueSlider, { target: { value: 80 } } );

expect( hueSlider ).toHaveValue( '80' );
expect( hueNumberInput ).toHaveValue( 80 );
expect( onChange ).not.toHaveBeenCalled();

// Interact with the Saturation slider, it should change its value (and the
// value of the associated number input), but it shouldn't cause the
// `onChange` callback to fire, since the resulting color is still black.
fireEvent.change( saturationSlider, { target: { value: 50 } } );

expect( saturationSlider ).toHaveValue( '50' );
expect( saturationNumberInput ).toHaveValue( 50 );
expect( onChange ).not.toHaveBeenCalled();

// Interact with the Lightness slider, it should change its value (and the
// value of the associated number input). It should also cause the
// `onChange` callback to fire, since changing the lightness actually
// causes the color to change.
fireEvent.change( lightnessSlider, { target: { value: 30 } } );

await waitFor( () =>
expect( lightnessSlider ).toHaveValue( '30' )
);
expect( lightnessNumberInput ).toHaveValue( 30 );
expect( onChange ).toHaveBeenCalledTimes( 1 );
expect( onChange ).toHaveBeenLastCalledWith( '#597326' );
} );

describe.each( [
[ 'hue', 'Hue', '#aad52a' ],
[ 'saturation', 'Saturation', '#20dfdf' ],
[ 'lightness', 'Lightness', '#95eaea' ],
] )( 'HSL inputs', ( colorInput, inputLabel, expected ) => {
it( `should fire onChange with the correct value when the ${ colorInput } value is updated`, async () => {
const user = userEvent.setup();
const onChange = jest.fn();
const color = '#2ad5d5';

render(
<ColorPicker
onChange={ onChange }
color={ color }
enableAlpha={ false }
/>
);

const formatSelector = screen.getByRole( 'combobox' );
expect( formatSelector ).toBeVisible();

await user.selectOptions( formatSelector, 'hsl' );

const inputElement = screen.getByRole( 'spinbutton', {
name: inputLabel,
} );
expect( inputElement ).toBeVisible();

await user.clear( inputElement );
await user.type( inputElement, '75' );

expect( onChange ).toHaveBeenCalledTimes( 3 );
expect( onChange ).toHaveBeenLastCalledWith( expected );
} );
} );
} );
} );

0 comments on commit 3c6a860

Please sign in to comment.