mirror of
https://gitee.com/ant-design/ant-design.git
synced 2024-12-03 04:30:06 +08:00
test: replace layout test case with test lib (#36323)
* test: replace layout test case with test lib * test: fix react 18 * test: clean up Co-authored-by: zombiej <smith3816@gmail.com>
This commit is contained in:
parent
1d82f221b6
commit
40728fb4dc
@ -3,7 +3,7 @@
|
|||||||
exports[`Layout renders string width correctly 1`] = `
|
exports[`Layout renders string width correctly 1`] = `
|
||||||
<aside
|
<aside
|
||||||
class="ant-layout-sider ant-layout-sider-dark"
|
class="ant-layout-sider ant-layout-sider-dark"
|
||||||
style="flex:0 0 200px;max-width:200px;min-width:200px;width:200px"
|
style="flex: 0 0 200px; max-width: 200px; min-width: 200px; width: 200px;"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="ant-layout-sider-children"
|
class="ant-layout-sider-children"
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { mount } from 'enzyme';
|
|
||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
import Sider from '../Sider';
|
import Sider from '../Sider';
|
||||||
|
import { render, fireEvent } from '../../../tests/utils';
|
||||||
|
|
||||||
const Content = () => {
|
const Content = () => {
|
||||||
const [breakpoint, setBreakpoint] = useState('sm');
|
const [breakpoint, setBreakpoint] = useState('sm');
|
||||||
@ -23,25 +23,27 @@ const Content = () => {
|
|||||||
it('Dynamic breakpoint in Sider component', () => {
|
it('Dynamic breakpoint in Sider component', () => {
|
||||||
const add = jest.fn();
|
const add = jest.fn();
|
||||||
const remove = jest.fn();
|
const remove = jest.fn();
|
||||||
jest.spyOn(window, 'matchMedia').mockReturnValue({
|
const newMatch = jest.spyOn(window, 'matchMedia').mockReturnValue({
|
||||||
matches: true,
|
matches: true,
|
||||||
addEventListener: add,
|
addEventListener: add,
|
||||||
removeEventListener: remove,
|
removeEventListener: remove,
|
||||||
} as any);
|
} as any);
|
||||||
|
|
||||||
const wrapper = mount(<Content />);
|
const { container } = render(<Content />);
|
||||||
const newMatch = window.matchMedia as jest.Mock;
|
|
||||||
|
// Record here since React 18 strict mode will render twice at first mount
|
||||||
|
const originCallTimes = newMatch.mock.calls.length;
|
||||||
|
expect(originCallTimes <= 2).toBeTruthy();
|
||||||
|
|
||||||
// subscribe at first
|
// subscribe at first
|
||||||
expect(newMatch.mock.calls.length).toBe(1);
|
expect(add.mock.calls).toHaveLength(originCallTimes);
|
||||||
expect(add.mock.calls.length).toBe(1);
|
expect(remove.mock.calls).toHaveLength(originCallTimes - 1);
|
||||||
expect(remove.mock.calls.length).toBe(0);
|
|
||||||
|
|
||||||
wrapper.find('#toggle').at(0).simulate('click');
|
fireEvent.click(container.querySelector('#toggle') as Element);
|
||||||
// unsubscribe then subscribe again
|
|
||||||
expect(newMatch.mock.calls.length).toBe(2);
|
expect(newMatch.mock.calls).toHaveLength(originCallTimes + 1);
|
||||||
expect(add.mock.calls.length).toBe(2);
|
expect(add.mock.calls).toHaveLength(originCallTimes + 1);
|
||||||
expect(remove.mock.calls.length).toBe(1);
|
expect(remove.mock.calls).toHaveLength(originCallTimes);
|
||||||
|
|
||||||
jest.restoreAllMocks();
|
jest.restoreAllMocks();
|
||||||
});
|
});
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
import { mount, render } from 'enzyme';
|
|
||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
|
import { act } from 'react-dom/test-utils';
|
||||||
import Layout from '..';
|
import Layout from '..';
|
||||||
import mountTest from '../../../tests/shared/mountTest';
|
import mountTest from '../../../tests/shared/mountTest';
|
||||||
import rtlTest from '../../../tests/shared/rtlTest';
|
import rtlTest from '../../../tests/shared/rtlTest';
|
||||||
import Icon from '../../icon';
|
import Icon from '../../icon';
|
||||||
import Menu from '../../menu';
|
import Menu from '../../menu';
|
||||||
|
import { fireEvent, render } from '../../../tests/utils';
|
||||||
|
|
||||||
const { Sider, Content, Footer, Header } = Layout;
|
const { Sider, Content, Footer, Header } = Layout;
|
||||||
|
|
||||||
@ -24,14 +25,16 @@ describe('Layout', () => {
|
|||||||
rtlTest(Sider);
|
rtlTest(Sider);
|
||||||
|
|
||||||
it('detect the sider as children', () => {
|
it('detect the sider as children', () => {
|
||||||
const wrapper = mount(
|
const { container, unmount } = render(
|
||||||
<Layout>
|
<Layout>
|
||||||
<Sider>Sider</Sider>
|
<Sider>Sider</Sider>
|
||||||
<Content>Content</Content>
|
<Content>Content</Content>
|
||||||
</Layout>,
|
</Layout>,
|
||||||
);
|
);
|
||||||
expect(wrapper.find('.ant-layout').hasClass('ant-layout-has-sider')).toBe(true);
|
expect(container.querySelector('.ant-layout').className.includes('ant-layout-has-sider')).toBe(
|
||||||
wrapper.unmount();
|
true,
|
||||||
|
);
|
||||||
|
unmount();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('umount from multiple siders', async () => {
|
it('umount from multiple siders', async () => {
|
||||||
@ -53,16 +56,22 @@ describe('Layout', () => {
|
|||||||
</Layout>
|
</Layout>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
const wrapper = mount(<App />);
|
const { container } = render(<App />);
|
||||||
expect(wrapper.find('.ant-layout').hasClass('ant-layout-has-sider')).toBe(true);
|
expect(container.querySelector('.ant-layout').className.includes('ant-layout-has-sider')).toBe(
|
||||||
wrapper.find('button').at(0).simulate('click');
|
true,
|
||||||
expect(wrapper.find('.ant-layout').hasClass('ant-layout-has-sider')).toBe(true);
|
);
|
||||||
wrapper.find('button').at(1).simulate('click');
|
fireEvent.click(container.querySelectorAll('button')[0]);
|
||||||
expect(wrapper.find('.ant-layout').hasClass('ant-layout-has-sider')).toBe(false);
|
expect(container.querySelector('.ant-layout').className.includes('ant-layout-has-sider')).toBe(
|
||||||
|
true,
|
||||||
|
);
|
||||||
|
fireEvent.click(container.querySelectorAll('button')[1]);
|
||||||
|
expect(container.querySelector('.ant-layout').className.includes('ant-layout-has-sider')).toBe(
|
||||||
|
false,
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('detect the sider inside the children', async () => {
|
it('detect the sider inside the children', async () => {
|
||||||
const wrapper = mount(
|
const { container } = render(
|
||||||
<Layout>
|
<Layout>
|
||||||
<div>
|
<div>
|
||||||
<Sider>Sider</Sider>
|
<Sider>Sider</Sider>
|
||||||
@ -70,11 +79,13 @@ describe('Layout', () => {
|
|||||||
<Content>Content</Content>
|
<Content>Content</Content>
|
||||||
</Layout>,
|
</Layout>,
|
||||||
);
|
);
|
||||||
expect(wrapper.find('.ant-layout').hasClass('ant-layout-has-sider')).toBe(true);
|
expect(container.querySelector('.ant-layout').className.includes('ant-layout-has-sider')).toBe(
|
||||||
|
true,
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('detect ant-layout-sider-has-trigger class in sider when ant-layout-sider-trigger div tag exists', async () => {
|
it('detect ant-layout-sider-has-trigger class in sider when ant-layout-sider-trigger div tag exists', async () => {
|
||||||
const wrapper = mount(
|
const { container } = render(
|
||||||
<Layout>
|
<Layout>
|
||||||
<div>
|
<div>
|
||||||
<Sider collapsible>Sider</Sider>
|
<Sider collapsible>Sider</Sider>
|
||||||
@ -82,11 +93,15 @@ describe('Layout', () => {
|
|||||||
<Content>Content</Content>
|
<Content>Content</Content>
|
||||||
</Layout>,
|
</Layout>,
|
||||||
);
|
);
|
||||||
expect(wrapper.find('.ant-layout-sider').hasClass('ant-layout-sider-has-trigger')).toBe(true);
|
expect(
|
||||||
|
container
|
||||||
|
.querySelector('.ant-layout-sider')
|
||||||
|
.className.includes('ant-layout-sider-has-trigger'),
|
||||||
|
).toBe(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should have 50% width of sidebar', async () => {
|
it('should have 50% width of sidebar', async () => {
|
||||||
const wrapper = mount(
|
const { container } = render(
|
||||||
<Layout>
|
<Layout>
|
||||||
<div>
|
<div>
|
||||||
<Sider width="50%">Sider</Sider>
|
<Sider width="50%">Sider</Sider>
|
||||||
@ -94,13 +109,13 @@ describe('Layout', () => {
|
|||||||
<Content>Content</Content>
|
<Content>Content</Content>
|
||||||
</Layout>,
|
</Layout>,
|
||||||
);
|
);
|
||||||
expect(wrapper.find('.ant-layout-sider').at(0).prop('style').width).toBe('50%');
|
expect(container.querySelector('.ant-layout-sider').style.width).toBe('50%');
|
||||||
expect(wrapper.find('.ant-layout-sider').at(0).prop('style').flex).toBe('0 0 50%');
|
expect(container.querySelector('.ant-layout-sider').style.flex).toBe('0 0 50%');
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('zeroWidth', () => {
|
describe('zeroWidth', () => {
|
||||||
it('detect ant-layout-sider-zero-width class in sider when its width is 0%', async () => {
|
it('detect ant-layout-sider-zero-width class in sider when its width is 0%', async () => {
|
||||||
const wrapper = mount(
|
const { container } = render(
|
||||||
<Layout>
|
<Layout>
|
||||||
<div>
|
<div>
|
||||||
<Sider width="0%">Sider</Sider>
|
<Sider width="0%">Sider</Sider>
|
||||||
@ -108,14 +123,18 @@ describe('Layout', () => {
|
|||||||
<Content>Content</Content>
|
<Content>Content</Content>
|
||||||
</Layout>,
|
</Layout>,
|
||||||
);
|
);
|
||||||
expect(wrapper.find('.ant-layout-sider').hasClass('ant-layout-sider-zero-width')).toBe(true);
|
expect(
|
||||||
|
container
|
||||||
|
.querySelector('.ant-layout-sider')
|
||||||
|
.className.includes('ant-layout-sider-zero-width'),
|
||||||
|
).toBe(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('should collapsible', () => {
|
describe('should collapsible', () => {
|
||||||
it('uncontrolled', () => {
|
it('uncontrolled', () => {
|
||||||
const onCollapse = jest.fn();
|
const onCollapse = jest.fn();
|
||||||
|
|
||||||
const wrapper = mount(
|
const { container } = render(
|
||||||
<Layout>
|
<Layout>
|
||||||
<Sider collapsible breakpoint="lg" collapsedWidth="0" onCollapse={onCollapse}>
|
<Sider collapsible breakpoint="lg" collapsedWidth="0" onCollapse={onCollapse}>
|
||||||
Sider
|
Sider
|
||||||
@ -125,8 +144,7 @@ describe('Layout', () => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
onCollapse.mockReset();
|
onCollapse.mockReset();
|
||||||
|
fireEvent.click(container.querySelector('.ant-layout-sider-zero-width-trigger'));
|
||||||
wrapper.find('.ant-layout-sider-zero-width-trigger').simulate('click');
|
|
||||||
expect(onCollapse).toHaveBeenCalledTimes(1);
|
expect(onCollapse).toHaveBeenCalledTimes(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -150,50 +168,54 @@ describe('Layout', () => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const wrapper = mount(<Demo />);
|
const { container } = render(<Demo />);
|
||||||
expect(wrapper.find(Sider).prop('collapsed')).toBeTruthy();
|
expect(container.querySelector('.ant-layout-sider-collapsed')).toBeTruthy();
|
||||||
|
fireEvent.click(container.querySelector('.ant-layout-sider-zero-width-trigger'));
|
||||||
wrapper.find('.ant-layout-sider-zero-width-trigger').simulate('click');
|
expect(container.querySelector('.ant-layout-sider-collapsed')).toBeFalsy();
|
||||||
expect(wrapper.find(Sider).prop('collapsed')).toBeFalsy();
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('detect ant-layout-sider-dark as default theme', async () => {
|
it('detect ant-layout-sider-dark as default theme', async () => {
|
||||||
const wrapper = mount(<Sider>Sider</Sider>);
|
const { container } = render(<Sider>Sider</Sider>);
|
||||||
expect(wrapper.find('.ant-layout-sider').hasClass('ant-layout-sider-dark')).toBe(true);
|
expect(
|
||||||
|
container.querySelector('.ant-layout-sider').className.includes('ant-layout-sider-dark'),
|
||||||
|
).toBe(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('detect ant-layout-sider-light when set light theme', async () => {
|
it('detect ant-layout-sider-light when set light theme', async () => {
|
||||||
const wrapper = mount(<Sider theme="light">Sider</Sider>);
|
const { container } = render(<Sider theme="light">Sider</Sider>);
|
||||||
expect(wrapper.find('.ant-layout-sider').hasClass('ant-layout-sider-light')).toBe(true);
|
expect(
|
||||||
|
container.querySelector('.ant-layout-sider').className.includes('ant-layout-sider-light'),
|
||||||
|
).toBe(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('renders string width correctly', () => {
|
it('renders string width correctly', () => {
|
||||||
const wrapper = render(<Sider width="200">Sider</Sider>);
|
const { asFragment } = render(<Sider width="200">Sider</Sider>);
|
||||||
expect(wrapper).toMatchSnapshot();
|
expect(asFragment().firstChild).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should be controlled by collapsed', () => {
|
it('should be controlled by collapsed', () => {
|
||||||
const wrapper = mount(<Sider>Sider</Sider>);
|
const { asFragment, rerender } = render(<Sider>Sider</Sider>);
|
||||||
expect(wrapper.render()).toMatchSnapshot();
|
expect(asFragment().firstChild).toMatchSnapshot();
|
||||||
wrapper.setProps({ collapsed: true });
|
rerender(<Sider collapsed>Sider</Sider>);
|
||||||
wrapper.update();
|
expect(asFragment().firstChild).toMatchSnapshot();
|
||||||
expect(wrapper.render()).toMatchSnapshot();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not add ant-layout-has-sider when `hasSider` is `false`', () => {
|
it('should not add ant-layout-has-sider when `hasSider` is `false`', () => {
|
||||||
const wrapper = mount(
|
const { container } = render(
|
||||||
<Layout hasSider={false}>
|
<Layout hasSider={false}>
|
||||||
<Sider>Sider</Sider>
|
<Sider>Sider</Sider>
|
||||||
</Layout>,
|
</Layout>,
|
||||||
);
|
);
|
||||||
expect(wrapper.find('.ant-layout').hasClass('ant-layout-has-sider')).toBe(false);
|
expect(container.querySelector('.ant-layout').className.includes('ant-layout-has-sider')).toBe(
|
||||||
|
false,
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('render correct with Tooltip', () => {
|
it('render correct with Tooltip', () => {
|
||||||
jest.useFakeTimers();
|
jest.useFakeTimers();
|
||||||
const wrapper = mount(
|
const { container, rerender } = render(
|
||||||
<Sider collapsible collapsed={false}>
|
<Sider collapsible collapsed={false}>
|
||||||
<Menu mode="inline">
|
<Menu mode="inline">
|
||||||
<Menu.Item key="1">
|
<Menu.Item key="1">
|
||||||
@ -204,19 +226,27 @@ describe('Layout', () => {
|
|||||||
</Sider>,
|
</Sider>,
|
||||||
);
|
);
|
||||||
|
|
||||||
wrapper.find('.ant-menu-item').hostNodes().simulate('mouseenter');
|
fireEvent.mouseEnter(container.querySelector('.ant-menu-item'));
|
||||||
jest.runAllTimers();
|
act(() => {
|
||||||
wrapper.update();
|
jest.runAllTimers();
|
||||||
expect(wrapper.find('.ant-tooltip-inner').length).toBeFalsy();
|
});
|
||||||
wrapper.find('.ant-menu-item').hostNodes().simulate('mouseout');
|
expect(container.querySelectorAll('.ant-tooltip-inner').length).toBeFalsy();
|
||||||
jest.runAllTimers();
|
|
||||||
wrapper.update();
|
|
||||||
|
|
||||||
wrapper.setProps({ collapsed: true });
|
rerender(
|
||||||
wrapper.find('.ant-menu-item').hostNodes().simulate('mouseenter');
|
<Sider collapsible collapsed>
|
||||||
jest.runAllTimers();
|
<Menu mode="inline">
|
||||||
wrapper.update();
|
<Menu.Item key="1">
|
||||||
expect(wrapper.find('.ant-tooltip-inner').length).toBeTruthy();
|
<Icon type="user" />
|
||||||
|
<span>Light</span>
|
||||||
|
</Menu.Item>
|
||||||
|
</Menu>
|
||||||
|
</Sider>,
|
||||||
|
);
|
||||||
|
fireEvent.mouseEnter(container.querySelector('.ant-menu-item'));
|
||||||
|
act(() => {
|
||||||
|
jest.runAllTimers();
|
||||||
|
});
|
||||||
|
expect(container.querySelectorAll('.ant-tooltip-inner').length).toBeTruthy();
|
||||||
|
|
||||||
jest.useRealTimers();
|
jest.useRealTimers();
|
||||||
});
|
});
|
||||||
@ -236,7 +266,7 @@ describe('Sider', () => {
|
|||||||
it('should trigger onBreakpoint', async () => {
|
it('should trigger onBreakpoint', async () => {
|
||||||
const onBreakpoint = jest.fn();
|
const onBreakpoint = jest.fn();
|
||||||
|
|
||||||
mount(
|
render(
|
||||||
<Sider breakpoint="md" onBreakpoint={onBreakpoint}>
|
<Sider breakpoint="md" onBreakpoint={onBreakpoint}>
|
||||||
Sider
|
Sider
|
||||||
</Sider>,
|
</Sider>,
|
||||||
@ -245,7 +275,7 @@ describe('Sider', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should warning if use `inlineCollapsed` with menu', () => {
|
it('should warning if use `inlineCollapsed` with menu', () => {
|
||||||
mount(
|
render(
|
||||||
<Sider collapsible>
|
<Sider collapsible>
|
||||||
<Menu mode="inline" inlineCollapsed />
|
<Menu mode="inline" inlineCollapsed />
|
||||||
</Sider>,
|
</Sider>,
|
||||||
@ -256,7 +286,7 @@ describe('Sider', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('zeroWidthTriggerStyle should work', () => {
|
it('zeroWidthTriggerStyle should work', () => {
|
||||||
const wrapper = mount(
|
const { container } = render(
|
||||||
<Sider collapsedWidth={0} collapsible zeroWidthTriggerStyle={{ background: '#F96' }}>
|
<Sider collapsedWidth={0} collapsible zeroWidthTriggerStyle={{ background: '#F96' }}>
|
||||||
<Menu theme="dark" mode="inline" defaultSelectedKeys={['1']}>
|
<Menu theme="dark" mode="inline" defaultSelectedKeys={['1']}>
|
||||||
<Menu.Item key="1">
|
<Menu.Item key="1">
|
||||||
@ -266,13 +296,13 @@ describe('Sider', () => {
|
|||||||
</Menu>
|
</Menu>
|
||||||
</Sider>,
|
</Sider>,
|
||||||
);
|
);
|
||||||
expect(wrapper.find('.ant-layout-sider-zero-width-trigger').props().style).toEqual({
|
expect(
|
||||||
background: '#F96',
|
container.querySelector('.ant-layout-sider-zero-width-trigger').style.background,
|
||||||
});
|
).toEqual('rgb(255, 153, 102)');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should be able to customize zero width trigger by trigger prop', () => {
|
it('should be able to customize zero width trigger by trigger prop', () => {
|
||||||
const wrapper = mount(
|
const { container } = render(
|
||||||
<Sider collapsedWidth={0} collapsible trigger={<span className="my-trigger" />}>
|
<Sider collapsedWidth={0} collapsible trigger={<span className="my-trigger" />}>
|
||||||
<Menu theme="dark" mode="inline" defaultSelectedKeys={['1']}>
|
<Menu theme="dark" mode="inline" defaultSelectedKeys={['1']}>
|
||||||
<Menu.Item key="1">
|
<Menu.Item key="1">
|
||||||
@ -282,7 +312,9 @@ describe('Sider', () => {
|
|||||||
</Menu>
|
</Menu>
|
||||||
</Sider>,
|
</Sider>,
|
||||||
);
|
);
|
||||||
expect(wrapper.find('.ant-layout-sider-zero-width-trigger').find('.my-trigger').length).toBe(1);
|
expect(
|
||||||
|
container.querySelector('.ant-layout-sider-zero-width-trigger').querySelector('.my-trigger'),
|
||||||
|
).toBeTruthy();
|
||||||
});
|
});
|
||||||
|
|
||||||
['Layout', 'Header', 'Footer', 'Sider'].forEach(tag => {
|
['Layout', 'Header', 'Footer', 'Sider'].forEach(tag => {
|
||||||
@ -292,7 +324,7 @@ describe('Sider', () => {
|
|||||||
const onSelect = jest.fn();
|
const onSelect = jest.fn();
|
||||||
const Component = ComponentMap[tag];
|
const Component = ComponentMap[tag];
|
||||||
|
|
||||||
mount(
|
render(
|
||||||
<Component onSelect={onSelect} ref={ref}>
|
<Component onSelect={onSelect} ref={ref}>
|
||||||
{tag}
|
{tag}
|
||||||
</Component>,
|
</Component>,
|
||||||
|
Loading…
Reference in New Issue
Block a user