diff --git a/cli/main.rs b/cli/main.rs index 6069f44792..93bae02206 100644 --- a/cli/main.rs +++ b/cli/main.rs @@ -1026,17 +1026,19 @@ async fn test_command( // TODO(caspervonb) clean this up. let resolver = |changed: Option>| { - let doc_modules_result = test_runner::collect_test_module_specifiers( - include.clone(), - &cwd, - fs_util::is_supported_ext, - ); - - let test_modules_result = test_runner::collect_test_module_specifiers( - include.clone(), - &cwd, - tools::test_runner::is_supported, - ); + let test_modules_result = if doc { + test_runner::collect_test_module_specifiers( + include.clone(), + &cwd, + fs_util::is_supported_ext, + ) + } else { + test_runner::collect_test_module_specifiers( + include.clone(), + &cwd, + tools::test_runner::is_supported, + ) + }; let paths_to_watch = paths_to_watch.clone(); let paths_to_watch_clone = paths_to_watch.clone(); @@ -1045,8 +1047,6 @@ async fn test_command( let program_state = program_state.clone(); let files_changed = changed.is_some(); async move { - let doc_modules = if doc { doc_modules_result? } else { Vec::new() }; - let test_modules = test_modules_result?; let mut paths_to_watch = paths_to_watch_clone; @@ -1072,12 +1072,6 @@ async fn test_command( .await?; let graph = builder.get_graph(); - for specifier in doc_modules { - if let Ok(path) = specifier.to_file_path() { - paths_to_watch.push(path); - } - } - for specifier in test_modules { fn get_dependencies<'a>( graph: &'a module_graph::Graph, @@ -1165,15 +1159,49 @@ async fn test_command( }) }; - file_watcher::watch_func( - resolver, - |modules_to_reload| { + let operation = |modules_to_reload: Vec| { + let cwd = cwd.clone(); + let filter = filter.clone(); + let include = include.clone(); + let lib = lib.clone(); + let permissions = permissions.clone(); + let program_state = program_state.clone(); + + async move { + let doc_modules = if doc { + test_runner::collect_test_module_specifiers( + include.clone(), + &cwd, + fs_util::is_supported_ext, + )? + } else { + Vec::new() + }; + + let doc_modules_to_reload = doc_modules + .iter() + .filter(|specifier| modules_to_reload.contains(specifier)) + .cloned() + .collect(); + + let test_modules = test_runner::collect_test_module_specifiers( + include.clone(), + &cwd, + tools::test_runner::is_supported, + )?; + + let test_modules_to_reload = test_modules + .iter() + .filter(|specifier| modules_to_reload.contains(specifier)) + .cloned() + .collect(); + test_runner::run_tests( program_state.clone(), permissions.clone(), lib.clone(), - modules_to_reload.clone(), - modules_to_reload, + doc_modules_to_reload, + test_modules_to_reload, no_run, fail_fast, quiet, @@ -1182,11 +1210,13 @@ async fn test_command( shuffle, concurrent_jobs, ) - .map(|res| res.map(|_| ())) - }, - "Test", - ) - .await?; + .await?; + + Ok(()) + } + }; + + file_watcher::watch_func(resolver, operation, "Test").await?; } else { let doc_modules = if doc { test_runner::collect_test_module_specifiers( diff --git a/cli/tests/integration/watcher_tests.rs b/cli/tests/integration/watcher_tests.rs index 3e9aa563a7..ed574a0bf1 100644 --- a/cli/tests/integration/watcher_tests.rs +++ b/cli/tests/integration/watcher_tests.rs @@ -595,3 +595,77 @@ fn test_watch() { child.kill().unwrap(); drop(t); } + +// TODO(bartlomieju): flaky (https://github.com/denoland/deno/issues/10552) +#[ignore] +#[test] +fn test_watch_doc() { + macro_rules! assert_contains { + ($string:expr, $($test:expr),+) => { + let string = $string; // This might be a function call or something + if !($(string.contains($test))||+) { + panic!("{:?} does not contain any of {:?}", string, [$($test),+]); + } + } + } + + let t = TempDir::new().expect("tempdir fail"); + + let mut child = util::deno_cmd() + .current_dir(util::root_path()) + .arg("test") + .arg("--watch") + .arg("--doc") + .arg("--unstable") + .arg(&t.path()) + .env("NO_COLOR", "1") + .stdout(std::process::Stdio::piped()) + .stderr(std::process::Stdio::piped()) + .spawn() + .expect("failed to spawn script"); + + let stdout = child.stdout.as_mut().unwrap(); + let mut stdout_lines = + std::io::BufReader::new(stdout).lines().map(|r| r.unwrap()); + let stderr = child.stderr.as_mut().unwrap(); + let mut stderr_lines = + std::io::BufReader::new(stderr).lines().map(|r| r.unwrap()); + + assert_contains!( + stdout_lines.next().unwrap(), + "No matching test modules found" + ); + + wait_for_process_finished("Test", &mut stderr_lines); + + let foo_file = t.path().join("foo.ts"); + std::fs::write( + &foo_file, + r#" + export default function foo() {} + "#, + ) + .expect("error writing file"); + + std::fs::write( + &foo_file, + r#" + /** + * ```ts + * import foo from "./foo.ts"; + * ``` + */ + export default function foo() {} + "#, + ) + .expect("error writing file"); + + // We only need to scan for a Check file://.../foo.ts$3-6 line that + // corresponds to the documentation block being type-checked. + assert_contains!(skip_restarting_line(stderr_lines), "foo.ts$3-6"); + + assert!(child.try_wait().unwrap().is_none()); + child.kill().unwrap(); + + drop(t); +}