7
7
*/
8
8
9
9
import { NodePath } from 'ast-types' ;
10
- import * as utils from '../../../tests/utils' ;
10
+ import {
11
+ getParser ,
12
+ parse as parseSource ,
13
+ statement ,
14
+ noopImporter ,
15
+ makeMockImporter ,
16
+ } from '../../../tests/utils' ;
11
17
import findAllComponentDefinitions from '../findAllComponentDefinitions' ;
12
18
13
19
describe ( 'findAllComponentDefinitions' , ( ) => {
14
- function parse ( source , importer = utils . noopImporter ) {
20
+ function parse ( source , importer = noopImporter ) {
15
21
return findAllComponentDefinitions (
16
- utils . parse ( source ) ,
17
- utils . getParser ( ) ,
22
+ parseSource ( source ) ,
23
+ getParser ( ) ,
18
24
importer ,
19
25
) ;
20
26
}
21
27
28
+ const mockImporter = makeMockImporter ( {
29
+ obj : statement ( `
30
+ export default {};
31
+ ` ) . get ( 'declaration' ) ,
32
+
33
+ reactComponent : statement ( `
34
+ export default React.Component;
35
+ import React from 'react';
36
+ ` ) . get ( 'declaration' ) ,
37
+
38
+ reactPureComponent : statement ( `
39
+ export default React.PureComponent;
40
+ import React from 'react';
41
+ ` ) . get ( 'declaration' ) ,
42
+
43
+ jsxDiv : statement ( `
44
+ export default <div />;
45
+ ` ) . get ( 'declaration' ) ,
46
+
47
+ createElement : statement ( `
48
+ export default React.createElement('div', null);
49
+ import React from 'react';
50
+ ` ) . get ( 'declaration' ) ,
51
+
52
+ arrowJsx : statement ( `
53
+ export default (props) => <div>{props.children}</div>;
54
+ ` ) . get ( 'declaration' ) ,
55
+
56
+ coloredView : statement ( `
57
+ export default function ColoredView(props, ref) {
58
+ return <div ref={ref} style={{backgroundColor: props.color}} />
59
+ };
60
+ ` ) . get ( 'declaration' ) ,
61
+ } ) ;
62
+
22
63
describe ( 'React.createClass' , ( ) => {
23
64
it ( 'finds React.createClass' , ( ) => {
24
65
const source = `
@@ -34,6 +75,21 @@ describe('findAllComponentDefinitions', () => {
34
75
expect ( result [ 0 ] . node . type ) . toBe ( 'ObjectExpression' ) ;
35
76
} ) ;
36
77
78
+ it ( 'resolves imported values inside React.createClass' , ( ) => {
79
+ const source = `
80
+ import obj from 'obj';
81
+ var React = require("React");
82
+ var Component = React.createClass(obj);
83
+ module.exports = Component;
84
+ ` ;
85
+
86
+ const result = parse ( source , mockImporter ) ;
87
+ expect ( Array . isArray ( result ) ) . toBe ( true ) ;
88
+ expect ( result . length ) . toBe ( 1 ) ;
89
+ expect ( result [ 0 ] instanceof NodePath ) . toBe ( true ) ;
90
+ expect ( result [ 0 ] . node . type ) . toBe ( 'ObjectExpression' ) ;
91
+ } ) ;
92
+
37
93
it ( 'finds React.createClass, independent of the var name' , ( ) => {
38
94
const source = `
39
95
var R = require("React");
@@ -112,7 +168,20 @@ describe('findAllComponentDefinitions', () => {
112
168
expect ( result . length ) . toBe ( 4 ) ;
113
169
} ) ;
114
170
115
- it ( 'finds React.createClass, independent of the var name' , ( ) => {
171
+ it ( 'resolves extends React.Component/React.PureComponent from import' , ( ) => {
172
+ const source = `
173
+ import Component from 'reactComponent';
174
+ import PureComponent from 'reactPureComponent';
175
+ class ComponentA extends Component {}
176
+ var ComponentC = class extends PureComponent {}
177
+ ` ;
178
+
179
+ const result = parse ( source , mockImporter ) ;
180
+ expect ( Array . isArray ( result ) ) . toBe ( true ) ;
181
+ expect ( result . length ) . toBe ( 2 ) ;
182
+ } ) ;
183
+
184
+ it ( 'finds React.Component, independent of the var name' , ( ) => {
116
185
const source = `
117
186
import R from 'React';
118
187
class Component extends R.Component {};
@@ -123,7 +192,7 @@ describe('findAllComponentDefinitions', () => {
123
192
expect ( result . length ) . toBe ( 1 ) ;
124
193
} ) ;
125
194
126
- it ( 'does not process X.createClass of other modules' , ( ) => {
195
+ it ( 'does not process X.Component of other modules' , ( ) => {
127
196
const source = `
128
197
import R from 'FakeReact';
129
198
class Component extends R.Component {};
@@ -166,6 +235,21 @@ describe('findAllComponentDefinitions', () => {
166
235
expect ( result . length ) . toBe ( 7 ) ;
167
236
} ) ;
168
237
238
+ it ( 'resolve renders from imports' , ( ) => {
239
+ const source = `
240
+ import jsxDiv from 'jsxDiv';
241
+ import createElement from 'createElement';
242
+ import arrowJsx from 'arrowJsx';
243
+ let ComponentA = () => jsxDiv;
244
+ function ComponentB () { return createElement; }
245
+ const ComponentC = function(props) { return arrowJsx(props); };
246
+ ` ;
247
+
248
+ const result = parse ( source , mockImporter ) ;
249
+ expect ( Array . isArray ( result ) ) . toBe ( true ) ;
250
+ expect ( result . length ) . toBe ( 3 ) ;
251
+ } ) ;
252
+
169
253
it ( 'finds React.createElement, independent of the var name' , ( ) => {
170
254
const source = `
171
255
import AlphaBetters from 'react';
@@ -178,7 +262,7 @@ describe('findAllComponentDefinitions', () => {
178
262
expect ( result . length ) . toBe ( 1 ) ;
179
263
} ) ;
180
264
181
- it ( 'does not process X.createClass of other modules' , ( ) => {
265
+ it ( 'does not process X.createElement of other modules' , ( ) => {
182
266
const source = `
183
267
import R from 'FakeReact';
184
268
const ComponentA = () => R.createElement('div', null);
@@ -228,6 +312,19 @@ describe('findAllComponentDefinitions', () => {
228
312
expect ( result . length ) . toBe ( 1 ) ;
229
313
expect ( result [ 0 ] . value . type ) . toEqual ( 'CallExpression' ) ;
230
314
} ) ;
315
+
316
+ it ( 'resolves imported component wrapped with forwardRef' , ( ) => {
317
+ const source = `
318
+ import React from 'react';
319
+ import ColoredView from 'coloredView';
320
+ const ForwardedColoredView = React.forwardRef(ColoredView);
321
+ ` ;
322
+
323
+ const result = parse ( source , mockImporter ) ;
324
+ expect ( Array . isArray ( result ) ) . toBe ( true ) ;
325
+ expect ( result . length ) . toBe ( 1 ) ;
326
+ expect ( result [ 0 ] . value . type ) . toEqual ( 'CallExpression' ) ;
327
+ } ) ;
231
328
} ) ;
232
329
233
330
describe ( 'regressions' , ( ) => {
0 commit comments