Skip to content

Commit 2d90d95

Browse files
authored
Merge pull request #12 from pvasek/fix/HOC_not_working_for_external_functions
HOC not working for external functions
2 parents 340df1d + 0aa98f3 commit 2d90d95

10 files changed

+135
-57
lines changed

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "react-docgen-typescript",
3-
"version": "0.0.9",
3+
"version": "0.0.10",
44
"description": "",
55
"main": "lib/index.js",
66
"scripts": {
@@ -21,7 +21,7 @@
2121
"devDependencies": {
2222
"@types/chai": "^3.4.35",
2323
"@types/mocha": "^2.2.39",
24-
"@types/node": "^7.0.5",
24+
"@types/node": "^7.0.16",
2525
"@types/react": "^15.0.14",
2626
"@types/react-dom": "^0.14.23",
2727
"babel-core": "^6.8.0",

src/__tests__/data/ColumnHigherOrderComponent.tsx

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import * as React from 'react';
2+
import { externalHoc } from "./ColumnHigherOrderComponentHoc";
23
/**
34
* Column properties.
45
*/
@@ -62,13 +63,16 @@ function hoc<T>(C: T): T {
6263
return ((props) => <div>{C}</div>) as any as T;
6364
}
6465

65-
/** ColumnHighOrderComponent1 specific comment */
66-
export const ColumnHighOrderComponent1 = hoc(Column);
66+
/** ColumnHigherOrderComponent1 specific comment */
67+
export const ColumnHigherOrderComponent1 = hoc(Column);
6768

68-
export const ColumnHighOrderComponent2 = hoc(Column);
69+
export const ColumnHigherOrderComponent2 = hoc(Column);
6970

70-
/** RowHighOrderComponent1 specific comment */
71-
export const RowHighOrderComponent1 = hoc(Row);
71+
/** RowHigherOrderComponent1 specific comment */
72+
export const RowHigherOrderComponent1 = hoc(Row);
7273

73-
export const RowHighOrderComponent2 = hoc(Row);
74+
export const RowHigherOrderComponent2 = hoc(Row);
75+
76+
export const ColumnExternalHigherOrderComponent = externalHoc(Column);
77+
export const RowExternalHigherOrderComponent = externalHoc(Row);
7478

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import * as React from 'react';
2+
3+
export function externalHoc<T>(C: T): T {
4+
return ((props) => <div>{C}</div>) as any as T;
5+
}

src/__tests__/data/transformAST.tsx

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { externalHoc } from './transformAST_hoc';
2+
13
const unexportedVar = 10;
24
export const exportedVar = 10;
35

@@ -51,5 +53,15 @@ export function hoc<T>(component: T): T {
5153
return component;
5254
}
5355

54-
/** exportedHoc comment */
55-
export const exportedHoc = hoc(ExportedClass);
56+
/** exportedHoc1 comment */
57+
export const exportedHoc1 = hoc(ExportedClass);
58+
59+
/** exportedHoc2 comment */
60+
export const exportedHoc2 = hoc(exportedFunction);
61+
62+
63+
/** exportedExternalHoc1 comment */
64+
export const exportedExternalHoc1 = externalHoc(ExportedClass);
65+
66+
/** exportedExternalHoc2 comment */
67+
export const exportedExternalHoc2 = externalHoc(exportedFunction);
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export function externalHoc<T>(component: T): T {
2+
return component;
3+
}

src/__tests__/getFileDocumentation.spec.ts

Lines changed: 54 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -173,39 +173,72 @@ describe('getFileDocumentation', () => {
173173
const fileName = path.join(__dirname, '../../src/__tests__/data/ColumnHigherOrderComponent.tsx'); // it's running in ./temp
174174
const result = getFileDocumentation(fileName);
175175
assert.ok(result.components);
176-
assert.equal(4, result.components.length);
176+
assert.equal(6, result.components.length);
177177

178178
const r1 = result.components[0];
179-
assert.equal('ColumnHighOrderComponent1', r1.name);
180-
assert.equal('ColumnHighOrderComponent1 specific comment', r1.comment);
179+
assert.equal('ColumnHigherOrderComponent1', r1.name);
180+
assert.equal('ColumnHigherOrderComponent1 specific comment', r1.comment);
181181
assert.equal('Column', r1.extends);
182182
assert.isNotNull(r1.propInterface);
183183

184-
const i = r1.propInterface;
185-
assert.equal('IColumnProps', i.name);
186-
assert.equal('Column properties.', i.comment);
187-
assert.equal(4, i.members.length);
188-
assert.equal('prop1', i.members[0].name);
189-
assert.equal('prop1 description', i.members[0].comment);
190-
assert.equal(false, i.members[0].isRequired);
184+
const p1 = r1.propInterface;
185+
assert.equal('IColumnProps', p1.name);
186+
assert.equal('Column properties.', p1.comment);
187+
assert.equal(4, p1.members.length);
188+
assert.equal('prop1', p1.members[0].name);
189+
assert.equal('prop1 description', p1.members[0].comment);
190+
assert.equal(false, p1.members[0].isRequired);
191191

192-
assert.equal('prop2', i.members[1].name);
193-
assert.equal('prop2 description', i.members[1].comment);
194-
assert.equal(true, i.members[1].isRequired);
192+
assert.equal('prop2', p1.members[1].name);
193+
assert.equal('prop2 description', p1.members[1].comment);
194+
assert.equal(true, p1.members[1].isRequired);
195195

196-
assert.equal('prop3', i.members[2].name);
197-
assert.equal('prop3 description', i.members[2].comment);
198-
assert.equal(true, i.members[2].isRequired);
196+
assert.equal('prop3', p1.members[2].name);
197+
assert.equal('prop3 description', p1.members[2].comment);
198+
assert.equal(true, p1.members[2].isRequired);
199199

200-
assert.equal('prop4', i.members[3].name);
201-
assert.equal('prop4 description', i.members[3].comment);
202-
assert.equal(true, i.members[3].isRequired);
200+
assert.equal('prop4', p1.members[3].name);
201+
assert.equal('prop4 description', p1.members[3].comment);
202+
assert.equal(true, p1.members[3].isRequired);
203203

204204
const r2 = result.components[1];
205-
assert.equal('ColumnHighOrderComponent2', r2.name);
205+
assert.equal('ColumnHigherOrderComponent2', r2.name);
206206
assert.equal('Form column.', r2.comment);
207207
assert.equal('Column', r2.extends);
208208
assert.isNotNull(r2.propInterface);
209-
209+
const p2 = r2.propInterface;
210+
assert.equal('IColumnProps', p2.name);
211+
212+
const r3 = result.components[2];
213+
assert.equal('ColumnExternalHigherOrderComponent', r3.name);
214+
assert.equal('Form column.', r3.comment);
215+
assert.equal('Column', r3.extends);
216+
assert.isNotNull(r3.propInterface);
217+
const p3 = r3.propInterface;
218+
assert.equal('IColumnProps', p3.name);
219+
220+
const r4 = result.components[3];
221+
assert.equal('RowHigherOrderComponent1', r4.name);
222+
assert.equal('RowHigherOrderComponent1 specific comment', r4.comment);
223+
assert.equal('Row', r4.extends);
224+
assert.isNotNull(r4.propInterface);
225+
const p4 = r4.propInterface;
226+
assert.equal('IRowProps', p4.name);
227+
228+
const r5 = result.components[4];
229+
assert.equal('RowHigherOrderComponent2', r5.name);
230+
assert.equal('Form row.', r5.comment);
231+
assert.equal('Row', r5.extends);
232+
assert.isNotNull(r5.propInterface);
233+
const p5 = r5.propInterface;
234+
assert.equal('IRowProps', p5.name);
235+
236+
const r6 = result.components[5];
237+
assert.equal('RowExternalHigherOrderComponent', r6.name);
238+
assert.equal('Form row.', r6.comment);
239+
assert.equal('Row', r6.extends);
240+
assert.isNotNull(r6.propInterface);
241+
const p6 = r6.propInterface;
242+
assert.equal('IRowProps', p6.name);
210243
});
211244
});

