Skip to content

Commit 61a3286

Browse files
authored
feat: update react and react-dom version to 18+ (#431)
* feat: update react and react-dom version to 18+ * tests: enzyme => @testing-library/react
1 parent 065ac98 commit 61a3286

File tree

5 files changed

+112
-85
lines changed

5 files changed

+112
-85
lines changed

package.json

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -43,23 +43,21 @@
4343
"rc-trigger": "^5.3.1"
4444
},
4545
"devDependencies": {
46+
"@testing-library/react": "^13.4.0",
4647
"@types/jest": "^26.0.0",
47-
"@types/react": "^17.0.15",
48-
"@types/react-dom": "^16.9.2",
48+
"@types/react": "^18.0.26",
49+
"@types/react-dom": "^18.0.10",
4950
"@types/warning": "^3.0.0",
5051
"cross-env": "^7.0.0",
5152
"dumi": "^2.1.1",
52-
"enzyme": "^3.10.0",
53-
"enzyme-adapter-react-16": "^1.15.1",
54-
"enzyme-to-json": "^3.4.3",
5553
"eslint": "^7.1.0",
5654
"father": "^2.23.1",
5755
"father-build": "^1.18.6",
5856
"gh-pages": "^3.1.0",
5957
"less": "^3.11.1",
6058
"np": "^7.1.0",
61-
"react": "^16.10.2",
62-
"react-dom": "^16.10.2",
59+
"react": "^18.2.0",
60+
"react-dom": "^18.2.0",
6361
"typescript": "^4.0.5"
6462
},
6563
"maintainers": [
Lines changed: 70 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,27 @@
1-
import React from 'react';
2-
import { mount } from 'enzyme';
1+
import React, { useState } from 'react';
2+
import { render, fireEvent } from '@testing-library/react';
33
import Tooltip from '../src';
44

5-
const verifyContent = (wrapper, content) => {
6-
expect(wrapper.find('.x-content').text()).toBe(content);
7-
expect(wrapper.find('Trigger').instance().getPopupDomNode()).toBeTruthy();
8-
wrapper.find('.target').simulate('click');
9-
expect(wrapper.find('.rc-tooltip').hostNodes().hasClass('rc-tooltip-hidden')).toBe(true);
5+
const verifyContent = (wrapper: HTMLElement, content: string) => {
6+
expect(wrapper.querySelector('.x-content').textContent).toBe(content);
7+
fireEvent.click(wrapper.querySelector('.target'));
8+
expect(wrapper.querySelector('.rc-tooltip').classList.contains('rc-tooltip-hidden')).toBe(true);
109
};
1110

1211
describe('rc-tooltip', () => {
1312
window.requestAnimationFrame = window.setTimeout;
1413
window.cancelAnimationFrame = window.clearTimeout;
14+
beforeEach(() => {
15+
jest.useFakeTimers();
16+
});
17+
18+
afterEach(() => {
19+
jest.useRealTimers();
20+
});
1521

1622
describe('shows and hides itself on click', () => {
1723
it('using an element overlay', () => {
18-
const wrapper = mount(
24+
const { container } = render(
1925
<Tooltip
2026
trigger={['click']}
2127
placement="left"
@@ -24,12 +30,12 @@ describe('rc-tooltip', () => {
2430
<div className="target">Click this</div>
2531
</Tooltip>,
2632
);
27-
wrapper.find('.target').simulate('click');
28-
verifyContent(wrapper, 'Tooltip content');
33+
fireEvent.click(container.querySelector('.target'));
34+
verifyContent(container, 'Tooltip content');
2935
});
3036

3137
it('using a function overlay', () => {
32-
const wrapper = mount(
38+
const { container } = render(
3339
<Tooltip
3440
trigger={['click']}
3541
placement="left"
@@ -38,13 +44,13 @@ describe('rc-tooltip', () => {
3844
<div className="target">Click this</div>
3945
</Tooltip>,
4046
);
41-
wrapper.find('.target').simulate('click');
42-
verifyContent(wrapper, 'Tooltip content');
47+
fireEvent.click(container.querySelector('.target'));
48+
verifyContent(container, 'Tooltip content');
4349
});
4450

4551
// https://github.com/ant-design/ant-design/pull/23155
4652
it('using style inner style', () => {
47-
const wrapper = mount(
53+
const { container } = render(
4854
<Tooltip
4955
trigger={['click']}
5056
placement="left"
@@ -54,13 +60,15 @@ describe('rc-tooltip', () => {
5460
<div className="target">Click this</div>
5561
</Tooltip>,
5662
);
57-
wrapper.find('.target').simulate('click');
58-
expect(wrapper.find('.rc-tooltip-inner').props().style).toEqual({ background: 'red' });
63+
fireEvent.click(container.querySelector('.target'));
64+
expect(
65+
(container.querySelector('.rc-tooltip-inner') as HTMLElement).style.background,
66+
).toEqual('red');
5967
});
6068

6169
it('access of ref', () => {
6270
const domRef = React.createRef();
63-
mount(
71+
render(
6472
<Tooltip
6573
trigger={['click']}
6674
placement="left"
@@ -74,14 +82,13 @@ describe('rc-tooltip', () => {
7482
});
7583
});
7684
describe('destroyTooltipOnHide', () => {
77-
const destroyVerifyContent = (wrapper, content) => {
78-
wrapper.find('.target').simulate('click');
79-
expect(wrapper.find('.x-content').text()).toBe(content);
80-
expect(wrapper.find('Trigger').instance().getPopupDomNode()).toBeTruthy();
81-
wrapper.find('.target').simulate('click');
85+
const destroyVerifyContent = (wrapper: HTMLElement, content: string) => {
86+
fireEvent.click(wrapper.querySelector('.target'));
87+
expect(wrapper.querySelector('.x-content').textContent).toBe(content);
88+
fireEvent.click(wrapper.querySelector('.target'));
8289
};
8390
it('default value', () => {
84-
const wrapper = mount(
91+
const { container } = render(
8592
<Tooltip
8693
trigger={['click']}
8794
placement="left"
@@ -90,11 +97,11 @@ describe('rc-tooltip', () => {
9097
<div className="target">Click this</div>
9198
</Tooltip>,
9299
);
93-
wrapper.find('.target').simulate('click');
94-
verifyContent(wrapper, 'Tooltip content');
100+
fireEvent.click(container.querySelector('.target'));
101+
verifyContent(container, 'Tooltip content');
95102
});
96103
it('should only remove tooltip when value is true', () => {
97-
const wrapper = mount(
104+
const { container } = render(
98105
<Tooltip
99106
destroyTooltipOnHide
100107
trigger={['click']}
@@ -104,11 +111,11 @@ describe('rc-tooltip', () => {
104111
<div className="target">Click this</div>
105112
</Tooltip>,
106113
);
107-
destroyVerifyContent(wrapper, 'Tooltip content');
108-
expect(wrapper.html()).toBe('<div class="target">Click this</div><div></div>');
114+
destroyVerifyContent(container, 'Tooltip content');
115+
expect(container.innerHTML).toBe('<div class="target">Click this</div><div></div>');
109116
});
110117
it('should only remove tooltip when keepParent is true', () => {
111-
const wrapper = mount(
118+
const { container } = render(
112119
<Tooltip
113120
destroyTooltipOnHide={{ keepParent: true }}
114121
trigger={['click']}
@@ -118,11 +125,11 @@ describe('rc-tooltip', () => {
118125
<div className="target">Click this</div>
119126
</Tooltip>,
120127
);
121-
destroyVerifyContent(wrapper, 'Tooltip content');
122-
expect(wrapper.html()).toBe('<div class="target">Click this</div><div></div>');
128+
destroyVerifyContent(container, 'Tooltip content');
129+
expect(container.innerHTML).toBe('<div class="target">Click this</div><div></div>');
123130
});
124131
it('should remove tooltip and container when keepParent is false', () => {
125-
const wrapper = mount(
132+
const { container } = render(
126133
<Tooltip
127134
destroyTooltipOnHide={{ keepParent: false }}
128135
trigger={['click']}
@@ -132,48 +139,31 @@ describe('rc-tooltip', () => {
132139
<div className="target">Click this</div>
133140
</Tooltip>,
134141
);
135-
destroyVerifyContent(wrapper, 'Tooltip content');
136-
expect(wrapper.html()).toBe('<div class="target">Click this</div>');
142+
destroyVerifyContent(container, 'Tooltip content');
143+
expect(container.innerHTML).toBe('<div class="target">Click this</div>');
137144
});
138145
});
139146

140-
// This is only test for motion pass to internal rc-trigger
141-
// It's safe to remove since meaningless to rc-tooltip if refactor
142-
it('should motion props work', () => {
143-
const wrapper = mount(
144-
<Tooltip overlay="Light" motion={{ motionName: 'bamboo-is-light' }}>
145-
<span>Bamboo</span>
146-
</Tooltip>,
147-
);
148-
149-
expect(wrapper.find('Trigger').props().popupMotion).toEqual({ motionName: 'bamboo-is-light' });
150-
});
151-
152147
it('zIndex', () => {
153148
jest.useFakeTimers();
154149

155-
const wrapper = mount(
150+
const { container } = render(
156151
<Tooltip trigger={['click']} zIndex={903} overlay="Bamboo">
157152
<div className="target">Light</div>
158153
</Tooltip>,
159154
);
160-
wrapper.find('.target').simulate('click');
155+
fireEvent.click(container.querySelector('.target'));
161156

162157
jest.runAllTimers();
163-
wrapper.update();
164158

165-
expect(wrapper.find('div.rc-tooltip').prop('style')).toEqual(
166-
expect.objectContaining({
167-
zIndex: 903,
168-
}),
169-
);
159+
expect((container.querySelector('div.rc-tooltip') as HTMLElement).style.zIndex).toBe('903');
170160

171161
jest.useRealTimers();
172162
});
173163

174164
describe('showArrow', () => {
175165
it('should show tooltip arrow default', () => {
176-
const wrapper = mount(
166+
const { container } = render(
177167
<Tooltip
178168
destroyTooltipOnHide={{ keepParent: false }}
179169
trigger={['click']}
@@ -183,13 +173,13 @@ describe('rc-tooltip', () => {
183173
<div className="target">Click this</div>
184174
</Tooltip>,
185175
);
186-
wrapper.find('.target').simulate('click');
187-
expect(wrapper.find('.rc-tooltip-content').html()).toBe(
176+
fireEvent.click(container.querySelector('.target'));
177+
expect(container.querySelector('.rc-tooltip-content').outerHTML).toBe(
188178
'<div class="rc-tooltip-content"><div class="rc-tooltip-arrow"></div><div class="rc-tooltip-inner" role="tooltip"><strong class="x-content">Tooltip content</strong></div></div>',
189179
);
190180
});
191181
it('should show tooltip arrow when showArrow is true', () => {
192-
const wrapper = mount(
182+
const { container } = render(
193183
<Tooltip
194184
destroyTooltipOnHide={{ keepParent: false }}
195185
trigger={['click']}
@@ -200,13 +190,13 @@ describe('rc-tooltip', () => {
200190
<div className="target">Click this</div>
201191
</Tooltip>,
202192
);
203-
wrapper.find('.target').simulate('click');
204-
expect(wrapper.find('.rc-tooltip-content').html()).toBe(
193+
fireEvent.click(container.querySelector('.target'));
194+
expect(container.querySelector('.rc-tooltip-content').outerHTML).toBe(
205195
'<div class="rc-tooltip-content"><div class="rc-tooltip-arrow"></div><div class="rc-tooltip-inner" role="tooltip"><strong class="x-content">Tooltip content</strong></div></div>',
206196
);
207197
});
208198
it('should hide tooltip arrow when showArrow is false', () => {
209-
const wrapper = mount(
199+
const { container } = render(
210200
<Tooltip
211201
destroyTooltipOnHide={{ keepParent: false }}
212202
trigger={['click']}
@@ -217,23 +207,32 @@ describe('rc-tooltip', () => {
217207
<div className="target">Click this</div>
218208
</Tooltip>,
219209
);
220-
wrapper.find('.target').simulate('click');
221-
expect(wrapper.find('.rc-tooltip-content').html()).toBe(
210+
fireEvent.click(container.querySelector('.target'));
211+
expect(container.querySelector('.rc-tooltip-content').outerHTML).toBe(
222212
'<div class="rc-tooltip-content"><div class="rc-tooltip-inner" role="tooltip"><strong class="x-content">Tooltip content</strong></div></div>',
223213
);
224214
});
225215
});
226216

227217
it('visible', () => {
228-
const wrapper = mount(
229-
<Tooltip overlay={<strong className="x-content">Tooltip content</strong>} visible={false}>
230-
<div />
231-
</Tooltip>,
232-
);
218+
const App = () => {
219+
const [open, setOpen] = useState(false);
220+
return (
221+
<Tooltip overlay={<strong className="x-content">Tooltip content</strong>} visible={open}>
222+
<div
223+
className="target"
224+
onClick={() => {
225+
setOpen(true);
226+
}}
227+
/>
228+
</Tooltip>
229+
);
230+
};
231+
const { container } = render(<App />);
233232

234-
expect(wrapper.exists('.x-content')).toBeFalsy();
233+
expect(container.querySelector('.x-content')).toBeFalsy();
235234

236-
wrapper.setProps({ visible: true });
237-
expect(wrapper.exists('.x-content')).toBeTruthy();
235+
fireEvent.click(container.querySelector('.target'));
236+
expect(container.querySelector('.x-content')).toBeTruthy();
238237
});
239238
});
File renamed without changes.

tests/setup.js

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,38 @@
1-
global.requestAnimationFrame = global.requestAnimationFrame || function requestAnimationFrame(cb) {
2-
return setTimeout(cb, 0);
3-
};
1+
const React = require('react');
2+
const util = require('util');
43

5-
const Enzyme = require('enzyme');
6-
const Adapter = require('enzyme-adapter-react-16');
4+
// eslint-disable-next-line no-console
5+
console.log('Current React Version:', React.version);
76

8-
Enzyme.configure({ adapter: new Adapter() });
7+
/* eslint-disable global-require */
8+
if (typeof window !== 'undefined') {
9+
global.window.resizeTo = (width, height) => {
10+
global.window.innerWidth = width || global.window.innerWidth;
11+
global.window.innerHeight = height || global.window.innerHeight;
12+
global.window.dispatchEvent(new Event('resize'));
13+
};
14+
global.window.scrollTo = () => {};
15+
// ref: https://github.com/ant-design/ant-design/issues/18774
16+
if (!window.matchMedia) {
17+
Object.defineProperty(global.window, 'matchMedia', {
18+
writable: true,
19+
configurable: true,
20+
value: jest.fn((query) => ({
21+
matches: query.includes('max-width'),
22+
addListener: jest.fn(),
23+
removeListener: jest.fn(),
24+
})),
25+
});
26+
}
27+
28+
// Fix css-animation or rc-motion deps on these
29+
// https://github.com/react-component/motion/blob/9c04ef1a210a4f3246c9becba6e33ea945e00669/src/util/motion.ts#L27-L35
30+
// https://github.com/yiminghe/css-animation/blob/a5986d73fd7dfce75665337f39b91483d63a4c8c/src/Event.js#L44
31+
window.AnimationEvent = window.AnimationEvent || window.Event;
32+
window.TransitionEvent = window.TransitionEvent || window.Event;
33+
34+
// ref: https://jestjs.io/docs/manual-mocks#mocking-methods-which-are-not-implemented-in-jsdom
35+
// ref: https://github.com/jsdom/jsdom/issues/2524
36+
Object.defineProperty(window, 'TextEncoder', { writable: true, value: util.TextEncoder });
37+
Object.defineProperty(window, 'TextDecoder', { writable: true, value: util.TextDecoder });
38+
}

tsconfig.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,5 @@
1313
"rc-tooltip": ["src/index.tsx"]
1414
}
1515
},
16-
"include": [".dumi/**/*", ".dumirc.ts", "./src/**/*.ts", "./src/**/*.tsx", "./docs/**/*.tsx"]
16+
"include": [".dumi/**/*", ".dumirc.ts", "./src/**/*.ts", "./src/**/*.tsx", "./docs/**/*.tsx", "./tests/**/*.tsx"]
1717
}

0 commit comments

Comments
 (0)