From e91d25622b5b7e26d8d76d0d43deb71267a77105 Mon Sep 17 00:00:00 2001 From: Zheeeng Date: Wed, 19 Oct 2022 11:50:18 +0800 Subject: [PATCH] chore: signatures for tests (#37949) * fix: signatures for tests * fix: remove unused * fix: test cases * fix: test cases --- .eslintrc.js | 2 +- components/_util/__tests__/easings.test.ts | 1 - components/_util/__tests__/scrollTo.test.ts | 9 ++-- .../_util/__tests__/useSyncState.test.tsx | 2 +- components/_util/__tests__/wave.test.tsx | 18 ++++---- components/_util/wave.tsx | 7 +--- .../button/__tests__/delay-timer.test.tsx | 20 +++++---- components/button/__tests__/index.test.tsx | 4 +- components/button/__tests__/wave.test.tsx | 14 ++++--- components/calendar/__tests__/index.test.tsx | 41 +++++++++---------- components/checkbox/__tests__/group.test.tsx | 4 +- tests/utils.tsx | 5 +++ 12 files changed, 66 insertions(+), 61 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index 855bbc528a..d77a68dea6 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -31,7 +31,7 @@ module.exports = { '@typescript-eslint/no-unused-vars': [2, { args: 'none' }], 'no-unused-expressions': 'off', '@typescript-eslint/no-unused-expressions': 2, - '@typescript-eslint/consistent-type-imports': 2, + '@typescript-eslint/consistent-type-imports': [2, { disallowTypeAnnotations: false }], }, }, { diff --git a/components/_util/__tests__/easings.test.ts b/components/_util/__tests__/easings.test.ts index 5fcf58bd95..963b863a50 100644 --- a/components/_util/__tests__/easings.test.ts +++ b/components/_util/__tests__/easings.test.ts @@ -3,7 +3,6 @@ import { easeInOutCubic } from '../easings'; describe('Test easings', () => { it('easeInOutCubic return value', () => { const nums: number[] = []; - // eslint-disable-next-line no-plusplus for (let index = 0; index < 5; index++) { nums.push(easeInOutCubic(index, 1, 5, 4)); } diff --git a/components/_util/__tests__/scrollTo.test.ts b/components/_util/__tests__/scrollTo.test.ts index c60214492e..5fe2e09502 100644 --- a/components/_util/__tests__/scrollTo.test.ts +++ b/components/_util/__tests__/scrollTo.test.ts @@ -2,17 +2,14 @@ import { waitFakeTimer } from '../../../tests/utils'; import scrollTo from '../scrollTo'; describe('Test ScrollTo function', () => { - let dateNowMock: jest.SpyInstance; + const dateNowMock = jest.spyOn(Date, 'now'); beforeAll(() => { jest.useFakeTimers(); }); beforeEach(() => { - dateNowMock = jest - .spyOn(Date, 'now') - .mockImplementationOnce(() => 0) - .mockImplementationOnce(() => 1000); + dateNowMock.mockReturnValueOnce(0).mockReturnValueOnce(1000); }); afterAll(() => { @@ -21,7 +18,7 @@ describe('Test ScrollTo function', () => { afterEach(() => { jest.clearAllTimers(); - dateNowMock.mockRestore(); + dateNowMock.mockClear(); }); it('test scrollTo', async () => { diff --git a/components/_util/__tests__/useSyncState.test.tsx b/components/_util/__tests__/useSyncState.test.tsx index c00c833f8d..b0c0d96971 100644 --- a/components/_util/__tests__/useSyncState.test.tsx +++ b/components/_util/__tests__/useSyncState.test.tsx @@ -4,7 +4,7 @@ import { render, fireEvent } from '../../../tests/utils'; describe('Table', () => { it('useSyncState', () => { - const Test: React.FC = () => { + const Test = () => { const [getVal, setVal] = useSyncState('light'); return setVal('bamboo')}>{getVal()}; }; diff --git a/components/_util/__tests__/wave.test.tsx b/components/_util/__tests__/wave.test.tsx index 804a63a2b3..5028b7bcde 100644 --- a/components/_util/__tests__/wave.test.tsx +++ b/components/_util/__tests__/wave.test.tsx @@ -236,15 +236,19 @@ describe('Wave component', () => { fakeDoc.appendChild(document.createElement('span')); expect(fakeDoc.childNodes).toHaveLength(2); - (container.querySelector('.bamboo') as any).getRootNode = () => fakeDoc; + const elem = container.querySelector('.bamboo'); - // Click should not throw - fireEvent.click(container.querySelector('.bamboo')!); - act(() => { - jest.runAllTimers(); - }); + if (elem) { + elem.getRootNode = () => fakeDoc; - expect(fakeDoc.querySelector('style')).toBeTruthy(); + // Click should not throw + fireEvent.click(elem); + act(() => { + jest.runAllTimers(); + }); + + expect(fakeDoc.querySelector('style')).toBeTruthy(); + } jest.useRealTimers(); }); diff --git a/components/_util/wave.tsx b/components/_util/wave.tsx index f254eadebc..0569966e55 100644 --- a/components/_util/wave.tsx +++ b/components/_util/wave.tsx @@ -1,7 +1,6 @@ import { updateCSS } from 'rc-util/lib/Dom/dynamicCSS'; import { composeRef, supportRef } from 'rc-util/lib/ref'; import * as React from 'react'; -import { forwardRef } from 'react'; import type { ConfigConsumerProps, CSPConfig } from '../config-provider'; import { ConfigConsumer, ConfigContext } from '../config-provider'; import raf from './raf'; @@ -42,7 +41,7 @@ export interface WaveProps { children?: React.ReactNode; } -class InternalWave extends React.Component { +class Wave extends React.Component { static contextType = ConfigContext; private instance?: { @@ -237,8 +236,4 @@ class InternalWave extends React.Component { } } -const Wave = forwardRef((props, ref) => ( - -)); - export default Wave; diff --git a/components/button/__tests__/delay-timer.test.tsx b/components/button/__tests__/delay-timer.test.tsx index 4f4f724f21..f4832987e6 100644 --- a/components/button/__tests__/delay-timer.test.tsx +++ b/components/button/__tests__/delay-timer.test.tsx @@ -29,17 +29,17 @@ const Content = () => { }; it('Delay loading timer in Button component', () => { - const otherTimer: any = 9528; - jest.spyOn(window, 'setTimeout').mockReturnValue(otherTimer); + const otherTimer = 9528; + jest.spyOn(window, 'setTimeout').mockReturnValue(otherTimer); jest.restoreAllMocks(); const wrapper = render(); - const btnTimer: any = 9527; - jest.spyOn(window, 'setTimeout').mockReturnValue(btnTimer); - jest.spyOn(window, 'clearTimeout'); - const setTimeoutMock = window.setTimeout as any as jest.Mock; - const clearTimeoutMock = window.clearTimeout as any as jest.Mock; + const btnTimer = 9527; + const setTimeoutMock = jest + .spyOn(window, 'setTimeout') + .mockReturnValue(btnTimer); + const clearTimeoutMock = jest.spyOn(window, 'clearTimeout'); // other component may call setTimeout or clearTimeout const setTimeoutCount = () => { @@ -58,7 +58,11 @@ it('Delay loading timer in Button component', () => { // trigger timer handler act(() => { - setTimeoutMock.mock.calls[0][0](); + const timerHandler = setTimeoutMock.mock.calls[0][0]; + + if (typeof timerHandler === 'function') { + timerHandler(); + } }); expect(setTimeoutCount()).toBe(1); expect(clearTimeoutCount()).toBe(0); diff --git a/components/button/__tests__/index.test.tsx b/components/button/__tests__/index.test.tsx index ae05f2e1bf..0c370abe1a 100644 --- a/components/button/__tests__/index.test.tsx +++ b/components/button/__tests__/index.test.tsx @@ -7,7 +7,6 @@ import mountTest from '../../../tests/shared/mountTest'; import rtlTest from '../../../tests/shared/rtlTest'; import { fireEvent, render, sleep } from '../../../tests/utils'; import ConfigProvider from '../../config-provider'; -import type { SizeType } from '../../config-provider/SizeContext'; describe('Button', () => { mountTest(Button); @@ -38,7 +37,8 @@ describe('Button', () => { it('warns if size is wrong', () => { resetWarned(); const mockWarn = jest.spyOn(console, 'error').mockImplementation(() => {}); - const size = 'who am I' as any as SizeType; + const size = 'who am I'; + // @ts-expect-error: Type '"who am I"' is not assignable to type 'SizeType'.ts(2322) render(); expect(mockWarn).toHaveBeenCalledWith('Warning: [antd: Button.Group] Invalid prop `size`.'); diff --git a/components/button/__tests__/wave.test.tsx b/components/button/__tests__/wave.test.tsx index bcda6baf63..126e387be8 100644 --- a/components/button/__tests__/wave.test.tsx +++ b/components/button/__tests__/wave.test.tsx @@ -1,18 +1,19 @@ import React from 'react'; import Button from '..'; -import { fireEvent, render, sleep } from '../../../tests/utils'; +import { fireEvent, render, sleep, assertsExist } from '../../../tests/utils'; // Mock Wave ref -let waveInstanceMock: any; +let waveInstanceMock: InstanceType | null; jest.mock('../../_util/wave', () => { - const Wave = jest.requireActual('../../_util/wave'); + const Wave: typeof import('../../_util/wave') = jest.requireActual('../../_util/wave'); const WaveComponent = Wave.default; + return { ...Wave, __esModule: true, - default: (props: any) => ( + default: (props: import('../../_util/wave').WaveProps) => ( { + ref={node => { waveInstanceMock = node; }} {...props} @@ -77,12 +78,14 @@ describe('click wave effect', () => { it('should run resetEffect in transitionstart', async () => { const wrapper = render(); + assertsExist(waveInstanceMock); const resetEffect = jest.spyOn(waveInstanceMock, 'resetEffect'); await clickButton(wrapper); expect(resetEffect).toHaveBeenCalledTimes(1); fireEvent.click(wrapper.container.querySelector('.ant-btn')!); await sleep(10); expect(resetEffect).toHaveBeenCalledTimes(2); + // @ts-expect-error: Property 'animationStart' is private and only accessible within class 'Wave'.ts(2341) waveInstanceMock.animationStart = false; fireEvent(wrapper.container.querySelector('.ant-btn')!, new Event('transitionstart')); expect(resetEffect).toHaveBeenCalledTimes(3); @@ -91,6 +94,7 @@ describe('click wave effect', () => { it('should handle transitionend', async () => { const wrapper = render(); + assertsExist(waveInstanceMock); const resetEffect = jest.spyOn(waveInstanceMock, 'resetEffect'); await clickButton(wrapper); expect(resetEffect).toHaveBeenCalledTimes(1); diff --git a/components/calendar/__tests__/index.test.tsx b/components/calendar/__tests__/index.test.tsx index 9e974ed1dc..54b9e2b415 100644 --- a/components/calendar/__tests__/index.test.tsx +++ b/components/calendar/__tests__/index.test.tsx @@ -13,19 +13,16 @@ import Button from '../../radio/radioButton'; import Select from '../../select'; import Header, { type CalendarHeaderProps } from '../Header'; -function calendarProps(): PickerPanelProps { - return (global as any).calendarProps; -} - -function calendarHeaderProps(): CalendarHeaderProps { - return (global as any).calendarHeaderProps; -} +const ref: { + calendarProps?: PickerPanelProps; + calendarHeaderProps?: CalendarHeaderProps; +} = {}; jest.mock('../Header', () => { const HeaderModule = jest.requireActual('../Header'); const HeaderComponent = HeaderModule.default; return (props: CalendarHeaderProps) => { - (global as any).calendarHeaderProps = props; + ref.calendarHeaderProps = props; return ; }; }); @@ -35,8 +32,8 @@ jest.mock('rc-picker', () => { const PickerPanelComponent = RcPicker.PickerPanel; return { ...RcPicker, - PickerPanel: (props: PickerPanelProps) => { - (global as any).calendarProps = props; + PickerPanel: (props: PickerPanelProps) => { + ref.calendarProps = props; return ; }, }; @@ -152,8 +149,8 @@ describe('Calendar', () => { it('getDateRange should returns a disabledDate function', () => { const validRange: [Moment.Moment, Moment.Moment] = [Moment('2018-02-02'), Moment('2018-05-18')]; render(); - expect(calendarProps().disabledDate?.(Moment('2018-06-02'))).toBe(true); - expect(calendarProps().disabledDate?.(Moment('2018-04-02'))).toBe(false); + expect(ref.calendarProps?.disabledDate?.(Moment('2018-06-02'))).toBe(true); + expect(ref.calendarProps?.disabledDate?.(Moment('2018-04-02'))).toBe(false); }); it('validRange should work with disabledDate function', () => { @@ -162,11 +159,11 @@ describe('Calendar', () => { data.isSame(Moment('2018-02-03'))} />, ); - expect(calendarProps().disabledDate?.(Moment('2018-02-01'))).toBe(true); - expect(calendarProps().disabledDate?.(Moment('2018-02-02'))).toBe(false); - expect(calendarProps().disabledDate?.(Moment('2018-02-03'))).toBe(true); - expect(calendarProps().disabledDate?.(Moment('2018-02-04'))).toBe(false); - expect(calendarProps().disabledDate?.(Moment('2018-06-01'))).toBe(true); + expect(ref.calendarProps?.disabledDate?.(Moment('2018-02-01'))).toBe(true); + expect(ref.calendarProps?.disabledDate?.(Moment('2018-02-02'))).toBe(false); + expect(ref.calendarProps?.disabledDate?.(Moment('2018-02-03'))).toBe(true); + expect(ref.calendarProps?.disabledDate?.(Moment('2018-02-04'))).toBe(false); + expect(ref.calendarProps?.disabledDate?.(Moment('2018-06-01'))).toBe(true); }); it('Calendar MonthSelect should display correct label', () => { @@ -181,9 +178,9 @@ describe('Calendar', () => { const monthMode = 'month'; const yearMode = 'year'; const wrapper = render(); - expect(calendarHeaderProps().mode).toEqual(monthMode); + expect(ref.calendarHeaderProps?.mode).toEqual(monthMode); wrapper.rerender(); - expect(calendarHeaderProps().mode).toEqual(yearMode); + expect(ref.calendarHeaderProps?.mode).toEqual(yearMode); }); it('Calendar should switch mode', () => { @@ -191,9 +188,9 @@ describe('Calendar', () => { const yearMode = 'year'; const onPanelChangeStub = jest.fn(); const wrapper = render(); - expect(calendarHeaderProps().mode).toEqual(yearMode); + expect(ref.calendarHeaderProps?.mode).toEqual(yearMode); wrapper.rerender(); - expect(calendarHeaderProps().mode).toEqual(monthMode); + expect(ref.calendarHeaderProps?.mode).toEqual(monthMode); expect(onPanelChangeStub).toHaveBeenCalledTimes(0); }); @@ -234,7 +231,7 @@ describe('Calendar', () => { const date = Moment(new Date(Date.UTC(2017, 7, 9, 8))); const wrapper = render(); - expect(calendarHeaderProps().mode).toBe('month'); + expect(ref.calendarHeaderProps?.mode).toBe('month'); expect(wrapper.container.querySelectorAll('.ant-picker-date-panel').length).toBe(1); expect(wrapper.container.querySelectorAll('.ant-picker-month-panel').length).toBe(0); fireEvent.click(wrapper.container.querySelector('.ant-radio-button-input[value="year"]')!); diff --git a/components/checkbox/__tests__/group.test.tsx b/components/checkbox/__tests__/group.test.tsx index b22065d489..6d2399ae7a 100644 --- a/components/checkbox/__tests__/group.test.tsx +++ b/components/checkbox/__tests__/group.test.tsx @@ -242,10 +242,10 @@ describe('CheckboxGroup', () => { const onChange = jest.fn(); const Demo: React.FC = () => { - const [v, setV] = useState(''); + const [v, setV] = useState(''); React.useEffect(() => { - setTimeout(setV('1') as unknown as TimerHandler, 1000); + setV('1'); }, []); return ( diff --git a/tests/utils.tsx b/tests/utils.tsx index edb2fccc58..cb17caffb6 100644 --- a/tests/utils.tsx +++ b/tests/utils.tsx @@ -6,6 +6,11 @@ import { render, act } from '@testing-library/react'; import { _rs as onLibResize } from 'rc-resize-observer/lib/utils/observerUtil'; import { _rs as onEsResize } from 'rc-resize-observer/es/utils/observerUtil'; +export function assertsExist(item: T | null | undefined): asserts item is T { + expect(item).not.toBeUndefined(); + expect(item).not.toBeNull(); +} + export function setMockDate(dateString = '2017-09-18T03:30:07.795') { MockDate.set(dateString); }