From d471426dbe8a85569492fb3934aacc02cc2ec6f0 Mon Sep 17 00:00:00 2001 From: Marco Ciampini Date: Wed, 9 Mar 2022 19:10:05 +0100 Subject: [PATCH 01/13] Include TypeScript tests in TSConfig --- packages/components/tsconfig.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/components/tsconfig.json b/packages/components/tsconfig.json index bb38249afa6248..d45b82d6e48b4e 100644 --- a/packages/components/tsconfig.json +++ b/packages/components/tsconfig.json @@ -87,7 +87,7 @@ "src/**/*.native.js", "src/**/react-native-*", "src/**/stories/**.js", // only exclude js files, tsx files should be checked - "src/**/test", + "src/**/test/**.js", // only exclude js files, ts{x} files should be checked "src/ui/__storybook-utils", "src/ui/font-size-control" ] From fd07e7be6480a8303e476cb926ff1681beb8de9d Mon Sep 17 00:00:00 2001 From: Marco Ciampini Date: Wed, 9 Mar 2022 23:16:31 +0100 Subject: [PATCH 02/13] Add `@jest/globals` to dev dependencies --- package-lock.json | 19 +++++++++++++++++++ packages/components/package.json | 3 +++ 2 files changed, 22 insertions(+) diff --git a/package-lock.json b/package-lock.json index 37ed00efb43bc8..5c3502b22dbfc2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -22926,6 +22926,25 @@ "find-up": "^4.0.0" } }, + "plist": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/plist/-/plist-3.0.2.tgz", + "integrity": "sha512-MSrkwZBdQ6YapHy87/8hDU8MnIcyxBKjeF+McXnr5A9MtffPewTs7G3hlpodT5TacyfIyFTaJEhh3GGcmasTgQ==", + "dev": true, + "requires": { + "base64-js": "^1.5.1", + "xmlbuilder": "^9.0.7", + "xmldom": "^0.5.0" + }, + "dependencies": { + "xmlbuilder": { + "version": "9.0.7", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz", + "integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0=", + "dev": true + } + } + }, "pluralize": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz", diff --git a/packages/components/package.json b/packages/components/package.json index 9cf758b5cd407a..d1cae38c0d5b31 100644 --- a/packages/components/package.json +++ b/packages/components/package.json @@ -69,6 +69,9 @@ "reakit": "^1.3.8", "uuid": "^8.3.0" }, + "devDependencies": { + "@jest/globals": "27.5.1" + }, "peerDependencies": { "react": "^17.0.0", "react-dom": "^17.0.0" From 3c8064ac70a61c22a145d08a998c66ea92891f56 Mon Sep 17 00:00:00 2001 From: Marco Ciampini Date: Wed, 9 Mar 2022 23:18:46 +0100 Subject: [PATCH 03/13] Rename `utils.js` to `utils.ts` --- packages/components/src/unit-control/test/{utils.js => utils.ts} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename packages/components/src/unit-control/test/{utils.js => utils.ts} (100%) diff --git a/packages/components/src/unit-control/test/utils.js b/packages/components/src/unit-control/test/utils.ts similarity index 100% rename from packages/components/src/unit-control/test/utils.js rename to packages/components/src/unit-control/test/utils.ts From afd07e3b03266268f93acc50c5986c4dbdc5b71e Mon Sep 17 00:00:00 2001 From: Marco Ciampini Date: Wed, 9 Mar 2022 23:19:59 +0100 Subject: [PATCH 04/13] Tweak `UnitControl` s utils --- packages/components/src/unit-control/utils.ts | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/packages/components/src/unit-control/utils.ts b/packages/components/src/unit-control/utils.ts index 87c0142ec9774c..d992db157f149a 100644 --- a/packages/components/src/unit-control/utils.ts +++ b/packages/components/src/unit-control/utils.ts @@ -155,7 +155,7 @@ export function getParsedQuantityAndUnit( * @param units List of units. * @return Whether the list actually contains any units. */ -export function hasUnits( units?: WPUnitControlUnit[] ): boolean { +export function hasUnits( units?: WPUnitControlUnit[] ) { // Although the `isArray` check shouldn't be necessary (given the signature of // this typed function), it's better to stay on the side of caution, since // this function may be called from un-typed environments. @@ -218,7 +218,7 @@ export function parseQuantityAndUnitFromRawValue( */ export function getValidParsedQuantityAndUnit( rawValue: string | number, - allowedUnits: WPUnitControlUnit[], + allowedUnits?: WPUnitControlUnit[], fallbackQuantity?: number, fallbackUnit?: string ): [ number | undefined, string | undefined ] { @@ -236,7 +236,9 @@ export function getValidParsedQuantityAndUnit( let unitToReturn = parsedUnit || fallbackUnit; if ( ! unitToReturn && hasUnits( allowedUnits ) ) { - unitToReturn = allowedUnits[ 0 ].value; + // The `hasUnit` check guarantees that `allowedUnits`, for the next line, + // is an array with at least one item. + unitToReturn = ( allowedUnits as WPUnitControlUnit[] )[ 0 ].value; } return [ quantityToReturn, unitToReturn ]; @@ -295,7 +297,7 @@ export const useCustomUnits = ( { }: { units?: WPUnitControlUnit[]; availableUnits?: string[]; - defaultValues: Record< string, number >; + defaultValues?: Record< string, number >; } ): WPUnitControlUnit[] => { const customUnitsToReturn = filterUnitsWithSettings( availableUnits, From 4e2696f2b854a20bde74de7a47d2c6a2389bc20a Mon Sep 17 00:00:00 2001 From: Marco Ciampini Date: Wed, 9 Mar 2022 23:20:41 +0100 Subject: [PATCH 05/13] Fix TypeScript errors in utils tests --- .../components/src/unit-control/test/utils.ts | 62 +++++++++++++------ 1 file changed, 43 insertions(+), 19 deletions(-) diff --git a/packages/components/src/unit-control/test/utils.ts b/packages/components/src/unit-control/test/utils.ts index b5fe385716dedf..7487f16f6cef50 100644 --- a/packages/components/src/unit-control/test/utils.ts +++ b/packages/components/src/unit-control/test/utils.ts @@ -1,3 +1,8 @@ +/** + * External dependencies + */ +import { describe, expect, it } from '@jest/globals'; + /** * Internal dependencies */ @@ -7,21 +12,28 @@ import { getValidParsedQuantityAndUnit, getUnitsWithCurrentUnit, } from '../utils'; +import type { WPUnitControlUnit } from '../types'; describe( 'UnitControl utils', () => { describe( 'useCustomUnits', () => { it( 'should return filtered css units', () => { - const cssUnits = [ { value: 'px' }, { value: '%' } ]; + const cssUnits = [ + { value: 'px', label: 'pixel' }, + { value: '%', label: 'percent' }, + ]; const units = useCustomUnits( { availableUnits: [ 'em', 'px' ], units: cssUnits, } ); - expect( units ).toEqual( [ { value: 'px' } ] ); + expect( units ).toEqual( [ { value: 'px', label: 'pixel' } ] ); } ); it( 'should add default values to available units', () => { - const cssUnits = [ { value: 'px' }, { value: '%' } ]; + const cssUnits = [ + { value: 'px', label: 'pixel' }, + { value: '%', label: 'percent' }, + ]; const units = useCustomUnits( { availableUnits: [ '%', 'px' ], defaultValues: { '%': 10, px: 10 }, @@ -29,8 +41,8 @@ describe( 'UnitControl utils', () => { } ); expect( units ).toEqual( [ - { value: 'px', default: 10 }, - { value: '%', default: 10 }, + { value: 'px', label: 'pixel', default: 10 }, + { value: '%', label: 'percent', default: 10 }, ] ); } ); @@ -38,24 +50,32 @@ describe( 'UnitControl utils', () => { // Although the public APIs of the component expect a `number` as the type of the // default values, it's still good to test for strings (as it can happen in un-typed // environments) - const cssUnits = [ { value: 'px' }, { value: '%' } ]; + const cssUnits = [ + { value: 'px', label: 'pixel' }, + { value: '%', label: 'percent' }, + ]; const units = useCustomUnits( { availableUnits: [ '%', 'px' ], defaultValues: { + // @ts-ignore (passing a string instead of a number is the point of the test) '%': '14', + // @ts-ignore (passing a string instead of a number is the point of the test) px: 'not a valid numeric quantity', }, units: cssUnits, } ); expect( units ).toEqual( [ - { value: 'px', default: undefined }, - { value: '%', default: 14 }, + { value: 'px', label: 'pixel', default: undefined }, + { value: '%', label: 'percent', default: 14 }, ] ); } ); it( 'should return an empty array where availableUnits match no preferred css units', () => { - const cssUnits = [ { value: 'em' }, { value: 'vh' } ]; + const cssUnits = [ + { value: 'em', label: 'em' }, + { value: 'vh', label: 'vh' }, + ]; const units = useCustomUnits( { availableUnits: [ '%', 'px' ], defaultValues: { '%': 10, px: 10 }, @@ -69,16 +89,19 @@ describe( 'UnitControl utils', () => { describe( 'filterUnitsWithSettings', () => { it( 'should return filtered units array', () => { const preferredUnits = [ '%', 'px' ]; - const availableUnits = [ { value: 'px' }, { value: 'em' } ]; + const availableUnits = [ + { value: 'px', label: 'pixel' }, + { value: 'em', label: 'em' }, + ]; expect( filterUnitsWithSettings( preferredUnits, availableUnits ) - ).toEqual( [ { value: 'px' } ] ); + ).toEqual( [ { value: 'px', label: 'pixel' } ] ); } ); it( 'should return empty array where preferred units match no available css unit', () => { const preferredUnits = [ '%', 'px' ]; - const availableUnits = [ { value: 'em' } ]; + const availableUnits = [ { value: 'em', label: 'em' } ]; expect( filterUnitsWithSettings( preferredUnits, availableUnits ) @@ -92,13 +115,14 @@ describe( 'UnitControl utils', () => { const availableUnits = false; expect( + // @ts-ignore (passing `false` instead of a valid array of units is the point of the test) filterUnitsWithSettings( preferredUnits, availableUnits ) ).toEqual( [] ); } ); it( 'should return empty array where available units is set to an empty array', () => { const preferredUnits = [ '%', 'px' ]; - const availableUnits = []; + const availableUnits: WPUnitControlUnit[] = []; expect( filterUnitsWithSettings( preferredUnits, availableUnits ) @@ -127,7 +151,7 @@ describe( 'UnitControl utils', () => { it( 'should return fallback value', () => { const nextValue = 'thirteen'; - const preferredUnits = [ { value: 'em' } ]; + const preferredUnits = [ { value: 'em', label: 'em' } ]; const fallbackValue = 13; expect( @@ -155,7 +179,7 @@ describe( 'UnitControl utils', () => { it( 'should return first unit in preferred units collection as second fallback unit', () => { const nextValue = 101; - const preferredUnits = [ { value: 'px' } ]; + const preferredUnits = [ { value: 'px', label: 'pixel' } ]; expect( getValidParsedQuantityAndUnit( nextValue, preferredUnits ) @@ -185,8 +209,8 @@ describe( 'UnitControl utils', () => { expect( result ).toHaveLength( 3 ); const currentUnit = result.shift(); - expect( currentUnit.value ).toBe( '%' ); - expect( currentUnit.label ).toBe( '%' ); + expect( currentUnit?.value ).toBe( '%' ); + expect( currentUnit?.label ).toBe( '%' ); expect( result ).toEqual( limitedUnits ); } ); @@ -196,8 +220,8 @@ describe( 'UnitControl utils', () => { expect( result ).toHaveLength( 3 ); const currentUnit = result.shift(); - expect( currentUnit.value ).toBe( '%' ); - expect( currentUnit.label ).toBe( '%' ); + expect( currentUnit?.value ).toBe( '%' ); + expect( currentUnit?.label ).toBe( '%' ); expect( result ).toEqual( limitedUnits ); } ); From b0a8cec8bb20ba33e20118758b5a95421b41194f Mon Sep 17 00:00:00 2001 From: Marco Ciampini Date: Wed, 9 Mar 2022 23:22:02 +0100 Subject: [PATCH 06/13] Rename `index.js` to `index.tsx` --- packages/components/src/unit-control/test/{index.js => index.tsx} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename packages/components/src/unit-control/test/{index.js => index.tsx} (100%) diff --git a/packages/components/src/unit-control/test/index.js b/packages/components/src/unit-control/test/index.tsx similarity index 100% rename from packages/components/src/unit-control/test/index.js rename to packages/components/src/unit-control/test/index.tsx From 6709b557ca7612b463d475dc2d8bd4c8a0cf96bc Mon Sep 17 00:00:00 2001 From: Marco Ciampini Date: Thu, 10 Mar 2022 01:12:59 +0100 Subject: [PATCH 07/13] Update `index.tsx` to fix most TypeScript errors --- packages/components/package.json | 3 +- .../test/__snapshots__/index.tsx.snap | 33 ++++ .../src/unit-control/test/index.tsx | 178 +++++++++++------- 3 files changed, 141 insertions(+), 73 deletions(-) create mode 100644 packages/components/src/unit-control/test/__snapshots__/index.tsx.snap diff --git a/packages/components/package.json b/packages/components/package.json index d1cae38c0d5b31..fd1534b3574a3b 100644 --- a/packages/components/package.json +++ b/packages/components/package.json @@ -70,7 +70,8 @@ "uuid": "^8.3.0" }, "devDependencies": { - "@jest/globals": "27.5.1" + "@jest/globals": "27.5.1", + "@testing-library/react": "11.2.2" }, "peerDependencies": { "react": "^17.0.0", diff --git a/packages/components/src/unit-control/test/__snapshots__/index.tsx.snap b/packages/components/src/unit-control/test/__snapshots__/index.tsx.snap new file mode 100644 index 00000000000000..8caf79556bd9b3 --- /dev/null +++ b/packages/components/src/unit-control/test/__snapshots__/index.tsx.snap @@ -0,0 +1,33 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`UnitControl Basic rendering should render custom className 1`] = ` +Snapshot Diff: +- First value ++ Second value + +@@ -1,10 +1,10 @@ +
+
+
+ - document.body.querySelector( '.components-unit-control' ); -const getInput = () => - document.body.querySelector( '.components-unit-control input' ); -const getSelect = () => - document.body.querySelector( '.components-unit-control select' ); -const getUnitLabel = () => - document.body.querySelector( '.components-unit-control__unit-label' ); - -const fireKeyDown = ( data ) => - fireEvent.keyDown( document.activeElement || document.body, data ); +// TODO: What determines spinbutton or textbox ? +const getInput = ( isNumeric: boolean = false ) => + screen.getByRole( + isNumeric ? 'spinbutton' : 'textbox' + ) as HTMLInputElement; +const getSelect = () => screen.getByRole( 'combobox' ) as HTMLSelectElement; +const getSelectOptions = () => + screen.getAllByRole( 'option' ) as HTMLOptionElement[]; const ControlledSyncUnits = () => { - const [ state, setState ] = useState( { valueA: '', valueB: '' } ); + const [ state, setState ] = useState( { + valueA: '', + valueB: '', + } ); // Keep the unit sync'd between the two `UnitControl` instances. - const onUnitControlChange = ( fieldName, newValue ) => { - // eslint-disable-next-line @wordpress/no-unused-vars-before-return - const [ quantity, newUnit ] = parseQuantityAndUnitFromRawValue( + const onUnitControlChange = ( + fieldName: 'valueA' | 'valueB', + newValue?: string | number + ) => { + const parsedQuantityAndUnit = parseQuantityAndUnitFromRawValue( newValue ); + const quantity = parsedQuantityAndUnit[ 0 ]; if ( ! Number.isFinite( quantity ) ) { return; } - const nextState = { ...state, [ fieldName ]: newValue }; + const newUnit = parsedQuantityAndUnit[ 1 ]; + + const nextState = { + ...state, + [ fieldName ]: newValue, + }; Object.entries( state ).forEach( ( [ stateProp, stateValue ] ) => { const [ @@ -50,7 +60,9 @@ const ControlledSyncUnits = () => { ] = parseQuantityAndUnitFromRawValue( stateValue ); if ( stateProp !== fieldName && stateUnit !== newUnit ) { - nextState[ stateProp ] = `${ stateQuantity }${ newUnit }`; + nextState[ + stateProp as 'valueA' | 'valueB' + ] = `${ stateQuantity }${ newUnit }`; } } ); @@ -77,38 +89,46 @@ describe( 'UnitControl', () => { describe( 'Basic rendering', () => { it( 'should render', () => { render( ); - const input = getInput(); + const input = getInput( true ); const select = getSelect(); - expect( input ).toBeTruthy(); - expect( select ).toBeTruthy(); + expect( input ).toBeInTheDocument(); + expect( select ).toBeInTheDocument(); } ); + // TODO: update TS matchers it( 'should render custom className', () => { - render( ); + const { container: noClassName } = render( ); - const el = getComponent(); + const { container: withClassName } = render( + + ); - expect( el.classList.contains( 'hello' ) ).toBe( true ); + expect( noClassName.firstChild ).toMatchDiffSnapshot( + withClassName.firstChild + ); } ); + // TODO: update TS matchers it( 'should not render select, if units are disabled', () => { render( ); - const input = getInput(); - const select = getSelect(); + const input = getInput( true ); + const select = screen.queryByRole( 'combobox' ); - expect( input ).toBeTruthy(); - expect( select ).toBeFalsy(); + expect( input ).toBeInTheDocument(); + expect( select ).not.toBeInTheDocument(); } ); - it( 'should render label if single units', () => { + // TODO: update TS matchers + // Check why it errors + it.skip( 'should render label if single units', () => { render( ); - const select = getSelect(); - const label = getUnitLabel(); + const select = screen.queryByRole( 'combobox' ); + const label = screen.getByText( '%' ); - expect( select ).toBeFalsy(); - expect( label ).toBeTruthy(); + expect( select ).not.toBeInTheDocument(); + expect( label ).toBeInTheDocument(); } ); } ); @@ -119,7 +139,7 @@ describe( 'UnitControl', () => { render( ); - const input = getInput(); + const input = getInput( true ); input.focus(); fireEvent.change( input, { target: { value: 62 } } ); @@ -128,56 +148,65 @@ describe( 'UnitControl', () => { } ); it( 'should increment value on UP press', () => { - let state = '50px'; - const setState = ( nextState ) => ( state = nextState ); + let state: string | undefined = '50px'; + const setState: UnitControlOnChangeCallback = ( nextState ) => + ( state = nextState ); render( ); - getInput().focus(); - fireKeyDown( { keyCode: UP } ); + const input = getInput( true ); + input.focus(); + fireEvent.keyDown( input, { keyCode: UP } ); expect( state ).toBe( '51px' ); } ); it( 'should increment value on UP + SHIFT press, with step', () => { - let state = '50px'; - const setState = ( nextState ) => ( state = nextState ); + let state: string | undefined = '50px'; + const setState: UnitControlOnChangeCallback = ( nextState ) => + ( state = nextState ); render( ); - getInput().focus(); - fireKeyDown( { keyCode: UP, shiftKey: true } ); + const input = getInput( true ); + input.focus(); + fireEvent.keyDown( input, { keyCode: UP, shiftKey: true } ); expect( state ).toBe( '60px' ); } ); it( 'should decrement value on DOWN press', () => { - let state = 50; - const setState = ( nextState ) => ( state = nextState ); + let state: string | number | undefined = 50; + const setState: UnitControlOnChangeCallback = ( nextState ) => + ( state = nextState ); render( ); - getInput().focus(); - fireKeyDown( { keyCode: DOWN } ); + const input = getInput( true ); + input.focus(); + fireEvent.keyDown( input, { keyCode: DOWN } ); expect( state ).toBe( '49px' ); } ); it( 'should decrement value on DOWN + SHIFT press, with step', () => { - let state = 50; - const setState = ( nextState ) => ( state = nextState ); + let state: string | number | undefined = 50; + const setState: UnitControlOnChangeCallback = ( nextState ) => + ( state = nextState ); render( ); - getInput().focus(); - fireKeyDown( { keyCode: DOWN, shiftKey: true } ); + const input = getInput( true ); + input.focus(); + fireEvent.keyDown( input, { keyCode: DOWN, shiftKey: true } ); expect( state ).toBe( '40px' ); } ); it( 'should cancel change when ESCAPE key is pressed', () => { - let state = 50; - const setState = ( nextState ) => ( state = nextState ); + let state: string | number | undefined = 50; + const setState: UnitControlOnChangeCallback = ( nextState ) => + ( state = nextState ); render( { /> ); - const input = getInput(); + const input = getInput() as HTMLInputElement; input.focus(); fireEvent.change( input, { target: { value: '300px' } } ); @@ -195,7 +224,7 @@ describe( 'UnitControl', () => { expect( input.value ).toBe( '300px' ); expect( state ).toBe( 50 ); - fireKeyDown( { keyCode: ESCAPE } ); + fireEvent.keyDown( input, { keyCode: ESCAPE } ); expect( input.value ).toBe( '50' ); expect( state ).toBe( 50 ); @@ -204,8 +233,9 @@ describe( 'UnitControl', () => { describe( 'Unit', () => { it( 'should update unit value on change', () => { - let state = 'px'; - const setState = ( nextState ) => ( state = nextState ); + let state: string | undefined = 'px'; + const setState: UnitControlOnChangeCallback = ( nextState ) => + ( state = nextState ); render( ); @@ -224,8 +254,7 @@ describe( 'UnitControl', () => { render( ); - const select = getSelect(); - const options = select.querySelectorAll( 'option' ); + const options = getSelectOptions(); expect( options.length ).toBe( 2 ); @@ -236,8 +265,9 @@ describe( 'UnitControl', () => { } ); it( 'should reset value on unit change, if unit has default value', () => { - let state = 50; - const setState = ( nextState ) => ( state = nextState ); + let state: string | number | undefined = 50; + const setState: UnitControlOnChangeCallback = ( nextState ) => + ( state = nextState ); const units = [ { value: 'pt', label: 'pt', default: 25 }, @@ -266,8 +296,9 @@ describe( 'UnitControl', () => { } ); it( 'should not reset value on unit change, if disabled', () => { - let state = 50; - const setState = ( nextState ) => ( state = nextState ); + let state: string | number | undefined = 50; + const setState: UnitControlOnChangeCallback = ( nextState ) => + ( state = nextState ); const units = [ { value: 'pt', label: 'pt', default: 25 }, @@ -296,8 +327,9 @@ describe( 'UnitControl', () => { } ); it( 'should set correct unit if single units', () => { - let state = '50%'; - const setState = ( value ) => ( state = value ); + let state: string | undefined = '50%'; + const setState: UnitControlOnChangeCallback = ( value ) => + ( state = value ); render( { /> ); - const input = getInput(); + const input = getInput( true ); input.focus(); fireEvent.change( input, { target: { value: 62 } } ); expect( state ).toBe( '62%' ); } ); + // TODO: update TS matchers it( 'should update unit value when a new raw value is passed', () => { render( ); @@ -357,7 +390,7 @@ describe( 'UnitControl', () => { const input = getInput(); input.focus(); fireEvent.change( input, { target: { value: '55 em' } } ); - fireKeyDown( { keyCode: ENTER } ); + fireEvent.keyDown( input, { keyCode: ENTER } ); expect( state ).toBe( '55em' ); } ); @@ -374,7 +407,7 @@ describe( 'UnitControl', () => { const input = getInput(); input.focus(); fireEvent.change( input, { target: { value: '61 PX' } } ); - fireKeyDown( { keyCode: ENTER } ); + fireEvent.keyDown( input, { keyCode: ENTER } ); expect( state ).toBe( '61px' ); } ); @@ -391,7 +424,7 @@ describe( 'UnitControl', () => { const input = getInput(); input.focus(); fireEvent.change( input, { target: { value: '55 em' } } ); - fireKeyDown( { keyCode: ENTER } ); + fireEvent.keyDown( input, { keyCode: ENTER } ); expect( state ).toBe( '55em' ); } ); @@ -408,7 +441,7 @@ describe( 'UnitControl', () => { const input = getInput(); input.focus(); fireEvent.change( input, { target: { value: '-10 %' } } ); - fireKeyDown( { keyCode: ENTER } ); + fireEvent.keyDown( input, { keyCode: ENTER } ); expect( state ).toBe( '-10%' ); } ); @@ -427,7 +460,7 @@ describe( 'UnitControl', () => { fireEvent.change( input, { target: { value: '123 rEm ' }, } ); - fireKeyDown( { keyCode: ENTER } ); + fireEvent.keyDown( input, { keyCode: ENTER } ); expect( state ).toBe( '123rem' ); } ); @@ -435,7 +468,7 @@ describe( 'UnitControl', () => { it( 'should update unit after initial render and with new unit prop', () => { const { rerender } = render( ); - const select = getSelect(); + const select = getSelect() as HTMLSelectElement; expect( select.value ).toBe( '%' ); @@ -447,7 +480,8 @@ describe( 'UnitControl', () => { it( 'should fallback to default unit if parsed unit is invalid', () => { render( ); - expect( getSelect().value ).toBe( 'px' ); + const select = getSelect() as HTMLSelectElement; + expect( select.value ).toBe( 'px' ); } ); it( 'should display valid CSS unit when not explicitly included in units list', () => { @@ -462,7 +496,7 @@ describe( 'UnitControl', () => { ); const select = getSelect(); - const options = select.querySelectorAll( 'option' ); + const options = getSelectOptions(); expect( select.value ).toBe( '%' ); expect( options.length ).toBe( 3 ); From 4c293281d47a9f2408019d0417cf5deecf84ceb7 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Fri, 11 Mar 2022 13:42:00 +0100 Subject: [PATCH 08/13] Fix type problems with jest, testing-library, snapshot-diff --- packages/components/src/unit-control/test/index.tsx | 1 - packages/components/src/unit-control/test/utils.ts | 5 ----- packages/components/tsconfig.json | 7 ++++++- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/packages/components/src/unit-control/test/index.tsx b/packages/components/src/unit-control/test/index.tsx index ce814d1039653b..31469412ae6a2e 100644 --- a/packages/components/src/unit-control/test/index.tsx +++ b/packages/components/src/unit-control/test/index.tsx @@ -1,7 +1,6 @@ /** * External dependencies */ -import { describe, expect, it } from '@jest/globals'; import { render, fireEvent, screen } from '@testing-library/react'; /** diff --git a/packages/components/src/unit-control/test/utils.ts b/packages/components/src/unit-control/test/utils.ts index 7487f16f6cef50..7a6645d1c02564 100644 --- a/packages/components/src/unit-control/test/utils.ts +++ b/packages/components/src/unit-control/test/utils.ts @@ -1,8 +1,3 @@ -/** - * External dependencies - */ -import { describe, expect, it } from '@jest/globals'; - /** * Internal dependencies */ diff --git a/packages/components/tsconfig.json b/packages/components/tsconfig.json index d45b82d6e48b4e..2e66472d220fa2 100644 --- a/packages/components/tsconfig.json +++ b/packages/components/tsconfig.json @@ -3,7 +3,12 @@ "compilerOptions": { "rootDir": "src", "declarationDir": "build-types", - "types": [ "gutenberg-env" ], + "types": [ + "gutenberg-env", + "jest", + "@testing-library/jest-dom", + "snapshot-diff" + ], // Some errors in Reakit types with TypeScript 4.3 // Remove the following line when they've been addressed. "skipLibCheck": true, From 441816d557fc7d00136501d45b8f633282e9bb24 Mon Sep 17 00:00:00 2001 From: Marco Ciampini Date: Fri, 11 Mar 2022 17:17:26 +0100 Subject: [PATCH 09/13] Remove dev dependencies from components's package.json --- package-lock.json | 19 ------------------- packages/components/package.json | 4 ---- 2 files changed, 23 deletions(-) diff --git a/package-lock.json b/package-lock.json index 5c3502b22dbfc2..37ed00efb43bc8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -22926,25 +22926,6 @@ "find-up": "^4.0.0" } }, - "plist": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/plist/-/plist-3.0.2.tgz", - "integrity": "sha512-MSrkwZBdQ6YapHy87/8hDU8MnIcyxBKjeF+McXnr5A9MtffPewTs7G3hlpodT5TacyfIyFTaJEhh3GGcmasTgQ==", - "dev": true, - "requires": { - "base64-js": "^1.5.1", - "xmlbuilder": "^9.0.7", - "xmldom": "^0.5.0" - }, - "dependencies": { - "xmlbuilder": { - "version": "9.0.7", - "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz", - "integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0=", - "dev": true - } - } - }, "pluralize": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz", diff --git a/packages/components/package.json b/packages/components/package.json index fd1534b3574a3b..9cf758b5cd407a 100644 --- a/packages/components/package.json +++ b/packages/components/package.json @@ -69,10 +69,6 @@ "reakit": "^1.3.8", "uuid": "^8.3.0" }, - "devDependencies": { - "@jest/globals": "27.5.1", - "@testing-library/react": "11.2.2" - }, "peerDependencies": { "react": "^17.0.0", "react-dom": "^17.0.0" From ec16572397d170fd70dbe84888cb72aefaadaf91 Mon Sep 17 00:00:00 2001 From: Marco Ciampini Date: Fri, 11 Mar 2022 17:18:23 +0100 Subject: [PATCH 10/13] Ignore eslint error about missing dependency in package.json --- packages/components/src/unit-control/test/index.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/components/src/unit-control/test/index.tsx b/packages/components/src/unit-control/test/index.tsx index 31469412ae6a2e..5d69a37f0b668c 100644 --- a/packages/components/src/unit-control/test/index.tsx +++ b/packages/components/src/unit-control/test/index.tsx @@ -1,6 +1,7 @@ /** * External dependencies */ +// eslint-disable-next-line import/no-extraneous-dependencies import { render, fireEvent, screen } from '@testing-library/react'; /** From 2395cdf6a13791855d00b24beec6751cf2e80517 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Fri, 11 Mar 2022 17:52:49 +0100 Subject: [PATCH 11/13] setup test ts project --- packages/components/tsconfig.json | 9 ++---- tsconfig.json | 3 +- tsconfig.test.json | 49 +++++++++++++++++++++++++++++++ 3 files changed, 53 insertions(+), 8 deletions(-) create mode 100644 tsconfig.test.json diff --git a/packages/components/tsconfig.json b/packages/components/tsconfig.json index 2e66472d220fa2..bb38249afa6248 100644 --- a/packages/components/tsconfig.json +++ b/packages/components/tsconfig.json @@ -3,12 +3,7 @@ "compilerOptions": { "rootDir": "src", "declarationDir": "build-types", - "types": [ - "gutenberg-env", - "jest", - "@testing-library/jest-dom", - "snapshot-diff" - ], + "types": [ "gutenberg-env" ], // Some errors in Reakit types with TypeScript 4.3 // Remove the following line when they've been addressed. "skipLibCheck": true, @@ -92,7 +87,7 @@ "src/**/*.native.js", "src/**/react-native-*", "src/**/stories/**.js", // only exclude js files, tsx files should be checked - "src/**/test/**.js", // only exclude js files, ts{x} files should be checked + "src/**/test", "src/ui/__storybook-utils", "src/ui/font-size-control" ] diff --git a/tsconfig.json b/tsconfig.json index 53ab6c77aa41b5..2df18b596bb4c0 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -32,7 +32,8 @@ { "path": "packages/token-list" }, { "path": "packages/url" }, { "path": "packages/warning" }, - { "path": "packages/wordcount" } + { "path": "packages/wordcount" }, + { "path": "./tsconfig.test.json" } ], "files": [] } diff --git a/tsconfig.test.json b/tsconfig.test.json new file mode 100644 index 00000000000000..95ec84f34214f9 --- /dev/null +++ b/tsconfig.test.json @@ -0,0 +1,49 @@ +{ + "extends": "./tsconfig.base.json", + "compilerOptions": { + "noEmit": true, + "emitDeclarationOnly": false, + "types": [ + "gutenberg-env", + "jest", + "@testing-library/jest-dom", + "snapshot-diff" + ] + }, + "references": [ + { "path": "packages/a11y" }, + { "path": "packages/api-fetch" }, + { "path": "packages/autop" }, + { "path": "packages/blob" }, + { "path": "packages/block-editor" }, + { "path": "packages/components" }, + { "path": "packages/compose" }, + { "path": "packages/data" }, + { "path": "packages/date" }, + { "path": "packages/deprecated" }, + { "path": "packages/docgen" }, + { "path": "packages/dom" }, + { "path": "packages/element" }, + { "path": "packages/dom-ready" }, + { "path": "packages/escape-html" }, + { "path": "packages/eslint-plugin" }, + { "path": "packages/html-entities" }, + { "path": "packages/hooks" }, + { "path": "packages/i18n" }, + { "path": "packages/icons" }, + { "path": "packages/is-shallow-equal" }, + { "path": "packages/keycodes" }, + { "path": "packages/lazy-import" }, + { "path": "packages/prettier-config" }, + { "path": "packages/primitives" }, + { "path": "packages/priority-queue" }, + { "path": "packages/project-management-automation" }, + { "path": "packages/react-i18n" }, + { "path": "packages/token-list" }, + { "path": "packages/url" }, + { "path": "packages/warning" }, + { "path": "packages/wordcount" } + ], + "include": [ "packages/**/test/*.ts", "packages/**/test/*.tsx" ], + "exclude": [] +} From 15ff9dd2e920b60163f7232c0bb05bff57b77416 Mon Sep 17 00:00:00 2001 From: Marco Ciampini Date: Fri, 11 Mar 2022 18:17:13 +0100 Subject: [PATCH 12/13] Add `@emotion/core` to test config --- tsconfig.test.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tsconfig.test.json b/tsconfig.test.json index 95ec84f34214f9..56ab3c3f03681b 100644 --- a/tsconfig.test.json +++ b/tsconfig.test.json @@ -7,8 +7,9 @@ "gutenberg-env", "jest", "@testing-library/jest-dom", - "snapshot-diff" - ] + "snapshot-diff", + "@emotion/core" + ], }, "references": [ { "path": "packages/a11y" }, From 21a7e5202833ad1f5f25801ff5a81fac424a7d5a Mon Sep 17 00:00:00 2001 From: Marco Ciampini Date: Fri, 11 Mar 2022 18:53:27 +0100 Subject: [PATCH 13/13] Require `snapshot-diff` in testing-library setup file --- test/unit/config/testing-library.js | 1 + 1 file changed, 1 insertion(+) diff --git a/test/unit/config/testing-library.js b/test/unit/config/testing-library.js index dd8c725c6f4ae6..5b29b671c5ebe8 100644 --- a/test/unit/config/testing-library.js +++ b/test/unit/config/testing-library.js @@ -1,3 +1,4 @@ require( '@testing-library/jest-dom' ); +require( 'snapshot-diff' ); require( 'snapshot-diff/extend-expect' ); require( './matchers/to-match-style-diff-snapshot' );