Skip to content

Commit ea4d650

Browse files
committed
docs: clarify test file discovery prioritization behavior
1 parent f589fb3 commit ea4d650

File tree

1 file changed

+38
-22
lines changed

1 file changed

+38
-22
lines changed

readme.md

Lines changed: 38 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ The `tsd` CLI will search for the main `.d.ts` file in the current or specified
2222

2323
Use `tsd --help` for usage information. See [Order of Operations](#order-of-operations) for more details on how `tsd` finds and executes tests.
2424

25-
*Note: the CLI is primarily used to test an entire project, not a specific file. For more specific configuration and advanced usage, see [Configuration](#configuration) and [Programmatic API](#programmatic-api).*
25+
_Note: the CLI is primarily used to test an entire project, not a specific file. For more specific configuration and advanced usage, see [Configuration](#configuration) and [Programmatic API](#programmatic-api)._
2626

2727
## Usage
2828

@@ -40,9 +40,9 @@ export default concat;
4040
In order to test this definition, add a `index.test-d.ts` file.
4141

4242
```ts
43-
import concat from '.';
43+
import concat from ".";
4444

45-
concat('foo', 'bar');
45+
concat("foo", "bar");
4646
concat(1, 2);
4747
```
4848

@@ -51,10 +51,10 @@ Running `npx tsd` as a command will verify that the type definition works correc
5151
Let's add some extra [assertions](#assertions). We can assert the return type of our function call to match a certain type.
5252

5353
```ts
54-
import {expectType} from 'tsd';
55-
import concat from '.';
54+
import { expectType } from "tsd";
55+
import concat from ".";
5656

57-
expectType<string>(concat('foo', 'bar'));
57+
expectType<string>(concat("foo", "bar"));
5858
expectType<string>(concat(1, 2));
5959
```
6060

@@ -80,11 +80,11 @@ If we don't change the test file and we run the `tsd` command again, the test wi
8080
Type assertions are strict. This means that if you expect the type to be `string | number` but the argument is of type `string`, the tests will fail.
8181

8282
```ts
83-
import {expectType} from 'tsd';
84-
import concat from '.';
83+
import { expectType } from "tsd";
84+
import concat from ".";
8585

86-
expectType<string>(concat('foo', 'bar'));
87-
expectType<string | number>(concat('foo', 'bar'));
86+
expectType<string>(concat("foo", "bar"));
87+
expectType<string | number>(concat("foo", "bar"));
8888
```
8989

9090
If we run `tsd`, we will notice that it reports an error because the `concat` method returns the type `string` and not `string | number`.
@@ -94,24 +94,24 @@ If we run `tsd`, we will notice that it reports an error because the `concat` me
9494
If you still want loose type assertion, you can use `expectAssignable` for that.
9595

9696
```ts
97-
import {expectType, expectAssignable} from 'tsd';
98-
import concat from '.';
97+
import { expectType, expectAssignable } from "tsd";
98+
import concat from ".";
9999

100-
expectType<string>(concat('foo', 'bar'));
101-
expectAssignable<string | number>(concat('foo', 'bar'));
100+
expectType<string>(concat("foo", "bar"));
101+
expectAssignable<string | number>(concat("foo", "bar"));
102102
```
103103

104104
### Top-level `await`
105105

106106
If your method returns a `Promise`, you can use top-level `await` to resolve the value instead of wrapping it in an `async` [IIFE](https://developer.mozilla.org/en-US/docs/Glossary/IIFE).
107107

108108
```ts
109-
import {expectType, expectError} from 'tsd';
110-
import concat from '.';
109+
import { expectType, expectError } from "tsd";
110+
import concat from ".";
111111

112-
expectType<Promise<string>>(concat('foo', 'bar'));
112+
expectType<Promise<string>>(concat("foo", "bar"));
113113

114-
expectType<string>(await concat('foo', 'bar'));
114+
expectType<string>(await concat("foo", "bar"));
115115

116116
expectError(await concat(true, false));
117117
```
@@ -124,7 +124,15 @@ When searching for `.test-d.ts` files and executing them, `tsd` does the followi
124124

125125
2. Finds a `.d.ts` file, checking to see if one was specified manually or in the `types` field of the `package.json`. If neither is found, attempts to find one in the project directory named the same as the `main` field of the `package.json` or `index.d.ts`. Fails if no `.d.ts` file is found.
126126

127-
3. Finds `.test-d.ts` and `.test-d.tsx` files, which can either be in the project's root directory, a [specific folder](#test-directory) (by default `/[project-root]/test-d`), or specified individually [programatically](#testfiles) or via [the CLI](#via-the-cli). Fails if no test files are found.
127+
3. Finds `.test-d.ts` and `.test-d.tsx` files using the following priority order:
128+
129+
- **First**: Looks for test files in the project's root directory (e.g., `index.test-d.ts`)
130+
- **Second**: Only if no root test files are found, looks in the [test directory](#test-directory) (by default `/[project-root]/test-d`) for any `.ts` or `.tsx` files
131+
- **Alternative**: Test files can be specified individually [programatically](#testfiles) or via [the CLI](#via-the-cli)
132+
133+
**Important**: If you have both a root-level test file (like `index.test-d.ts`) and a test directory (like `test-d/`), only the root-level file will be executed. The test directory will be ignored. To use both, either move all tests to the test directory or use the `--files` flag to specify all test files explicitly.
134+
135+
Fails if no test files are found.
128136

129137
4. Runs the `.test-d.ts` files through the TypeScript compiler and statically analyzes them for errors.
130138

@@ -203,6 +211,8 @@ When you have spread your tests over multiple files, you can store all those fil
203211

204212
Now you can put all your test files in the `my-test-dir` directory.
205213

214+
**Note**: The test directory is only used when no test files are found in the project root. If you have both root-level test files (like `index.test-d.ts`) and a test directory, only the root files will be executed. See [Order of Operations](#order-of-operations) for more details.
215+
206216
#### Custom TypeScript Config
207217

208218
By default, `tsd` applies the following configuration:
@@ -240,7 +250,7 @@ These options will be overridden if a `tsconfig.json` file is found in your proj
240250
}
241251
```
242252

243-
*Default options will apply if you don't override them explicitly. You can't override the `moduleResolution` or `skipLibCheck` options.*
253+
_Default options will apply if you don't override them explicitly. You can't override the `moduleResolution` or `skipLibCheck` options._
244254

245255
### Via the CLI
246256

@@ -258,12 +268,18 @@ Alias: `-f`
258268

259269
An array of test files with their path. Same as [`testFiles`](#testfiles).
260270

271+
This is particularly useful when you need to run tests from multiple locations (e.g., both root-level and test directory files):
272+
273+
```bash
274+
tsd --files "index.test-d.ts" --files "test-d/**/*.test-d.ts"
275+
```
276+
261277
## Programmatic API
262278

263279
You can use the programmatic API to retrieve the diagnostics and do something with them. This can be useful to run the tests with AVA, Jest or any other testing framework.
264280

265281
```ts
266-
import tsd from 'tsd';
282+
import tsd from "tsd";
267283

268284
const diagnostics = await tsd();
269285

@@ -274,7 +290,7 @@ console.log(diagnostics.length);
274290
You can also make use of the CLI's formatter to generate the same formatting output when running `tsd` programmatically.
275291

276292
```ts
277-
import tsd, {formatter} from 'tsd';
293+
import tsd, { formatter } from "tsd";
278294

279295
const formattedDiagnostics = formatter(await tsd());
280296
```

0 commit comments

Comments
 (0)