Skip to content

Commit

Permalink
Fix Issue #132; determine parent fileNames relative to the current di…
Browse files Browse the repository at this point in the history
…rectory
  • Loading branch information
thomasmost authored and pvasek committed Oct 7, 2018
1 parent 25fd767 commit c07e2be
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 12 deletions.
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

23 changes: 21 additions & 2 deletions src/__tests__/parser.ts
Expand Up @@ -227,6 +227,26 @@ describe('parser', () => {
});
});

// see issue #132 (https://github.com/styleguidist/react-docgen-typescript/issues/132)
it('should determine the parent fileName relative to the project directory', () => {
check(
'ExportsPropTypeImport',
{
ExportsPropTypes: {
foo: {
parent: {
fileName:
'react-docgen-typescript/src/__tests__/data/ExportsPropTypeImport.tsx',
name: 'ExportsPropTypesProps'
},
type: 'any'
} as any
}
},
true
);
});

describe('component with default props', () => {
const expectation = {
ComponentWithDefaultProps: {
Expand Down Expand Up @@ -804,10 +824,9 @@ describe('parser', () => {
const [parsed] = parse(
fixturePath('StatelessDisplayNameStyledComponent'),
{
componentNameResolver: (exp, source) => (
componentNameResolver: (exp, source) =>
exp.getName() === 'StyledComponentClass' &&
getDefaultExportForFile(source)
)
}
);
assert.equal(parsed.displayName, 'StatelessDisplayNameStyledComponent');
Expand Down
19 changes: 19 additions & 0 deletions src/__tests__/testUtils.ts
Expand Up @@ -20,6 +20,10 @@ export interface ExpectedProp {
required?: boolean;
description?: string;
defaultValue?: string | null;
parent?: {
name: string;
fileName: string;
};
}

export function fixturePath(componentName: string) {
Expand Down Expand Up @@ -128,6 +132,21 @@ export function checkComponent(
}`
);
}
const expectedParentFileName = expectedProp.parent
? expectedProp.parent.fileName
: undefined;
if (
expectedParentFileName &&
prop.parent &&
expectedParentFileName !== prop.parent.fileName
) {
errors.push(
// tslint:disable-next-line:max-line-length
`Property '${compName}.${expectedPropName}' parent fileName is different - expected: ${expectedParentFileName}, actual: ${
prop.parent.fileName
}`
);
}
const expectedRequired =
expectedProp.required === undefined ? true : expectedProp.required;
if (expectedRequired !== prop.required) {
Expand Down
47 changes: 38 additions & 9 deletions src/parser.ts
Expand Up @@ -4,6 +4,11 @@ import * as ts from 'typescript';

import { buildFilter } from './buildFilter';

// We'll use the currentDirectoryName to trim parent fileNames
const currentDirectoryPath = process.cwd();
const currentDirectoryParts = currentDirectoryPath.split('/');
const currentDirectoryName =
currentDirectoryParts[currentDirectoryParts.length - 1];
export interface StringIndexedObject<T> {
[key: string]: T;
}
Expand Down Expand Up @@ -41,7 +46,10 @@ export interface ParentType {

export type PropFilter = (props: PropItem, component: Component) => boolean;

export type ComponentNameResolver = (exp: ts.Symbol, source: ts.SourceFile) => string | undefined | null | false;
export type ComponentNameResolver = (
exp: ts.Symbol,
source: ts.SourceFile
) => string | undefined | null | false;

export interface ParserOptions {
propFilter?: StaticPropFilter | PropFilter;
Expand Down Expand Up @@ -209,7 +217,8 @@ class Parser {

if (propsType) {
const resolvedComponentName = componentNameResolver(exp, source);
const componentName = resolvedComponentName || computeComponentName(exp, source);
const componentName =
resolvedComponentName || computeComponentName(exp, source);
const defaultProps = this.extractDefaultPropsFromComponent(exp, source);
const props = this.getPropsInfo(propsType, defaultProps);

Expand Down Expand Up @@ -678,19 +687,17 @@ function computeComponentName(exp: ts.Symbol, source: ts.SourceFile) {
exportName === '__function' ||
exportName === 'StatelessComponent'
) {
return getDefaultExportForFile(source);
return getDefaultExportForFile(source);
} else {
return exportName;
}
}

// Default export for a file: named after file
export function getDefaultExportForFile(source: ts.SourceFile) {
const name = path.basename(source.fileName, path.extname(source.fileName));
const name = path.basename(source.fileName, path.extname(source.fileName));

return name === 'index'
? path.basename(path.dirname(source.fileName))
: name;
return name === 'index' ? path.basename(path.dirname(source.fileName)) : name;
}

function getParentType(prop: ts.Symbol): ParentType | undefined {
Expand All @@ -710,8 +717,24 @@ function getParentType(prop: ts.Symbol): ParentType | undefined {
const parentName = parent.name.text;
const { fileName } = parent.getSourceFile();

const fileNameParts = fileName.split('/');
const trimmedFileNameParts = fileNameParts.slice();

while (trimmedFileNameParts.length) {
if (trimmedFileNameParts[0] === currentDirectoryName) {
break;
}
trimmedFileNameParts.splice(0, 1);
}
let trimmedFileName;
if (trimmedFileNameParts.length) {
trimmedFileName = trimmedFileNameParts.join('/');
} else {
trimmedFileName = fileName;
}

return {
fileName,
fileName: trimmedFileName,
name: parentName
};
}
Expand Down Expand Up @@ -760,7 +783,13 @@ function parseWithProgramProvider(
docs,
checker
.getExportsOfModule(moduleSymbol)
.map(exp => parser.getComponentInfo(exp, sourceFile, parserOpts.componentNameResolver))
.map(exp =>
parser.getComponentInfo(
exp,
sourceFile,
parserOpts.componentNameResolver
)
)
.filter((comp): comp is ComponentDoc => comp !== null)
.filter((comp, index, comps) =>
comps
Expand Down

0 comments on commit c07e2be

Please sign in to comment.