Add test cases for context below and above setState
Dan Abramov committed
Nov 15, 2016 at 13:22 UTC
299009c41fb6a2dd92247f806bef32859e2b9336
1 file changed
+148
-3
src/renderers/shared/fiber/__tests__/ReactIncremental-test.js
+148
-3
@@ -1547,7 +1547,6 @@ describe('ReactIncremental', () => {
1547
static contextTypes = {
1548
locale: React.PropTypes.string,
1549
};
1550
-
1550
render() {
1551
ops.push('ShowLocale ' + JSON.stringify(this.context));
1552
return this.context.locale;
@@ -1558,7 +1557,6 @@ describe('ReactIncremental', () => {
1557
static contextTypes = {
1558
route: React.PropTypes.string,
1559
};
1561
-
1560
render() {
1561
ops.push('ShowRoute ' + JSON.stringify(this.context));
1562
return this.context.route;
@@ -1721,7 +1719,6 @@ describe('ReactIncremental', () => {
1719
static contextTypes = {
1720
locale: React.PropTypes.string,
1721
};
1724
-
1722
render() {
1723
ops.push('ShowLocale ' + JSON.stringify(this.context));
1724
return this.context.locale;
@@ -1756,4 +1753,152 @@ describe('ReactIncremental', () => {
1753
'ShowLocale {"locale":"ru"}',
1754
]);
1755
});
1756
+
1757
+ it('reads context when setState is below the provider', () => {
1758
+ var ops = [];
1759
+ var statefulInst;
1760
+
1761
+ class Intl extends React.Component {
1762
+ static childContextTypes = {
1763
+ locale: React.PropTypes.string,
1764
+ };
1765
+ getChildContext() {
1766
+ const childContext = {
1767
+ locale: this.props.locale,
1768
+ };
1769
+ ops.push('Intl:provide ' + JSON.stringify(childContext));
1770
+ return childContext;
1771
+ }
1772
+ render() {
1773
+ ops.push('Intl:read ' + JSON.stringify(this.context));
1774
+ return this.props.children;
1775
+ }
1776
+ }
1777
+
1778
+ class ShowLocaleClass extends React.Component {
1779
+ static contextTypes = {
1780
+ locale: React.PropTypes.string,
1781
+ };
1782
+ render() {
1783
+ ops.push('ShowLocaleClass:read ' + JSON.stringify(this.context));
1784
+ return this.context.locale;
1785
+ }
1786
+ }
1787
+
1788
+ function ShowLocaleFn(props, context) {
1789
+ ops.push('ShowLocaleFn:read ' + JSON.stringify(context));
1790
+ return context.locale;
1791
+ }
1792
+ ShowLocaleFn.contextTypes = {
1793
+ locale: React.PropTypes.string,
1794
+ };
1795
+
1796
+ class Stateful extends React.Component {
1797
+ state = {x: 0};
1798
+ render() {
1799
+ statefulInst = this;
1800
+ return [
1801
+ <ShowLocaleClass />,
1802
+ <ShowLocaleFn />,
1803
+ ];
1804
+ }
1805
+ }
1806
+
1807
+ ops.length = 0;
1808
+ ReactNoop.render(
1809
+ <Intl locale="fr">
1810
+ <Stateful />
1811
+ </Intl>
1812
+ );
1813
+ ReactNoop.flush();
1814
+ expect(ops).toEqual([
1815
+ 'Intl:read null',
1816
+ 'Intl:provide {"locale":"fr"}',
1817
+ 'ShowLocaleClass:read {"locale":"fr"}',
1818
+ 'ShowLocaleFn:read {"locale":"fr"}',
1819
+ ]);
1820
+
1821
+ ops.length = 0;
1822
+ statefulInst.setState({x: 1});
1823
+ ReactNoop.flush();
1824
+ expect(ops).toEqual([
1825
+ // TODO: we should be able to reuse the previous child context.
1826
+ 'Intl:provide {"locale":"fr"}',
1827
+ 'ShowLocaleClass:read {"locale":"fr"}',
1828
+ 'ShowLocaleFn:read {"locale":"fr"}',
1829
+ ]);
1830
+ });
1831
+
1832
+ it('reads context when setState is above the provider', () => {
1833
+ var ops = [];
1834
+ var statefulInst;
1835
+
1836
+ class Intl extends React.Component {
1837
+ static childContextTypes = {
1838
+ locale: React.PropTypes.string,
1839
+ };
1840
+ getChildContext() {
1841
+ const childContext = {
1842
+ locale: this.props.locale,
1843
+ };
1844
+ ops.push('Intl:provide ' + JSON.stringify(childContext));
1845
+ return childContext;
1846
+ }
1847
+ render() {
1848
+ ops.push('Intl:read ' + JSON.stringify(this.context));
1849
+ return this.props.children;
1850
+ }
1851
+ }
1852
+
1853
+ class ShowLocaleClass extends React.Component {
1854
+ static contextTypes = {
1855
+ locale: React.PropTypes.string,
1856
+ };
1857
+ render() {
1858
+ ops.push('ShowLocaleClass:read ' + JSON.stringify(this.context));
1859
+ return this.context.locale;
1860
+ }
1861
+ }
1862
+
1863
+ function ShowLocaleFn(props, context) {
1864
+ ops.push('ShowLocaleFn:read ' + JSON.stringify(context));
1865
+ return context.locale;
1866
+ }
1867
+ ShowLocaleFn.contextTypes = {
1868
+ locale: React.PropTypes.string,
1869
+ };
1870
+
1871
+ class Stateful extends React.Component {
1872
+ state = {locale: 'fr'};
1873
+ render() {
1874
+ statefulInst = this;
1875
+ return (
1876
+ <Intl locale={this.state.locale}>
1877
+ <ShowLocaleClass />
1878
+ <ShowLocaleFn />
1879
+ </Intl>
1880
+ );
1881
+ }
1882
+ }
1883
+
1884
+ ops.length = 0;
1885
+ ReactNoop.render(<Stateful />);
1886
+ ReactNoop.flush();
1887
+ expect(ops).toEqual([
1888
+ 'Intl:read null',
1889
+ 'Intl:provide {"locale":"fr"}',
1890
+ 'ShowLocaleClass:read {"locale":"fr"}',
1891
+ 'ShowLocaleFn:read {"locale":"fr"}',
1892
+ ]);
1893
+
1894
+ ops.length = 0;
1895
+ statefulInst.setState({locale: 'gr'});
1896
+ ReactNoop.flush();
1897
+ expect(ops).toEqual([
1898
+ 'Intl:read null',
1899
+ 'Intl:provide {"locale":"gr"}',
1900
+ 'ShowLocaleClass:read {"locale":"gr"}',
1901
+ 'ShowLocaleFn:read {"locale":"gr"}',
1902
+ ]);
1903
+ });
1904
});