Skip to content

Commit

Permalink
Merge pull request #405 from ecraig12345/fix-trim-filename
Browse files Browse the repository at this point in the history
Fix trimming of filenames
  • Loading branch information
pvasek authored Dec 11, 2021
2 parents 707be2c + 149c8f7 commit 8b25549
Show file tree
Hide file tree
Showing 6 changed files with 178 additions and 50 deletions.
33 changes: 18 additions & 15 deletions .github/workflows/nodejs.yml
Original file line number Diff line number Diff line change
@@ -1,27 +1,30 @@
name: Node CI

on: [push]
on:
push:
branches: [master]
pull_request:
branches: [master]

jobs:
build:

runs-on: ubuntu-latest

strategy:
matrix:
node-version: [14.x]

steps:
- uses: actions/checkout@v1
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}
- name: install dependencies
run: npm install
env:
CI: true
- name: test
run: npm test
env:
CI: true
- uses: actions/checkout@v1
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}
- name: install dependencies
run: npm install
env:
CI: true
- name: test
run: npm test
env:
CI: true
119 changes: 119 additions & 0 deletions src/__tests__/trimFileName.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
import { assert } from 'chai';
import { trimFileName } from '../trimFileName';

describe.only('trimFileName', () => {
describe('posix', () => {
const cwd = '/home/user/projects/react-docgen-typescript';
const platform = 'posix';

it('works with simple path', () => {
const input = `${cwd}/src/__tests__/data/ExportsPropTypeImport.tsx`;
assert.equal(
trimFileName(input, cwd, platform),
'react-docgen-typescript/src/__tests__/data/ExportsPropTypeImport.tsx'
);
});

it('works with repeated path segments', () => {
const input = `${cwd}/react-docgen-typescript/src/__tests__/data/ExportsPropTypeImport.tsx`;
assert.equal(
trimFileName(input, cwd, platform),
'react-docgen-typescript/react-docgen-typescript/src/__tests__/data/ExportsPropTypeImport.tsx'
);
});

it('preserves package name from node_modules', () => {
const input = `${cwd}/node_modules/@types/react/index.d.ts`;
assert.equal(
trimFileName(input, cwd, platform),
'react-docgen-typescript/node_modules/@types/react/index.d.ts'
);
});

it('preserves package name from node_modules in monorepo', () => {
// This simulates running docgen in an individual package in a monorepo
const monorepoCwd = cwd + '/packages/foo';
const input = `${cwd}/node_modules/@types/react/index.d.ts`;
assert.equal(
trimFileName(input, monorepoCwd, platform),
'react-docgen-typescript/node_modules/@types/react/index.d.ts'
);
});

it('returns full path if there is no common root', () => {
const input = '/somewhere/else/foo.d.ts';
assert.equal(trimFileName(input, cwd, platform), input);
});

it('works when run at the root directory', () => {
// This is more of a theoretical edge case
const input = `/src/__tests__/data/ExportsPropTypeImport.tsx`;
assert.equal(
trimFileName(input, '/', platform),
'src/__tests__/data/ExportsPropTypeImport.tsx'
);
});
});

describe('windows', () => {
const cwd = 'C:\\Users\\user\\projects\\react-docgen-typescript';
// typescript uses forward slashes even in windows paths
const cwdForwardSlash = cwd.replace(/\\/g, '/');
const platform = 'win32';

it('works with simple path', () => {
const input = `${cwdForwardSlash}/src/__tests__/data/ExportsPropTypeImport.tsx`;
assert.equal(
trimFileName(input, cwd, platform),
'react-docgen-typescript/src/__tests__/data/ExportsPropTypeImport.tsx'
);
});

it('works with repeated path segments', () => {
const input = `${cwdForwardSlash}/react-docgen-typescript/src/__tests__/data/ExportsPropTypeImport.tsx`;
assert.equal(
trimFileName(input, cwd, platform),
'react-docgen-typescript/react-docgen-typescript/src/__tests__/data/ExportsPropTypeImport.tsx'
);
});

it('preserves package name from node_modules', () => {
const input = `${cwdForwardSlash}/node_modules/@types/react/index.d.ts`;
assert.equal(
trimFileName(input, cwd, platform),
'react-docgen-typescript/node_modules/@types/react/index.d.ts'
);
});

it('preserves package name from node_modules in monorepo', () => {
const monorepoCwd = cwd + '\\packages\\foo';
const input = `${cwdForwardSlash}/node_modules/@types/react/index.d.ts`;
assert.equal(
trimFileName(input, monorepoCwd, platform),
'react-docgen-typescript/node_modules/@types/react/index.d.ts'
);
});

it('returns full path if there is no common root', () => {
const input = 'D:/somewhere/else/foo.d.ts';
assert.equal(trimFileName(input, cwd, platform), input);
});

it('works when run at the filesystem root', () => {
const input = `C:/src/__tests__/data/ExportsPropTypeImport.tsx`;
assert.equal(
trimFileName(input, 'C:\\', platform),
'src/__tests__/data/ExportsPropTypeImport.tsx'
);
});

it('works with backslashes', () => {
// typescript uses forward slashes in file paths, but test with backslashes too
const input = `${cwd}\\src\\__tests__\\data\\ExportsPropTypeImport.tsx`;
assert.equal(
trimFileName(input, cwd, platform),
'react-docgen-typescript\\src\\__tests__\\data\\ExportsPropTypeImport.tsx'
);
});
});
});
21 changes: 0 additions & 21 deletions src/__tests__/utils.ts

This file was deleted.

2 changes: 1 addition & 1 deletion src/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import * as ts from 'typescript';

import { buildFilter } from './buildFilter';
import { SymbolDisplayPart } from 'typescript';
import { trimFileName } from './utils';
import { trimFileName } from './trimFileName';

type InterfaceOrTypeAliasDeclaration =
| ts.TypeAliasDeclaration
Expand Down
40 changes: 40 additions & 0 deletions src/trimFileName.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import * as path from 'path';

const slashRegex = /[\\/]/g;

export function trimFileName(
fileName: string,
cwd: string = process.cwd(),
platform?: 'posix' | 'win32'
) {
// This allows tests to run regardless of current platform
const pathLib = platform ? path[platform] : path;

// Typescript formats Windows paths with forward slashes. For easier use of
// the path utilities, normalize to platform-standard slashes, then restore
// the original slashes when returning the result.
const originalSep = fileName.match(slashRegex)?.[0] || pathLib.sep;
const normalizedFileName = pathLib.normalize(fileName);
const root = pathLib.parse(cwd).root;

// Walk up paths from the current directory until we find a common ancestor,
// and return the path relative to that. This will work in either a single-
// package repo or a monorepo (where dependencies may be installed at the
// root, but commands may be run in a package folder).
let parent = cwd;
do {
if (normalizedFileName.startsWith(parent)) {
return (
pathLib
// Preserve the parent directory name to match existing behavior
.relative(pathLib.dirname(parent), normalizedFileName)
// Restore original type of slashes
.replace(slashRegex, originalSep)
);
}
parent = pathLib.dirname(parent);
} while (parent !== root);

// No common ancestor, so return the path as-is
return fileName;
}
13 changes: 0 additions & 13 deletions src/utils.ts

This file was deleted.

0 comments on commit 8b25549

Please sign in to comment.