Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Codemod it.experimental to gate pragma #18582

Merged
merged 2 commits into from
Apr 13, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
466 changes: 230 additions & 236 deletions packages/react-dom/src/__tests__/ReactDOMFiberAsync-test.js

Large diffs are not rendered by default.

66 changes: 32 additions & 34 deletions packages/react-dom/src/__tests__/ReactDOMHooks-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -105,41 +105,39 @@ describe('ReactDOMHooks', () => {
expect(labelRef.current.innerHTML).toBe('abc');
});

it.experimental(
'should not bail out when an update is scheduled from within an event handler in Concurrent Mode',
() => {
const {createRef, useCallback, useState} = React;

const Example = ({inputRef, labelRef}) => {
const [text, setText] = useState('');
const handleInput = useCallback(event => {
setText(event.target.value);
});

return (
<>
<input ref={inputRef} onInput={handleInput} />
<label ref={labelRef}>{text}</label>
</>
);
};

const inputRef = createRef();
const labelRef = createRef();

const root = ReactDOM.createRoot(container);
root.render(<Example inputRef={inputRef} labelRef={labelRef} />);

Scheduler.unstable_flushAll();

inputRef.current.value = 'abc';
inputRef.current.dispatchEvent(
new Event('input', {bubbles: true, cancelable: true}),
// @gate experimental
it('should not bail out when an update is scheduled from within an event handler in Concurrent Mode', () => {
const {createRef, useCallback, useState} = React;

const Example = ({inputRef, labelRef}) => {
const [text, setText] = useState('');
const handleInput = useCallback(event => {
setText(event.target.value);
});

return (
<>
<input ref={inputRef} onInput={handleInput} />
<label ref={labelRef}>{text}</label>
</>
);
};

Scheduler.unstable_flushAll();
const inputRef = createRef();
const labelRef = createRef();

const root = ReactDOM.createRoot(container);
root.render(<Example inputRef={inputRef} labelRef={labelRef} />);

Scheduler.unstable_flushAll();

inputRef.current.value = 'abc';
inputRef.current.dispatchEvent(
new Event('input', {bubbles: true, cancelable: true}),
);

expect(labelRef.current.innerHTML).toBe('abc');
},
);
Scheduler.unstable_flushAll();

expect(labelRef.current.innerHTML).toBe('abc');
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -491,23 +491,21 @@ describe('ReactDOMServerHydration', () => {
expect(element.textContent).toBe('Hello world');
});

it.experimental(
'does not re-enter hydration after committing the first one',
() => {
const finalHTML = ReactDOMServer.renderToString(<div />);
const container = document.createElement('div');
container.innerHTML = finalHTML;
const root = ReactDOM.createRoot(container, {hydrate: true});
root.render(<div />);
Scheduler.unstable_flushAll();
root.render(null);
Scheduler.unstable_flushAll();
// This should not reenter hydration state and therefore not trigger hydration
// warnings.
root.render(<div />);
Scheduler.unstable_flushAll();
},
);
// @gate experimental
it('does not re-enter hydration after committing the first one', () => {
const finalHTML = ReactDOMServer.renderToString(<div />);
const container = document.createElement('div');
container.innerHTML = finalHTML;
const root = ReactDOM.createRoot(container, {hydrate: true});
root.render(<div />);
Scheduler.unstable_flushAll();
root.render(null);
Scheduler.unstable_flushAll();
// This should not reenter hydration state and therefore not trigger hydration
// warnings.
root.render(<div />);
Scheduler.unstable_flushAll();
});

it('Suspense + hydration in legacy mode', () => {
const element = document.createElement('div');
Expand Down
6 changes: 4 additions & 2 deletions packages/react-dom/src/__tests__/ReactTestUtilsAct-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,8 @@ describe('ReactTestUtils.act()', () => {
]);
});

it.experimental('warns in blocking mode', () => {
// @gate experimental
it('warns in blocking mode', () => {
expect(() => {
const root = ReactDOM.createBlockingRoot(document.createElement('div'));
root.render(<App />);
Expand All @@ -134,7 +135,8 @@ describe('ReactTestUtils.act()', () => {
]);
});

it.experimental('warns in concurrent mode', () => {
// @gate experimental
it('warns in concurrent mode', () => {
expect(() => {
const root = ReactDOM.createRoot(document.createElement('div'));
root.render(<App />);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ it('does not warn when rendering in legacy mode', () => {
}).toErrorDev([]);
});

it.experimental('should warn when rendering in concurrent mode', () => {
// @gate experimental
it('should warn when rendering in concurrent mode', () => {
expect(() => {
ReactDOM.createRoot(document.createElement('div')).render(<App />);
}).toErrorDev(
Expand All @@ -41,7 +42,8 @@ it.experimental('should warn when rendering in concurrent mode', () => {
}).toErrorDev([]);
});

it.experimental('should warn when rendering in blocking mode', () => {
// @gate experimental
it('should warn when rendering in blocking mode', () => {
expect(() => {
ReactDOM.createBlockingRoot(document.createElement('div')).render(<App />);
}).toErrorDev(
Expand Down
100 changes: 49 additions & 51 deletions packages/react-dom/src/__tests__/ReactUpdates-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -1287,64 +1287,62 @@ describe('ReactUpdates', () => {
expect(ops).toEqual(['Foo', 'Bar', 'Baz']);
});

it.experimental(
'delays sync updates inside hidden subtrees in Concurrent Mode',
() => {
const container = document.createElement('div');

function Baz() {
Scheduler.unstable_yieldValue('Baz');
return <p>baz</p>;
}

let setCounter;
function Bar() {
const [counter, _setCounter] = React.useState(0);
setCounter = _setCounter;
Scheduler.unstable_yieldValue('Bar');
return <p>bar {counter}</p>;
}
// @gate experimental
it('delays sync updates inside hidden subtrees in Concurrent Mode', () => {
const container = document.createElement('div');

function Foo() {
Scheduler.unstable_yieldValue('Foo');
React.useEffect(() => {
Scheduler.unstable_yieldValue('Foo#effect');
});
return (
<div>
<div hidden={true}>
<Bar />
</div>
<Baz />
</div>
);
}
function Baz() {
Scheduler.unstable_yieldValue('Baz');
return <p>baz</p>;
}

const root = ReactDOM.createRoot(container);
let hiddenDiv;
act(() => {
root.render(<Foo />);
expect(Scheduler).toFlushAndYieldThrough(['Foo', 'Baz', 'Foo#effect']);
hiddenDiv = container.firstChild.firstChild;
expect(hiddenDiv.hidden).toBe(true);
expect(hiddenDiv.innerHTML).toBe('');
// Run offscreen update
expect(Scheduler).toFlushAndYield(['Bar']);
expect(hiddenDiv.hidden).toBe(true);
expect(hiddenDiv.innerHTML).toBe('<p>bar 0</p>');
});
let setCounter;
function Bar() {
const [counter, _setCounter] = React.useState(0);
setCounter = _setCounter;
Scheduler.unstable_yieldValue('Bar');
return <p>bar {counter}</p>;
}

ReactDOM.flushSync(() => {
setCounter(1);
function Foo() {
Scheduler.unstable_yieldValue('Foo');
React.useEffect(() => {
Scheduler.unstable_yieldValue('Foo#effect');
});
// Should not flush yet
expect(hiddenDiv.innerHTML).toBe('<p>bar 0</p>');
return (
<div>
<div hidden={true}>
<Bar />
</div>
<Baz />
</div>
);
}

const root = ReactDOM.createRoot(container);
let hiddenDiv;
act(() => {
root.render(<Foo />);
expect(Scheduler).toFlushAndYieldThrough(['Foo', 'Baz', 'Foo#effect']);
hiddenDiv = container.firstChild.firstChild;
expect(hiddenDiv.hidden).toBe(true);
expect(hiddenDiv.innerHTML).toBe('');
// Run offscreen update
expect(Scheduler).toFlushAndYield(['Bar']);
expect(hiddenDiv.innerHTML).toBe('<p>bar 1</p>');
},
);
expect(hiddenDiv.hidden).toBe(true);
expect(hiddenDiv.innerHTML).toBe('<p>bar 0</p>');
});

ReactDOM.flushSync(() => {
setCounter(1);
});
// Should not flush yet
expect(hiddenDiv.innerHTML).toBe('<p>bar 0</p>');

// Run offscreen update
expect(Scheduler).toFlushAndYield(['Bar']);
expect(hiddenDiv.innerHTML).toBe('<p>bar 1</p>');
});

it('can render ridiculously large number of roots without triggering infinite update loop error', () => {
class Foo extends React.Component {
Expand Down
Loading