@samitouri / QOS-React / commits / c0e5df66ec

Make disableNewFiberFeatures = true the default when runnings tests

This exposed a few more cases that I missed.

Andrew Clark committed Jan 17, 2017 at 11:16 UTC c0e5df66ecc4f98140d1089bc1feb4a78f2a32f5
17 files changed +143 -87
scripts/fiber/tests-passing.txt
-1
@@ -554,7 +554,6 @@ src/renderers/dom/fiber/__tests__/ReactDOMFiber-test.js
554 * should not crash encountering low-priority tree
555 * throws if non-element passed to top-level render
556 * throws if something other than false, null, or an element is returned from render
557 -* still accepts arrays and iterables as host children
557
558 src/renderers/dom/shared/__tests__/CSSProperty-test.js
559 * should generate browser prefixes for its `isUnitlessNumber`
scripts/jest/test-framework-setup.js
+6
@@ -9,6 +9,12 @@ jest.mock('ReactDOMFeatureFlags', () => {
9 useFiber: flags.useFiber || !!process.env.REACT_DOM_JEST_USE_FIBER,
10 });
11 });
12 +jest.mock('ReactFeatureFlags', () => {
13 + const flags = require.requireActual('ReactFeatureFlags');
14 + return Object.assign({}, flags, {
15 + disableNewFiberFeatures: true,
16 + });
17 +});
18
19 // Error logging varies between Fiber and Stack;
20 // Rather than fork dozens of tests, mock the error-logging file by default.
src/renderers/dom/fiber/ReactDOMFiber.js
+15
@@ -18,6 +18,7 @@ import type { ReactNodeList } from 'ReactTypes';
18 var ReactBrowserEventEmitter = require('ReactBrowserEventEmitter');
19 var ReactControlledComponent = require('ReactControlledComponent');
20 var ReactDOMComponentTree = require('ReactDOMComponentTree');
21 +var ReactFeatureFlags = require('ReactFeatureFlags');
22 var ReactDOMFeatureFlags = require('ReactDOMFeatureFlags');
23 var ReactDOMFiberComponent = require('ReactDOMFiberComponent');
24 var ReactDOMFrameScheduling = require('ReactDOMFrameScheduling');
@@ -27,6 +28,8 @@ var ReactFiberReconciler = require('ReactFiberReconciler');
28 var ReactInputSelection = require('ReactInputSelection');
29 var ReactInstanceMap = require('ReactInstanceMap');
30 var ReactPortal = require('ReactPortal');
31 +var { isValidElement } = require('ReactElement');
32 +
33
34 var findDOMNode = require('findDOMNode');
35 var invariant = require('invariant');
@@ -49,6 +52,7 @@ if (__DEV__) {
52 var { updatedAncestorInfo } = validateDOMNesting;
53 }
54
55 +
56 const DOCUMENT_NODE = 9;
57
58 ReactDOMInjection.inject();
@@ -352,6 +356,17 @@ var ReactDOM = {
356
357 render(element : ReactElement<any>, container : DOMContainerElement, callback: ?Function) {
358 validateContainer(container);
359 +
360 + if (ReactFeatureFlags.disableNewFiberFeatures) {
361 + // Top-level check occurs here instead of inside child reconciler because
362 + // because requirements vary between renderers. E.g. React Art
363 + // allows arrays.
364 + invariant(
365 + isValidElement(element),
366 + 'render(): Invalid component element.'
367 + );
368 + }
369 +
370 return renderSubtreeIntoContainer(null, element, container, callback);
371 },
372
src/renderers/dom/fiber/__tests__/ReactDOMFiber-test.js
+40 -37
@@ -18,9 +18,17 @@ var ReactTestUtils = require('ReactTestUtils');
18
19 describe('ReactDOMFiber', () => {
20 var container;
21 + var ReactFeatureFlags;
22
23 beforeEach(() => {
24 container = document.createElement('div');
25 + ReactFeatureFlags = require('ReactFeatureFlags');
26 + ReactFeatureFlags.disableNewFiberFeatures = false;
27 + });
28 +
29 + afterEach(() => {
30 + ReactFeatureFlags = require('ReactFeatureFlags');
31 + ReactFeatureFlags.disableNewFiberFeatures = true;
32 });
33
34 it('should render strings as children', () => {
@@ -1085,47 +1093,42 @@ describe('ReactDOMFiber', () => {
1093 container
1094 );
1095 });
1096 + }
1097 +});
1098
1089 - describe('disableNewFiberFeatures', () => {
1090 - var ReactFeatureFlags = require('ReactFeatureFlags');
1091 -
1092 - beforeEach(() => {
1093 - ReactFeatureFlags.disableNewFiberFeatures = true;
1094 - });
1099 +// disableNewFiberFeatures currently defaults to true in test
1100 +describe('disableNewFiberFeatures', () => {
1101 + var container;
1102 + var ReactFeatureFlags;
1103
1096 - afterEach(() => {
1097 - ReactFeatureFlags.disableNewFiberFeatures = false;
1098 - });
1104 + beforeEach(() => {
1105 + container = document.createElement('div');
1106 + ReactFeatureFlags = require('ReactFeatureFlags');
1107 + ReactFeatureFlags.disableNewFiberFeatures = true;
1108 + });
1109
1100 - it('throws if non-element passed to top-level render', () => {
1101 - const message = 'render(): Invalid component element.';
1102 - expect(() => ReactDOM.render(null, container)).toThrow(message, container);
1103 - expect(() => ReactDOM.render(undefined, container)).toThrow(message, container);
1104 - expect(() => ReactDOM.render(false, container)).toThrow(message, container);
1105 - expect(() => ReactDOM.render('Hi', container)).toThrow(message, container);
1106 - expect(() => ReactDOM.render(999, container)).toThrow(message, container);
1107 - expect(() => ReactDOM.render([<div />], container)).toThrow(message, container);
1108 - });
1110 + afterEach(() => {
1111 + ReactFeatureFlags = require('ReactFeatureFlags');
1112 + ReactFeatureFlags.disableNewFiberFeatures = false;
1113 + });
1114
1110 - it('throws if something other than false, null, or an element is returned from render', () => {
1111 - function Render(props) {
1112 - return props.children;
1113 - }
1115 + it('throws if non-element passed to top-level render', () => {
1116 + const message = 'render(): Invalid component element.';
1117 + expect(() => ReactDOM.render(null, container)).toThrow(message, container);
1118 + expect(() => ReactDOM.render(undefined, container)).toThrow(message, container);
1119 + expect(() => ReactDOM.render(false, container)).toThrow(message, container);
1120 + expect(() => ReactDOM.render('Hi', container)).toThrow(message, container);
1121 + expect(() => ReactDOM.render(999, container)).toThrow(message, container);
1122 + expect(() => ReactDOM.render([<div />], container)).toThrow(message, container);
1123 + });
1124
1115 - expect(() => ReactDOM.render(<Render>Hi</Render>, container)).toThrow(/You may have returned undefined/);
1116 - expect(() => ReactDOM.render(<Render>{999}</Render>, container)).toThrow(/You may have returned undefined/);
1117 - expect(() => ReactDOM.render(<Render>[<div />]</Render>, container)).toThrow(/You may have returned undefined/);
1118 - });
1125 + it('throws if something other than false, null, or an element is returned from render', () => {
1126 + function Render(props) {
1127 + return props.children;
1128 + }
1129
1120 - it('still accepts arrays and iterables as host children', () => {
1121 - function Render(props) {
1122 - return <div>{props.children}</div>;
1123 - }
1124 - ReactDOM.render(<Render>{['foo', 'bar']}</Render>, container);
1125 - expect(container.textContent).toEqual('foobar');
1126 - ReactDOM.render(<Render>{new Set(['foo', 'bar'])}</Render>, container);
1127 - expect(container.textContent).toEqual('foobar');
1128 - });
1129 - });
1130 - }
1130 + expect(() => ReactDOM.render(<Render>Hi</Render>, container)).toThrow(/You may have returned undefined/);
1131 + expect(() => ReactDOM.render(<Render>{999}</Render>, container)).toThrow(/You may have returned undefined/);
1132 + expect(() => ReactDOM.render(<Render>[<div />]</Render>, container)).toThrow(/You may have returned undefined/);
1133 + });
1134 });
src/renderers/shared/fiber/ReactChildFiber.js
+31 -33
@@ -75,7 +75,6 @@ const {
75 NoEffect,
76 Placement,
77 Deletion,
78 - Err,
78 } = ReactTypeOfSideEffect;
79
80 function coerceRef(current: ?Fiber, element: ReactElement) {
@@ -1127,41 +1126,40 @@ function ChildReconciler(shouldClone, shouldTrackSideEffects) {
1126 }
1127 }
1128
1130 - if (returnFiber.tag === HostRoot) {
1131 - // Top-level only accepts elements or portals
1132 - invariant(
1133 - // If the root has an error effect, this is an intentional unmount.
1134 - // Don't throw an error.
1135 - returnFiber.effectTag & Err,
1136 - 'render(): Invalid component element.'
1137 - );
1138 - } else {
1139 - switch (returnFiber.tag) {
1140 - case ClassComponent: {
1141 - if (__DEV__) {
1142 - const instance = returnFiber.stateNode;
1143 - if (instance.render._isMockFunction) {
1144 - // We allow auto-mocks to proceed as if they're
1145 - // returning null.
1146 - break;
1147 - }
1129 + switch (returnFiber.tag) {
1130 + case ClassComponent: {
1131 + if (__DEV__) {
1132 + const instance = returnFiber.stateNode;
1133 + if (instance.render._isMockFunction) {
1134 + // We allow auto-mocks to proceed as if they're
1135 + // returning null.
1136 + break;
1137 }
1138 }
1150 - // Intentionally fall through to the next case, which handles both
1151 - // functions and classes
1152 - // eslint-disable-next-lined no-fallthrough
1153 - case FunctionalComponent: {
1154 - // Composites accept elements, portals, null, or false
1155 - const Component = returnFiber.type;
1156 - invariant(
1157 - newChild === null || newChild === false,
1158 - '%s.render(): A valid React element (or null) must be ' +
1159 - 'returned. You may have returned undefined, an array or some ' +
1160 - 'other invalid object.',
1161 - Component.displayName || Component.name || 'Component'
1162 - );
1163 - }
1139 }
1140 + // Intentionally fall through to the next case, which handles both
1141 + // functions and classes
1142 + // eslint-disable-next-lined no-fallthrough
1143 + case FunctionalComponent: {
1144 + // Composites accept elements, portals, null, or false
1145 + const Component = returnFiber.type;
1146 + invariant(
1147 + newChild === null || newChild === false,
1148 + '%s(...): A valid React element (or null) must be ' +
1149 + 'returned. You may have returned undefined, an array or some ' +
1150 + 'other invalid object.',
1151 + Component.displayName || Component.name || 'Component'
1152 + );
1153 + }
1154 + }
1155 +
1156 + if (typeof newChild === 'string' || typeof newChild === 'number') {
1157 + return placeSingleChild(reconcileSingleTextNode(
1158 + returnFiber,
1159 + currentFirstChild,
1160 + '' + newChild,
1161 + priority
1162 + ));
1163 }
1164
1165 if (isArray(newChild)) {
src/renderers/shared/fiber/__tests__/ReactCoroutine-test.js
+3
@@ -14,6 +14,7 @@
14 var React;
15 var ReactNoop;
16 var ReactCoroutine;
17 +var ReactFeatureFlags;
18
19 describe('ReactCoroutine', () => {
20 beforeEach(() => {
@@ -21,6 +22,8 @@ describe('ReactCoroutine', () => {
22 React = require('React');
23 ReactNoop = require('ReactNoop');
24 ReactCoroutine = require('ReactCoroutine');
25 + ReactFeatureFlags = require('ReactFeatureFlags');
26 + ReactFeatureFlags.disableNewFiberFeatures = false;
27 });
28
29 it('should render a coroutine', () => {
src/renderers/shared/fiber/__tests__/ReactIncremental-test.js
+4
@@ -13,12 +13,16 @@
13
14 var React;
15 var ReactNoop;
16 +var ReactFeatureFlags;
17
18 describe('ReactIncremental', () => {
19 beforeEach(() => {
20 jest.resetModules();
21 React = require('React');
22 ReactNoop = require('ReactNoop');
23 +
24 + ReactFeatureFlags = require('ReactFeatureFlags');
25 + ReactFeatureFlags.disableNewFiberFeatures = false;
26 });
27
28 it('should render a simple component', () => {
src/renderers/shared/fiber/__tests__/ReactIncrementalErrorHandling-test.js
+3
@@ -13,12 +13,15 @@
13
14 var React;
15 var ReactNoop;
16 +var ReactFeatureFlags;
17
18 describe('ReactIncrementalErrorHandling', () => {
19 beforeEach(() => {
20 jest.resetModules();
21 React = require('React');
22 ReactNoop = require('ReactNoop');
23 + ReactFeatureFlags = require('ReactFeatureFlags');
24 + ReactFeatureFlags.disableNewFiberFeatures = false;
25 });
26
27 function div(...children) {
src/renderers/shared/fiber/__tests__/ReactIncrementalReflection-test.js
+3
@@ -13,12 +13,15 @@
13
14 var React;
15 var ReactNoop;
16 +var ReactFeatureFlags;
17
18 describe('ReactIncrementalReflection', () => {
19 beforeEach(() => {
20 jest.resetModules();
21 React = require('React');
22 ReactNoop = require('ReactNoop');
23 + ReactFeatureFlags = require('ReactFeatureFlags');
24 + ReactFeatureFlags.disableNewFiberFeatures = false;
25 });
26
27 it('handles isMounted even when the initial render is deferred', () => {
src/renderers/shared/fiber/__tests__/ReactIncrementalScheduling-test.js
+3
@@ -13,12 +13,15 @@
13
14 var React;
15 var ReactNoop;
16 +var ReactFeatureFlags;
17
18 describe('ReactIncrementalScheduling', () => {
19 beforeEach(() => {
20 jest.resetModules();
21 React = require('React');
22 ReactNoop = require('ReactNoop');
23 + ReactFeatureFlags = require('ReactFeatureFlags');
24 + ReactFeatureFlags.disableNewFiberFeatures = false;
25 });
26
27 function span(prop) {
src/renderers/shared/fiber/__tests__/ReactIncrementalSideEffects-test.js
+3
@@ -13,12 +13,15 @@
13
14 var React;
15 var ReactNoop;
16 +var ReactFeatureFlags;
17
18 describe('ReactIncrementalSideEffects', () => {
19 beforeEach(() => {
20 jest.resetModules();
21 React = require('React');
22 ReactNoop = require('ReactNoop');
23 + ReactFeatureFlags = require('ReactFeatureFlags');
24 + ReactFeatureFlags.disableNewFiberFeatures = false;
25 });
26
27 function normalizeCodeLocInfo(str) {
src/renderers/shared/fiber/__tests__/ReactIncrementalUpdates-test.js
+3
@@ -13,12 +13,15 @@
13
14 var React;
15 var ReactNoop;
16 +var ReactFeatureFlags;
17
18 describe('ReactIncrementalUpdates', () => {
19 beforeEach(() => {
20 jest.resetModuleRegistry();
21 React = require('React');
22 ReactNoop = require('ReactNoop');
23 + ReactFeatureFlags = require('ReactFeatureFlags');
24 + ReactFeatureFlags.disableNewFiberFeatures = false;
25 });
26
27 it('applies updates in order of priority', () => {
src/renderers/shared/fiber/__tests__/ReactTopLevelFragment-test.js
+3
@@ -13,6 +13,7 @@
13
14 var React;
15 var ReactNoop;
16 +var ReactFeatureFlags;
17
18 // This is a new feature in Fiber so I put it in its own test file. It could
19 // probably move to one of the other test files once it is official.
@@ -21,6 +22,8 @@ describe('ReactTopLevelFragment', function() {
22 jest.resetModules();
23 React = require('React');
24 ReactNoop = require('ReactNoop');
25 + ReactFeatureFlags = require('ReactFeatureFlags');
26 + ReactFeatureFlags.disableNewFiberFeatures = false;
27 });
28
29 it('should render a simple fragment at the top of a component', function() {
src/renderers/shared/fiber/__tests__/ReactTopLevelText-test.js
+3
@@ -13,6 +13,7 @@
13
14 var React;
15 var ReactNoop;
16 +var ReactFeatureFlags;
17
18 // This is a new feature in Fiber so I put it in its own test file. It could
19 // probably move to one of the other test files once it is official.
@@ -21,6 +22,8 @@ describe('ReactTopLevelText', () => {
22 jest.resetModules();
23 React = require('React');
24 ReactNoop = require('ReactNoop');
25 + ReactFeatureFlags = require('ReactFeatureFlags');
26 + ReactFeatureFlags.disableNewFiberFeatures = false;
27 });
28
29 it('should render a component returning strings directly from render', () => {
src/renderers/shared/shared/__tests__/ReactEmptyComponent-test.js
+15 -9
@@ -247,18 +247,24 @@ describe('ReactEmptyComponent', () => {
247 });
248
249 it('can render null at the top level', () => {
250 + var ReactFeatureFlags = require('ReactFeatureFlags');
251 + ReactFeatureFlags.disableNewFiberFeatures = false;
252 var div = document.createElement('div');
253
252 - if (ReactDOMFeatureFlags.useFiber) {
253 - ReactDOM.render(null, div);
254 - expect(div.innerHTML).toBe('');
255 - } else {
256 - // Stack does not implement this.
257 - expect(function() {
254 + try {
255 + if (ReactDOMFeatureFlags.useFiber) {
256 ReactDOM.render(null, div);
259 - }).toThrowError(
260 - 'ReactDOM.render(): Invalid component element.'
261 - );
257 + expect(div.innerHTML).toBe('');
258 + } else {
259 + // Stack does not implement this.
260 + expect(function() {
261 + ReactDOM.render(null, div);
262 + }).toThrowError(
263 + 'ReactDOM.render(): Invalid component element.'
264 + );
265 + }
266 + } finally {
267 + ReactFeatureFlags.disableNewFiberFeatures = true;
268 }
269 });
270
src/renderers/shared/shared/__tests__/ReactStatelessComponent-test.js
+2 -7
@@ -152,13 +152,8 @@ describe('ReactStatelessComponent', () => {
152 expect(function() {
153 ReactTestUtils.renderIntoDocument(<div><NotAComponent /></div>);
154 }).toThrowError(
155 - ReactDOMFeatureFlags.useFiber ?
156 - // Fiber gives a more specific error message for undefined because it
157 - // supports more return types.
158 - 'NotAComponent(...): Nothing was returned from render' :
159 - // Stack's message is generic.
160 - 'NotAComponent(...): A valid React element (or null) must be returned. ' +
161 - 'You may have returned undefined, an array or some other invalid object.'
155 + 'NotAComponent(...): A valid React element (or null) must be returned. ' +
156 + 'You may have returned undefined, an array or some other invalid object.'
157 );
158 });
159
src/renderers/testing/__tests__/ReactTestRenderer-test.js
+6
@@ -14,8 +14,14 @@
14 var React = require('React');
15 var ReactTestRenderer = require('ReactTestRenderer');
16 var ReactDOMFeatureFlags = require('ReactDOMFeatureFlags');
17 +var ReactFeatureFlags;
18
19 describe('ReactTestRenderer', () => {
20 + beforeEach(() => {
21 + ReactFeatureFlags = require('ReactFeatureFlags');
22 + ReactFeatureFlags.disableNewFiberFeatures = false;
23 + });
24 +
25 function normalizeCodeLocInfo(str) {
26 return str && str.replace(/\(at .+?:\d+\)/g, '(at **)');
27 }