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
}