Skip to content

Commit

Permalink
fix: Form in React 18 StrictMode (ant-design#35096)
Browse files Browse the repository at this point in the history
* test: fix with react 18

* fix: Form in StrictMode

* test: clean up

* test: clean up

* chore: bump rc-motion version

* chore: fix test case logic

* test: back of it

* test: back missing test case
  • Loading branch information
zombieJ authored Apr 19, 2022
1 parent 50a6a44 commit b8eaecb
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 55 deletions.
4 changes: 1 addition & 3 deletions components/form/__tests__/index.test.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import React, { Component, useState } from 'react';
import { mount } from 'enzyme';
import { act } from 'react-dom/test-utils';
import { render as testingRender } from '@testing-library/react';
import scrollIntoView from 'scroll-into-view-if-needed';
import Form from '..';
import * as Util from '../util';
Expand Down Expand Up @@ -128,8 +127,7 @@ describe('Form', () => {
);
};

// FIXME: @zombieJ React 18 StrictMode
const { container } = testingRender(<Demo />);
const { container } = render(<Demo />);
await change(container, 0, '1', true);
expect(container.querySelector('.ant-form-item-explain').textContent).toEqual('aaa');
await change(container, 0, '2', true);
Expand Down
3 changes: 1 addition & 2 deletions components/form/__tests__/list.test.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import React from 'react';
import { act } from 'react-dom/test-utils';
import { render as testingRender } from '@testing-library/react';
import Form from '..';
import Input from '../../input';
import Button from '../../button';
Expand All @@ -16,7 +15,7 @@ describe('Form.List', () => {
it(name, async () => {
jest.useFakeTimers();

const { container } = testingRender(
const { container } = render(
<Form>
<Form.List name="list">
{(fields, { add, remove }) => (
Expand Down
11 changes: 6 additions & 5 deletions components/form/hooks/useFrameState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,14 @@ export default function useFrameState<ValueType>(
const batchRef = useRef<Updater<ValueType>[]>([]);
const destroyRef = useRef(false);

React.useEffect(
() => () => {
React.useEffect(() => {
destroyRef.current = false;
return () => {
destroyRef.current = true;
raf.cancel(frameRef.current!);
},
[],
);
frameRef.current = null;
};
}, []);

function setFrameValue(updater: Updater<ValueType>) {
if (destroyRef.current) {
Expand Down
97 changes: 53 additions & 44 deletions components/upload/__tests__/upload.test.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* eslint-disable react/no-string-refs, react/prefer-es6-class */
import React from 'react';
import { mount, originMount } from 'enzyme';
import { mount } from 'enzyme';
import { act } from 'react-dom/test-utils';
import produce from 'immer';
import { cloneDeep } from 'lodash';
Expand Down Expand Up @@ -450,38 +450,41 @@ describe('Upload', () => {
});

// https://github.com/ant-design/ant-design/issues/18902
it('should not abort uploading until return value of onRemove is resolved as true', done => {
let wrapper;

const props = {
onRemove: async () => {
await act(async () => {
await sleep(100);
wrapper.update();
expect(props.fileList).toHaveLength(1);
expect(props.fileList[0].status).toBe('uploading');
});

return true;
},
fileList: [
{
uid: '-1',
name: 'foo.png',
status: 'uploading',
url: 'http://www.baidu.com/xxx.png',
},
],
onChange: () => {
expect(props.fileList).toHaveLength(1);
expect(props.fileList[0].status).toBe('removed');
done();
},
it('should not abort uploading until return value of onRemove is resolved as true', async () => {
const file = {
uid: '-1',
name: 'foo.png',
status: 'uploading',
url: 'http://www.baidu.com/xxx.png',
};

wrapper = mount(<Upload {...props} />);
let removePromise;

wrapper.find('div.ant-upload-list-item .anticon-delete').simulate('click');
const onRemove = () =>
new Promise(resolve => {
expect(file.status).toBe('uploading');
removePromise = resolve;
});
const onChange = jest.fn();

const { container } = render(
<Upload fileList={[file]} onChange={onChange} onRemove={onRemove} />,
);
fireEvent.click(container.querySelector('div.ant-upload-list-item .anticon-delete'));

// uploadStart is a batch work which we need wait for react act
await act(async () => {
await Promise.resolve();
});

// Delay return true for remove
await sleep(100);
await act(async () => {
await removePromise(true);
});

expect(onChange).toHaveBeenCalled();
expect(file.status).toBe('removed');
});

it('should not stop download when return use onDownload', done => {
Expand Down Expand Up @@ -874,27 +877,33 @@ describe('Upload', () => {
expect(onChange.mock.calls[0][0].fileList).toHaveLength(1);
});

// FIXME: @zombieJ React 18 StrictMode
// https://github.com/ant-design/ant-design/issues/33819
it('should show the animation of the upload children leaving when the upload children becomes null', async () => {
const wrapper = originMount(
jest.useFakeTimers();

const { container, rerender } = render(
<Upload listType="picture-card">
<button type="button">upload</button>
</Upload>,
);
wrapper.setProps({ children: null });
expect(wrapper.find('.ant-upload-select-picture-card').getDOMNode().style.display).not.toBe(
'none',
);
await act(async () => {
await sleep(100);
wrapper
.find('.ant-upload-select-picture-card')
.getDOMNode()
.dispatchEvent(new Event('animationend'));
await sleep(20);

rerender(<Upload listType="picture-card" />);
expect(container.querySelector('.ant-upload-select-picture-card')).not.toHaveStyle({
display: 'none',
});

// Motion leave status change: start > active
act(() => {
jest.runAllTimers();
});
expect(wrapper.find('.ant-upload-select-picture-card').getDOMNode().style.display).toBe('none');

fireEvent.animationEnd(container.querySelector('.ant-upload-select-picture-card'));

expect(container.querySelector('.ant-upload-select-picture-card')).toHaveStyle({
display: 'none',
});

jest.useRealTimers();
});

it('<Upload /> should pass <UploadList /> prefixCls', async () => {
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@
"rc-input-number": "~7.3.0",
"rc-mentions": "~1.7.0",
"rc-menu": "~9.5.5",
"rc-motion": "^2.4.4",
"rc-motion": "^2.5.1",
"rc-notification": "~4.6.0",
"rc-pagination": "~3.1.9",
"rc-picker": "~2.6.4",
Expand Down

0 comments on commit b8eaecb

Please sign in to comment.