Skip to content

Commit 05dbfd3

Browse files
committed
Add tests from docs examples
1 parent 07fc453 commit 05dbfd3

File tree

1 file changed

+163
-2
lines changed

1 file changed

+163
-2
lines changed

packages/react-reconciler/src/__tests__/useEvent-test.internal.js

Lines changed: 163 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,21 +19,27 @@ describe('useEvent', () => {
1919
let ReactNoop;
2020
let Scheduler;
2121
let act;
22+
let createContext;
23+
let useContext;
2224
let useState;
2325
let useEvent;
2426
let useEffect;
2527
let useLayoutEffect;
28+
let useMemo;
2629

2730
beforeEach(() => {
2831
React = require('react');
2932
ReactNoop = require('react-noop-renderer');
3033
Scheduler = require('scheduler');
3134

3235
act = require('jest-react').act;
36+
createContext = React.createContext;
37+
useContext = React.useContext;
3338
useState = React.useState;
3439
useEvent = React.experimental_useEvent;
3540
useEffect = React.useEffect;
3641
useLayoutEffect = React.useLayoutEffect;
42+
useMemo = React.useMemo;
3743
});
3844

3945
function span(prop) {
@@ -150,7 +156,7 @@ describe('useEvent', () => {
150156
});
151157

152158
// @gate enableUseEventHook
153-
it('useLayoutEffect shouldnt re-fire when event handlers change', () => {
159+
it("useLayoutEffect shouldn't re-fire when event handlers change", () => {
154160
class IncrementButton extends React.PureComponent {
155161
increment = () => {
156162
this.props.onClick();
@@ -235,7 +241,7 @@ describe('useEvent', () => {
235241
});
236242

237243
// @gate enableUseEventHook
238-
it('useEffect shouldnt re-fire when event handlers change', () => {
244+
it("useEffect shouldn't re-fire when event handlers change", () => {
239245
class IncrementButton extends React.PureComponent {
240246
increment = () => {
241247
this.props.onClick();
@@ -431,4 +437,159 @@ describe('useEvent', () => {
431437
act(() => ReactNoop.render(<Counter value={2} />));
432438
expect(Scheduler).toHaveYielded(['Effect value: 2', 'Event value: 2']);
433439
});
440+
441+
// @gate enableUseEventHook
442+
it('integration: implements docs chat room example', () => {
443+
function createConnection() {
444+
let connectedCallback;
445+
let timeout;
446+
return {
447+
connect() {
448+
timeout = setTimeout(() => {
449+
if (connectedCallback) {
450+
connectedCallback();
451+
}
452+
}, 100);
453+
},
454+
on(event, callback) {
455+
if (connectedCallback) {
456+
throw Error('Cannot add the handler twice.');
457+
}
458+
if (event !== 'connected') {
459+
throw Error('Only "connected" event is supported.');
460+
}
461+
connectedCallback = callback;
462+
},
463+
disconnect() {
464+
clearTimeout(timeout);
465+
},
466+
};
467+
}
468+
469+
function ChatRoom({roomId, theme}) {
470+
const onConnected = useEvent(() => {
471+
Scheduler.unstable_yieldValue('Connected! theme: ' + theme);
472+
});
473+
474+
useEffect(() => {
475+
const connection = createConnection(roomId);
476+
connection.on('connected', () => {
477+
onConnected();
478+
});
479+
connection.connect();
480+
return () => connection.disconnect();
481+
}, [roomId, onConnected]);
482+
483+
return <Text text={`Welcome to the ${roomId} room!`} />;
484+
}
485+
486+
act(() => ReactNoop.render(<ChatRoom roomId="general" theme="light" />));
487+
expect(Scheduler).toHaveYielded(['Welcome to the general room!']);
488+
expect(ReactNoop.getChildren()).toEqual([
489+
span('Welcome to the general room!'),
490+
]);
491+
492+
jest.advanceTimersByTime(100);
493+
Scheduler.unstable_advanceTime(100);
494+
expect(Scheduler).toHaveYielded(['Connected! theme: light']);
495+
496+
// change roomId only
497+
act(() => ReactNoop.render(<ChatRoom roomId="music" theme="light" />));
498+
expect(Scheduler).toHaveYielded(['Welcome to the music room!']);
499+
expect(ReactNoop.getChildren()).toEqual([
500+
span('Welcome to the music room!'),
501+
]);
502+
jest.advanceTimersByTime(100);
503+
Scheduler.unstable_advanceTime(100);
504+
// should trigger a reconnect
505+
expect(Scheduler).toHaveYielded(['Connected! theme: light']);
506+
507+
// change theme only
508+
act(() => ReactNoop.render(<ChatRoom roomId="music" theme="dark" />));
509+
expect(Scheduler).toHaveYielded(['Welcome to the music room!']);
510+
expect(ReactNoop.getChildren()).toEqual([
511+
span('Welcome to the music room!'),
512+
]);
513+
jest.advanceTimersByTime(100);
514+
Scheduler.unstable_advanceTime(100);
515+
// should not trigger a reconnect
516+
expect(Scheduler).toFlushWithoutYielding();
517+
518+
// change roomId only
519+
act(() => ReactNoop.render(<ChatRoom roomId="travel" theme="dark" />));
520+
expect(Scheduler).toHaveYielded(['Welcome to the travel room!']);
521+
expect(ReactNoop.getChildren()).toEqual([
522+
span('Welcome to the travel room!'),
523+
]);
524+
jest.advanceTimersByTime(100);
525+
Scheduler.unstable_advanceTime(100);
526+
// should trigger a reconnect
527+
expect(Scheduler).toHaveYielded(['Connected! theme: dark']);
528+
});
529+
530+
// @gate enableUseEventHook
531+
it('integration: implements the docs logVisit example', () => {
532+
class AddToCartButton extends React.PureComponent {
533+
addToCart = () => {
534+
this.props.onClick();
535+
};
536+
render() {
537+
return <Text text="Add to cart" />;
538+
}
539+
}
540+
const ShoppingCartContext = createContext(null);
541+
542+
function AppShell({children}) {
543+
const [items, updateItems] = useState([]);
544+
const value = useMemo(() => ({items, updateItems}), [items, updateItems]);
545+
546+
return (
547+
<ShoppingCartContext.Provider value={value}>
548+
{children}
549+
</ShoppingCartContext.Provider>
550+
);
551+
}
552+
553+
function Page({url}) {
554+
const {items, updateItems} = useContext(ShoppingCartContext);
555+
const onClick = useEvent(() => updateItems([...items, 1]));
556+
const numberOfItems = items.length;
557+
558+
const onVisit = useEvent(visitedUrl => {
559+
Scheduler.unstable_yieldValue(
560+
'url: ' + url + ', numberOfItems: ' + numberOfItems,
561+
);
562+
});
563+
564+
useEffect(() => {
565+
onVisit(url);
566+
}, [url]);
567+
568+
return <AddToCartButton onClick={onClick} ref={button} />;
569+
}
570+
571+
const button = React.createRef(null);
572+
act(() =>
573+
ReactNoop.render(
574+
<AppShell>
575+
<Page url="/shop/1" />
576+
</AppShell>,
577+
),
578+
);
579+
expect(Scheduler).toHaveYielded([
580+
'Add to cart',
581+
'url: /shop/1, numberOfItems: 0',
582+
]);
583+
act(button.current.addToCart);
584+
expect(Scheduler).toFlushWithoutYielding();
585+
586+
act(() =>
587+
ReactNoop.render(
588+
<AppShell>
589+
<Page url="/shop/2" />
590+
</AppShell>,
591+
),
592+
);
593+
expect(Scheduler).toHaveYielded(['url: /shop/2, numberOfItems: 1']);
594+
});
434595
});

0 commit comments

Comments
 (0)