Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 12 additions & 7 deletions source/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,14 @@ const cli = meow(`
The given directory must contain a package.json and a typings file.

Info
--help Display help text
--version Display version info
--help Display help text
--version Display version info

Options
--typings -t Type definition file to test [Default: "types" property in package.json]
--files -f Glob of files to test [Default: '/path/test-d/**/*.test-d.ts' or '.tsx']
--show-diff Show type error diffs [Default: don't show]
--typings -t Type definition file to test [Default: "types" property in package.json]
--files -f Glob of files to test [Default: '/path/test-d/**/*.test-d.ts' or '.tsx']
--show-diff Show type error diffs [Default: don't show]
--pass-with-no-tests Pass when no tests are found [Default: false]

Examples
$ tsd /path/to/project
Expand All @@ -42,6 +43,10 @@ const cli = meow(`
showDiff: {
type: 'boolean',
},
passWithNoTests: {
default: false,
type: 'boolean',
},
},
});

Expand All @@ -64,9 +69,9 @@ const exit = (message: string, {isError = true}: {isError?: boolean} = {}) => {
(async () => {
try {
const cwd = cli.input.length > 0 ? cli.input[0] : process.cwd();
const {typings: typingsFile, files: testFiles, showDiff} = cli.flags;
const {typings: typingsFile, files: testFiles, showDiff, passWithNoTests} = cli.flags;

const diagnostics = await tsd({cwd, typingsFile, testFiles});
const diagnostics = await tsd({cwd, typingsFile, testFiles, passWithNoTests});

if (diagnostics.length > 0) {
const hasErrors = diagnostics.some(diagnostic => diagnostic.severity === 'error');
Expand Down
15 changes: 13 additions & 2 deletions source/lib/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export interface Options {
cwd: string;
typingsFile?: string;
testFiles?: readonly string[];
passWithNoTests?: boolean;
}

const findTypingsFile = async (pkg: PackageJsonWithTsdConfig, options: Options): Promise<string> => {
Expand Down Expand Up @@ -39,9 +40,13 @@ const normalizeTypingsFilePath = (typingsFilePath: string, options: Options) =>
return typingsFilePath;
};

const findCustomTestFiles = async (testFilesPattern: readonly string[], cwd: string) => {
const findCustomTestFiles = async (testFilesPattern: readonly string[], cwd: string, passWithNoTests: boolean) => {
const testFiles = await globby(testFilesPattern, {cwd});

if (testFiles.length === 0 && passWithNoTests) {
return [];
}

if (testFiles.length === 0) {
throw new TsdError('Could not find any test files with the given pattern(s). Create one and try again.');
}
Expand All @@ -50,8 +55,10 @@ const findCustomTestFiles = async (testFilesPattern: readonly string[], cwd: str
};

const findTestFiles = async (typingsFilePath: string, options: Options & {config: Config}) => {
const passWithNoTests = options.passWithNoTests === true;

if (options.testFiles?.length) {
return findCustomTestFiles(options.testFiles, options.cwd);
return findCustomTestFiles(options.testFiles, options.cwd, passWithNoTests);
}

// Return only the filename if the `typingsFile` option is used.
Expand All @@ -64,6 +71,10 @@ const findTestFiles = async (typingsFilePath: string, options: Options & {config
let testFiles = await globby([testFile, tsxTestFile], {cwd: options.cwd});
const testDirExists = await pathExists(path.join(options.cwd, testDir));

if (testFiles.length === 0 && passWithNoTests) {
return [];
}

if (testFiles.length === 0 && !testDirExists) {
throw new TsdError(`The test file \`${testFile}\` or \`${tsxTestFile}\` does not exist in \`${options.cwd}\`. Create one and try again.`);
}
Expand Down
26 changes: 26 additions & 0 deletions source/test/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,32 @@ test('cli typings and files flags', async t => {
]);
});

test('cli passWithNoTests flag', async t => {
const runTest = async (arg: '--passWithNoTests') => {
const {exitCode} = await execa('../../../cli.js', [arg], {
cwd: path.join(__dirname, 'fixtures/no-test')
});

t.is(exitCode, 0);
};

await runTest('--passWithNoTests');
});

test('cli passWithNoTests flag and files', async t => {
const runTest = async (arg: '--pass-with-no-tests') => {
const testFile = path.join(__dirname, 'fixtures/does-not-exist.test-d.ts');

const {exitCode} = await execa('../../../cli.js', [arg, `--files ${testFile}`], {
cwd: path.join(__dirname, 'fixtures/no-test')
});

t.is(exitCode, 0);
};

await runTest('--pass-with-no-tests');
});

test('tsd logs stacktrace on failure', async t => {
const {exitCode, stderr} = await t.throwsAsync<ExecaError>(execa('../../../cli.js', {
cwd: path.join(__dirname, 'fixtures/empty-package-json')
Expand Down
Loading