Skip to content

Commit 149568c

Browse files
authored
test: migrate switch tests to testing library (#164)
1 parent 552d320 commit 149568c

3 files changed

Lines changed: 81 additions & 67 deletions

File tree

package.json

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -43,22 +43,19 @@
4343
]
4444
},
4545
"dependencies": {
46-
"@rc-component/util": "^1.3.0",
46+
"@rc-component/util": "^1.11.1",
4747
"clsx": "^2.1.1"
4848
},
4949
"devDependencies": {
50-
"@rc-component/father-plugin": "^2.0.0",
50+
"@rc-component/father-plugin": "^2.2.0",
5151
"@rc-component/np": "^1.0.3",
52+
"@testing-library/react": "^16.0.1",
5253
"@types/jest": "^29.4.0",
5354
"@types/node": "^24.5.2",
5455
"@types/react": "^19.1.14",
5556
"@types/react-dom": "^19.1.9",
5657
"@umijs/fabric": "^3.0.0",
57-
"cheerio": "1.0.0-rc.12",
5858
"dumi": "^2.0.0",
59-
"enzyme": "^3.0.0",
60-
"enzyme-adapter-react-16": "^1.0.1",
61-
"enzyme-to-json": "^3.0.0",
6259
"eslint": "^8.55.0",
6360
"eslint-plugin-jest": "^27.6.0",
6461
"eslint-plugin-unicorn": "^49.0.0",
@@ -68,9 +65,8 @@
6865
"less": "^4.1.3",
6966
"lint-staged": "^15.1.0",
7067
"prettier": "^3.1.0",
71-
"react": "^16.0.0",
72-
"react-dom": "^16.0.0",
73-
"react-test-renderer": "^16.0.0",
68+
"react": "^18.0.0",
69+
"react-dom": "^18.0.0",
7470
"umi-test": "^1.9.7"
7571
},
7672
"peerDependencies": {

src/index.tsx

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,17 @@
11
import * as React from 'react';
22
import { clsx } from 'clsx';
3-
import useControlledState from '@rc-component/util/lib/hooks/useControlledState';
4-
import KeyCode from '@rc-component/util/lib/KeyCode';
3+
import { KeyCode, useControlledState } from '@rc-component/util';
54

65
export type SwitchChangeEventHandler = (
76
checked: boolean,
87
event: React.MouseEvent<HTMLButtonElement> | React.KeyboardEvent<HTMLButtonElement>,
98
) => void;
109
export type SwitchClickEventHandler = SwitchChangeEventHandler;
1110

12-
interface SwitchProps
13-
extends Omit<React.HTMLAttributes<HTMLButtonElement>, 'onChange' | 'onClick'> {
11+
interface SwitchProps extends Omit<
12+
React.HTMLAttributes<HTMLButtonElement>,
13+
'onChange' | 'onClick'
14+
> {
1415
className?: string;
1516
prefixCls?: string;
1617
disabled?: boolean;

tests/index.spec.js

Lines changed: 71 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
11
import React from 'react';
2-
import KeyCode from '@rc-component/util/lib/KeyCode';
3-
import { mount } from 'enzyme';
2+
import { KeyCode } from '@rc-component/util';
3+
import { fireEvent, render } from '@testing-library/react';
44
import Switch from '..';
55

66
describe('rc-switch', () => {
7+
function keyDownWithWhich(target, which) {
8+
fireEvent.keyDown(target, { keyCode: which });
9+
}
10+
711
function createSwitch(props = {}) {
8-
return mount(
12+
return render(
913
<Switch
1014
checkedChildren={<span className="checked" />}
1115
unCheckedChildren={<span className="unchecked" />}
@@ -15,127 +19,140 @@ describe('rc-switch', () => {
1519
}
1620

1721
it('works', () => {
18-
const wrapper = createSwitch();
19-
expect(wrapper.exists('.unchecked')).toBeTruthy();
20-
wrapper.simulate('click');
21-
expect(wrapper.exists('.checked')).toBeTruthy();
22+
const { getByRole } = createSwitch();
23+
const switchNode = getByRole('switch');
24+
25+
expect(switchNode.getAttribute('aria-checked')).toBe('false');
26+
fireEvent.click(switchNode);
27+
expect(switchNode.getAttribute('aria-checked')).toBe('true');
2228
});
2329

2430
it('should be checked upon right key and unchecked on left key', () => {
25-
const wrapper = createSwitch();
26-
expect(wrapper.exists('.unchecked')).toBeTruthy();
27-
wrapper.simulate('keydown', { which: KeyCode.RIGHT });
28-
expect(wrapper.exists('.checked')).toBeTruthy();
29-
wrapper.simulate('keydown', { which: KeyCode.LEFT });
30-
expect(wrapper.exists('.unchecked')).toBeTruthy();
31+
const { getByRole } = createSwitch();
32+
const switchNode = getByRole('switch');
33+
34+
expect(switchNode.getAttribute('aria-checked')).toBe('false');
35+
keyDownWithWhich(switchNode, KeyCode.RIGHT);
36+
expect(switchNode.getAttribute('aria-checked')).toBe('true');
37+
keyDownWithWhich(switchNode, KeyCode.LEFT);
38+
expect(switchNode.getAttribute('aria-checked')).toBe('false');
3139
});
3240

3341
it('should change from an initial checked state of true to false on click', () => {
3442
const onChange = jest.fn();
35-
const wrapper = createSwitch({ defaultChecked: true, onChange });
36-
expect(wrapper.exists('.checked')).toBeTruthy();
37-
wrapper.simulate('click');
38-
expect(wrapper.exists('.unchecked')).toBeTruthy();
43+
const { getByRole } = createSwitch({ defaultChecked: true, onChange });
44+
const switchNode = getByRole('switch');
45+
46+
expect(switchNode.getAttribute('aria-checked')).toBe('true');
47+
fireEvent.click(switchNode);
48+
expect(switchNode.getAttribute('aria-checked')).toBe('false');
3949
expect(onChange.mock.calls.length).toBe(1);
4050
});
4151

4252
it('should support onClick', () => {
4353
const onClick = jest.fn();
44-
const wrapper = createSwitch({ onClick });
45-
wrapper.simulate('click');
54+
const { getByRole } = createSwitch({ onClick });
55+
const switchNode = getByRole('switch');
56+
57+
fireEvent.click(switchNode);
4658
expect(onClick).toHaveBeenCalledWith(true, expect.objectContaining({ type: 'click' }));
4759
expect(onClick.mock.calls.length).toBe(1);
48-
wrapper.simulate('click');
60+
fireEvent.click(switchNode);
4961
expect(onClick).toHaveBeenCalledWith(false, expect.objectContaining({ type: 'click' }));
5062
expect(onClick.mock.calls.length).toBe(2);
5163
});
5264

5365
it('should not toggle when clicked in a disabled state', () => {
5466
const onChange = jest.fn();
55-
const wrapper = createSwitch({ disabled: true, checked: true, onChange });
56-
expect(wrapper.exists('.checked')).toBeTruthy();
57-
wrapper.simulate('click');
58-
expect(wrapper.exists('.checked')).toBeTruthy();
67+
const { getByRole } = createSwitch({ disabled: true, checked: true, onChange });
68+
const switchNode = getByRole('switch');
69+
70+
expect(switchNode.getAttribute('aria-checked')).toBe('true');
71+
fireEvent.click(switchNode);
72+
expect(switchNode.getAttribute('aria-checked')).toBe('true');
5973
expect(onChange.mock.calls.length).toBe(0);
6074
});
6175

6276
it('should support loading icon node', () => {
63-
const wrapper = mount(<Switch loadingIcon={<span className="extra">loading</span>} />);
64-
expect(wrapper.find('.extra').text()).toBe('loading');
77+
const { container } = render(<Switch loadingIcon={<span className="extra">loading</span>} />);
78+
expect(container.querySelector('.extra').textContent).toBe('loading');
6579
});
6680

6781
it('focus()', () => {
68-
const container = document.createElement('div');
69-
document.body.appendChild(container);
7082
const handleFocus = jest.fn();
7183
const ref = React.createRef();
72-
mount(<Switch ref={ref} onFocus={handleFocus} />, {
73-
attachTo: container,
74-
});
84+
render(<Switch ref={ref} onFocus={handleFocus} />);
85+
7586
ref.current.focus();
87+
expect(document.activeElement).toBe(ref.current);
88+
fireEvent.focus(ref.current);
7689
expect(handleFocus).toHaveBeenCalled();
7790
});
7891

7992
it('blur()', () => {
80-
const container = document.createElement('div');
81-
document.body.appendChild(container);
8293
const handleBlur = jest.fn();
8394
const ref = React.createRef();
84-
mount(<Switch ref={ref} onBlur={handleBlur} />, {
85-
attachTo: container,
86-
});
95+
render(<Switch ref={ref} onBlur={handleBlur} />);
96+
8797
ref.current.focus();
98+
expect(document.activeElement).toBe(ref.current);
8899
ref.current.blur();
100+
expect(document.activeElement).not.toBe(ref.current);
101+
fireEvent.blur(ref.current);
89102
expect(handleBlur).toHaveBeenCalled();
90103
});
91104

92105
describe('autoFocus', () => {
93106
it('basic', () => {
94-
const container = document.createElement('div');
95-
document.body.appendChild(container);
96107
const handleFocus = jest.fn();
97-
mount(<Switch autoFocus onFocus={handleFocus} />, { attachTo: container });
108+
const { getByRole } = render(<Switch autoFocus onFocus={handleFocus} />);
109+
const switchNode = getByRole('switch');
110+
111+
expect(document.activeElement).toBe(switchNode);
112+
fireEvent.focus(switchNode);
98113
expect(handleFocus).toHaveBeenCalled();
99114
});
100115

101116
it('not work when disabled', () => {
102-
const container = document.createElement('div');
103-
document.body.appendChild(container);
104117
const handleFocus = jest.fn();
105-
mount(<Switch autoFocus disabled onFocus={handleFocus} />, { attachTo: container });
118+
render(<Switch autoFocus disabled onFocus={handleFocus} />);
106119
expect(handleFocus).not.toHaveBeenCalled();
107120
});
108121
});
109122

110123
it('disabled', () => {
111-
const wrapper = createSwitch({ disabled: true });
112-
expect(wrapper.exists('.unchecked')).toBeTruthy();
113-
wrapper.simulate('keydown', { keyCode: 39 });
114-
expect(wrapper.exists('.unchecked')).toBeTruthy();
124+
const { getByRole } = createSwitch({ disabled: true });
125+
const switchNode = getByRole('switch');
126+
127+
expect(switchNode.getAttribute('aria-checked')).toBe('false');
128+
keyDownWithWhich(switchNode, KeyCode.RIGHT);
129+
expect(switchNode.getAttribute('aria-checked')).toBe('false');
115130
});
116131

117132
it('onMouseUp', () => {
118133
const onMouseUp = jest.fn();
119-
const wrapper = createSwitch({ onMouseUp });
120-
wrapper.simulate('mouseup');
134+
const { getByRole } = createSwitch({ onMouseUp });
135+
136+
fireEvent.mouseUp(getByRole('switch'));
121137
expect(onMouseUp).toHaveBeenCalled();
122138
});
123139

124140
it('disabled should click not to change', () => {
125141
const onChange = jest.fn();
126142
const onClick = jest.fn();
127-
const wrapper = createSwitch({ disabled: true, onChange, onClick, checked: true });
143+
const { getByRole } = createSwitch({ disabled: true, onChange, onClick, checked: true });
128144

129-
wrapper.simulate('click');
145+
fireEvent.click(getByRole('switch'));
130146
expect(onChange).not.toHaveBeenCalled();
131147
});
132148
it('support classnames and styles', () => {
133-
const wrapper = createSwitch({
149+
const { container } = createSwitch({
134150
classNames: { content: 'custom-content' },
135151
styles: { content: { background: 'red' } },
136152
});
137-
const contentElement = wrapper.find('.custom-content').at(0);
138-
expect(contentElement.exists()).toBe(true);
139-
expect(contentElement.prop('style')).toEqual({ background: 'red' });
153+
const contentElement = container.querySelector('.custom-content');
154+
155+
expect(contentElement).toBeTruthy();
156+
expect(contentElement.style.background).toBe('red');
140157
});
141158
});

0 commit comments

Comments
 (0)