src/__tests__/transformAST.spec.ts

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ describe('transformAST', () => {
1818

1919
it('should provide data about variables', () => {
2020
const result = target.variables;
21-
assert.equal(result.length, 5);
21+
assert.equal(result.length, 8);
2222

2323
const r1 = result[0];
2424
assert.equal(r1.name, 'unexportedVar');
@@ -48,14 +48,41 @@ describe('transformAST', () => {
4848
assert.equal(r4.arrowFunctionType, 'string');
4949
assert.deepEqual(r4.arrowFunctionParams, ['number', 'string']);
5050

51-
// hoc
51+
// hoc class
5252
const r5 = result[4];
53-
assert.equal(r5.name, 'exportedHoc');
53+
assert.equal(r5.name, 'exportedHoc1');
5454
assert.equal(r5.exported, true);
5555
assert.equal(r5.type, 'ExportedClass');
5656
assert.equal(r5.kind, 'callExpression');
57-
assert.equal(r5.comment, 'exportedHoc comment');
57+
assert.equal(r5.comment, 'exportedHoc1 comment');
5858
assert.deepEqual(r5.callExpressionArguments, ['ExportedClass']);
59+
60+
// hoc function
61+
const r6 = result[5];
62+
assert.equal(r6.name, 'exportedHoc2');
63+
assert.equal(r6.exported, true);
64+
assert.equal(r6.type, 'exportedFunction');
65+
assert.equal(r6.kind, 'callExpression');
66+
assert.equal(r6.comment, 'exportedHoc2 comment');
67+
assert.deepEqual(r6.callExpressionArguments, ['exportedFunction']);
68+
69+
// external hoc class
70+
const r7 = result[6];
71+
assert.equal(r7.name, 'exportedExternalHoc1');
72+
assert.equal(r7.exported, true);
73+
assert.equal(r7.type, 'ExportedClass');
74+
assert.equal(r7.kind, 'callExpression');
75+
assert.equal(r7.comment, 'exportedExternalHoc1 comment');
76+
assert.deepEqual(r7.callExpressionArguments, ['ExportedClass']);
77+
78+
// external hoc function
79+
const r8 = result[7];
80+
assert.equal(r8.name, 'exportedExternalHoc2');
81+
assert.equal(r8.exported, true);
82+
assert.equal(r8.type, 'exportedFunction');
83+
assert.equal(r8.kind, 'callExpression');
84+
assert.equal(r8.comment, 'exportedExternalHoc2 comment');
85+
assert.deepEqual(r8.callExpressionArguments, ['exportedFunction']);
5986
});
6087

6188
it('should provide data about interfaces', () => {

src/getFileDocumentation.ts

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -37,26 +37,28 @@ function isVarComponent(
3737
function isHocClassComponent(entry: VariableEntry, classes: ClassEntry[]): boolean {
3838
return entry.exported
3939
&& entry.kind === 'callExpression'
40-
&& entry.type !== null
40+
// quick fix for external hoc - && entry.type !== null
41+
&& entry.callExpressionArguments.length === 1
4142
&& classes
4243
.filter(i => isClassComponent(i, false))
43-
.some(i => i.name === entry.type);
44+
.some(i => i.name === entry.callExpressionArguments[0]);
4445
}
4546

46-
function isVarClassComponent(
47+
function isHocVarComponent(
4748
entry: VariableEntry,
4849
variables: VariableEntry[],
4950
interfaces: InterfaceEntry[]): boolean {
5051

5152
return entry.exported
5253
&& entry.kind === 'callExpression'
53-
&& entry.type === '__function'
54+
// quick fix for external hoc - && entry.type === '__function'
5455
&& entry.callExpressionArguments.length === 1
5556
&& variables
5657
.filter(i => isVarComponent(i, interfaces, false))
5758
.some(i => i.name === entry.callExpressionArguments[0]);
5859
}
5960

61+
6062
function getInterfaceDoc(entry: InterfaceEntry): InterfaceDoc {
6163
return {
6264
name: entry.name,
@@ -90,7 +92,7 @@ function getPropInterface(interfaces: InterfaceEntry[], propInterfaceName: strin
9092
}
9193
/** Generate documention for all classes in a set of .ts files */
9294
export function getFileDocumentation(fileName: string, options: ts.CompilerOptions = defaultOptions): FileDoc {
93-
const components: ComponentDoc[] = [];
95+
const components: ComponentDoc[] = [];
9496
let program = ts.createProgram([fileName], options);
9597
let checker = program.getTypeChecker();
9698
const model = transformAST(program.getSourceFile(fileName), checker);
@@ -119,24 +121,24 @@ export function getFileDocumentation(fileName: string, options: ts.CompilerOptio
119121
.filter(i => isHocClassComponent(i, classes))
120122
.map(i => ({
121123
variable: i,
122-
origin: classes.filter(c => c.name === i.type)[0]
124+
origin: classes.filter(c => c.name === i.callExpressionArguments[0])[0]
123125
}))
124126
.map(i => ({
125127
name: i.variable.name,
126-
extends: i.variable.type,
128+
extends: i.variable.callExpressionArguments[0],
127129
comment: i.variable.comment || i.origin.comment,
128130
propInterface: getClassPropInterface(interfaces, i.origin),
129131
}));
130132

131133
const hocVarComponents = variables
132-
.filter(i => isVarClassComponent(i, variables, interfaces))
134+
.filter(i => isHocVarComponent(i, variables, interfaces))
133135
.map(i => ({
134136
variable: i,
135137
origin: variables.filter(c => c.name === i.callExpressionArguments[0])[0]
136138
}))
137139
.map(i => ({
138140
name: i.variable.name,
139-
extends: i.variable.type,
141+
extends: i.variable.callExpressionArguments[0],
140142
comment: i.variable.comment || i.origin.comment,
141143
propInterface: getVarPropInterface(interfaces, i.origin),
142144
}));

src/transformAST.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ function findAllNodes(rootNode: ts.Node, result: ts.Node[]) {
7676
* Transform source file AST (abstract syntax tree) to our
7777
* model (classes, interfaces, variables, methods).
7878
*/
79-
export function transformAST(sourceFile: ts.SourceFile, checker: ts.TypeChecker) {
79+
export function transformAST(sourceFile: ts.SourceFile, checker: ts.TypeChecker) {
8080
const nodes = [];
8181
findAllNodes(sourceFile, nodes);
8282

@@ -116,7 +116,7 @@ export function transformAST(sourceFile: ts.SourceFile, checker: ts.TypeChecker)
116116
callExpressionArguments = callExpresson.arguments.map(i => i.getText());
117117
}
118118
}
119-
119+
120120
return {
121121
name: identifier.text,
122122
exported: isNodeExported(i),

yarn.lock

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
version "2.2.41"
1111
resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-2.2.41.tgz#e27cf0817153eb9f2713b2d3f6c68f1e1c3ca608"
1212

13-
"@types/node@^7.0.5":
13+
"@types/node@^7.0.16":
1414
version "7.0.16"
1515
resolved "https://registry.yarnpkg.com/@types/node/-/node-7.0.16.tgz#e3440e3ce4d4931616ac418cc4dc16cd94b80092"
1616

@@ -1592,14 +1592,10 @@ escape-html@~1.0.3:
15921592
version "1.0.3"
15931593
resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988"
15941594

1595-
1595+
[email protected], escape-string-regexp@^1.0.2:
15961596
version "1.0.2"
15971597
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.2.tgz#4dbc2fe674e71949caf3fb2695ce7f2dc1d9a8d1"
15981598

1599-
escape-string-regexp@^1.0.2:
1600-
version "1.0.5"
1601-
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
1602-
16031599
esprima-fb@~15001.1001.0-dev-harmony-fb:
16041600
version "15001.1001.0-dev-harmony-fb"
16051601
resolved "https://registry.yarnpkg.com/esprima-fb/-/esprima-fb-15001.1001.0-dev-harmony-fb.tgz#43beb57ec26e8cf237d3dd8b33e42533577f2659"
@@ -3298,11 +3294,7 @@ randomatic@^1.1.3:
32983294
is-number "^2.0.2"
32993295
kind-of "^3.0.2"
33003296

3301-
range-parser@^1.0.3:
3302-
version "1.2.0"
3303-
resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.0.tgz#f49be6b487894ddc40dcc94a322f611092e00d5e"
3304-
3305-
range-parser@~1.0.3:
3297+
range-parser@^1.0.3, range-parser@~1.0.3:
33063298
version "1.0.3"
33073299
resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.0.3.tgz#6872823535c692e2c2a0103826afd82c2e0ff175"
33083300

0 commit comments

Comments
 (0)