diff --git a/src/__tests__/event-wrapper-nesting.js b/src/__tests__/event-wrapper-nesting.js new file mode 100644 index 00000000..f05d1345 --- /dev/null +++ b/src/__tests__/event-wrapper-nesting.js @@ -0,0 +1,50 @@ +import * as React from 'react' +import {render, fireEvent, getConfig} from '../' + +const {useState, useEffect, useRef} = React + +const dispatchDOMEvent = (target, type) => + getConfig().eventWrapper(() => + target.dispatchEvent(new Event(type, {bubbles: true})), + ) + +test('does not warn about act when there are nested acts', () => { + function Fixture() { + const [open, setOpen] = useState(false) + const [fromEffect, setFromEffect] = useState(0) + const [fromEvent, setFromEvent] = useState(0) + const targetRef = useRef(null) + + useEffect(() => { + // eslint-disable-next-line jest/no-conditional-in-test + if (!open) { + return + } + dispatchDOMEvent(targetRef.current, 'input') + setFromEffect(n => n + 1) + }, [open]) + + return ( + <> + + setFromEvent(n => n + 1)} /> + + ) + } + + const errorSpy = jest.spyOn(console, 'error').mockImplementation(() => {}) + const {container} = render() + const button = container.querySelector('button') + + fireEvent.click(button) + + expect(button).toHaveTextContent('open:true effect:1 event:1') + const actWarnings = errorSpy.mock.calls + .map(args => String(args[0])) + .filter(message => message.includes('not wrapped in act')) + expect(actWarnings).toEqual([]) + + errorSpy.mockRestore() +}) diff --git a/src/pure.js b/src/pure.js index 054830fa..3ea36bfe 100644 --- a/src/pure.js +++ b/src/pure.js @@ -27,6 +27,8 @@ function jestFakeTimersAreEnabled() { return false } +let inEventWrapper = false + configureDTL({ unstable_advanceTimersWrapper: cb => { return act(cb) @@ -58,11 +60,19 @@ configureDTL({ } }, eventWrapper: cb => { - let result - act(() => { - result = cb() - }) - return result + if (inEventWrapper) { + return cb() + } + inEventWrapper = true + try { + let result + act(() => { + result = cb() + }) + return result + } finally { + inEventWrapper = false + } }, })