diff --git a/.husky/pre-commit b/.husky/pre-commit
deleted file mode 100755
index 7d0de5da..00000000
--- a/.husky/pre-commit
+++ /dev/null
@@ -1,4 +0,0 @@
-#!/usr/bin/env sh
-. "$(dirname -- "$0")/_/husky.sh"
-
-lint-staged
diff --git a/tests/index.spec.tsx b/tests/index.spec.tsx
index 206f81e2..0113f018 100644
--- a/tests/index.spec.tsx
+++ b/tests/index.spec.tsx
@@ -1,7 +1,8 @@
/* eslint-disable react/no-render-return-value, max-classes-per-file, func-names, no-console */
-import { render } from '@testing-library/react';
+import { fireEvent, render } from '@testing-library/react';
import type { ReactWrapper } from 'enzyme';
import { mount } from 'enzyme';
+import { Provider } from 'rc-motion';
import KeyCode from 'rc-util/lib/KeyCode';
import React, { cloneElement, useEffect } from 'react';
import { act } from 'react-dom/test-utils';
@@ -9,11 +10,21 @@ import type { DialogProps } from '../src';
import Dialog from '../src';
describe('dialog', () => {
+ async function runFakeTimer() {
+ for (let i = 0; i < 100; i += 1) {
+ await act(async () => {
+ jest.advanceTimersByTime(100);
+ await Promise.resolve();
+ });
+ }
+ }
+
beforeEach(() => {
jest.useFakeTimers();
});
afterEach(() => {
+ jest.clearAllTimers();
jest.useRealTimers();
});
@@ -251,15 +262,17 @@ describe('dialog', () => {
});
it('trap focus after shift-tabbing', () => {
- const wrapper = mount(, { attachTo: document.body });
- wrapper.find('.rc-dialog-wrap').simulate('keyDown', {
+ render();
+
+ document.querySelector('.rc-dialog > div').focus();
+
+ fireEvent.keyDown(document.querySelector('.rc-dialog-wrap'), {
keyCode: KeyCode.TAB,
+ key: 'Tab',
shiftKey: true,
});
- const sentinelEnd = document.querySelectorAll('.rc-dialog-content + div')[0];
+ const sentinelEnd = document.querySelector('.rc-dialog-content + div');
expect(document.activeElement).toBe(sentinelEnd);
-
- wrapper.unmount();
});
});
@@ -506,15 +519,32 @@ describe('dialog', () => {
});
describe('afterOpenChange', () => {
- it('should trigger afterOpenChange when visible changed', () => {
+ beforeEach(() => {
+ jest.useFakeTimers();
+ });
+
+ afterEach(() => {
+ jest.clearAllTimers();
+ jest.useRealTimers();
+ });
+
+ it('should trigger afterOpenChange when visible changed', async () => {
const afterOpenChange = jest.fn();
- const wrapper = mount();
- jest.runAllTimers();
+ const Demo = (props: any) => (
+
+
+
+ );
- wrapper.setProps({ visible: false });
- jest.runAllTimers();
+ const { rerender } = render();
+ await runFakeTimer();
+ expect(afterOpenChange).toHaveBeenCalledWith(true);
+ expect(afterOpenChange).toHaveBeenCalledTimes(1);
+ rerender();
+ await runFakeTimer();
+ expect(afterOpenChange).toHaveBeenCalledWith(false);
expect(afterOpenChange).toHaveBeenCalledTimes(2);
});
});
diff --git a/tests/setup.js b/tests/setup.js
index 9d51ef44..fa14f0a0 100644
--- a/tests/setup.js
+++ b/tests/setup.js
@@ -1,5 +1,16 @@
/* eslint-disable no-console */
-global.requestAnimationFrame = cb => setTimeout(cb, 0);
+global.requestAnimationFrame = (cb) => {
+ return global.setTimeout(cb, 0);
+};
+global.cancelAnimationFrame = (cb) => {
+ return global.clearTimeout(cb, 0);
+};
+window.requestAnimationFrame = (cb) => {
+ return window.setTimeout(cb, 0);
+};
+window.cancelAnimationFrame = (cb) => {
+ return window.clearTimeout(cb, 0);
+};
const originError = console.error;
const ignoreList = [
@@ -7,7 +18,7 @@ const ignoreList = [
'Warning: unmountComponentAtNode():',
];
console.error = (...args) => {
- if (ignoreList.some(str => args[0].includes(str))) {
+ if (ignoreList.some((str) => args[0].includes(str))) {
return;
}