Skip to content

Commit

Permalink
Refactor hydrate warnings with feedback from @KidkArolis, @mxstbr (fa…
Browse files Browse the repository at this point in the history
…cebook#10085)

- Change headline to contain only the tag names, not attributes and children.
- Add newlines between headline, diff, and stack.

Besides the above feedback:
- Add comment nodes display in the diff.
- Add weird node handling in the diff.
  • Loading branch information
sompylasar committed Jun 8, 2018
1 parent 73e0aba commit a934494
Show file tree
Hide file tree
Showing 3 changed files with 220 additions and 100 deletions.
161 changes: 117 additions & 44 deletions packages/react-dom/src/__tests__/ReactMount-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -125,8 +125,11 @@ describe('ReactMount', () => {
container.innerHTML = ReactDOMServer.renderToString(<div />) + ' ';

expect(() => ReactDOM.hydrate(<div />, container)).toWarnDev(
"Warning: Did not expect server HTML to contain the text node {' '}" +
' in <container><div data-reactroot=""></div> </container>.',
"Warning: Did not expect server HTML to contain the text node {' '} in <container>.\n\n" +
' <container>\n' +
' <div data-reactroot=""></div>\n' +
"- {' '}\n" +
' </container>\n',
);
});

Expand All @@ -135,8 +138,11 @@ describe('ReactMount', () => {
container.innerHTML = ' ' + ReactDOMServer.renderToString(<div />);

expect(() => ReactDOM.hydrate(<div />, container)).toWarnDev(
"Warning: Did not expect server HTML to contain the text node {' '}" +
' in <container> <div data-reactroot=""></div></container>.',
"Warning: Did not expect server HTML to contain the text node {' '} in <container>.\n\n" +
' <container>\n' +
"- {' '}\n" +
' <div data-reactroot=""></div>\n' +
' </container>\n',
);
});

Expand Down Expand Up @@ -263,33 +269,37 @@ describe('ReactMount', () => {
const div = document.createElement('div');
const markup = ReactDOMServer.renderToString(
<Component>
nested{' '}
nested{' '}
<p>
children <b>text</b>
</p>
</Component>,
);
div.innerHTML = markup;

expect(div.outerHTML).toEqual(
'<div>nested<!-- --> <p>children <b>text</b></p></div>',
);

expect(() =>
ReactDOM.hydrate(
<Component>
nested{' '}
nested{' '}
<div>
children <b>text</b>
</div>
</Component>,
div,
),
).toWarnDev(
"Warning: Expected server HTML to contain a matching <div>{['children ', …]}</div>" +
' in <div>nested<!-- --> <p>children <b>text</b></p></div>.\n' +
'Warning: Expected server HTML to contain a matching <div> in <div>.\n\n' +
' <div>\n' +
" {'nested'}\n" +
" {' '}\n" +
' <!-- -->\n' +
" {' '}\n" +
'- <p>children <b>text</b></p>\n' +
"+ <div>{['children ', …]}</div>\n" +
' </div>\n' +
' </div>\n\n' +
' in div (at **)\n' +
' in Component (at **)',
);
Expand All @@ -307,18 +317,22 @@ describe('ReactMount', () => {
const div = document.createElement('div');
const markup = ReactDOMServer.renderToString(
<Component>
nested{' '}
nested{' '}
<p>
children <b>text</b>
</p>
</Component>,
);
div.innerHTML = markup;

expect(div.outerHTML).toEqual(
'<div>nested<!-- --> <p>children <b>text</b></p></div>',
);

expect(() =>
ReactDOM.hydrate(
<Component>
nested{' '}
nested{' '}
<p>
children <b>text</b>
</p>
Expand All @@ -329,14 +343,14 @@ describe('ReactMount', () => {
div,
),
).toWarnDev(
"Warning: Expected server HTML to contain a matching <div>{['children ', …]}</div>" +
' in <div>nested<!-- --> <p>children <b>text</b></p></div>.\n' +
'Warning: Expected server HTML to contain a matching <div> in <div>.\n\n' +
' <div>\n' +
" {'nested'}\n" +
" {' '}\n" +
' <!-- -->\n' +
" {' '}\n" +
' <p>children <b>text</b></p>\n' +
"+ <div>{['children ', …]}</div>\n" +
' </div>\n' +
' </div>\n\n' +
' in div (at **)\n' +
' in Component (at **)',
);
Expand Down Expand Up @@ -483,15 +497,13 @@ describe('ReactMount', () => {
div,
),
).toWarnDev(
'Warning: Did not expect server HTML to contain a <br />' +
' in <div data-ssr-mismatch-test-hydrate-root="">SSRMismatchTest first text' +
'<br><br>SSRMismatchTest second text</div>.\n' +
'Warning: Did not expect server HTML to contain a <br> in <div>.\n\n' +
' <div data-ssr-mismatch-test-hydrate-root="">\n' +
" {'SSRMismatchTest first text'}\n" +
' <br />\n' +
'- <br />\n' +
" {'SSRMismatchTest second text'}\n" +
' </div>',
' </div>\n',
);
});

Expand Down Expand Up @@ -520,9 +532,7 @@ describe('ReactMount', () => {
div,
),
).toWarnDev(
'Warning: Did not expect server HTML to contain a <div>SSRMismatchTest default text</div>' +
' in <div data-reactroot=""><div>SSRMismatchTest default text</div><span></span>' +
'<div data-ssr-mismatch-padding-after=""></div><d…</div>.\n' +
'Warning: Did not expect server HTML to contain a <div> in <div>.\n\n' +
' <div data-reactroot="">\n' +
'- <div>SSRMismatchTest default text</div>\n' +
' <span></span>\n' +
Expand All @@ -531,7 +541,7 @@ describe('ReactMount', () => {
' <div data-ssr-mismatch-padding-after=""></div>\n' +
' <div data-ssr-mismatch-padding-after=""></div>\n' +
' <div data-ssr-mismatch-padding-after=""></div>\n' +
' </div>\n' +
' </div>\n\n' +
' in span (at **)\n' +
' in div (at **)',
);
Expand All @@ -556,9 +566,7 @@ describe('ReactMount', () => {
expect(() =>
ReactDOM.hydrate([<br key={1} />, 'SSRMismatchTest default text'], div),
).toWarnDev(
"Warning: Did not expect server HTML to contain the text node {'SSRMismatchTest server text'}" +
' in <div data-ssr-mismatch-test-hydrate-root="">SSRMismatchTest server text' +
'<br>SSRMismatchTest default text<div data-ssr-mismatch-padding-after=""><…</div>.\n' +
"Warning: Did not expect server HTML to contain the text node {'SSRMismatchTest server text'} in <div>.\n\n" +
' <div data-ssr-mismatch-test-hydrate-root="">\n' +
"- {'SSRMismatchTest server text'}\n" +
' <br />\n' +
Expand All @@ -568,7 +576,7 @@ describe('ReactMount', () => {
' <div data-ssr-mismatch-padding-after=""></div>\n' +
' <div data-ssr-mismatch-padding-after=""></div>\n' +
' <div data-ssr-mismatch-padding-after=""></div>\n' +
' </div>\n' +
' </div>\n\n' +
' in br (at **)',
);
});
Expand Down Expand Up @@ -598,9 +606,7 @@ describe('ReactMount', () => {
div,
),
).toWarnDev(
"Warning: Did not expect server HTML to contain the text node {'SSRMismatchTest server text'}" +
' in <div data-reactroot="">SSRMismatchTest server text<span></span>' +
'<div data-ssr-mismatch-padding-after=""></div><div data-ssr-…</div>.\n' +
"Warning: Did not expect server HTML to contain the text node {'SSRMismatchTest server text'} in <div>.\n\n" +
' <div data-reactroot="">\n' +
"- {'SSRMismatchTest server text'}\n" +
' <span></span>\n' +
Expand All @@ -609,7 +615,7 @@ describe('ReactMount', () => {
' <div data-ssr-mismatch-padding-after=""></div>\n' +
' <div data-ssr-mismatch-padding-after=""></div>\n' +
' <div data-ssr-mismatch-padding-after=""></div>\n' +
' </div>\n' +
' </div>\n\n' +
' in span (at **)\n' +
' in div (at **)',
);
Expand All @@ -625,12 +631,11 @@ describe('ReactMount', () => {
expect(() =>
ReactDOM.hydrate(<span>SSRMismatchTest default text</span>, div),
).toWarnDev(
'Warning: Expected server HTML to contain a matching <span>SSRMismatchTest default text</span>' +
' in <div>SSRMismatchTest default text</div>.\n' +
'Warning: Expected server HTML to contain a matching <span> in <div>.\n\n' +
' <div>\n' +
"- {'SSRMismatchTest default text'}\n" +
'+ <span>SSRMismatchTest default text</span>\n' +
' </div>\n' +
' </div>\n\n' +
' in span (at **)',
);
});
Expand All @@ -654,12 +659,11 @@ describe('ReactMount', () => {
div,
),
).toWarnDev(
'Warning: Expected server HTML to contain a matching <p>SSRMismatchTest default text</p>' +
' in <div data-reactroot=""><em>SSRMismatchTest default text</em></div>.\n' +
'Warning: Expected server HTML to contain a matching <p> in <div>.\n\n' +
' <div data-reactroot="">\n' +
'- <em>SSRMismatchTest default text</em>\n' +
'+ <p>SSRMismatchTest default text</p>\n' +
' </div>\n' +
' </div>\n\n' +
' in p (at **)\n' +
' in div (at **)',
);
Expand All @@ -677,8 +681,12 @@ describe('ReactMount', () => {
expect(() =>
ReactDOM.hydrate('SSRMismatchTest default text', div),
).toWarnDev(
"Warning: Expected server HTML to contain a matching text node for {'SSRMismatchTest default text'}" +
' in <div><span data-reactroot="">SSRMismatchTest default text</span></div>.',
'Warning: Expected server HTML to contain a matching text node' +
" for {'SSRMismatchTest default text'} in <div>.\n\n" +
' <div>\n' +
'- <span data-reactroot="">SSRMismatchTest default text</span>\n' +
"+ {'SSRMismatchTest default text'}\n" +
' </div>\n',
);
});

Expand Down Expand Up @@ -709,9 +717,8 @@ describe('ReactMount', () => {
div,
),
).toWarnDev(
"Warning: Expected server HTML to contain a matching text node for {'SSRMismatchTest client text'}" +
' in <div data-reactroot=""><span></span><span></span>' +
'<div data-ssr-mismatch-padding-after=""></div><div data-ssr-mismatch-paddi…</div>.\n' +
'Warning: Expected server HTML to contain a matching text node' +
" for {'SSRMismatchTest client text'} in <div>.\n\n" +
' <div data-reactroot="">\n' +
' <span></span>\n' +
'- <span></span>\n' +
Expand All @@ -721,7 +728,73 @@ describe('ReactMount', () => {
' <div data-ssr-mismatch-padding-after=""></div>\n' +
' <div data-ssr-mismatch-padding-after=""></div>\n' +
' <div data-ssr-mismatch-padding-after=""></div>\n' +
' </div>\n' +
' </div>\n\n' +
' in div (at **)',
);
});

it('should warn when hydrate inserts an element after a comment node', () => {
const div = document.createElement('div');
div.innerHTML = '<div><!-- a comment --></div>';

expect(() =>
ReactDOM.hydrate(
<div>
<span />
</div>,
div,
),
).toWarnDev(
'Warning: Expected server HTML to contain a matching <span> in <div>.\n\n' +
' <div>\n' +
' <!-- a comment -->\n' +
'+ <span></span>\n' +
' </div>\n\n' +
' in span (at **)\n' +
' in div (at **)',
);
});

it('should warn when hydrate replaces an element after a comment node', () => {
const div = document.createElement('div');
div.innerHTML = '<div><!-- a comment --><div></div></div>';

expect(() =>
ReactDOM.hydrate(
<div>
<span />
<div />
</div>,
div,
),
).toWarnDev(
'Warning: Expected server HTML to contain a matching <span> in <div>.\n\n' +
' <div>\n' +
' <!-- a comment -->\n' +
'- <div></div>\n' +
'+ <span></span>\n' +
' </div>\n\n' +
' in span (at **)\n' +
' in div (at **)',
);
});

it('should warn when hydrate inserts an element after a node that is not an element, text, or comment', () => {
// This is an artificial test case to check how we print weird nodes if they somehow end up in the DOM.
const xml = document.createElement('xml');
xml.appendChild(
document.createProcessingInstruction(
'dom-processing-instruction',
'content',
),
);

expect(() => ReactDOM.hydrate(<div />, xml)).toWarnDev(
'Warning: Expected server HTML to contain a matching <div> in <xml>.\n\n' +
' <xml>\n' +
' <?dom-processing-instruction content?>\n' +
'+ <div></div>\n' +
' </xml>\n\n' +
' in div (at **)',
);
});
Expand Down
Loading

0 comments on commit a934494

Please sign in to comment.