test: move test cases to testing-library for DropDown (#37003)

* temp

* fix: mock esmodule default for Dropdown

* test: move test cases to testing-library for DropDown

* chore: remove console

* fix: snapshot test

* refactor: jest mock improvement
This commit is contained in:
Yuki Zhang 2022-08-15 17:47:10 +08:00 committed by GitHub
parent 19ab86e67a
commit 969925653c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 154 additions and 126 deletions

View File

@ -1,106 +0,0 @@
import { mount } from 'enzyme';
import React from 'react';
import Dropdown from '..';
import mountTest from '../../../tests/shared/mountTest';
import rtlTest from '../../../tests/shared/rtlTest';
import Menu from '../../menu';
describe('DropdownButton', () => {
mountTest(Dropdown.Button);
rtlTest(Dropdown.Button);
it('pass appropriate props to Dropdown', () => {
const props = {
align: {
offset: [10, 20],
},
overlay: (
<Menu>
<Menu.Item key="1">foo</Menu.Item>
</Menu>
),
disabled: false,
trigger: ['hover'],
visible: true,
onVisibleChange: () => {},
};
const wrapper = mount(<Dropdown.Button {...props} />);
const dropdownProps = wrapper.find(Dropdown).props();
Object.keys(props).forEach(key => {
expect(dropdownProps[key]).toBe(props[key]);
});
});
it("don't pass visible to Dropdown if it's not exits", () => {
const menu = (
<Menu>
<Menu.Item key="1">foo</Menu.Item>
</Menu>
);
const wrapper = mount(<Dropdown.Button overlay={menu} />);
const dropdownProps = wrapper.find(Dropdown).props();
expect('visible' in dropdownProps).toBe(false);
});
it('should support href like Button', () => {
const menu = (
<Menu>
<Menu.Item key="1">foo</Menu.Item>
</Menu>
);
const wrapper = mount(<Dropdown.Button overlay={menu} href="https://ant.design" />);
expect(wrapper.render()).toMatchSnapshot();
});
it('have static property for type detecting', () => {
const menu = (
<Menu>
<Menu.Item key="1">foo</Menu.Item>
</Menu>
);
const wrapper = mount(<Dropdown.Button overlay={menu} />);
expect(wrapper.find(Dropdown.Button).type().__ANT_BUTTON).toBe(true);
});
it('should pass mouseEnterDelay and mouseLeaveDelay to Dropdown', () => {
const menu = (
<Menu>
<Menu.Item key="1">foo</Menu.Item>
</Menu>
);
const wrapper = mount(
<Dropdown.Button mouseEnterDelay={1} mouseLeaveDelay={2} overlay={menu} />,
);
expect(wrapper.find('Dropdown').props().mouseEnterDelay).toBe(1);
expect(wrapper.find('Dropdown').props().mouseLeaveDelay).toBe(2);
});
it('should support overlayClassName and overlayStyle', () => {
const menu = (
<Menu>
<Menu.Item key="1">foo</Menu.Item>
</Menu>
);
const wrapper = mount(
<Dropdown.Button
overlayClassName="className"
overlayStyle={{ color: 'red' }}
overlay={menu}
visible
/>,
);
expect(wrapper.find('.ant-dropdown').getDOMNode().className).toContain('className');
expect(wrapper.find('.ant-dropdown').getDOMNode().style.color).toContain('red');
});
it('should support loading', () => {
const wrapper = mount(<Dropdown.Button loading />);
expect(wrapper.find('.ant-dropdown-button .ant-btn-loading').getDOMNode().className).toContain(
'ant-btn',
);
});
});

View File

@ -0,0 +1,117 @@
import React from 'react';
import DropdownButton from '../dropdown-button';
import mountTest from '../../../tests/shared/mountTest';
import rtlTest from '../../../tests/shared/rtlTest';
import Menu from '../../menu';
import type { DropdownProps } from '../dropdown';
import { render } from '../../../tests/utils';
let dropdownProps: DropdownProps;
jest.mock('../dropdown', () => {
const ActualDropdown = jest.requireActual('../dropdown');
const ActualDropdownComponent = ActualDropdown.default;
const h: typeof React = jest.requireActual('react');
const mockedDropdown = (props: DropdownProps) => {
dropdownProps = props;
const { children, ...restProps } = props;
return h.createElement(ActualDropdownComponent, { ...restProps }, children);
};
mockedDropdown.defaultProps = ActualDropdownComponent.defaultProps;
mockedDropdown.Button = ActualDropdownComponent.Button;
return {
...ActualDropdown,
__esModule: true,
default: mockedDropdown,
};
});
describe('DropdownButton', () => {
mountTest(DropdownButton);
rtlTest(DropdownButton);
it('pass appropriate props to Dropdown', () => {
const props: DropdownProps = {
align: {
offset: [10, 20],
},
overlay: (
<Menu>
<Menu.Item key="1">foo</Menu.Item>
</Menu>
),
disabled: false,
trigger: ['hover'],
visible: true,
onVisibleChange: () => {},
};
render(<DropdownButton {...props} />);
Object.keys(props).forEach((key: keyof DropdownProps) => {
expect(dropdownProps[key]).toBe(props[key]);
});
});
it("don't pass visible to Dropdown if it's not exits", () => {
const menu = (
<Menu>
<Menu.Item key="1">foo</Menu.Item>
</Menu>
);
render(<DropdownButton overlay={menu} />);
expect('visible' in dropdownProps).toBe(false);
});
it('should support href like Button', () => {
const menu = (
<Menu>
<Menu.Item key="1">foo</Menu.Item>
</Menu>
);
const { asFragment } = render(<DropdownButton overlay={menu} href="https://ant.design" />);
expect(asFragment().firstChild).toMatchSnapshot();
});
it('have static property for type detecting', () => {
expect(DropdownButton.__ANT_BUTTON).toBe(true);
});
it('should pass mouseEnterDelay and mouseLeaveDelay to Dropdown', () => {
const menu = (
<Menu>
<Menu.Item key="1">foo</Menu.Item>
</Menu>
);
render(<DropdownButton mouseEnterDelay={1} mouseLeaveDelay={2} overlay={menu} />);
expect(dropdownProps.mouseEnterDelay).toBe(1);
expect(dropdownProps.mouseLeaveDelay).toBe(2);
});
it('should support overlayClassName and overlayStyle', () => {
const menu = (
<Menu>
<Menu.Item key="1">foo</Menu.Item>
</Menu>
);
const { container } = render(
<DropdownButton
overlayClassName="className"
overlayStyle={{ color: 'red' }}
overlay={menu}
visible
/>,
);
expect(container.querySelector('.ant-dropdown')?.classList).toContain('className');
expect((container.querySelector('.ant-dropdown') as HTMLElement).style.color).toContain('red');
});
it('should support loading', () => {
const { container } = render(<DropdownButton overlay={<div />} loading />);
expect(container.querySelector('.ant-dropdown-button .ant-btn-loading')?.classList).toContain(
'ant-btn',
);
});
});

View File

@ -1,44 +1,61 @@
import { mount } from 'enzyme';
import React from 'react';
import type { TriggerProps } from 'rc-trigger';
import Dropdown from '..';
import type { DropDownProps } from '..';
import mountTest from '../../../tests/shared/mountTest';
import rtlTest from '../../../tests/shared/rtlTest';
import { act, fireEvent, render, sleep } from '../../../tests/utils';
import Menu from '../../menu';
let triggerProps: TriggerProps;
jest.mock('rc-trigger', () => {
let Trigger = jest.requireActual('rc-trigger/lib/mock');
Trigger = Trigger.default || Trigger;
const h: typeof React = jest.requireActual('react');
return {
default: h.forwardRef<unknown, TriggerProps>((props, ref) => {
triggerProps = props;
return h.createElement(Trigger, { ref, ...props });
}),
__esModule: true,
};
});
describe('Dropdown', () => {
mountTest(() => (
<Dropdown menu={<Menu />}>
<Dropdown overlay={<Menu />}>
<span />
</Dropdown>
));
rtlTest(() => (
<Dropdown menu={<Menu />}>
<Dropdown overlay={<Menu />}>
<span />
</Dropdown>
));
it('overlay is function and has custom transitionName', () => {
const wrapper = mount(
const { asFragment } = render(
<Dropdown overlay={() => <div>menu</div>} transitionName="move-up" visible>
<button type="button">button</button>
</Dropdown>,
);
expect(wrapper.render()).toMatchSnapshot();
expect(Array.from(asFragment().childNodes)).toMatchSnapshot();
});
it('overlay is string', () => {
const wrapper = mount(
<Dropdown overlay="string" visible>
const { asFragment } = render(
<Dropdown overlay={'string' as any} visible>
<button type="button">button</button>
</Dropdown>,
);
expect(wrapper.render()).toMatchSnapshot();
expect(Array.from(asFragment().childNodes)).toMatchSnapshot();
});
it('support Menu expandIcon', async () => {
const props = {
const props: DropDownProps = {
overlay: (
<Menu expandIcon={<span id="customExpandIcon" />}>
<Menu.Item key="1">foo</Menu.Item>
@ -51,23 +68,23 @@ describe('Dropdown', () => {
getPopupContainer: node => node,
};
const wrapper = mount(
const { container } = render(
<Dropdown {...props}>
<button type="button">button</button>
</Dropdown>,
);
await sleep(500);
expect(wrapper.find(Dropdown).find('#customExpandIcon').length).toBe(1);
expect(container.querySelectorAll('#customExpandIcon').length).toBe(1);
});
it('should warn if use topCenter or bottomCenter', () => {
const error = jest.spyOn(console, 'error');
mount(
render(
<div>
<Dropdown overlay="123" placement="bottomCenter">
<Dropdown overlay={'123' as any} placement="bottomCenter">
<button type="button">bottomCenter</button>
</Dropdown>
<Dropdown overlay="123" placement="topCenter">
<Dropdown overlay={'123' as any} placement="topCenter">
<button type="button">topCenter</button>
</Dropdown>
</div>,
@ -82,13 +99,13 @@ describe('Dropdown', () => {
// zombieJ: when replaced with react test lib, it may be mock fully content
it('dropdown should support auto adjust placement', () => {
const wrapper = mount(
render(
<Dropdown overlay={<div>menu</div>} visible>
<button type="button">button</button>
</Dropdown>,
);
expect(wrapper.find('Trigger').prop('builtinPlacements')).toEqual(
expect(triggerProps.builtinPlacements).toEqual(
expect.objectContaining({
bottomLeft: expect.objectContaining({
overflow: {
@ -104,7 +121,7 @@ describe('Dropdown', () => {
jest.useFakeTimers();
const { container } = render(
<Dropdown
trigger="click"
trigger={['click']}
overlay={
<Menu
items={[
@ -127,13 +144,13 @@ describe('Dropdown', () => {
);
// Open
fireEvent.click(container.querySelector('a'));
fireEvent.click(container.querySelector('a')!);
act(() => {
jest.runAllTimers();
});
// Close
fireEvent.click(container.querySelector('.ant-dropdown-menu-item'));
fireEvent.click(container.querySelector('.ant-dropdown-menu-item')!);
// Force Motion move on
for (let i = 0; i < 10; i += 1) {
@ -143,7 +160,7 @@ describe('Dropdown', () => {
}
// Motion End
fireEvent.animationEnd(container.querySelector('.ant-slide-up-leave-active'));
fireEvent.animationEnd(container.querySelector('.ant-slide-up-leave-active')!);
expect(container.querySelector('.ant-dropdown-hidden')).toBeTruthy();