Skip to content

Commit c8c0064

Browse files
author
古映杰
committed
support react 15.0-rc1 style
1 parent 6891ac4 commit c8c0064

13 files changed

Lines changed: 386 additions & 226 deletions

__tests__/ReactEmptyComponent-test.js

Lines changed: 76 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/**
2-
* Copyright 2014-2015, Facebook, Inc.
2+
* Copyright 2014-present, Facebook, Inc.
33
* All rights reserved.
44
*
55
* This source code is licensed under the BSD-style license found in the
@@ -10,16 +10,19 @@
1010
*/
1111

1212
'use strict';
13-
jest.dontMock('../src');
13+
jest.dontMock('../src');
1414
var React;
1515
var ReactDOM;
1616
var ReactTestUtils;
1717
var TogglingComponent;
1818

1919
var reactComponentExpect;
2020

21+
var log;
22+
2123
describe('ReactEmptyComponent', function() {
2224
beforeEach(function() {
25+
jest.resetModuleRegistry();
2326

2427
React = require('../src');
2528
ReactDOM = require('../src');
@@ -34,17 +37,20 @@ describe('ReactEmptyComponent', function() {
3437
return ReactDOM.render(instance, div);
3538
}
3639
};
40+
// reactComponentExpect = require('reactComponentExpect');
41+
42+
log = jasmine.createSpy();
3743

3844
TogglingComponent = React.createClass({
3945
getInitialState: function() {
4046
return {component: this.props.firstComponent};
4147
},
4248
componentDidMount: function() {
43-
console.log(ReactDOM.findDOMNode(this));
49+
log(ReactDOM.findDOMNode(this));
4450
this.setState({component: this.props.secondComponent});
4551
},
4652
componentDidUpdate: function() {
47-
console.log(ReactDOM.findDOMNode(this));
53+
log(ReactDOM.findDOMNode(this));
4854
},
4955
render: function() {
5056
var Component = this.state.component;
@@ -59,9 +65,20 @@ describe('ReactEmptyComponent', function() {
5965
return null;
6066
},
6167
});
68+
var Component2 = React.createClass({
69+
render: function() {
70+
return false;
71+
},
72+
});
6273

63-
var instance = ReactTestUtils.renderIntoDocument(<Component1 />);
64-
expect(ReactDOM.findDOMNode(instance) === null)
74+
var instance1 = ReactTestUtils.renderIntoDocument(<Component1 />);
75+
var instance2 = ReactTestUtils.renderIntoDocument(<Component2 />);
76+
// reactComponentExpect(instance1)
77+
// .expectRenderedChild()
78+
// .toBeEmptyComponent();
79+
// reactComponentExpect(instance2)
80+
// .expectRenderedChild()
81+
// .toBeEmptyComponent();
6582
});
6683

6784
it('should still throw when rendering to undefined', () => {
@@ -70,11 +87,13 @@ describe('ReactEmptyComponent', function() {
7087
});
7188
expect(function() {
7289
ReactTestUtils.renderIntoDocument(<Component />);
73-
}).toThrow();
90+
}).toThrow(
91+
// 'Component.render(): A valid React element (or null) must be returned. You may ' +
92+
// 'have returned undefined, an array or some other invalid object.'
93+
);
7494
});
7595

7696
it('should be able to switch between rendering null and a normal tag', () => {
77-
spyOn(console, 'log');
7897
var instance1 =
7998
<TogglingComponent
8099
firstComponent={null}
@@ -89,17 +108,39 @@ describe('ReactEmptyComponent', function() {
89108
ReactTestUtils.renderIntoDocument(instance1);
90109
ReactTestUtils.renderIntoDocument(instance2);
91110

92-
expect(console.log.argsForCall.length).toBe(4);
93-
expect(console.log.argsForCall[0][0]).toBe(null);
94-
expect(console.log.argsForCall[1][0].tagName).toBe('DIV');
95-
expect(console.log.argsForCall[2][0].tagName).toBe('DIV');
96-
expect(console.log.argsForCall[3][0]).toBe(null);
111+
expect(log.argsForCall.length).toBe(4);
112+
expect(log.argsForCall[0][0]).toBe(null);
113+
expect(log.argsForCall[1][0].tagName).toBe('DIV');
114+
expect(log.argsForCall[2][0].tagName).toBe('DIV');
115+
expect(log.argsForCall[3][0]).toBe(null);
116+
});
117+
118+
it('should be able to switch in a list of children', () => {
119+
var instance1 =
120+
<TogglingComponent
121+
firstComponent={null}
122+
secondComponent={'div'}
123+
/>;
124+
125+
ReactTestUtils.renderIntoDocument(
126+
<div>
127+
{instance1}
128+
{instance1}
129+
{instance1}
130+
</div>
131+
);
132+
133+
expect(log.argsForCall.length).toBe(6);
134+
expect(log.argsForCall[0][0]).toBe(null);
135+
expect(log.argsForCall[1][0]).toBe(null);
136+
expect(log.argsForCall[2][0]).toBe(null);
137+
expect(log.argsForCall[3][0].tagName).toBe('DIV');
138+
expect(log.argsForCall[4][0].tagName).toBe('DIV');
139+
expect(log.argsForCall[5][0].tagName).toBe('DIV');
97140
});
98141

99142
it('should distinguish between a script placeholder and an actual script tag',
100143
() => {
101-
spyOn(console, 'log');
102-
103144
var instance1 =
104145
<TogglingComponent
105146
firstComponent={null}
@@ -118,18 +159,17 @@ describe('ReactEmptyComponent', function() {
118159
ReactTestUtils.renderIntoDocument(instance2);
119160
}).not.toThrow();
120161

121-
expect(console.log.argsForCall.length).toBe(4);
122-
expect(console.log.argsForCall[0][0]).toBe(null);
123-
expect(console.log.argsForCall[1][0].tagName).toBe('SCRIPT');
124-
expect(console.log.argsForCall[2][0].tagName).toBe('SCRIPT');
125-
expect(console.log.argsForCall[3][0]).toBe(null);
162+
expect(log.argsForCall.length).toBe(4);
163+
expect(log.argsForCall[0][0]).toBe(null);
164+
expect(log.argsForCall[1][0].tagName).toBe('SCRIPT');
165+
expect(log.argsForCall[2][0].tagName).toBe('SCRIPT');
166+
expect(log.argsForCall[3][0]).toBe(null);
126167
}
127168
);
128169

129-
it('should have getDOMNode return null when multiple layers of composite ' +
130-
'components render to the same null placeholder', () => {
131-
spyOn(console, 'log');
132-
170+
it('should have findDOMNode return null when multiple layers of composite ' +
171+
'components render to the same null placeholder',
172+
() => {
133173
var GrandChild = React.createClass({
134174
render: function() {
135175
return null;
@@ -159,11 +199,12 @@ describe('ReactEmptyComponent', function() {
159199
expect(function() {
160200
ReactTestUtils.renderIntoDocument(instance2);
161201
}).not.toThrow();
162-
expect(console.log.argsForCall.length).toBe(4);
163-
expect(console.log.argsForCall[0][0].tagName).toBe('DIV');
164-
expect(console.log.argsForCall[1][0]).toBe(null);
165-
expect(console.log.argsForCall[2][0]).toBe(null);
166-
expect(console.log.argsForCall[3][0].tagName).toBe('DIV');
202+
203+
expect(log.argsForCall.length).toBe(4);
204+
expect(log.argsForCall[0][0].tagName).toBe('DIV');
205+
expect(log.argsForCall[1][0]).toBe(null);
206+
expect(log.argsForCall[2][0]).toBe(null);
207+
expect(log.argsForCall[3][0].tagName).toBe('DIV');
167208
}
168209
);
169210

@@ -215,7 +256,9 @@ describe('ReactEmptyComponent', function() {
215256
var div = document.createElement('div');
216257
expect(function() {
217258
ReactDOM.render(null, div);
218-
}).toThrow();
259+
}).toThrow(
260+
// 'ReactDOM.render(): Invalid component element.'
261+
);
219262
});
220263

221264
it('does not break when updating during mount', function() {
@@ -265,12 +308,13 @@ describe('ReactEmptyComponent', function() {
265308

266309
ReactDOM.render(<Empty />, container);
267310
var noscript1 = container.firstChild;
268-
expect(noscript1.tagName).toBe('NOSCRIPT');
311+
expect(noscript1.nodeName).toBe('#comment');
269312

270313
// This update shouldn't create a DOM node
271314
ReactDOM.render(<Empty />, container);
272315
var noscript2 = container.firstChild;
273-
expect(noscript2.tagName).toBe('NOSCRIPT');
316+
expect(noscript2.nodeName).toBe('#comment');
317+
274318
expect(noscript1).toBe(noscript2);
275319
});
276320
});

__tests__/ReactStatelessComponent-test.js

Lines changed: 63 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/**
2-
* Copyright 2013-2015, Facebook, Inc.
2+
* Copyright 2013-present, Facebook, Inc.
33
* All rights reserved.
44
*
55
* This source code is licensed under the BSD-style license found in the
@@ -10,7 +10,7 @@
1010
*/
1111

1212
'use strict';
13-
jest.dontMock('../src');
13+
jest.dontMock('../src');
1414
var React;
1515
var ReactDOM;
1616
var ReactTestUtils;
@@ -108,19 +108,19 @@ describe('ReactStatelessComponent', function() {
108108
expect(el.textContent).toBe('mest');
109109
});
110110

111-
it('should support module pattern components', function() {
112-
function Child({test}) {
113-
return {
114-
render() {
115-
return <div>{test}</div>;
116-
},
117-
};
111+
it('should warn when stateless component returns array', function() {
112+
spyOn(console, 'error');
113+
function NotAComponent() {
114+
return [<div />, <div />];
118115
}
119-
120-
var el = document.createElement('div');
121-
ReactDOM.render(<Child test="test" />, el);
122-
123-
expect(el.textContent).toBe('test');
116+
expect(function() {
117+
ReactTestUtils.renderIntoDocument(<div><NotAComponent /></div>);
118+
}).toThrow();
119+
// expect(console.error.calls.length).toBe(1);
120+
// expect(console.error.argsForCall[0][0]).toContain(
121+
// 'NotAComponent(...): A valid React element (or null) must be returned. '+
122+
// 'You may have returned undefined, an array or some other invalid object.'
123+
// );
124124
});
125125

126126
// it('should throw on string refs in pure functions', function() {
@@ -131,7 +131,7 @@ describe('ReactStatelessComponent', function() {
131131
// expect(function() {
132132
// ReactTestUtils.renderIntoDocument(<Child test="test" />);
133133
// }).toThrow(
134-
// 'Invariant Violation: Stateless function components cannot have refs.'
134+
// 'Stateless function components cannot have refs.'
135135
// );
136136
// });
137137

@@ -148,7 +148,10 @@ describe('ReactStatelessComponent', function() {
148148

149149
// expect(console.error.argsForCall.length).toBe(1);
150150
// expect(console.error.argsForCall[0][0]).toContain(
151-
// 'Stateless function components cannot be given refs');
151+
// 'Stateless function components cannot be given refs ' +
152+
// '(See ref "stateless" in StatelessComponent created by Parent). ' +
153+
// 'Attempts to access this ref will fail.'
154+
// );
152155
// });
153156

154157
it('should provide a null ref', function() {
@@ -172,14 +175,21 @@ describe('ReactStatelessComponent', function() {
172175
// expect(console.error.argsForCall[0][0]).toContain('Child');
173176
// });
174177

175-
it('should support default props', function() {
176-
function Child(props) {
177-
expect(props.test).toBe(2)
178-
return <div>{props.test}</div>;
179-
}
180-
Child.defaultProps = {test: 2};
181-
ReactTestUtils.renderIntoDocument(<Child />);
182-
});
178+
// it('should support default props and prop types', function() {
179+
// function Child(props) {
180+
// return <div>{props.test}</div>;
181+
// }
182+
// Child.defaultProps = {test: 2};
183+
// Child.propTypes = {test: React.PropTypes.string};
184+
185+
// spyOn(console, 'error');
186+
// ReactTestUtils.renderIntoDocument(<Child />);
187+
// expect(console.error.argsForCall.length).toBe(1);
188+
// expect(console.error.argsForCall[0][0]).toBe(
189+
// 'Warning: Failed propType: Invalid prop `test` of type `number` ' +
190+
// 'supplied to `Child`, expected `string`.'
191+
// );
192+
// });
183193

184194
it('should receive context', function() {
185195
var Parent = React.createClass({
@@ -204,10 +214,6 @@ describe('ReactStatelessComponent', function() {
204214
});
205215

206216
it('should work with arrow functions', function() {
207-
// TODO: actually use arrow functions, probably need node v4 and maybe
208-
// a separate file that we blacklist from the arrow function transform.
209-
// We can't actually test this without native arrow functions since the
210-
// issues (non-newable) don't apply to any other functions.
211217
var Child = function() {
212218
return <div />;
213219
};
@@ -217,4 +223,33 @@ describe('ReactStatelessComponent', function() {
217223

218224
expect(() => ReactTestUtils.renderIntoDocument(<Child />)).not.toThrow();
219225
});
226+
227+
it('should allow simple functions to return null', function() {
228+
var Child = function() {
229+
return null;
230+
};
231+
expect(() => ReactTestUtils.renderIntoDocument(<Child />)).not.toThrow();
232+
});
233+
234+
it('should allow simple functions to return false', function() {
235+
function Child() {
236+
return false;
237+
}
238+
expect(() => ReactTestUtils.renderIntoDocument(<Child />)).not.toThrow();
239+
});
240+
241+
// it('should warn when using non-React functions in JSX', function() {
242+
// spyOn(console, 'error');
243+
// function NotAComponent() {
244+
// return [<div />, <div />];
245+
// }
246+
// expect(function() {
247+
// ReactTestUtils.renderIntoDocument(<div><NotAComponent /></div>);
248+
// }).toThrow(); // has no method 'render'
249+
// expect(console.error.calls.length).toBe(1);
250+
// expect(console.error.argsForCall[0][0]).toContain(
251+
// 'NotAComponent(...): A valid React element (or null) must be returned. You may ' +
252+
// 'have returned undefined, an array or some other invalid object.'
253+
// );
254+
// });
220255
});

0 commit comments

Comments
 (0)