Use empty object if context does not exist
This matches Stack behavior. Had to rewrite a test that used Simulate because Fiber doesn't support events yet. Also changed tests for componentDidUpdate() since Fiber intentionally doesn't pass prevContext argument.
Dan Abramov committed
Nov 15, 2016 at 16:34 UTC
2397f1fce6082591be7c319c709906e0fa4426ae
5 files changed
+38
-33
scripts/fiber/tests-failing.txt
-2
@@ -425,8 +425,6 @@ src/renderers/shared/stack/reconciler/__tests__/ReactCompositeComponent-test.js
425
* should warn about `setState` on unmounted components
426
* should warn about `setState` in render
427
* should warn about `setState` in getChildContext
428
-* unmasked context propagates through updates
429
-* should trigger componentWillReceiveProps for context changes
428
* should update refs if shouldComponentUpdate gives false
429
* should support objects with prototypes as state
430
scripts/fiber/tests-passing.txt
+2
@@ -1041,6 +1041,8 @@ src/renderers/shared/stack/reconciler/__tests__/ReactCompositeComponent-test.js
1041
* should pass context when re-rendered for static child within a composite component
1042
* should pass context transitively
1043
* should pass context when re-rendered
1044
+* unmasked context propagates through updates
1045
+* should trigger componentWillReceiveProps for context changes
1046
* only renders once if updated in componentWillReceiveProps
1047
* should allow access to findDOMNode in componentWillUnmount
1048
* context should be passed down from the parent
src/renderers/shared/fiber/ReactFiberContext.js
+1
-1
@@ -42,7 +42,7 @@ exports.getMaskedContext = function(fiber : Fiber) {
42
const type = fiber.type;
43
const contextTypes = type.contextTypes;
44
if (!contextTypes) {
45
- return null;
45
+ return emptyObject;
46
}
47
48
const unmaskedContext = getUnmaskedContext();
src/renderers/shared/fiber/__tests__/ReactIncremental-test.js
+19
-19
@@ -1605,7 +1605,7 @@ describe('ReactIncremental', () => {
1605
);
1606
ReactNoop.flush();
1607
expect(ops).toEqual([
1608
- 'Intl null',
1608
+ 'Intl {}',
1609
'ShowLocale {"locale":"fr"}',
1610
'ShowBoth {"locale":"fr"}',
1611
]);
@@ -1621,7 +1621,7 @@ describe('ReactIncremental', () => {
1621
);
1622
ReactNoop.flush();
1623
expect(ops).toEqual([
1624
- 'Intl null',
1624
+ 'Intl {}',
1625
'ShowLocale {"locale":"de"}',
1626
'ShowBoth {"locale":"de"}',
1627
]);
@@ -1637,7 +1637,7 @@ describe('ReactIncremental', () => {
1637
);
1638
ReactNoop.flushDeferredPri(15);
1639
expect(ops).toEqual([
1640
- 'Intl null',
1640
+ 'Intl {}',
1641
]);
1642
1643
ops.length = 0;
@@ -1652,14 +1652,14 @@ describe('ReactIncremental', () => {
1652
);
1653
ReactNoop.flush();
1654
expect(ops).toEqual([
1655
- 'Intl null',
1655
+ 'Intl {}',
1656
'ShowLocale {"locale":"en"}',
1657
- 'Router null',
1658
- 'Indirection null',
1657
+ 'Router {}',
1658
+ 'Indirection {}',
1659
'ShowLocale {"locale":"en"}',
1660
'ShowRoute {"route":"/about"}',
1661
- 'ShowNeither null',
1662
- 'Intl null',
1661
+ 'ShowNeither {}',
1662
+ 'Intl {}',
1663
'ShowBoth {"locale":"ru","route":"/about"}',
1664
'ShowBoth {"locale":"en","route":"/about"}',
1665
'ShowBoth {"locale":"en"}',
@@ -1740,7 +1740,7 @@ describe('ReactIncremental', () => {
1740
);
1741
ReactNoop.flushDeferredPri(40);
1742
expect(ops).toEqual([
1743
- 'Intl null',
1743
+ 'Intl {}',
1744
'ShowLocale {"locale":"fr"}',
1745
'ShowLocale {"locale":"fr"}',
1746
]);
@@ -1749,7 +1749,7 @@ describe('ReactIncremental', () => {
1749
ReactNoop.flush();
1750
expect(ops).toEqual([
1751
'ShowLocale {"locale":"fr"}',
1752
- 'Intl null',
1752
+ 'Intl {}',
1753
'ShowLocale {"locale":"ru"}',
1754
]);
1755
});
@@ -1828,10 +1828,10 @@ describe('ReactIncremental', () => {
1828
);
1829
ReactNoop.flush();
1830
expect(ops).toEqual([
1831
- 'Intl:read null',
1831
+ 'Intl:read {}',
1832
'Intl:provide {"locale":"fr"}',
1833
- 'IndirectionFn null',
1834
- 'IndirectionClass null',
1833
+ 'IndirectionFn {}',
1834
+ 'IndirectionClass {}',
1835
'ShowLocaleClass:read {"locale":"fr"}',
1836
'ShowLocaleFn:read {"locale":"fr"}',
1837
]);
@@ -1920,10 +1920,10 @@ describe('ReactIncremental', () => {
1920
);
1921
ReactNoop.flush();
1922
expect(ops).toEqual([
1923
- 'Intl:read null',
1923
+ 'Intl:read {}',
1924
'Intl:provide {"locale":"fr"}',
1925
- 'IndirectionFn null',
1926
- 'IndirectionClass null',
1925
+ 'IndirectionFn {}',
1926
+ 'IndirectionClass {}',
1927
'ShowLocaleClass:read {"locale":"fr"}',
1928
'ShowLocaleFn:read {"locale":"fr"}',
1929
]);
@@ -1935,12 +1935,12 @@ describe('ReactIncremental', () => {
1935
// Intl is below setState() so it might have been
1936
// affected by it. Therefore we re-render and recompute
1937
// its child context.
1938
- 'Intl:read null',
1938
+ 'Intl:read {}',
1939
'Intl:provide {"locale":"gr"}',
1940
// TODO: it's unfortunate that we can't reuse work on
1941
// these components even though they don't depend on context.
1942
- 'IndirectionFn null',
1943
- 'IndirectionClass null',
1942
+ 'IndirectionFn {}',
1943
+ 'IndirectionClass {}',
1944
// These components depend on context:
1945
'ShowLocaleClass:read {"locale":"gr"}',
1946
'ShowLocaleFn:read {"locale":"gr"}',
src/renderers/shared/stack/reconciler/__tests__/ReactCompositeComponent-test.js
+16
-11
@@ -15,6 +15,7 @@ var ChildUpdates;
15
var MorphingComponent;
16
var React;
17
var ReactDOM;
18
+var ReactDOMFeatureFlags;
19
var ReactCurrentOwner;
20
var ReactPropTypes;
21
var ReactServerRendering;
@@ -26,6 +27,7 @@ describe('ReactCompositeComponent', () => {
27
jest.resetModuleRegistry();
28
React = require('React');
29
ReactDOM = require('ReactDOM');
30
+ ReactDOMFeatureFlags = require('ReactDOMFeatureFlags');
31
ReactCurrentOwner = require('ReactCurrentOwner');
32
ReactPropTypes = require('ReactPropTypes');
33
ReactTestUtils = require('ReactTestUtils');
@@ -830,7 +832,10 @@ describe('ReactCompositeComponent', () => {
832
}
833
834
componentDidUpdate(prevProps, prevState, prevContext) {
833
- expect('foo' in prevContext).toBe(true);
835
+ if (!ReactDOMFeatureFlags.useFiber) {
836
+ // Fiber does not pass the previous context.
837
+ expect('foo' in prevContext).toBe(true);
838
+ }
839
}
840
841
shouldComponentUpdate(nextProps, nextState, nextContext) {
@@ -849,7 +854,10 @@ describe('ReactCompositeComponent', () => {
854
}
855
856
componentDidUpdate(prevProps, prevState, prevContext) {
852
- expect('foo' in prevContext).toBe(false);
857
+ if (!ReactDOMFeatureFlags.useFiber) {
858
+ // Fiber does not pass the previous context.
859
+ expect('foo' in prevContext).toBe(false);
860
+ }
861
}
862
863
shouldComponentUpdate(nextProps, nextState, nextContext) {
@@ -971,21 +979,16 @@ describe('ReactCompositeComponent', () => {
979
};
980
}
981
974
- onClick = () => {
975
- this.setState({
976
- foo: 'def',
977
- });
978
- };
979
-
982
render() {
981
- return <div className="parent" onClick={this.onClick}>{this.props.children}</div>;
983
+ return <div className="parent">{this.props.children}</div>;
984
}
985
}
986
987
var div = document.createElement('div');
988
989
+ var parentInstance = null;
990
ReactDOM.render(
988
- <Parent>
991
+ <Parent ref={inst => parentInstance = inst}>
992
<ChildWithoutContext>
993
A1
994
<GrandChild>A2</GrandChild>
@@ -999,7 +1002,9 @@ describe('ReactCompositeComponent', () => {
1002
div
1003
);
1004
1002
- ReactTestUtils.Simulate.click(div.childNodes[0]);
1005
+ parentInstance.setState({
1006
+ foo: 'def',
1007
+ });
1008
1009
expect(propChanges).toBe(0);
1010
expect(contextChanges).toBe(3); // ChildWithContext, GrandChild x 2