1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-12-15 11:58:42 -05:00
denoland-deno/tests/specs/test/doc_duplicate_identifier/main.ts

34 lines
1 KiB
TypeScript
Raw Normal View History

feat(cli): evaluate code snippets in JSDoc and markdown (#25220) This commit lets `deno test --doc` command actually evaluate code snippets in JSDoc and markdown files. ## How it works 1. Extract code snippets from JSDoc or code fences 2. Convert them into pseudo files by wrapping them in `Deno.test(...)` 3. Register the pseudo files as in-memory files 4. Run type-check and evaluation We apply some magic at the step 2 - let's say we have the following file named `mod.ts` as an input: ````ts /** * ```ts * import { assertEquals } from "jsr:@std/assert/equals"; * * assertEquals(add(1, 2), 3); * ``` */ export function add(a: number, b: number) { return a + b; } ```` This is virtually transformed into: ```ts import { assertEquals } from "jsr:@std/assert/equals"; import { add } from "files:///path/to/mod.ts"; Deno.test("mod.ts$2-7.ts", async () => { assertEquals(add(1, 2), 3); }); ``` Note that a new import statement is inserted here to make `add` function available. In a nutshell, all items exported from `mod.ts` become available in the generated pseudo file with this automatic import insertion. The intention behind this design is that, from library user's standpoint, it should be very obvious that this `add` function is what this example code is attached to. Also, if there is an explicit import statement like `import { add } from "./mod.ts"`, this import path `./mod.ts` is not helpful for doc readers because they will need to import it in a different way. The automatic import insertion has some edge cases, in particular where there is a local variable in a snippet with the same name as one of the exported items. This case is addressed by employing swc's scope analysis (see test cases for more details). ## "type-checking only" mode stays around This change will likely impact a lot of existing doc tests in the ecosystem because some doc tests rely on the fact that they are not evaluated - some cause side effects if executed, some throw errors at runtime although they do pass the type check, etc. To help those tests gradually transition to the ones runnable with the new `deno test --doc`, we will keep providing the ability to run type-checking only via `deno check --doc`. Additionally there is a `--doc-only` option added to the `check` subcommand too, which is useful when you want to type-check on code snippets in markdown files, as normal `deno check` command doesn't accept markdown. ## Demo https://github.com/user-attachments/assets/47e9af73-d16e-472d-b09e-1853b9e8f5ce --- Closes #4716
2024-09-18 00:35:48 -04:00
// `deno test --doc` tries to convert the example code snippets into pseudo
// test files in a way that all the exported items are available without
// explicit import statements. Therefore, in the test code, you don't have to
// write like `import { add } from "./main.ts";`.
// However, this automatic import resolution might conflict with other
// explicitly declared identifiers in the test code you write. This spec test
// makes sure that such cases will not cause any issues - explicit identifiers
// take precedence.
/**
* ```ts
* import { assertEquals } from "@std/assert/equals";
* import { getModuleName, createFoo } from "./mod.ts";
*
* const foo = createFoo();
* assertEquals(getModuleName(), "mod.ts");
* assertEquals(add(1, 2), foo());
* ```
*/
export function add(a: number, b: number): number {
return a + b;
}
/**
* ```ts
* import { assertEquals } from "@std/assert/equals";
*
* assertEquals(getModuleName(), "main.ts");
* ```
*/
export const getModuleName = () => "main.ts";
export let foo = 1234;