@samitouri / QOS-React / commits / 983ec90764

Always run React.Fragment tests (#11430)

Dan Abramov committed Nov 2, 2017 at 13:31 UTC 983ec907649be4259ecbc7241c5ab7a43a9cecf5
3 files changed +608 -615
packages/react-dom/src/__tests__/ReactDOMServerIntegration-test.js
+45 -47
@@ -316,6 +316,7 @@ function resetModules() {
316
317 // TODO: can we express this test with only public API?
318 ExecutionEnvironment = require('fbjs/lib/ExecutionEnvironment');
319 + require('shared/ReactFeatureFlags').enableReactFragment = true;
320
321 PropTypes = require('prop-types');
322 React = require('react');
@@ -326,6 +327,7 @@ function resetModules() {
327 // Resetting is important because we want to avoid any shared state
328 // influencing the tests.
329 jest.resetModuleRegistry();
330 + require('shared/ReactFeatureFlags').enableReactFragment = true;
331 ReactDOMServer = require('react-dom/server');
332 }
333
@@ -404,56 +406,54 @@ describe('ReactDOMServerIntegration', () => {
406 expect(parent.childNodes[2].tagName).toBe('P');
407 });
408
407 - if (ReactFeatureFlags.enableReactFragment) {
408 - itRenders('a fragment with one child', async render => {
409 - let e = await render(<React.Fragment><div>text1</div></React.Fragment>);
410 - let parent = e.parentNode;
411 - expect(parent.childNodes[0].tagName).toBe('DIV');
412 - });
409 + itRenders('a fragment with one child', async render => {
410 + let e = await render(<React.Fragment><div>text1</div></React.Fragment>);
411 + let parent = e.parentNode;
412 + expect(parent.childNodes[0].tagName).toBe('DIV');
413 + });
414
414 - itRenders('a fragment with several children', async render => {
415 - let Header = props => {
416 - return <p>header</p>;
417 - };
418 - let Footer = props => {
419 - return <React.Fragment><h2>footer</h2><h3>about</h3></React.Fragment>;
420 - };
421 - let e = await render(
415 + itRenders('a fragment with several children', async render => {
416 + let Header = props => {
417 + return <p>header</p>;
418 + };
419 + let Footer = props => {
420 + return <React.Fragment><h2>footer</h2><h3>about</h3></React.Fragment>;
421 + };
422 + let e = await render(
423 + <React.Fragment>
424 + <div>text1</div>
425 + <span>text2</span>
426 + <Header />
427 + <Footer />
428 + </React.Fragment>,
429 + );
430 + let parent = e.parentNode;
431 + expect(parent.childNodes[0].tagName).toBe('DIV');
432 + expect(parent.childNodes[1].tagName).toBe('SPAN');
433 + expect(parent.childNodes[2].tagName).toBe('P');
434 + expect(parent.childNodes[3].tagName).toBe('H2');
435 + expect(parent.childNodes[4].tagName).toBe('H3');
436 + });
437 +
438 + itRenders('a nested fragment', async render => {
439 + let e = await render(
440 + <React.Fragment>
441 <React.Fragment>
442 <div>text1</div>
424 - <span>text2</span>
425 - <Header />
426 - <Footer />
427 - </React.Fragment>,
428 - );
429 - let parent = e.parentNode;
430 - expect(parent.childNodes[0].tagName).toBe('DIV');
431 - expect(parent.childNodes[1].tagName).toBe('SPAN');
432 - expect(parent.childNodes[2].tagName).toBe('P');
433 - expect(parent.childNodes[3].tagName).toBe('H2');
434 - expect(parent.childNodes[4].tagName).toBe('H3');
435 - });
436 -
437 - itRenders('a nested fragment', async render => {
438 - let e = await render(
443 + </React.Fragment>
444 + <span>text2</span>
445 <React.Fragment>
446 <React.Fragment>
441 - <div>text1</div>
447 + <React.Fragment>{null}<p /></React.Fragment>{false}
448 </React.Fragment>
443 - <span>text2</span>
444 - <React.Fragment>
445 - <React.Fragment>
446 - <React.Fragment>{null}<p /></React.Fragment>{false}
447 - </React.Fragment>
448 - </React.Fragment>
449 - </React.Fragment>,
450 - );
451 - let parent = e.parentNode;
452 - expect(parent.childNodes[0].tagName).toBe('DIV');
453 - expect(parent.childNodes[1].tagName).toBe('SPAN');
454 - expect(parent.childNodes[2].tagName).toBe('P');
455 - });
456 - }
449 + </React.Fragment>
450 + </React.Fragment>,
451 + );
452 + let parent = e.parentNode;
453 + expect(parent.childNodes[0].tagName).toBe('DIV');
454 + expect(parent.childNodes[1].tagName).toBe('SPAN');
455 + expect(parent.childNodes[2].tagName).toBe('P');
456 + });
457
458 itRenders('an iterable', async render => {
459 const threeDivIterable = {
@@ -487,9 +487,7 @@ describe('ReactDOMServerIntegration', () => {
487 // but server returns empty HTML. So we compare parent text.
488 expect((await render(<div>{''}</div>)).textContent).toBe('');
489
490 - if (ReactFeatureFlags.enableReactFragment) {
491 - expect(await render(<React.Fragment />)).toBe(null);
492 - }
490 + expect(await render(<React.Fragment />)).toBe(null);
491 expect(await render([])).toBe(null);
492 expect(await render(false)).toBe(null);
493 expect(await render(true)).toBe(null);
packages/react-reconciler/src/__tests__/ReactFragment-test.js
+502 -506
@@ -16,6 +16,10 @@ let ReactNoop;
16 describe('ReactFragment', () => {
17 beforeEach(function() {
18 jest.resetModules();
19 +
20 + const ReactFeatureFlags = require('shared/ReactFeatureFlags');
21 + ReactFeatureFlags.enableReactFragment = true;
22 +
23 React = require('react');
24 ReactNoop = require('react-noop-renderer');
25 });
@@ -33,699 +37,691 @@ describe('ReactFragment', () => {
37 return {type: 'div', children, prop: undefined};
38 }
39
36 - if (ReactFeatureFlags.enableReactFragment) {
37 - it('should render a single child via noop renderer', () => {
38 - const element = (
39 - <React.Fragment>
40 - <span>foo</span>
41 - </React.Fragment>
42 - );
40 + it('should render a single child via noop renderer', () => {
41 + const element = (
42 + <React.Fragment>
43 + <span>foo</span>
44 + </React.Fragment>
45 + );
46
44 - ReactNoop.render(element);
45 - ReactNoop.flush();
47 + ReactNoop.render(element);
48 + ReactNoop.flush();
49
47 - expect(ReactNoop.getChildren()).toEqual([span()]);
48 - });
49 -
50 - it('should render zero children via noop renderer', () => {
51 - const element = <React.Fragment />;
50 + expect(ReactNoop.getChildren()).toEqual([span()]);
51 + });
52
53 - ReactNoop.render(element);
54 - ReactNoop.flush();
53 + it('should render zero children via noop renderer', () => {
54 + const element = <React.Fragment />;
55
56 - expect(ReactNoop.getChildren()).toEqual([]);
57 - });
56 + ReactNoop.render(element);
57 + ReactNoop.flush();
58
59 - it('should render multiple children via noop renderer', () => {
60 - const element = (
61 - <React.Fragment>
62 - hello <span>world</span>
63 - </React.Fragment>
64 - );
59 + expect(ReactNoop.getChildren()).toEqual([]);
60 + });
61
66 - ReactNoop.render(element);
67 - ReactNoop.flush();
62 + it('should render multiple children via noop renderer', () => {
63 + const element = (
64 + <React.Fragment>
65 + hello <span>world</span>
66 + </React.Fragment>
67 + );
68
69 - expect(ReactNoop.getChildren()).toEqual([text('hello '), span()]);
70 - });
69 + ReactNoop.render(element);
70 + ReactNoop.flush();
71
72 - it('should render an iterable via noop renderer', () => {
73 - const element = (
74 - <React.Fragment>
75 - {new Set([<span key="a">hi</span>, <span key="b">bye</span>])}
76 - </React.Fragment>
77 - );
72 + expect(ReactNoop.getChildren()).toEqual([text('hello '), span()]);
73 + });
74
79 - ReactNoop.render(element);
80 - ReactNoop.flush();
75 + it('should render an iterable via noop renderer', () => {
76 + const element = (
77 + <React.Fragment>
78 + {new Set([<span key="a">hi</span>, <span key="b">bye</span>])}
79 + </React.Fragment>
80 + );
81
82 - expect(ReactNoop.getChildren()).toEqual([span(), span()]);
83 - });
82 + ReactNoop.render(element);
83 + ReactNoop.flush();
84
85 - it('should preserve state of children with 1 level nesting', function() {
86 - var ops = [];
85 + expect(ReactNoop.getChildren()).toEqual([span(), span()]);
86 + });
87
88 - class Stateful extends React.Component {
89 - componentDidUpdate() {
90 - ops.push('Update Stateful');
91 - }
88 + it('should preserve state of children with 1 level nesting', function() {
89 + var ops = [];
90
93 - render() {
94 - return <div>Hello</div>;
95 - }
91 + class Stateful extends React.Component {
92 + componentDidUpdate() {
93 + ops.push('Update Stateful');
94 }
95
98 - function Foo({condition}) {
99 - return condition
100 - ? <Stateful key="a" />
101 - : <React.Fragment>
102 - <Stateful key="a" />
103 - <div key="b">World</div>
104 - </React.Fragment>;
96 + render() {
97 + return <div>Hello</div>;
98 }
99 + }
100
107 - ReactNoop.render(<Foo condition={true} />);
108 - ReactNoop.flush();
101 + function Foo({condition}) {
102 + return condition
103 + ? <Stateful key="a" />
104 + : <React.Fragment>
105 + <Stateful key="a" />
106 + <div key="b">World</div>
107 + </React.Fragment>;
108 + }
109
110 - ReactNoop.render(<Foo condition={false} />);
111 - ReactNoop.flush();
110 + ReactNoop.render(<Foo condition={true} />);
111 + ReactNoop.flush();
112
113 - expect(ops).toEqual(['Update Stateful']);
114 - expect(ReactNoop.getChildren()).toEqual([div(), div()]);
113 + ReactNoop.render(<Foo condition={false} />);
114 + ReactNoop.flush();
115
116 - ReactNoop.render(<Foo condition={true} />);
117 - ReactNoop.flush();
116 + expect(ops).toEqual(['Update Stateful']);
117 + expect(ReactNoop.getChildren()).toEqual([div(), div()]);
118
119 - expect(ops).toEqual(['Update Stateful', 'Update Stateful']);
120 - expect(ReactNoop.getChildren()).toEqual([div()]);
121 - });
119 + ReactNoop.render(<Foo condition={true} />);
120 + ReactNoop.flush();
121
123 - it('should preserve state between top-level fragments', function() {
124 - var ops = [];
122 + expect(ops).toEqual(['Update Stateful', 'Update Stateful']);
123 + expect(ReactNoop.getChildren()).toEqual([div()]);
124 + });
125
126 - class Stateful extends React.Component {
127 - componentDidUpdate() {
128 - ops.push('Update Stateful');
129 - }
126 + it('should preserve state between top-level fragments', function() {
127 + var ops = [];
128
131 - render() {
132 - return <div>Hello</div>;
133 - }
129 + class Stateful extends React.Component {
130 + componentDidUpdate() {
131 + ops.push('Update Stateful');
132 }
133
136 - function Foo({condition}) {
137 - return condition
138 - ? <React.Fragment>
139 - <Stateful />
140 - </React.Fragment>
141 - : <React.Fragment>
142 - <Stateful />
143 - </React.Fragment>;
134 + render() {
135 + return <div>Hello</div>;
136 }
137 + }
138
146 - ReactNoop.render(<Foo condition={true} />);
147 - ReactNoop.flush();
139 + function Foo({condition}) {
140 + return condition
141 + ? <React.Fragment>
142 + <Stateful />
143 + </React.Fragment>
144 + : <React.Fragment>
145 + <Stateful />
146 + </React.Fragment>;
147 + }
148
149 - ReactNoop.render(<Foo condition={false} />);
150 - ReactNoop.flush();
149 + ReactNoop.render(<Foo condition={true} />);
150 + ReactNoop.flush();
151
152 - expect(ops).toEqual(['Update Stateful']);
153 - expect(ReactNoop.getChildren()).toEqual([div()]);
152 + ReactNoop.render(<Foo condition={false} />);
153 + ReactNoop.flush();
154
155 - ReactNoop.render(<Foo condition={true} />);
156 - ReactNoop.flush();
155 + expect(ops).toEqual(['Update Stateful']);
156 + expect(ReactNoop.getChildren()).toEqual([div()]);
157
158 - expect(ops).toEqual(['Update Stateful', 'Update Stateful']);
159 - expect(ReactNoop.getChildren()).toEqual([div()]);
160 - });
158 + ReactNoop.render(<Foo condition={true} />);
159 + ReactNoop.flush();
160
162 - it('should preserve state of children nested at same level', function() {
163 - var ops = [];
161 + expect(ops).toEqual(['Update Stateful', 'Update Stateful']);
162 + expect(ReactNoop.getChildren()).toEqual([div()]);
163 + });
164 +
165 + it('should preserve state of children nested at same level', function() {
166 + var ops = [];
167
165 - class Stateful extends React.Component {
166 - componentDidUpdate() {
167 - ops.push('Update Stateful');
168 - }
168 + class Stateful extends React.Component {
169 + componentDidUpdate() {
170 + ops.push('Update Stateful');
171 + }
172
170 - render() {
171 - return <div>Hello</div>;
172 - }
173 + render() {
174 + return <div>Hello</div>;
175 }
176 + }
177
175 - function Foo({condition}) {
176 - return condition
177 - ? <React.Fragment>
178 + function Foo({condition}) {
179 + return condition
180 + ? <React.Fragment>
181 + <React.Fragment>
182 <React.Fragment>
179 - <React.Fragment>
180 - <Stateful key="a" />
181 - </React.Fragment>
183 + <Stateful key="a" />
184 </React.Fragment>
185 </React.Fragment>
184 - : <React.Fragment>
186 + </React.Fragment>
187 + : <React.Fragment>
188 + <React.Fragment>
189 <React.Fragment>
186 - <React.Fragment>
187 - <div />
188 - <Stateful key="a" />
189 - </React.Fragment>
190 + <div />
191 + <Stateful key="a" />
192 </React.Fragment>
191 - </React.Fragment>;
192 - }
193 -
194 - ReactNoop.render(<Foo condition={true} />);
195 - ReactNoop.flush();
193 + </React.Fragment>
194 + </React.Fragment>;
195 + }
196
197 - ReactNoop.render(<Foo condition={false} />);
198 - ReactNoop.flush();
197 + ReactNoop.render(<Foo condition={true} />);
198 + ReactNoop.flush();
199
200 - expect(ops).toEqual(['Update Stateful']);
201 - expect(ReactNoop.getChildren()).toEqual([div(), div()]);
200 + ReactNoop.render(<Foo condition={false} />);
201 + ReactNoop.flush();
202
203 - ReactNoop.render(<Foo condition={true} />);
204 - ReactNoop.flush();
203 + expect(ops).toEqual(['Update Stateful']);
204 + expect(ReactNoop.getChildren()).toEqual([div(), div()]);
205
206 - expect(ops).toEqual(['Update Stateful', 'Update Stateful']);
207 - expect(ReactNoop.getChildren()).toEqual([div()]);
208 - });
206 + ReactNoop.render(<Foo condition={true} />);
207 + ReactNoop.flush();
208
210 - it('should not preserve state in non-top-level fragment nesting', function() {
211 - var ops = [];
209 + expect(ops).toEqual(['Update Stateful', 'Update Stateful']);
210 + expect(ReactNoop.getChildren()).toEqual([div()]);
211 + });
212
213 - class Stateful extends React.Component {
214 - componentDidUpdate() {
215 - ops.push('Update Stateful');
216 - }
213 + it('should not preserve state in non-top-level fragment nesting', function() {
214 + var ops = [];
215
218 - render() {
219 - return <div>Hello</div>;
220 - }
216 + class Stateful extends React.Component {
217 + componentDidUpdate() {
218 + ops.push('Update Stateful');
219 }
220
223 - function Foo({condition}) {
224 - return condition
225 - ? <React.Fragment>
226 - <React.Fragment><Stateful key="a" /></React.Fragment>
227 - </React.Fragment>
228 - : <React.Fragment><Stateful key="a" /></React.Fragment>;
221 + render() {
222 + return <div>Hello</div>;
223 }
224 + }
225
231 - ReactNoop.render(<Foo condition={true} />);
232 - ReactNoop.flush();
226 + function Foo({condition}) {
227 + return condition
228 + ? <React.Fragment>
229 + <React.Fragment><Stateful key="a" /></React.Fragment>
230 + </React.Fragment>
231 + : <React.Fragment><Stateful key="a" /></React.Fragment>;
232 + }
233
234 - ReactNoop.render(<Foo condition={false} />);
235 - ReactNoop.flush();
234 + ReactNoop.render(<Foo condition={true} />);
235 + ReactNoop.flush();
236
237 - expect(ops).toEqual([]);
238 - expect(ReactNoop.getChildren()).toEqual([div()]);
237 + ReactNoop.render(<Foo condition={false} />);
238 + ReactNoop.flush();
239
240 - ReactNoop.render(<Foo condition={true} />);
241 - ReactNoop.flush();
240 + expect(ops).toEqual([]);
241 + expect(ReactNoop.getChildren()).toEqual([div()]);
242
243 - expect(ops).toEqual([]);
244 - expect(ReactNoop.getChildren()).toEqual([div()]);
245 - });
243 + ReactNoop.render(<Foo condition={true} />);
244 + ReactNoop.flush();
245
247 - it('should not preserve state of children if nested 2 levels without siblings', function() {
248 - var ops = [];
246 + expect(ops).toEqual([]);
247 + expect(ReactNoop.getChildren()).toEqual([div()]);
248 + });
249
250 - class Stateful extends React.Component {
251 - componentDidUpdate() {
252 - ops.push('Update Stateful');
253 - }
250 + it('should not preserve state of children if nested 2 levels without siblings', function() {
251 + var ops = [];
252
255 - render() {
256 - return <div>Hello</div>;
257 - }
253 + class Stateful extends React.Component {
254 + componentDidUpdate() {
255 + ops.push('Update Stateful');
256 }
257
260 - function Foo({condition}) {
261 - return condition
262 - ? <Stateful key="a" />
263 - : <React.Fragment>
264 - <React.Fragment>
265 - <Stateful key="a" />
266 - </React.Fragment>
267 - </React.Fragment>;
258 + render() {
259 + return <div>Hello</div>;
260 }
261 + }
262
270 - ReactNoop.render(<Foo condition={true} />);
271 - ReactNoop.flush();
263 + function Foo({condition}) {
264 + return condition
265 + ? <Stateful key="a" />
266 + : <React.Fragment>
267 + <React.Fragment>
268 + <Stateful key="a" />
269 + </React.Fragment>
270 + </React.Fragment>;
271 + }
272
273 - ReactNoop.render(<Foo condition={false} />);
274 - ReactNoop.flush();
273 + ReactNoop.render(<Foo condition={true} />);
274 + ReactNoop.flush();
275
276 - expect(ops).toEqual([]);
277 - expect(ReactNoop.getChildren()).toEqual([div()]);
276 + ReactNoop.render(<Foo condition={false} />);
277 + ReactNoop.flush();
278
279 - ReactNoop.render(<Foo condition={true} />);
280 - ReactNoop.flush();
279 + expect(ops).toEqual([]);
280 + expect(ReactNoop.getChildren()).toEqual([div()]);
281
282 - expect(ops).toEqual([]);
283 - expect(ReactNoop.getChildren()).toEqual([div()]);
284 - });
282 + ReactNoop.render(<Foo condition={true} />);
283 + ReactNoop.flush();
284
286 - it('should not preserve state of children if nested 2 levels with siblings', function() {
287 - var ops = [];
285 + expect(ops).toEqual([]);
286 + expect(ReactNoop.getChildren()).toEqual([div()]);
287 + });
288
289 - class Stateful extends React.Component {
290 - componentDidUpdate() {
291 - ops.push('Update Stateful');
292 - }
289 + it('should not preserve state of children if nested 2 levels with siblings', function() {
290 + var ops = [];
291
294 - render() {
295 - return <div>Hello</div>;
296 - }
292 + class Stateful extends React.Component {
293 + componentDidUpdate() {
294 + ops.push('Update Stateful');
295 }
296
299 - function Foo({condition}) {
300 - return condition
301 - ? <Stateful key="a" />
302 - : <React.Fragment>
303 - <React.Fragment>
304 - <Stateful key="a" />
305 - </React.Fragment>
306 - <div />
307 - </React.Fragment>;
297 + render() {
298 + return <div>Hello</div>;
299 }
300 + }
301
310 - ReactNoop.render(<Foo condition={true} />);
311 - ReactNoop.flush();
302 + function Foo({condition}) {
303 + return condition
304 + ? <Stateful key="a" />
305 + : <React.Fragment>
306 + <React.Fragment>
307 + <Stateful key="a" />
308 + </React.Fragment>
309 + <div />
310 + </React.Fragment>;
311 + }
312
313 - ReactNoop.render(<Foo condition={false} />);
314 - ReactNoop.flush();
313 + ReactNoop.render(<Foo condition={true} />);
314 + ReactNoop.flush();
315
316 - expect(ops).toEqual([]);
317 - expect(ReactNoop.getChildren()).toEqual([div(), div()]);
316 + ReactNoop.render(<Foo condition={false} />);
317 + ReactNoop.flush();
318
319 - ReactNoop.render(<Foo condition={true} />);
320 - ReactNoop.flush();
319 + expect(ops).toEqual([]);
320 + expect(ReactNoop.getChildren()).toEqual([div(), div()]);
321
322 - expect(ops).toEqual([]);
323 - expect(ReactNoop.getChildren()).toEqual([div()]);
324 - });
322 + ReactNoop.render(<Foo condition={true} />);
323 + ReactNoop.flush();
324
326 - it('should preserve state between array nested in fragment and fragment', function() {
327 - var ops = [];
325 + expect(ops).toEqual([]);
326 + expect(ReactNoop.getChildren()).toEqual([div()]);
327 + });
328
329 - class Stateful extends React.Component {
330 - componentDidUpdate() {
331 - ops.push('Update Stateful');
332 - }
329 + it('should preserve state between array nested in fragment and fragment', function() {
330 + var ops = [];
331
334 - render() {
335 - return <div>Hello</div>;
336 - }
332 + class Stateful extends React.Component {
333 + componentDidUpdate() {
334 + ops.push('Update Stateful');
335 }
336
339 - function Foo({condition}) {
340 - return condition
341 - ? <React.Fragment>
342 - <Stateful key="a" />
343 - </React.Fragment>
344 - : <React.Fragment>
345 - {[<Stateful key="a" />]}
346 - </React.Fragment>;
337 + render() {
338 + return <div>Hello</div>;
339 }
340 + }
341
349 - ReactNoop.render(<Foo condition={true} />);
350 - ReactNoop.flush();
342 + function Foo({condition}) {
343 + return condition
344 + ? <React.Fragment>
345 + <Stateful key="a" />
346 + </React.Fragment>
347 + : <React.Fragment>
348 + {[<Stateful key="a" />]}
349 + </React.Fragment>;
350 + }
351
352 - ReactNoop.render(<Foo condition={false} />);
353 - ReactNoop.flush();
352 + ReactNoop.render(<Foo condition={true} />);
353 + ReactNoop.flush();
354
355 - expect(ops).toEqual(['Update Stateful']);
356 - expect(ReactNoop.getChildren()).toEqual([div()]);
355 + ReactNoop.render(<Foo condition={false} />);
356 + ReactNoop.flush();
357
358 - ReactNoop.render(<Foo condition={true} />);
359 - ReactNoop.flush();
358 + expect(ops).toEqual(['Update Stateful']);
359 + expect(ReactNoop.getChildren()).toEqual([div()]);
360
361 - expect(ops).toEqual(['Update Stateful', 'Update Stateful']);
362 - expect(ReactNoop.getChildren()).toEqual([div()]);
363 - });
361 + ReactNoop.render(<Foo condition={true} />);
362 + ReactNoop.flush();
363
365 - it('should preserve state between top level fragment and array', function() {
366 - var ops = [];
364 + expect(ops).toEqual(['Update Stateful', 'Update Stateful']);
365 + expect(ReactNoop.getChildren()).toEqual([div()]);
366 + });
367
368 - class Stateful extends React.Component {
369 - componentDidUpdate() {
370 - ops.push('Update Stateful');
371 - }
368 + it('should preserve state between top level fragment and array', function() {
369 + var ops = [];
370
373 - render() {
374 - return <div>Hello</div>;
375 - }
371 + class Stateful extends React.Component {
372 + componentDidUpdate() {
373 + ops.push('Update Stateful');
374 }
375
378 - function Foo({condition}) {
379 - return condition
380 - ? [<Stateful key="a" />]
381 - : <React.Fragment>
382 - <Stateful key="a" />
383 - </React.Fragment>;
376 + render() {
377 + return <div>Hello</div>;
378 }
379 + }
380
386 - ReactNoop.render(<Foo condition={true} />);
387 - ReactNoop.flush();
381 + function Foo({condition}) {
382 + return condition
383 + ? [<Stateful key="a" />]
384 + : <React.Fragment>
385 + <Stateful key="a" />
386 + </React.Fragment>;
387 + }
388
389 - ReactNoop.render(<Foo condition={false} />);
390 - ReactNoop.flush();
389 + ReactNoop.render(<Foo condition={true} />);
390 + ReactNoop.flush();
391
392 - expect(ops).toEqual(['Update Stateful']);
393 - expect(ReactNoop.getChildren()).toEqual([div()]);
392 + ReactNoop.render(<Foo condition={false} />);
393 + ReactNoop.flush();
394
395 - ReactNoop.render(<Foo condition={true} />);
396 - ReactNoop.flush();
395 + expect(ops).toEqual(['Update Stateful']);
396 + expect(ReactNoop.getChildren()).toEqual([div()]);
397
398 - expect(ops).toEqual(['Update Stateful', 'Update Stateful']);
399 - expect(ReactNoop.getChildren()).toEqual([div()]);
400 - });
398 + ReactNoop.render(<Foo condition={true} />);
399 + ReactNoop.flush();
400
402 - it('should not preserve state between array nested in fragment and double nested fragment', function() {
403 - var ops = [];
401 + expect(ops).toEqual(['Update Stateful', 'Update Stateful']);
402 + expect(ReactNoop.getChildren()).toEqual([div()]);
403 + });
404
405 - class Stateful extends React.Component {
406 - componentDidUpdate() {
407 - ops.push('Update Stateful');
408 - }
405 + it('should not preserve state between array nested in fragment and double nested fragment', function() {
406 + var ops = [];
407
410 - render() {
411 - return <div>Hello</div>;
412 - }
408 + class Stateful extends React.Component {
409 + componentDidUpdate() {
410 + ops.push('Update Stateful');
411 }
412
415 - function Foo({condition}) {
416 - return condition
417 - ? <React.Fragment>{[<Stateful key="a" />]}</React.Fragment>
418 - : <React.Fragment>
419 - <React.Fragment><Stateful key="a" /></React.Fragment>
420 - </React.Fragment>;
413 + render() {
414 + return <div>Hello</div>;
415 }
416 + }
417
423 - ReactNoop.render(<Foo condition={true} />);
424 - ReactNoop.flush();
418 + function Foo({condition}) {
419 + return condition
420 + ? <React.Fragment>{[<Stateful key="a" />]}</React.Fragment>
421 + : <React.Fragment>
422 + <React.Fragment><Stateful key="a" /></React.Fragment>
423 + </React.Fragment>;
424 + }
425
426 - ReactNoop.render(<Foo condition={false} />);
427 - ReactNoop.flush();
426 + ReactNoop.render(<Foo condition={true} />);
427 + ReactNoop.flush();
428
429 - expect(ops).toEqual([]);
430 - expect(ReactNoop.getChildren()).toEqual([div()]);
429 + ReactNoop.render(<Foo condition={false} />);
430 + ReactNoop.flush();
431
432 - ReactNoop.render(<Foo condition={true} />);
433 - ReactNoop.flush();
432 + expect(ops).toEqual([]);
433 + expect(ReactNoop.getChildren()).toEqual([div()]);
434
435 - expect(ops).toEqual([]);
436 - expect(ReactNoop.getChildren()).toEqual([div()]);
437 - });
435 + ReactNoop.render(<Foo condition={true} />);
436 + ReactNoop.flush();
437
439 - it('should not preserve state between array nested in fragment and double nested array', function() {
440 - var ops = [];
438 + expect(ops).toEqual([]);
439 + expect(ReactNoop.getChildren()).toEqual([div()]);
440 + });
441
442 - class Stateful extends React.Component {
443 - componentDidUpdate() {
444 - ops.push('Update Stateful');
445 - }
442 + it('should not preserve state between array nested in fragment and double nested array', function() {
443 + var ops = [];
444
447 - render() {
448 - return <div>Hello</div>;
449 - }
445 + class Stateful extends React.Component {
446 + componentDidUpdate() {
447 + ops.push('Update Stateful');
448 }
449
452 - function Foo({condition}) {
453 - return condition
454 - ? <React.Fragment>{[<Stateful key="a" />]}</React.Fragment>
455 - : [[<Stateful key="a" />]];
450 + render() {
451 + return <div>Hello</div>;
452 }
453 + }
454
458 - ReactNoop.render(<Foo condition={true} />);
459 - ReactNoop.flush();
455 + function Foo({condition}) {
456 + return condition
457 + ? <React.Fragment>{[<Stateful key="a" />]}</React.Fragment>
458 + : [[<Stateful key="a" />]];
459 + }
460
461 - ReactNoop.render(<Foo condition={false} />);
462 - ReactNoop.flush();
461 + ReactNoop.render(<Foo condition={true} />);
462 + ReactNoop.flush();
463
464 - expect(ops).toEqual([]);
465 - expect(ReactNoop.getChildren()).toEqual([div()]);
464 + ReactNoop.render(<Foo condition={false} />);
465 + ReactNoop.flush();
466
467 - ReactNoop.render(<Foo condition={true} />);
468 - ReactNoop.flush();
467 + expect(ops).toEqual([]);
468 + expect(ReactNoop.getChildren()).toEqual([div()]);
469
470 - expect(ops).toEqual([]);
471 - expect(ReactNoop.getChildren()).toEqual([div()]);
472 - });
470 + ReactNoop.render(<Foo condition={true} />);
471 + ReactNoop.flush();
472
474 - it('should preserve state between double nested fragment and double nested array', function() {
475 - var ops = [];
473 + expect(ops).toEqual([]);
474 + expect(ReactNoop.getChildren()).toEqual([div()]);
475 + });
476
477 - class Stateful extends React.Component {
478 - componentDidUpdate() {
479 - ops.push('Update Stateful');
480 - }
477 + it('should preserve state between double nested fragment and double nested array', function() {
478 + var ops = [];
479
482 - render() {
483 - return <div>Hello</div>;
484 - }
480 + class Stateful extends React.Component {
481 + componentDidUpdate() {
482 + ops.push('Update Stateful');
483 }
484
487 - function Foo({condition}) {
488 - return condition
489 - ? <React.Fragment>
490 - <React.Fragment><Stateful key="a" /></React.Fragment>
491 - </React.Fragment>
492 - : [[<Stateful key="a" />]];
485 + render() {
486 + return <div>Hello</div>;
487 }
488 + }
489
495 - ReactNoop.render(<Foo condition={true} />);
496 - ReactNoop.flush();
490 + function Foo({condition}) {
491 + return condition
492 + ? <React.Fragment>
493 + <React.Fragment><Stateful key="a" /></React.Fragment>
494 + </React.Fragment>
495 + : [[<Stateful key="a" />]];
496 + }
497
498 - ReactNoop.render(<Foo condition={false} />);
499 - ReactNoop.flush();
498 + ReactNoop.render(<Foo condition={true} />);
499 + ReactNoop.flush();
500
501 - expect(ops).toEqual(['Update Stateful']);
502 - expect(ReactNoop.getChildren()).toEqual([div()]);
501 + ReactNoop.render(<Foo condition={false} />);
502 + ReactNoop.flush();
503
504 - ReactNoop.render(<Foo condition={true} />);
505 - ReactNoop.flush();
504 + expect(ops).toEqual(['Update Stateful']);
505 + expect(ReactNoop.getChildren()).toEqual([div()]);
506
507 - expect(ops).toEqual(['Update Stateful', 'Update Stateful']);
508 - expect(ReactNoop.getChildren()).toEqual([div()]);
509 - });
507 + ReactNoop.render(<Foo condition={true} />);
508 + ReactNoop.flush();
509
511 - it('should not preserve state of children when the keys are different', function() {
512 - var ops = [];
510 + expect(ops).toEqual(['Update Stateful', 'Update Stateful']);
511 + expect(ReactNoop.getChildren()).toEqual([div()]);
512 + });
513
514 - class Stateful extends React.Component {
515 - componentDidUpdate() {
516 - ops.push('Update Stateful');
517 - }
514 + it('should not preserve state of children when the keys are different', function() {
515 + var ops = [];
516
519 - render() {
520 - return <div>Hello</div>;
521 - }
517 + class Stateful extends React.Component {
518 + componentDidUpdate() {
519 + ops.push('Update Stateful');
520 }
521
524 - function Foo({condition}) {
525 - return condition
526 - ? <React.Fragment key="a">
527 - <Stateful />
528 - </React.Fragment>
529 - : <React.Fragment key="b">
530 - <Stateful />
531 - <span>World</span>
532 - </React.Fragment>;
522 + render() {
523 + return <div>Hello</div>;
524 }
525 + }
526
535 - ReactNoop.render(<Foo condition={true} />);
536 - ReactNoop.flush();
527 + function Foo({condition}) {
528 + return condition
529 + ? <React.Fragment key="a">
530 + <Stateful />
531 + </React.Fragment>
532 + : <React.Fragment key="b">
533 + <Stateful />
534 + <span>World</span>
535 + </React.Fragment>;
536 + }
537
538 - ReactNoop.render(<Foo condition={false} />);
539 - ReactNoop.flush();
538 + ReactNoop.render(<Foo condition={true} />);
539 + ReactNoop.flush();
540
541 - expect(ops).toEqual([]);
542 - expect(ReactNoop.getChildren()).toEqual([div(), span()]);
541 + ReactNoop.render(<Foo condition={false} />);
542 + ReactNoop.flush();
543
544 - ReactNoop.render(<Foo condition={true} />);
545 - ReactNoop.flush();
544 + expect(ops).toEqual([]);
545 + expect(ReactNoop.getChildren()).toEqual([div(), span()]);
546
547 - expect(ops).toEqual([]);
548 - expect(ReactNoop.getChildren()).toEqual([div()]);
549 - });
547 + ReactNoop.render(<Foo condition={true} />);
548 + ReactNoop.flush();
549
551 - it('should not preserve state between unkeyed and keyed fragment', function() {
552 - var ops = [];
550 + expect(ops).toEqual([]);
551 + expect(ReactNoop.getChildren()).toEqual([div()]);
552 + });
553
554 - class Stateful extends React.Component {
555 - componentDidUpdate() {
556 - ops.push('Update Stateful');
557 - }
554 + it('should not preserve state between unkeyed and keyed fragment', function() {
555 + var ops = [];
556
559 - render() {
560 - return <div>Hello</div>;
561 - }
557 + class Stateful extends React.Component {
558 + componentDidUpdate() {
559 + ops.push('Update Stateful');
560 }
561
564 - function Foo({condition}) {
565 - return condition
566 - ? <React.Fragment key="a">
567 - <Stateful />
568 - </React.Fragment>
569 - : <React.Fragment>
570 - <Stateful />
571 - </React.Fragment>;
562 + render() {
563 + return <div>Hello</div>;
564 }
565 + }
566
574 - ReactNoop.render(<Foo condition={true} />);
575 - ReactNoop.flush();
567 + function Foo({condition}) {
568 + return condition
569 + ? <React.Fragment key="a">
570 + <Stateful />
571 + </React.Fragment>
572 + : <React.Fragment>
573 + <Stateful />
574 + </React.Fragment>;
575 + }
576
577 - ReactNoop.render(<Foo condition={false} />);
578 - ReactNoop.flush();
577 + ReactNoop.render(<Foo condition={true} />);
578 + ReactNoop.flush();
579
580 - expect(ops).toEqual([]);
581 - expect(ReactNoop.getChildren()).toEqual([div()]);
580 + ReactNoop.render(<Foo condition={false} />);
581 + ReactNoop.flush();
582
583 - ReactNoop.render(<Foo condition={true} />);
584 - ReactNoop.flush();
583 + expect(ops).toEqual([]);
584 + expect(ReactNoop.getChildren()).toEqual([div()]);
585
586 - expect(ops).toEqual([]);
587 - expect(ReactNoop.getChildren()).toEqual([div()]);
588 - });
586 + ReactNoop.render(<Foo condition={true} />);
587 + ReactNoop.flush();
588
590 - it('should preserve state with reordering in multiple levels', function() {
591 - var ops = [];
589 + expect(ops).toEqual([]);
590 + expect(ReactNoop.getChildren()).toEqual([div()]);
591 + });
592
593 - class Stateful extends React.Component {
594 - componentDidUpdate() {
595 - ops.push('Update Stateful');
596 - }
593 + it('should preserve state with reordering in multiple levels', function() {
594 + var ops = [];
595
598 - render() {
599 - return <div>Hello</div>;
600 - }
596 + class Stateful extends React.Component {
597 + componentDidUpdate() {
598 + ops.push('Update Stateful');
599 }
600
603 - function Foo({condition}) {
604 - return condition
605 - ? <div>
606 - <React.Fragment key="c">
607 - <span>foo</span>
608 - <div key="b">
609 - <Stateful key="a" />
610 - </div>
611 - </React.Fragment>
612 - <span>boop</span>
613 - </div>
614 - : <div>
615 - <span>beep</span>
616 - <React.Fragment key="c">
617 - <div key="b">
618 - <Stateful key="a" />
619 - </div>
620 - <span>bar</span>
621 - </React.Fragment>
622 - </div>;
601 + render() {
602 + return <div>Hello</div>;
603 }
604 + }
605
625 - ReactNoop.render(<Foo condition={true} />);
626 - ReactNoop.flush();
606 + function Foo({condition}) {
607 + return condition
608 + ? <div>
609 + <React.Fragment key="c">
610 + <span>foo</span>
611 + <div key="b">
612 + <Stateful key="a" />
613 + </div>
614 + </React.Fragment>
615 + <span>boop</span>
616 + </div>
617 + : <div>
618 + <span>beep</span>
619 + <React.Fragment key="c">
620 + <div key="b">
621 + <Stateful key="a" />
622 + </div>
623 + <span>bar</span>
624 + </React.Fragment>
625 + </div>;
626 + }
627
628 - ReactNoop.render(<Foo condition={false} />);
629 - ReactNoop.flush();
628 + ReactNoop.render(<Foo condition={true} />);
629 + ReactNoop.flush();
630
631 - expect(ops).toEqual(['Update Stateful']);
632 - expect(ReactNoop.getChildren()).toEqual([
633 - div(span(), div(div()), span()),
634 - ]);
631 + ReactNoop.render(<Foo condition={false} />);
632 + ReactNoop.flush();
633
636 - ReactNoop.render(<Foo condition={true} />);
637 - ReactNoop.flush();
634 + expect(ops).toEqual(['Update Stateful']);
635 + expect(ReactNoop.getChildren()).toEqual([div(span(), div(div()), span())]);
636
639 - expect(ops).toEqual(['Update Stateful', 'Update Stateful']);
640 - expect(ReactNoop.getChildren()).toEqual([
641 - div(span(), div(div()), span()),
642 - ]);
643 - });
637 + ReactNoop.render(<Foo condition={true} />);
638 + ReactNoop.flush();
639
645 - it('should not preserve state when switching to a keyed fragment to an array', function() {
646 - spyOn(console, 'error');
647 - var ops = [];
640 + expect(ops).toEqual(['Update Stateful', 'Update Stateful']);
641 + expect(ReactNoop.getChildren()).toEqual([div(span(), div(div()), span())]);
642 + });
643
649 - class Stateful extends React.Component {
650 - componentDidUpdate() {
651 - ops.push('Update Stateful');
652 - }
644 + it('should not preserve state when switching to a keyed fragment to an array', function() {
645 + spyOn(console, 'error');
646 + var ops = [];
647
654 - render() {
655 - return <div>Hello</div>;
656 - }
648 + class Stateful extends React.Component {
649 + componentDidUpdate() {
650 + ops.push('Update Stateful');
651 }
652
659 - function Foo({condition}) {
660 - return condition
661 - ? <div>
662 - {<React.Fragment key="foo"><Stateful /></React.Fragment>}<span />
663 - </div>
664 - : <div>{[<Stateful />]}<span /></div>;
653 + render() {
654 + return <div>Hello</div>;
655 }
656 + }
657
667 - ReactNoop.render(<Foo condition={true} />);
668 - ReactNoop.flush();
658 + function Foo({condition}) {
659 + return condition
660 + ? <div>
661 + {<React.Fragment key="foo"><Stateful /></React.Fragment>}<span />
662 + </div>
663 + : <div>{[<Stateful />]}<span /></div>;
664 + }
665
670 - ReactNoop.render(<Foo condition={false} />);
671 - ReactNoop.flush();
666 + ReactNoop.render(<Foo condition={true} />);
667 + ReactNoop.flush();
668
673 - expect(ops).toEqual([]);
674 - expect(ReactNoop.getChildren()).toEqual([div(div(), span())]);
669 + ReactNoop.render(<Foo condition={false} />);
670 + ReactNoop.flush();
671
676 - ReactNoop.render(<Foo condition={true} />);
677 - ReactNoop.flush();
672 + expect(ops).toEqual([]);
673 + expect(ReactNoop.getChildren()).toEqual([div(div(), span())]);
674
679 - expect(ops).toEqual([]);
680 - expect(ReactNoop.getChildren()).toEqual([div(div(), span())]);
681 - expectDev(console.error.calls.count()).toBe(1);
682 - expectDev(console.error.calls.argsFor(0)[0]).toContain(
683 - 'Each child in an array or iterator should have a unique "key" prop.',
684 - );
685 - });
675 + ReactNoop.render(<Foo condition={true} />);
676 + ReactNoop.flush();
677
687 - it('should preserve state when it does not change positions', function() {
688 - spyOn(console, 'error');
689 - var ops = [];
678 + expect(ops).toEqual([]);
679 + expect(ReactNoop.getChildren()).toEqual([div(div(), span())]);
680 + expectDev(console.error.calls.count()).toBe(1);
681 + expectDev(console.error.calls.argsFor(0)[0]).toContain(
682 + 'Each child in an array or iterator should have a unique "key" prop.',
683 + );
684 + });
685
691 - class Stateful extends React.Component {
692 - componentDidUpdate() {
693 - ops.push('Update Stateful');
694 - }
686 + it('should preserve state when it does not change positions', function() {
687 + spyOn(console, 'error');
688 + var ops = [];
689
696 - render() {
697 - return <div>Hello</div>;
698 - }
690 + class Stateful extends React.Component {
691 + componentDidUpdate() {
692 + ops.push('Update Stateful');
693 }
694
701 - function Foo({condition}) {
702 - return condition
703 - ? [<span />, <React.Fragment><Stateful /></React.Fragment>]
704 - : [<span />, <React.Fragment><Stateful /></React.Fragment>];
695 + render() {
696 + return <div>Hello</div>;
697 }
698 + }
699
707 - ReactNoop.render(<Foo condition={true} />);
708 - ReactNoop.flush();
700 + function Foo({condition}) {
701 + return condition
702 + ? [<span />, <React.Fragment><Stateful /></React.Fragment>]
703 + : [<span />, <React.Fragment><Stateful /></React.Fragment>];
704 + }
705
710 - ReactNoop.render(<Foo condition={false} />);
711 - ReactNoop.flush();
706 + ReactNoop.render(<Foo condition={true} />);
707 + ReactNoop.flush();
708
713 - expect(ops).toEqual(['Update Stateful']);
714 - expect(ReactNoop.getChildren()).toEqual([span(), div()]);
709 + ReactNoop.render(<Foo condition={false} />);
710 + ReactNoop.flush();
711
716 - ReactNoop.render(<Foo condition={true} />);
717 - ReactNoop.flush();
712 + expect(ops).toEqual(['Update Stateful']);
713 + expect(ReactNoop.getChildren()).toEqual([span(), div()]);
714
719 - expect(ops).toEqual(['Update Stateful', 'Update Stateful']);
720 - expect(ReactNoop.getChildren()).toEqual([span(), div()]);
721 - expectDev(console.error.calls.count()).toBe(3);
722 - for (let errorIndex = 0; errorIndex < 3; ++errorIndex) {
723 - expectDev(console.error.calls.argsFor(errorIndex)[0]).toContain(
724 - 'Each child in an array or iterator should have a unique "key" prop.',
725 - );
726 - }
727 - });
728 - } else {
729 - it('should not run any tests', function() {});
730 - }
715 + ReactNoop.render(<Foo condition={true} />);
716 + ReactNoop.flush();
717 +
718 + expect(ops).toEqual(['Update Stateful', 'Update Stateful']);
719 + expect(ReactNoop.getChildren()).toEqual([span(), div()]);
720 + expectDev(console.error.calls.count()).toBe(3);
721 + for (let errorIndex = 0; errorIndex < 3; ++errorIndex) {
722 + expectDev(console.error.calls.argsFor(errorIndex)[0]).toContain(
723 + 'Each child in an array or iterator should have a unique "key" prop.',
724 + );
725 + }
726 + });
727 });
packages/react/src/__tests__/ReactJSXElementValidator-test.js
+61 -62
@@ -29,6 +29,9 @@ describe('ReactJSXElementValidator', () => {
29 beforeEach(() => {
30 jest.resetModules();
31
32 + const ReactFeatureFlags = require('shared/ReactFeatureFlags');
33 + ReactFeatureFlags.enableReactFragment = true;
34 +
35 PropTypes = require('prop-types');
36 React = require('react');
37 ReactDOM = require('react-dom');
@@ -87,50 +90,48 @@ describe('ReactJSXElementValidator', () => {
90 );
91 });
92
90 - if (ReactFeatureFlags.enableReactFragment) {
91 - it('warns for fragments with illegal attributes', () => {
92 - spyOn(console, 'error');
93 + it('warns for fragments with illegal attributes', () => {
94 + spyOn(console, 'error');
95
94 - class Foo extends React.Component {
95 - render() {
96 - return <React.Fragment a={1} b={2}>hello</React.Fragment>;
97 - }
96 + class Foo extends React.Component {
97 + render() {
98 + return <React.Fragment a={1} b={2}>hello</React.Fragment>;
99 }
100 + }
101
100 - ReactTestUtils.renderIntoDocument(<Foo />);
102 + ReactTestUtils.renderIntoDocument(<Foo />);
103
102 - expectDev(console.error.calls.count()).toBe(1);
103 - expectDev(console.error.calls.argsFor(0)[0]).toContain('Invalid prop `');
104 - expectDev(console.error.calls.argsFor(0)[0]).toContain(
105 - '` supplied to `React.Fragment`. React.Fragment ' +
106 - 'can only have `key` and `children` props.',
107 - );
108 - });
104 + expectDev(console.error.calls.count()).toBe(1);
105 + expectDev(console.error.calls.argsFor(0)[0]).toContain('Invalid prop `');
106 + expectDev(console.error.calls.argsFor(0)[0]).toContain(
107 + '` supplied to `React.Fragment`. React.Fragment ' +
108 + 'can only have `key` and `children` props.',
109 + );
110 + });
111
110 - it('warns for fragments with refs', () => {
111 - spyOn(console, 'error');
112 -
113 - class Foo extends React.Component {
114 - render() {
115 - return (
116 - <React.Fragment
117 - ref={bar => {
118 - this.foo = bar;
119 - }}>
120 - hello
121 - </React.Fragment>
122 - );
123 - }
112 + it('warns for fragments with refs', () => {
113 + spyOn(console, 'error');
114 +
115 + class Foo extends React.Component {
116 + render() {
117 + return (
118 + <React.Fragment
119 + ref={bar => {
120 + this.foo = bar;
121 + }}>
122 + hello
123 + </React.Fragment>
124 + );
125 }
126 + }
127
126 - ReactTestUtils.renderIntoDocument(<Foo />);
128 + ReactTestUtils.renderIntoDocument(<Foo />);
129
128 - expectDev(console.error.calls.count()).toBe(1);
129 - expectDev(console.error.calls.argsFor(0)[0]).toContain(
130 - 'Invalid attribute `ref` supplied to `React.Fragment`.',
131 - );
132 - });
133 - }
130 + expectDev(console.error.calls.count()).toBe(1);
131 + expectDev(console.error.calls.argsFor(0)[0]).toContain(
132 + 'Invalid attribute `ref` supplied to `React.Fragment`.',
133 + );
134 + });
135
136 it('warns for keys for iterables of elements in rest args', () => {
137 spyOn(console, 'error');
@@ -155,33 +156,31 @@ describe('ReactJSXElementValidator', () => {
156 );
157 });
158
158 - if (ReactFeatureFlags.enableReactFragment) {
159 - it('does not warn for fragments of multiple elements without keys', () => {
160 - ReactTestUtils.renderIntoDocument(
161 - <React.Fragment>
162 - <span>1</span>
163 - <span>2</span>
164 - </React.Fragment>,
165 - );
166 - });
159 + it('does not warn for fragments of multiple elements without keys', () => {
160 + ReactTestUtils.renderIntoDocument(
161 + <React.Fragment>
162 + <span>1</span>
163 + <span>2</span>
164 + </React.Fragment>,
165 + );
166 + });
167
168 - it('warns for fragments of multiple elements with same key', () => {
169 - spyOn(console, 'error');
170 -
171 - ReactTestUtils.renderIntoDocument(
172 - <React.Fragment>
173 - <span key="a">1</span>
174 - <span key="a">2</span>
175 - <span key="b">3</span>
176 - </React.Fragment>,
177 - );
178 -
179 - expectDev(console.error.calls.count()).toBe(1);
180 - expectDev(console.error.calls.argsFor(0)[0]).toContain(
181 - 'Encountered two children with the same key, `a`.',
182 - );
183 - });
184 - }
168 + it('warns for fragments of multiple elements with same key', () => {
169 + spyOn(console, 'error');
170 +
171 + ReactTestUtils.renderIntoDocument(
172 + <React.Fragment>
173 + <span key="a">1</span>
174 + <span key="a">2</span>
175 + <span key="b">3</span>
176 + </React.Fragment>,
177 + );
178 +
179 + expectDev(console.error.calls.count()).toBe(1);
180 + expectDev(console.error.calls.argsFor(0)[0]).toContain(
181 + 'Encountered two children with the same key, `a`.',
182 + );
183 + });
184
185 it('does not warn for arrays of elements with keys', () => {
186 spyOn(console, 'error');