Adding new SSR tests for context, refs, and reviving markup. (#9257)
Sasha Aickin committed
Mar 26, 2017 at 13:32 UTC
c51411c812d60072a1e5f1b654d7408727093821
4 files changed
+549
scripts/fiber/tests-failing.txt
+11
@@ -102,6 +102,17 @@ src/renderers/dom/shared/__tests__/ReactDOMServerIntegration-test.js
102
* renders >,<, and & as single child with client render on top of good server markup
103
* renders >,<, and & as multiple children with server string render
104
* renders >,<, and & as multiple children with client render on top of good server markup
105
+* renders class child with context with client render on top of good server markup
106
+* renders stateless child with context with client render on top of good server markup
107
+* renders class child without context with client render on top of good server markup
108
+* renders stateless child without context with client render on top of good server markup
109
+* renders class child with wrong context with client render on top of good server markup
110
+* renders stateless child with wrong context with client render on top of good server markup
111
+* renders with context passed through to a grandchild with client render on top of good server markup
112
+* renders a child context overriding a parent context with client render on top of good server markup
113
+* renders a child context merged with a parent context with client render on top of good server markup
114
+* renders with a call to componentWillMount before getChildContext with client render on top of good server markup
115
+* should send the correct element to ref functions on client
116
117
src/renderers/dom/shared/__tests__/ReactDOMTextComponent-test.js
118
* can reconcile text merged by Node.normalize() alongside other elements
scripts/fiber/tests-passing-except-dev.txt
+29
@@ -95,6 +95,35 @@ src/renderers/dom/shared/__tests__/ReactDOMServerIntegration-test.js
95
* throws when rendering an undefined component with client render on top of bad server markup
96
* throws when rendering a number component with clean client render
97
* throws when rendering a number component with client render on top of bad server markup
98
+* renders class child with context with client render on top of bad server markup
99
+* renders stateless child with context with client render on top of bad server markup
100
+* renders class child without context with client render on top of bad server markup
101
+* renders stateless child without context with client render on top of bad server markup
102
+* renders class child with wrong context with client render on top of bad server markup
103
+* renders stateless child with wrong context with client render on top of bad server markup
104
+* renders with context passed through to a grandchild with client render on top of bad server markup
105
+* renders a child context overriding a parent context with client render on top of bad server markup
106
+* renders a child context merged with a parent context with client render on top of bad server markup
107
+* renders with a call to componentWillMount before getChildContext with client render on top of bad server markup
108
+* should error reconnecting different element types
109
+* should error reconnecting missing attributes
110
+* should error reconnecting added attributes
111
+* should error reconnecting different attribute values
112
+* should error reconnecting different text
113
+* should error reconnecting different numbers
114
+* should error reconnecting different number from text
115
+* should error reconnecting different text in two code blocks
116
+* should error reconnecting missing children
117
+* should error reconnecting added children
118
+* should error reconnecting more children
119
+* should error reconnecting fewer children
120
+* should error reconnecting reordered children
121
+* should error reconnecting a div with children separated by whitespace on the client
122
+* should error reconnecting a div with children separated by different whitespace on the server
123
+* should error reconnecting a div with children separated by different whitespace
124
+* can distinguish an empty component from a dom node
125
+* can distinguish an empty component from an empty text component
126
+* should error reconnecting a div with different dangerouslySetInnerHTML
127
128
src/renderers/dom/shared/__tests__/ReactMount-test.js
129
* should warn if mounting into dirty rendered markup
scripts/fiber/tests-passing.txt
+40
@@ -1154,6 +1154,46 @@ src/renderers/dom/shared/__tests__/ReactDOMServerIntegration-test.js
1154
* throws when rendering string with server string render
1155
* throws when rendering string with clean client render
1156
* throws when rendering string with client render on top of bad server markup
1157
+* renders class child with context with server string render
1158
+* renders class child with context with clean client render
1159
+* renders stateless child with context with server string render
1160
+* renders stateless child with context with clean client render
1161
+* renders class child without context with server string render
1162
+* renders class child without context with clean client render
1163
+* renders stateless child without context with server string render
1164
+* renders stateless child without context with clean client render
1165
+* renders class child with wrong context with server string render
1166
+* renders class child with wrong context with clean client render
1167
+* renders stateless child with wrong context with server string render
1168
+* renders stateless child with wrong context with clean client render
1169
+* renders with context passed through to a grandchild with server string render
1170
+* renders with context passed through to a grandchild with clean client render
1171
+* renders a child context overriding a parent context with server string render
1172
+* renders a child context overriding a parent context with clean client render
1173
+* renders a child context merged with a parent context with server string render
1174
+* renders a child context merged with a parent context with clean client render
1175
+* renders with a call to componentWillMount before getChildContext with server string render
1176
+* renders with a call to componentWillMount before getChildContext with clean client render
1177
+* throws when rendering if getChildContext exists without childContextTypes with server string render
1178
+* throws when rendering if getChildContext exists without childContextTypes with clean client render
1179
+* throws when rendering if getChildContext exists without childContextTypes with client render on top of bad server markup
1180
+* throws when rendering if getChildContext returns a value not in childContextTypes with server string render
1181
+* throws when rendering if getChildContext returns a value not in childContextTypes with clean client render
1182
+* throws when rendering if getChildContext returns a value not in childContextTypes with client render on top of bad server markup
1183
+* should not run ref code on server
1184
+* should run ref code on client
1185
+* should have string refs on client when rendered over server markup
1186
+* should reconnect ES6 Class to ES6 Class
1187
+* should reconnect Pure Component to ES6 Class
1188
+* should reconnect Bare Element to ES6 Class
1189
+* should reconnect ES6 Class to Pure Component
1190
+* should reconnect Pure Component to Pure Component
1191
+* should reconnect Bare Element to Pure Component
1192
+* should reconnect ES6 Class to Bare Element
1193
+* should reconnect Pure Component to Bare Element
1194
+* should reconnect Bare Element to Bare Element
1195
+* should reconnect a div with a number and string version of number
1196
+* should reconnect if component trees differ but resulting markup is the same
1197
1198
src/renderers/dom/shared/__tests__/ReactDOMTextComponent-test.js
1199
* updates a mounted text component in place
src/renderers/dom/shared/__tests__/ReactDOMServerIntegration-test.js
+469
@@ -174,6 +174,31 @@ function itThrowsWhenRendering(desc, testFn) {
174
);
175
}
176
177
+// renders serverElement to a string, sticks it into a DOM element, and then
178
+// tries to render clientElement on top of it. shouldMatch is a boolean
179
+// telling whether we should expect the markup to match or not.
180
+async function testMarkupMatch(serverElement, clientElement, shouldMatch) {
181
+ const domElement = await serverRender(serverElement);
182
+ resetModules();
183
+ return renderIntoDom(
184
+ clientElement,
185
+ domElement.parentNode,
186
+ shouldMatch ? 0 : 1,
187
+ );
188
+}
189
+
190
+// expects that rendering clientElement on top of a server-rendered
191
+// serverElement does NOT raise a markup mismatch warning.
192
+function expectMarkupMatch(serverElement, clientElement) {
193
+ return testMarkupMatch(serverElement, clientElement, true);
194
+}
195
+
196
+// expects that rendering clientElement on top of a server-rendered
197
+// serverElement DOES raise a markup mismatch warning.
198
+function expectMarkupMismatch(serverElement, clientElement) {
199
+ return testMarkupMatch(serverElement, clientElement, false);
200
+}
201
+
202
// When there is a test that renders on server and then on client and expects a logged
203
// error, you want to see the error show up both on server and client. Unfortunately,
204
// React refuses to issue the same error twice to avoid clogging up the console.
@@ -996,4 +1021,448 @@ describe('ReactDOMServerIntegration', () => {
1021
itThrowsWhenRendering('string', render => render('foo'));
1022
});
1023
});
1024
+
1025
+ describe('context', function() {
1026
+ let PurpleContext, RedContext;
1027
+ beforeEach(() => {
1028
+ class Parent extends React.Component {
1029
+ getChildContext() {
1030
+ return {text: this.props.text};
1031
+ }
1032
+ render() {
1033
+ return this.props.children;
1034
+ }
1035
+ }
1036
+ Parent.childContextTypes = {text: React.PropTypes.string};
1037
+
1038
+ PurpleContext = props => <Parent text="purple">{props.children}</Parent>;
1039
+ RedContext = props => <Parent text="red">{props.children}</Parent>;
1040
+ });
1041
+
1042
+ itRenders('class child with context', async render => {
1043
+ class ClassChildWithContext extends React.Component {
1044
+ render() {
1045
+ return <div>{this.context.text}</div>;
1046
+ }
1047
+ }
1048
+ ClassChildWithContext.contextTypes = {text: React.PropTypes.string};
1049
+
1050
+ const e = await render(
1051
+ <PurpleContext><ClassChildWithContext /></PurpleContext>,
1052
+ );
1053
+ expect(e.textContent).toBe('purple');
1054
+ });
1055
+
1056
+ itRenders('stateless child with context', async render => {
1057
+ function StatelessChildWithContext(props, context) {
1058
+ return <div>{context.text}</div>;
1059
+ }
1060
+ StatelessChildWithContext.contextTypes = {text: React.PropTypes.string};
1061
+
1062
+ const e = await render(
1063
+ <PurpleContext><StatelessChildWithContext /></PurpleContext>,
1064
+ );
1065
+ expect(e.textContent).toBe('purple');
1066
+ });
1067
+
1068
+ itRenders('class child without context', async render => {
1069
+ class ClassChildWithoutContext extends React.Component {
1070
+ render() {
1071
+ // this should render blank; context isn't passed to this component.
1072
+ return <div>{this.context.text}</div>;
1073
+ }
1074
+ }
1075
+
1076
+ const e = await render(
1077
+ <PurpleContext><ClassChildWithoutContext /></PurpleContext>,
1078
+ );
1079
+ expect(e.textContent).toBe('');
1080
+ });
1081
+
1082
+ itRenders('stateless child without context', async render => {
1083
+ function StatelessChildWithoutContext(props, context) {
1084
+ // this should render blank; context isn't passed to this component.
1085
+ return <div>{context.text}</div>;
1086
+ }
1087
+
1088
+ const e = await render(
1089
+ <PurpleContext><StatelessChildWithoutContext /></PurpleContext>,
1090
+ );
1091
+ expect(e.textContent).toBe('');
1092
+ });
1093
+
1094
+ itRenders('class child with wrong context', async render => {
1095
+ class ClassChildWithWrongContext extends React.Component {
1096
+ render() {
1097
+ // this should render blank; context.text isn't passed to this component.
1098
+ return <div id="classWrongChild">{this.context.text}</div>;
1099
+ }
1100
+ }
1101
+ ClassChildWithWrongContext.contextTypes = {foo: React.PropTypes.string};
1102
+
1103
+ const e = await render(
1104
+ <PurpleContext><ClassChildWithWrongContext /></PurpleContext>,
1105
+ );
1106
+ expect(e.textContent).toBe('');
1107
+ });
1108
+
1109
+ itRenders('stateless child with wrong context', async render => {
1110
+ function StatelessChildWithWrongContext(props, context) {
1111
+ // this should render blank; context.text isn't passed to this component.
1112
+ return <div id="statelessWrongChild">{context.text}</div>;
1113
+ }
1114
+ StatelessChildWithWrongContext.contextTypes = {
1115
+ foo: React.PropTypes.string,
1116
+ };
1117
+
1118
+ const e = await render(
1119
+ <PurpleContext><StatelessChildWithWrongContext /></PurpleContext>,
1120
+ );
1121
+ expect(e.textContent).toBe('');
1122
+ });
1123
+
1124
+ itRenders('with context passed through to a grandchild', async render => {
1125
+ function Grandchild(props, context) {
1126
+ return <div>{context.text}</div>;
1127
+ }
1128
+ Grandchild.contextTypes = {text: React.PropTypes.string};
1129
+
1130
+ const Child = props => <Grandchild />;
1131
+
1132
+ const e = await render(<PurpleContext><Child /></PurpleContext>);
1133
+ expect(e.textContent).toBe('purple');
1134
+ });
1135
+
1136
+ itRenders('a child context overriding a parent context', async render => {
1137
+ const Grandchild = (props, context) => {
1138
+ return <div>{context.text}</div>;
1139
+ };
1140
+ Grandchild.contextTypes = {text: React.PropTypes.string};
1141
+
1142
+ const e = await render(
1143
+ <PurpleContext><RedContext><Grandchild /></RedContext></PurpleContext>,
1144
+ );
1145
+ expect(e.textContent).toBe('red');
1146
+ });
1147
+
1148
+ itRenders('a child context merged with a parent context', async render => {
1149
+ class Parent extends React.Component {
1150
+ getChildContext() {
1151
+ return {text1: 'purple'};
1152
+ }
1153
+ render() {
1154
+ return <Child />;
1155
+ }
1156
+ }
1157
+ Parent.childContextTypes = {text1: React.PropTypes.string};
1158
+
1159
+ class Child extends React.Component {
1160
+ getChildContext() {
1161
+ return {text2: 'red'};
1162
+ }
1163
+ render() {
1164
+ return <Grandchild />;
1165
+ }
1166
+ }
1167
+ Child.childContextTypes = {text2: React.PropTypes.string};
1168
+
1169
+ const Grandchild = (props, context) => {
1170
+ return (
1171
+ <div>
1172
+ <div id="first">{context.text1}</div>
1173
+ <div id="second">{context.text2}</div>
1174
+ </div>
1175
+ );
1176
+ };
1177
+ Grandchild.contextTypes = {
1178
+ text1: React.PropTypes.string,
1179
+ text2: React.PropTypes.string,
1180
+ };
1181
+
1182
+ const e = await render(<Parent />);
1183
+ expect(e.querySelector('#first').textContent).toBe('purple');
1184
+ expect(e.querySelector('#second').textContent).toBe('red');
1185
+ });
1186
+
1187
+ itRenders(
1188
+ 'with a call to componentWillMount before getChildContext',
1189
+ async render => {
1190
+ class WillMountContext extends React.Component {
1191
+ getChildContext() {
1192
+ return {text: this.state.text};
1193
+ }
1194
+ componentWillMount() {
1195
+ this.setState({text: 'foo'});
1196
+ }
1197
+ render() {
1198
+ return <Child />;
1199
+ }
1200
+ }
1201
+ WillMountContext.childContextTypes = {text: React.PropTypes.string};
1202
+
1203
+ const Child = (props, context) => {
1204
+ return <div>{context.text}</div>;
1205
+ };
1206
+ Child.contextTypes = {text: React.PropTypes.string};
1207
+
1208
+ const e = await render(<WillMountContext />);
1209
+ expect(e.textContent).toBe('foo');
1210
+ },
1211
+ );
1212
+
1213
+ itThrowsWhenRendering(
1214
+ 'if getChildContext exists without childContextTypes',
1215
+ render => {
1216
+ class Component extends React.Component {
1217
+ render() {
1218
+ return <div />;
1219
+ }
1220
+ getChildContext() {
1221
+ return {foo: 'bar'};
1222
+ }
1223
+ }
1224
+ return render(<Component />);
1225
+ },
1226
+ );
1227
+
1228
+ itThrowsWhenRendering(
1229
+ 'if getChildContext returns a value not in childContextTypes',
1230
+ render => {
1231
+ class Component extends React.Component {
1232
+ render() {
1233
+ return <div />;
1234
+ }
1235
+ getChildContext() {
1236
+ return {value1: 'foo', value2: 'bar'};
1237
+ }
1238
+ }
1239
+ Component.childContextTypes = {value1: React.PropTypes.string};
1240
+ return render(<Component />);
1241
+ },
1242
+ );
1243
+ });
1244
+
1245
+ describe('refs', function() {
1246
+ it('should not run ref code on server', async () => {
1247
+ let refCount = 0;
1248
+ class RefsComponent extends React.Component {
1249
+ render() {
1250
+ return <div ref={e => refCount++} />;
1251
+ }
1252
+ }
1253
+ await expectMarkupMatch(<RefsComponent />, <div />);
1254
+ expect(refCount).toBe(0);
1255
+ });
1256
+
1257
+ it('should run ref code on client', async () => {
1258
+ let refCount = 0;
1259
+ class RefsComponent extends React.Component {
1260
+ render() {
1261
+ return <div ref={e => refCount++} />;
1262
+ }
1263
+ }
1264
+ await expectMarkupMatch(<div />, <RefsComponent />);
1265
+ expect(refCount).toBe(1);
1266
+ });
1267
+
1268
+ it('should send the correct element to ref functions on client', async () => {
1269
+ let refElement = null;
1270
+ class RefsComponent extends React.Component {
1271
+ render() {
1272
+ return <div ref={e => refElement = e} />;
1273
+ }
1274
+ }
1275
+ const e = await clientRenderOnServerString(<RefsComponent />);
1276
+ expect(refElement).not.toBe(null);
1277
+ expect(refElement).toBe(e);
1278
+ });
1279
+
1280
+ it('should have string refs on client when rendered over server markup', async () => {
1281
+ class RefsComponent extends React.Component {
1282
+ render() {
1283
+ return <div ref="myDiv" />;
1284
+ }
1285
+ }
1286
+
1287
+ const markup = ReactDOMServer.renderToString(<RefsComponent />);
1288
+ const root = document.createElement('div');
1289
+ root.innerHTML = markup;
1290
+ let component = null;
1291
+ resetModules();
1292
+ await asyncReactDOMRender(
1293
+ <RefsComponent ref={e => component = e} />,
1294
+ root,
1295
+ );
1296
+ expect(component.refs.myDiv).toBe(root.firstChild);
1297
+ });
1298
+ });
1299
+
1300
+ describe('reconnecting to server markup', function() {
1301
+ var EmptyComponent;
1302
+ beforeEach(() => {
1303
+ EmptyComponent = class extends React.Component {
1304
+ render() {
1305
+ return null;
1306
+ }
1307
+ };
1308
+ });
1309
+
1310
+ describe('elements', function() {
1311
+ describe('reconnecting different component implementations', function() {
1312
+ let ES6ClassComponent, PureComponent, bareElement;
1313
+ beforeEach(() => {
1314
+ // try each type of component on client and server.
1315
+ ES6ClassComponent = class extends React.Component {
1316
+ render() {
1317
+ return <div id={this.props.id} />;
1318
+ }
1319
+ };
1320
+ PureComponent = props => <div id={props.id} />;
1321
+ bareElement = <div id="foobarbaz" />;
1322
+ });
1323
+
1324
+ it('should reconnect ES6 Class to ES6 Class', () =>
1325
+ expectMarkupMatch(
1326
+ <ES6ClassComponent id="foobarbaz" />,
1327
+ <ES6ClassComponent id="foobarbaz" />,
1328
+ ));
1329
+
1330
+ it('should reconnect Pure Component to ES6 Class', () =>
1331
+ expectMarkupMatch(
1332
+ <ES6ClassComponent id="foobarbaz" />,
1333
+ <PureComponent id="foobarbaz" />,
1334
+ ));
1335
+
1336
+ it('should reconnect Bare Element to ES6 Class', () =>
1337
+ expectMarkupMatch(<ES6ClassComponent id="foobarbaz" />, bareElement));
1338
+
1339
+ it('should reconnect ES6 Class to Pure Component', () =>
1340
+ expectMarkupMatch(
1341
+ <PureComponent id="foobarbaz" />,
1342
+ <ES6ClassComponent id="foobarbaz" />,
1343
+ ));
1344
+
1345
+ it('should reconnect Pure Component to Pure Component', () =>
1346
+ expectMarkupMatch(
1347
+ <PureComponent id="foobarbaz" />,
1348
+ <PureComponent id="foobarbaz" />,
1349
+ ));
1350
+
1351
+ it('should reconnect Bare Element to Pure Component', () =>
1352
+ expectMarkupMatch(<PureComponent id="foobarbaz" />, bareElement));
1353
+
1354
+ it('should reconnect ES6 Class to Bare Element', () =>
1355
+ expectMarkupMatch(bareElement, <ES6ClassComponent id="foobarbaz" />));
1356
+
1357
+ it('should reconnect Pure Component to Bare Element', () =>
1358
+ expectMarkupMatch(bareElement, <PureComponent id="foobarbaz" />));
1359
+
1360
+ it('should reconnect Bare Element to Bare Element', () =>
1361
+ expectMarkupMatch(bareElement, bareElement));
1362
+ });
1363
+
1364
+ it('should error reconnecting different element types', () =>
1365
+ expectMarkupMismatch(<div />, <span />));
1366
+
1367
+ it('should error reconnecting missing attributes', () =>
1368
+ expectMarkupMismatch(<div id="foo" />, <div />));
1369
+
1370
+ it('should error reconnecting added attributes', () =>
1371
+ expectMarkupMismatch(<div />, <div id="foo" />));
1372
+
1373
+ it('should error reconnecting different attribute values', () =>
1374
+ expectMarkupMismatch(<div id="foo" />, <div id="bar" />));
1375
+ });
1376
+
1377
+ describe('text nodes', function() {
1378
+ it('should error reconnecting different text', () =>
1379
+ expectMarkupMismatch(<div>Text</div>, <div>Other Text</div>));
1380
+
1381
+ it('should reconnect a div with a number and string version of number', () =>
1382
+ expectMarkupMatch(<div>{2}</div>, <div>2</div>));
1383
+
1384
+ it('should error reconnecting different numbers', () =>
1385
+ expectMarkupMismatch(<div>{2}</div>, <div>{3}</div>));
1386
+
1387
+ it('should error reconnecting different number from text', () =>
1388
+ expectMarkupMismatch(<div>{2}</div>, <div>3</div>));
1389
+
1390
+ it('should error reconnecting different text in two code blocks', () =>
1391
+ expectMarkupMismatch(
1392
+ <div>{'Text1'}{'Text2'}</div>,
1393
+ <div>{'Text1'}{'Text3'}</div>,
1394
+ ));
1395
+ });
1396
+
1397
+ describe('element trees and children', function() {
1398
+ it('should error reconnecting missing children', () =>
1399
+ expectMarkupMismatch(<div><div /></div>, <div />));
1400
+
1401
+ it('should error reconnecting added children', () =>
1402
+ expectMarkupMismatch(<div />, <div><div /></div>));
1403
+
1404
+ it('should error reconnecting more children', () =>
1405
+ expectMarkupMismatch(<div><div /></div>, <div><div /><div /></div>));
1406
+
1407
+ it('should error reconnecting fewer children', () =>
1408
+ expectMarkupMismatch(<div><div /><div /></div>, <div><div /></div>));
1409
+
1410
+ it('should error reconnecting reordered children', () =>
1411
+ expectMarkupMismatch(
1412
+ <div><div /><span /></div>,
1413
+ <div><span /><div /></div>,
1414
+ ));
1415
+
1416
+ it('should error reconnecting a div with children separated by whitespace on the client', () =>
1417
+ expectMarkupMismatch(
1418
+ <div id="parent"><div id="child1" /><div id="child2" /></div>,
1419
+ // prettier-ignore
1420
+ <div id="parent"><div id="child1" /> <div id="child2" /></div>, // eslint-disable-line no-multi-spaces
1421
+ ));
1422
+
1423
+ it('should error reconnecting a div with children separated by different whitespace on the server', () =>
1424
+ expectMarkupMismatch(
1425
+ // prettier-ignore
1426
+ <div id="parent"><div id="child1" /> <div id="child2" /></div>, // eslint-disable-line no-multi-spaces
1427
+ <div id="parent"><div id="child1" /><div id="child2" /></div>,
1428
+ ));
1429
+
1430
+ it('should error reconnecting a div with children separated by different whitespace', () =>
1431
+ expectMarkupMismatch(
1432
+ <div id="parent"><div id="child1" /> <div id="child2" /></div>,
1433
+ // prettier-ignore
1434
+ <div id="parent"><div id="child1" /> <div id="child2" /></div>, // eslint-disable-line no-multi-spaces
1435
+ ));
1436
+
1437
+ it('can distinguish an empty component from a dom node', () =>
1438
+ expectMarkupMismatch(
1439
+ <div><span /></div>,
1440
+ <div><EmptyComponent /></div>,
1441
+ ));
1442
+
1443
+ it('can distinguish an empty component from an empty text component', () =>
1444
+ expectMarkupMismatch(<div><EmptyComponent /></div>, <div>{''}</div>));
1445
+
1446
+ it('should reconnect if component trees differ but resulting markup is the same', () => {
1447
+ class Component1 extends React.Component {
1448
+ render() {
1449
+ return <span id="foobar" />;
1450
+ }
1451
+ }
1452
+ class Component2 extends React.Component {
1453
+ render() {
1454
+ return <span id="foobar" />;
1455
+ }
1456
+ }
1457
+ return expectMarkupMatch(<Component1 />, <Component2 />);
1458
+ });
1459
+ });
1460
+
1461
+ // Markup Mismatches: misc
1462
+ it('should error reconnecting a div with different dangerouslySetInnerHTML', () =>
1463
+ expectMarkupMismatch(
1464
+ <div dangerouslySetInnerHTML={{__html: "<span id='child1'/>"}} />,
1465
+ <div dangerouslySetInnerHTML={{__html: "<span id='child2'/>"}} />,
1466
+ ));
1467
+ });
1468
});