Skip to content

Commit baa52bf

Browse files
authored
fix(test): handle snippet containing Deno.test in doc test (#29631)
1 parent e8dc887 commit baa52bf

File tree

1 file changed

+108
-8
lines changed

1 file changed

+108
-8
lines changed

cli/util/extract.rs

Lines changed: 108 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,11 @@ enum WrapKind {
4848
NoWrap,
4949
}
5050

51+
struct TestOrSnippet {
52+
file: File,
53+
has_deno_test: bool,
54+
}
55+
5156
fn extract_inner(
5257
file: File,
5358
wrap_kind: WrapKind,
@@ -86,8 +91,13 @@ fn extract_inner(
8691

8792
extracted_files
8893
.into_iter()
89-
.map(|extracted_file| {
90-
generate_pseudo_file(extracted_file, &file.specifier, &exports, wrap_kind)
94+
.map(|extracted| {
95+
let wrap_kind = if extracted.has_deno_test {
96+
WrapKind::NoWrap
97+
} else {
98+
wrap_kind
99+
};
100+
generate_pseudo_file(extracted.file, &file.specifier, &exports, wrap_kind)
91101
})
92102
.collect::<Result<_, _>>()
93103
}
@@ -96,7 +106,7 @@ fn extract_files_from_fenced_blocks(
96106
specifier: &ModuleSpecifier,
97107
source: &str,
98108
media_type: MediaType,
99-
) -> Result<Vec<File>, AnyError> {
109+
) -> Result<Vec<TestOrSnippet>, AnyError> {
100110
// The pattern matches code blocks as well as anything in HTML comment syntax,
101111
// but it stores the latter without any capturing groups. This way, a simple
102112
// check can be done to see if a block is inside a comment (and skip typechecking)
@@ -119,7 +129,7 @@ fn extract_files_from_source_comments(
119129
specifier: &ModuleSpecifier,
120130
source: Arc<str>,
121131
media_type: MediaType,
122-
) -> Result<Vec<File>, AnyError> {
132+
) -> Result<Vec<TestOrSnippet>, AnyError> {
123133
let parsed_source = deno_ast::parse_module(deno_ast::ParseParams {
124134
specifier: specifier.clone(),
125135
text: source,
@@ -165,7 +175,9 @@ fn extract_files_from_regex_blocks(
165175
file_line_index: usize,
166176
blocks_regex: &Regex,
167177
lines_regex: &Regex,
168-
) -> Result<Vec<File>, AnyError> {
178+
) -> Result<Vec<TestOrSnippet>, AnyError> {
179+
let tests_regex = lazy_regex::regex!(r"(?m)^\s*Deno\.test\(");
180+
169181
let files = blocks_regex
170182
.captures_iter(source)
171183
.filter_map(|block| {
@@ -229,12 +241,16 @@ fn extract_files_from_regex_blocks(
229241
mapped_specifier_for_tsc(&file_specifier, file_media_type)
230242
.map(|s| ModuleSpecifier::parse(&s).unwrap())
231243
.unwrap_or(file_specifier);
232-
233-
Some(File {
244+
let has_deno_test = tests_regex.is_match(&file_source);
245+
let file = File {
234246
url: file_specifier,
235247
mtime: None,
236248
maybe_headers: None,
237249
source: file_source.into_bytes().into(),
250+
};
251+
Some(TestOrSnippet {
252+
file,
253+
has_deno_test,
238254
})
239255
})
240256
.collect();
@@ -846,7 +862,7 @@ mod tests {
846862
/**
847863
* ```ts
848864
* import { assertEquals } from "@std/assert/equal";
849-
*
865+
*
850866
* assertEquals(add(1, 2), 3);
851867
* ```
852868
*/
@@ -1199,6 +1215,90 @@ Deno.test("file:///main.ts$3-7.ts", async ()=>{
11991215
media_type: MediaType::TypeScript,
12001216
}],
12011217
},
1218+
// https://github.com/denoland/deno/issues/29629
1219+
Test {
1220+
input: Input {
1221+
source: r#"
1222+
# Title
1223+
1224+
```ts
1225+
import { assertEquals } from "@std/assert/equals";
1226+
1227+
Deno.test("add", () => {
1228+
assertEquals(1 + 2, 3);
1229+
});
1230+
```
1231+
"#,
1232+
specifier: "file:///main.md",
1233+
},
1234+
expected: vec![Expected {
1235+
source: r#"import { assertEquals } from "@std/assert/equals";
1236+
Deno.test("add", ()=>{
1237+
assertEquals(1 + 2, 3);
1238+
});
1239+
"#,
1240+
specifier: "file:///main.md$4-11.ts",
1241+
media_type: MediaType::TypeScript,
1242+
}],
1243+
},
1244+
Test {
1245+
input: Input {
1246+
source: r#"
1247+
/**
1248+
* ```ts
1249+
* import { assertEquals } from "@std/assert/equals";
1250+
*
1251+
* Deno.test("add", () => {
1252+
* assertEquals(add(1, 2), 3);
1253+
* });
1254+
* ```
1255+
*/
1256+
export function add(a: number, b: number): number {
1257+
return a + b;
1258+
}
1259+
"#,
1260+
specifier: "file:///main.ts",
1261+
},
1262+
expected: vec![Expected {
1263+
source: r#"import { assertEquals } from "@std/assert/equals";
1264+
import { add } from "file:///main.ts";
1265+
Deno.test("add", ()=>{
1266+
assertEquals(add(1, 2), 3);
1267+
});
1268+
"#,
1269+
specifier: "file:///main.ts$3-10.ts",
1270+
media_type: MediaType::TypeScript,
1271+
}],
1272+
},
1273+
// commented out `Deno.test` should be ignored
1274+
Test {
1275+
input: Input {
1276+
source: r#"
1277+
/**
1278+
* ```ts
1279+
* import { assertEquals } from "@std/assert/equals";
1280+
* // Deno.test("add", () => {});
1281+
* assertEquals(add(1, 2), 3);
1282+
* ```
1283+
*/
1284+
export function add(a: number, b: number): number {
1285+
return a + b;
1286+
}
1287+
"#,
1288+
specifier: "file:///main.ts",
1289+
},
1290+
expected: vec![Expected {
1291+
source: r#"import { assertEquals } from "@std/assert/equals";
1292+
import { add } from "file:///main.ts";
1293+
Deno.test("file:///main.ts$3-8.ts", async ()=>{
1294+
// Deno.test("add", () => {});
1295+
assertEquals(add(1, 2), 3);
1296+
});
1297+
"#,
1298+
specifier: "file:///main.ts$3-8.ts",
1299+
media_type: MediaType::TypeScript,
1300+
}],
1301+
},
12021302
];
12031303

12041304
for test in tests {

0 commit comments

Comments
 (0)