diff --git a/.eslintrc.js b/.eslintrc.js index 817a77fb8a..1028b67970 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -1,7 +1,3 @@ -const commonGlobals = { - gtag: true, -}; - module.exports = { extends: [ 'airbnb', @@ -38,7 +34,6 @@ module.exports = { { files: ['*.md'], globals: { - ...commonGlobals, React: true, ReactDOM: true, mountNode: true, @@ -124,5 +119,7 @@ module.exports = { 'unicorn/expiring-todo-comments': 2, 'unicorn/no-abusive-eslint-disable': 2, }, - globals: commonGlobals, + globals: { + gtag: true, + }, }; diff --git a/components/affix/__tests__/Affix.test.tsx b/components/affix/__tests__/Affix.test.tsx index 7545258569..d86ce2739e 100644 --- a/components/affix/__tests__/Affix.test.tsx +++ b/components/affix/__tests__/Affix.test.tsx @@ -1,12 +1,13 @@ import React from 'react'; -import { mount } from 'enzyme'; -import Affix from '..'; +import { mount, ReactWrapper, HTMLAttributes } from 'enzyme'; +import ResizeObserverImpl from 'rc-resize-observer'; +import Affix, { AffixProps, AffixState } from '..'; import { getObserverEntities } from '../utils'; import Button from '../../button'; import rtlTest from '../../../tests/shared/rtlTest'; import { sleep } from '../../../tests/utils'; -const events: any = {}; +const events: Partial) => void>> = {}; class AffixMounter extends React.Component<{ offsetBottom?: number; @@ -15,12 +16,14 @@ class AffixMounter extends React.Component<{ }> { private container: HTMLDivElement; - private affix: Affix; + public affix: Affix; componentDidMount() { - this.container.addEventListener = jest.fn().mockImplementation((event, cb) => { - events[event] = cb; - }); + this.container.addEventListener = jest + .fn() + .mockImplementation((event: keyof HTMLElementEventMap, cb: (ev: Partial) => void) => { + events[event] = cb; + }); } getTarget = () => this.container; @@ -29,7 +32,7 @@ class AffixMounter extends React.Component<{ return (
{ - this.container = node; + this.container = node!; }} className="container" > @@ -37,7 +40,7 @@ class AffixMounter extends React.Component<{ className="fixed" target={this.getTarget} ref={ele => { - this.affix = ele; + this.affix = ele!; }} {...this.props} > @@ -51,14 +54,15 @@ class AffixMounter extends React.Component<{ describe('Affix Render', () => { rtlTest(Affix); - let wrapper; const domMock = jest.spyOn(HTMLElement.prototype, 'getBoundingClientRect'); + let affixMounterWrapper: ReactWrapper; + let affixWrapper: ReactWrapper; - const classRect: any = { + const classRect: Record = { container: { top: 0, bottom: 100, - }, + } as DOMRect, }; beforeAll(() => { @@ -76,11 +80,14 @@ describe('Affix Render', () => { domMock.mockRestore(); }); - const movePlaceholder = async top => { + const movePlaceholder = async (top: number) => { classRect.fixed = { top, bottom: top, - }; + } as DOMRect; + if (events.scroll == null) { + throw new Error('scroll should be set'); + } events.scroll({ type: 'scroll', }); @@ -90,53 +97,53 @@ describe('Affix Render', () => { it('Anchor render perfectly', async () => { document.body.innerHTML = '
'; - wrapper = mount(, { attachTo: document.getElementById('mounter') }); + affixMounterWrapper = mount(, { attachTo: document.getElementById('mounter') }); await sleep(20); await movePlaceholder(0); - expect(wrapper.instance().affix.state.affixStyle).toBeFalsy(); + expect(affixMounterWrapper.instance().affix.state.affixStyle).toBeFalsy(); await movePlaceholder(-100); - expect(wrapper.instance().affix.state.affixStyle).toBeTruthy(); + expect(affixMounterWrapper.instance().affix.state.affixStyle).toBeTruthy(); await movePlaceholder(0); - expect(wrapper.instance().affix.state.affixStyle).toBeFalsy(); + expect(affixMounterWrapper.instance().affix.state.affixStyle).toBeFalsy(); }); it('support offsetBottom', async () => { document.body.innerHTML = '
'; - wrapper = mount(, { + affixMounterWrapper = mount(, { attachTo: document.getElementById('mounter'), }); await sleep(20); await movePlaceholder(300); - expect(wrapper.instance().affix.state.affixStyle).toBeTruthy(); + expect(affixMounterWrapper.instance().affix.state.affixStyle).toBeTruthy(); await movePlaceholder(0); - expect(wrapper.instance().affix.state.affixStyle).toBeFalsy(); + expect(affixMounterWrapper.instance().affix.state.affixStyle).toBeFalsy(); await movePlaceholder(300); - expect(wrapper.instance().affix.state.affixStyle).toBeTruthy(); + expect(affixMounterWrapper.instance().affix.state.affixStyle).toBeTruthy(); }); it('updatePosition when offsetTop changed', async () => { document.body.innerHTML = '
'; - wrapper = mount(, { + affixMounterWrapper = mount(, { attachTo: document.getElementById('mounter'), }); await sleep(20); await movePlaceholder(-100); - expect(wrapper.instance().affix.state.affixStyle.top).toBe(0); - wrapper.setProps({ + expect(affixMounterWrapper.instance().affix.state.affixStyle?.top).toBe(0); + affixMounterWrapper.setProps({ offsetTop: 10, }); await sleep(20); - expect(wrapper.instance().affix.state.affixStyle.top).toBe(10); + expect(affixMounterWrapper.instance().affix.state.affixStyle?.top).toBe(10); }); describe('updatePosition when target changed', () => { @@ -144,11 +151,11 @@ describe('Affix Render', () => { document.body.innerHTML = '
'; const container = document.querySelector('#id') as HTMLDivElement; const getTarget = () => container; - wrapper = mount({null}); - wrapper.setProps({ target: null }); - expect(wrapper.instance().state.status).toBe(0); - expect(wrapper.instance().state.affixStyle).toBe(undefined); - expect(wrapper.instance().state.placeholderStyle).toBe(undefined); + affixWrapper = mount({null}); + affixWrapper.setProps({ target: () => null }); + expect(affixWrapper.instance().state.status).toBe(0); + expect(affixWrapper.instance().state.affixStyle).toBe(undefined); + expect(affixWrapper.instance().state.placeholderStyle).toBe(undefined); }); it('instance change', async () => { @@ -156,53 +163,68 @@ describe('Affix Render', () => { const container = document.createElement('div'); document.body.appendChild(container); - let target = container; + let target: HTMLDivElement | null = container; const originLength = getObserverLength(); const getTarget = () => target; - wrapper = mount({null}); + affixWrapper = mount({null}); await sleep(50); expect(getObserverLength()).toBe(originLength + 1); target = null; - wrapper.setProps({}); - wrapper.update(); + affixWrapper.setProps({}); + affixWrapper.update(); await sleep(50); expect(getObserverLength()).toBe(originLength); }); }); describe('updatePosition when size changed', () => { - function test(name, index) { - it(name, async () => { - document.body.innerHTML = '
'; + it.each([ + { name: 'inner', index: 0 }, + { name: 'outer', index: 1 }, + ])(name, async ({ index }) => { + document.body.innerHTML = '
'; - const updateCalled = jest.fn(); - wrapper = mount(, { + const updateCalled = jest.fn(); + affixMounterWrapper = mount( + , + { attachTo: document.getElementById('mounter'), - }); - - await sleep(20); - - await movePlaceholder(300); - expect(wrapper.instance().affix.state.affixStyle).toBeTruthy(); - await sleep(20); - wrapper.update(); - - // Mock trigger resize - updateCalled.mockReset(); - wrapper - .find('ResizeObserver') - .at(index) - .instance() - .onResize([{ target: { getBoundingClientRect: () => ({ width: 99, height: 99 }) } }]); - await sleep(20); - - expect(updateCalled).toHaveBeenCalled(); - }); - } + }, + ); - test('inner', 0); - test('outer', 1); + await sleep(20); + + await movePlaceholder(300); + expect(affixMounterWrapper.instance().affix.state.affixStyle).toBeTruthy(); + await sleep(20); + affixMounterWrapper.update(); + + // Mock trigger resize + updateCalled.mockReset(); + const resizeObserverInstance: ReactWrapper< + HTMLAttributes, + unknown, + ResizeObserverImpl + > = affixMounterWrapper.find('ResizeObserver') as any; + resizeObserverInstance + .at(index) + .instance() + .onResize( + [ + { + target: { + getBoundingClientRect: () => ({ width: 99, height: 99 }), + } as Element, + contentRect: {} as DOMRect, + }, + ], + ({} as unknown) as ResizeObserver, + ); + await sleep(20); + + expect(updateCalled).toHaveBeenCalled(); + }); }); }); diff --git a/tsconfig.json b/tsconfig.json index e0015c0709..cf511ab415 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -17,5 +17,5 @@ "lib": ["dom", "es2017"], "skipLibCheck": true }, - "exclude": ["node_modules", "lib", "es", "**/__tests__/**"] + "exclude": ["node_modules", "lib", "es"] }