Skip to content

Commit f00ec78

Browse files
committed
tests and flow
1 parent f8d4a93 commit f00ec78

File tree

5 files changed

+121
-24
lines changed

5 files changed

+121
-24
lines changed

packages/react-client/src/__tests__/ReactFlight-test.js

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,19 @@ describe('ReactFlight', () => {
4545
componentDidMount() {
4646
expect(this.state.hasError).toBe(true);
4747
expect(this.state.error).toBeTruthy();
48-
expect(this.state.error.message).toContain(this.props.expectedMessage);
48+
if (__DEV__) {
49+
expect(this.state.error.message).toContain(
50+
this.props.expectedMessage,
51+
);
52+
expect(this.state.error._digest).toContain('a dev digest');
53+
} else {
54+
expect(this.state.error.message).toContain(
55+
'An error occurred in the Server Components render.',
56+
);
57+
expect(this.state.error._digest).toContain(
58+
this.props.expectedMessage,
59+
);
60+
}
4961
}
5062
render() {
5163
if (this.state.hasError) {
@@ -371,8 +383,8 @@ describe('ReactFlight', () => {
371383
}
372384

373385
const options = {
374-
onError() {
375-
// ignore
386+
onError(x) {
387+
return __DEV__ ? 'a dev digest' : `digest("${x.message}")`;
376388
},
377389
};
378390
const event = ReactNoopFlightServer.render(<EventHandlerProp />, options);

packages/react-server-dom-relay/src/ReactFlightDOMRelayClient.js

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ import {
1616
resolveModel,
1717
resolveModule,
1818
resolveSymbol,
19-
resolveError,
19+
resolveErrorDev,
20+
resolveErrorProd,
2021
close,
2122
getRoot,
2223
} from 'react-client/src/ReactFlightClient';
@@ -34,7 +35,20 @@ export function resolveRow(response: Response, chunk: RowEncoding): void {
3435
// $FlowFixMe: Flow doesn't support disjoint unions on tuples.
3536
resolveSymbol(response, chunk[1], chunk[2]);
3637
} else {
37-
// $FlowFixMe: Flow doesn't support disjoint unions on tuples.
38-
resolveError(response, chunk[1], chunk[2].message, chunk[2].stack);
38+
if (__DEV__) {
39+
resolveErrorDev(
40+
response,
41+
chunk[1],
42+
// $FlowFixMe: Flow doesn't support disjoint unions on tuples.
43+
chunk[2].digest,
44+
// $FlowFixMe: Flow doesn't support disjoint unions on tuples.
45+
chunk[2].message || '',
46+
// $FlowFixMe: Flow doesn't support disjoint unions on tuples.
47+
chunk[2].stack || '',
48+
);
49+
} else {
50+
// $FlowFixMe: Flow doesn't support disjoint unions on tuples.
51+
resolveErrorPro(response, chunk[1], chunk[2].digest);
52+
}
3953
}
4054
}

packages/react-server-dom-relay/src/ReactFlightDOMRelayProtocol.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,9 @@ export type RowEncoding =
2626
'E',
2727
number,
2828
{
29-
message: string,
30-
stack: string,
29+
digest: string,
30+
message?: string,
31+
stack?: string,
3132
...
3233
},
3334
];

packages/react-server-dom-webpack/src/__tests__/ReactFlightDOM-test.js

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -332,7 +332,13 @@ describe('ReactFlightDOM', () => {
332332

333333
function MyErrorBoundary({children}) {
334334
return (
335-
<ErrorBoundary fallback={e => <p>{e.message}</p>}>
335+
<ErrorBoundary
336+
fallback={e => (
337+
<p>
338+
{__DEV__ ? e.message + ' + ' : null}
339+
{e._digest}
340+
</p>
341+
)}>
336342
{children}
337343
</ErrorBoundary>
338344
);
@@ -434,6 +440,7 @@ describe('ReactFlightDOM', () => {
434440
{
435441
onError(x) {
436442
reportedErrors.push(x);
443+
return __DEV__ ? 'a dev digest' : `digest("${x.message}")`;
437444
},
438445
},
439446
);
@@ -477,11 +484,14 @@ describe('ReactFlightDOM', () => {
477484
await act(async () => {
478485
rejectGames(theError);
479486
});
487+
const expectedGamesValue = __DEV__
488+
? '<p>Game over + a dev digest</p>'
489+
: '<p>digest("Game over")</p>';
480490
expect(container.innerHTML).toBe(
481491
'<div>:name::avatar:</div>' +
482492
'<p>(loading sidebar)</p>' +
483493
'<p>(loading posts)</p>' +
484-
'<p>Game over</p>', // TODO: should not have message in prod.
494+
expectedGamesValue,
485495
);
486496

487497
expect(reportedErrors).toEqual([theError]);
@@ -495,7 +505,7 @@ describe('ReactFlightDOM', () => {
495505
'<div>:name::avatar:</div>' +
496506
'<div>:photos::friends:</div>' +
497507
'<p>(loading posts)</p>' +
498-
'<p>Game over</p>', // TODO: should not have message in prod.
508+
expectedGamesValue,
499509
);
500510

501511
// Show everything.
@@ -506,7 +516,7 @@ describe('ReactFlightDOM', () => {
506516
'<div>:name::avatar:</div>' +
507517
'<div>:photos::friends:</div>' +
508518
'<div>:posts:</div>' +
509-
'<p>Game over</p>', // TODO: should not have message in prod.
519+
expectedGamesValue,
510520
);
511521

512522
expect(reportedErrors).toEqual([]);
@@ -611,6 +621,8 @@ describe('ReactFlightDOM', () => {
611621
{
612622
onError(x) {
613623
reportedErrors.push(x);
624+
const message = typeof x === 'string' ? x : x.message;
625+
return __DEV__ ? 'a dev digest' : `digest("${message}")`;
614626
},
615627
},
616628
);
@@ -626,7 +638,13 @@ describe('ReactFlightDOM', () => {
626638

627639
await act(async () => {
628640
root.render(
629-
<ErrorBoundary fallback={e => <p>{e.message}</p>}>
641+
<ErrorBoundary
642+
fallback={e => (
643+
<p>
644+
{__DEV__ ? e.message + ' + ' : null}
645+
{e._digest}
646+
</p>
647+
)}>
630648
<Suspense fallback={<p>(loading)</p>}>
631649
<App res={response} />
632650
</Suspense>
@@ -638,7 +656,13 @@ describe('ReactFlightDOM', () => {
638656
await act(async () => {
639657
abort('for reasons');
640658
});
641-
expect(container.innerHTML).toBe('<p>Error: for reasons</p>');
659+
if (__DEV__) {
660+
expect(container.innerHTML).toBe(
661+
'<p>Error: for reasons + a dev digest</p>',
662+
);
663+
} else {
664+
expect(container.innerHTML).toBe('<p>digest("for reasons")</p>');
665+
}
642666

643667
expect(reportedErrors).toEqual(['for reasons']);
644668
});

packages/react-server-dom-webpack/src/__tests__/ReactFlightDOMBrowser-test.js

Lines changed: 56 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -173,11 +173,25 @@ describe('ReactFlightDOMBrowser', () => {
173173
}
174174
}
175175

176+
let errorBoundaryFn;
177+
if (__DEV__) {
178+
errorBoundaryFn = e => (
179+
<p>
180+
{e.message} + {e._digest}
181+
</p>
182+
);
183+
} else {
184+
errorBoundaryFn = e => {
185+
expect(e.message).toBe(
186+
'An error occurred in the Server Components render.',
187+
);
188+
return <p>{e._digest}</p>;
189+
};
190+
}
191+
176192
function MyErrorBoundary({children}) {
177193
return (
178-
<ErrorBoundary fallback={e => <p>{e.message}</p>}>
179-
{children}
180-
</ErrorBoundary>
194+
<ErrorBoundary fallback={errorBoundaryFn}>{children}</ErrorBoundary>
181195
);
182196
}
183197

@@ -251,6 +265,7 @@ describe('ReactFlightDOMBrowser', () => {
251265
{
252266
onError(x) {
253267
reportedErrors.push(x);
268+
return __DEV__ ? `a dev digest` : `digest("${x.message}")`;
254269
},
255270
},
256271
);
@@ -293,11 +308,16 @@ describe('ReactFlightDOMBrowser', () => {
293308
await act(async () => {
294309
rejectGames(theError);
295310
});
311+
312+
let gamesExpectedValue = __DEV__
313+
? '<p>Game over + a dev digest</p>'
314+
: '<p>digest("Game over")</p>';
315+
296316
expect(container.innerHTML).toBe(
297317
'<div>:name::avatar:</div>' +
298318
'<p>(loading sidebar)</p>' +
299319
'<p>(loading posts)</p>' +
300-
'<p>Game over</p>', // TODO: should not have message in prod.
320+
gamesExpectedValue,
301321
);
302322

303323
expect(reportedErrors).toEqual([theError]);
@@ -311,7 +331,7 @@ describe('ReactFlightDOMBrowser', () => {
311331
'<div>:name::avatar:</div>' +
312332
'<div>:photos::friends:</div>' +
313333
'<p>(loading posts)</p>' +
314-
'<p>Game over</p>', // TODO: should not have message in prod.
334+
gamesExpectedValue,
315335
);
316336

317337
// Show everything.
@@ -322,7 +342,7 @@ describe('ReactFlightDOMBrowser', () => {
322342
'<div>:name::avatar:</div>' +
323343
'<div>:photos::friends:</div>' +
324344
'<div>:posts:</div>' +
325-
'<p>Game over</p>', // TODO: should not have message in prod.
345+
gamesExpectedValue,
326346
);
327347

328348
expect(reportedErrors).toEqual([]);
@@ -489,6 +509,22 @@ describe('ReactFlightDOMBrowser', () => {
489509
it('should be able to complete after aborting and throw the reason client-side', async () => {
490510
const reportedErrors = [];
491511

512+
let errorBoundaryFn;
513+
if (__DEV__) {
514+
errorBoundaryFn = e => (
515+
<p>
516+
{e.message} + {e._digest}
517+
</p>
518+
);
519+
} else {
520+
errorBoundaryFn = e => {
521+
expect(e.message).toBe(
522+
'An error occurred in the Server Components render.',
523+
);
524+
return <p>{e._digest}</p>;
525+
};
526+
}
527+
492528
class ErrorBoundary extends React.Component {
493529
state = {hasError: false, error: null};
494530
static getDerivedStateFromError(error) {
@@ -514,7 +550,9 @@ describe('ReactFlightDOMBrowser', () => {
514550
{
515551
signal: controller.signal,
516552
onError(x) {
553+
let message = typeof x === 'string' ? x : x.message;
517554
reportedErrors.push(x);
555+
return __DEV__ ? 'a dev digest' : `digest("${message}")`;
518556
},
519557
},
520558
);
@@ -529,7 +567,7 @@ describe('ReactFlightDOMBrowser', () => {
529567

530568
await act(async () => {
531569
root.render(
532-
<ErrorBoundary fallback={e => <p>{e.message}</p>}>
570+
<ErrorBoundary fallback={errorBoundaryFn}>
533571
<Suspense fallback={<p>(loading)</p>}>
534572
<App res={response} />
535573
</Suspense>
@@ -545,7 +583,10 @@ describe('ReactFlightDOMBrowser', () => {
545583
controller.signal.reason = 'for reasons';
546584
controller.abort('for reasons');
547585
});
548-
expect(container.innerHTML).toBe('<p>Error: for reasons</p>');
586+
const expectedValue = __DEV__
587+
? '<p>Error: for reasons + a dev digest</p>'
588+
: '<p>digest("for reasons")</p>';
589+
expect(container.innerHTML).toBe(expectedValue);
549590

550591
expect(reportedErrors).toEqual(['for reasons']);
551592
});
@@ -665,6 +706,7 @@ describe('ReactFlightDOMBrowser', () => {
665706
{
666707
onError(x) {
667708
reportedErrors.push(x);
709+
return __DEV__ ? 'a dev digest' : `digest("${x.message}")`;
668710
},
669711
},
670712
);
@@ -677,7 +719,9 @@ describe('ReactFlightDOMBrowser', () => {
677719
}
678720
render() {
679721
if (this.state.error) {
680-
return this.state.error.message;
722+
return __DEV__
723+
? this.state.error.message + ' + ' + this.state.error._digest
724+
: this.state.error._digest;
681725
}
682726
return this.props.children;
683727
}
@@ -696,7 +740,9 @@ describe('ReactFlightDOMBrowser', () => {
696740
</ErrorBoundary>,
697741
);
698742
});
699-
expect(container.innerHTML).toBe('Oops!');
743+
expect(container.innerHTML).toBe(
744+
__DEV__ ? 'Oops! + a dev digest' : 'digest("Oops!")',
745+
);
700746
expect(reportedErrors.length).toBe(1);
701747
expect(reportedErrors[0].message).toBe('Oops!');
702748
});

0 commit comments

Comments
 (0)