mirror of
https://github.com/denoland/deno.git
synced 2024-11-25 15:29:32 -05:00
refactor: clean up watcher tests (#12200)
This commit is contained in:
parent
c5442abc23
commit
da25bbff88
1 changed files with 176 additions and 301 deletions
|
@ -1,10 +1,20 @@
|
||||||
// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license.
|
// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license.
|
||||||
|
|
||||||
use flaky_test::flaky_test;
|
use flaky_test::flaky_test;
|
||||||
|
use std::fs::write;
|
||||||
use std::io::BufRead;
|
use std::io::BufRead;
|
||||||
use tempfile::TempDir;
|
use tempfile::TempDir;
|
||||||
use test_util as util;
|
use test_util as util;
|
||||||
|
|
||||||
|
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),+]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Helper function to skip watcher output that contains "Restarting"
|
// Helper function to skip watcher output that contains "Restarting"
|
||||||
// phrase.
|
// phrase.
|
||||||
fn skip_restarting_line(
|
fn skip_restarting_line(
|
||||||
|
@ -18,45 +28,40 @@ fn skip_restarting_line(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Helper function to skip watcher output that doesn't contain
|
fn wait_for(s: &str, lines: &mut impl Iterator<Item = String>) {
|
||||||
/// "{job_name} finished" phrase.
|
|
||||||
fn wait_for_process_finished(
|
|
||||||
job_name: &str,
|
|
||||||
stderr_lines: &mut impl Iterator<Item = String>,
|
|
||||||
) {
|
|
||||||
let phrase = format!("{} finished", job_name);
|
|
||||||
loop {
|
loop {
|
||||||
let msg = stderr_lines.next().unwrap();
|
let msg = lines.next().unwrap();
|
||||||
if msg.contains(&phrase) {
|
if msg.contains(s) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Helper function to skip watcher output that doesn't contain
|
fn check_alive_then_kill(mut child: std::process::Child) {
|
||||||
/// "{job_name} failed" phrase.
|
assert!(child.try_wait().unwrap().is_none());
|
||||||
fn wait_for_process_failed(
|
child.kill().unwrap();
|
||||||
job_name: &str,
|
}
|
||||||
stderr_lines: &mut impl Iterator<Item = String>,
|
|
||||||
) {
|
fn child_lines(
|
||||||
let phrase = format!("{} failed", job_name);
|
child: &mut std::process::Child,
|
||||||
loop {
|
) -> (impl Iterator<Item = String>, impl Iterator<Item = String>) {
|
||||||
let msg = stderr_lines.next().unwrap();
|
let stdout_lines = std::io::BufReader::new(child.stdout.take().unwrap())
|
||||||
if msg.contains(&phrase) {
|
.lines()
|
||||||
break;
|
.map(|r| r.unwrap());
|
||||||
}
|
let stderr_lines = std::io::BufReader::new(child.stderr.take().unwrap())
|
||||||
}
|
.lines()
|
||||||
|
.map(|r| r.unwrap());
|
||||||
|
(stdout_lines, stderr_lines)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn fmt_watch_test() {
|
fn fmt_watch_test() {
|
||||||
let t = TempDir::new().expect("tempdir fail");
|
let t = TempDir::new().unwrap();
|
||||||
let fixed = util::testdata_path().join("badly_formatted_fixed.js");
|
let fixed = util::testdata_path().join("badly_formatted_fixed.js");
|
||||||
let badly_formatted_original =
|
let badly_formatted_original =
|
||||||
util::testdata_path().join("badly_formatted.mjs");
|
util::testdata_path().join("badly_formatted.mjs");
|
||||||
let badly_formatted = t.path().join("badly_formatted.js");
|
let badly_formatted = t.path().join("badly_formatted.js");
|
||||||
std::fs::copy(&badly_formatted_original, &badly_formatted)
|
std::fs::copy(&badly_formatted_original, &badly_formatted).unwrap();
|
||||||
.expect("Failed to copy file");
|
|
||||||
|
|
||||||
let mut child = util::deno_cmd()
|
let mut child = util::deno_cmd()
|
||||||
.current_dir(util::testdata_path())
|
.current_dir(util::testdata_path())
|
||||||
|
@ -67,10 +72,8 @@ fn fmt_watch_test() {
|
||||||
.stdout(std::process::Stdio::piped())
|
.stdout(std::process::Stdio::piped())
|
||||||
.stderr(std::process::Stdio::piped())
|
.stderr(std::process::Stdio::piped())
|
||||||
.spawn()
|
.spawn()
|
||||||
.expect("Failed to spawn script");
|
.unwrap();
|
||||||
let stderr = child.stderr.as_mut().unwrap();
|
let (_stdout_lines, stderr_lines) = child_lines(&mut child);
|
||||||
let stderr_lines =
|
|
||||||
std::io::BufReader::new(stderr).lines().map(|r| r.unwrap());
|
|
||||||
|
|
||||||
// TODO(lucacasonato): remove this timeout. It seems to be needed on Linux.
|
// TODO(lucacasonato): remove this timeout. It seems to be needed on Linux.
|
||||||
std::thread::sleep(std::time::Duration::from_secs(1));
|
std::thread::sleep(std::time::Duration::from_secs(1));
|
||||||
|
@ -82,32 +85,25 @@ fn fmt_watch_test() {
|
||||||
assert_eq!(expected, actual);
|
assert_eq!(expected, actual);
|
||||||
|
|
||||||
// Change content of the file again to be badly formatted
|
// Change content of the file again to be badly formatted
|
||||||
std::fs::copy(&badly_formatted_original, &badly_formatted)
|
std::fs::copy(&badly_formatted_original, &badly_formatted).unwrap();
|
||||||
.expect("Failed to copy file");
|
|
||||||
std::thread::sleep(std::time::Duration::from_secs(1));
|
std::thread::sleep(std::time::Duration::from_secs(1));
|
||||||
|
|
||||||
// Check if file has been automatically formatted by watcher
|
// Check if file has been automatically formatted by watcher
|
||||||
let expected = std::fs::read_to_string(fixed).unwrap();
|
let expected = std::fs::read_to_string(fixed).unwrap();
|
||||||
let actual = std::fs::read_to_string(badly_formatted).unwrap();
|
let actual = std::fs::read_to_string(badly_formatted).unwrap();
|
||||||
assert_eq!(expected, actual);
|
assert_eq!(expected, actual);
|
||||||
|
check_alive_then_kill(child);
|
||||||
// the watcher process is still alive
|
|
||||||
assert!(child.try_wait().unwrap().is_none());
|
|
||||||
|
|
||||||
child.kill().unwrap();
|
|
||||||
drop(t);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn bundle_js_watch() {
|
fn bundle_js_watch() {
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
// Test strategy extends this of test bundle_js by adding watcher
|
// Test strategy extends this of test bundle_js by adding watcher
|
||||||
let t = TempDir::new().expect("tempdir fail");
|
let t = TempDir::new().unwrap();
|
||||||
let file_to_watch = t.path().join("file_to_watch.js");
|
let file_to_watch = t.path().join("file_to_watch.js");
|
||||||
std::fs::write(&file_to_watch, "console.log('Hello world');")
|
write(&file_to_watch, "console.log('Hello world');").unwrap();
|
||||||
.expect("error writing file");
|
|
||||||
assert!(file_to_watch.is_file());
|
assert!(file_to_watch.is_file());
|
||||||
let t = TempDir::new().expect("tempdir fail");
|
let t = TempDir::new().unwrap();
|
||||||
let bundle = t.path().join("mod6.bundle.js");
|
let bundle = t.path().join("mod6.bundle.js");
|
||||||
let mut deno = util::deno_cmd()
|
let mut deno = util::deno_cmd()
|
||||||
.current_dir(util::testdata_path())
|
.current_dir(util::testdata_path())
|
||||||
|
@ -120,57 +116,41 @@ fn bundle_js_watch() {
|
||||||
.stdout(std::process::Stdio::piped())
|
.stdout(std::process::Stdio::piped())
|
||||||
.stderr(std::process::Stdio::piped())
|
.stderr(std::process::Stdio::piped())
|
||||||
.spawn()
|
.spawn()
|
||||||
.expect("failed to spawn script");
|
.unwrap();
|
||||||
|
|
||||||
let stderr = deno.stderr.as_mut().unwrap();
|
let (_stdout_lines, mut stderr_lines) = child_lines(&mut deno);
|
||||||
let mut stderr_lines =
|
|
||||||
std::io::BufReader::new(stderr).lines().map(|r| r.unwrap());
|
|
||||||
|
|
||||||
std::thread::sleep(std::time::Duration::from_secs(1));
|
std::thread::sleep(std::time::Duration::from_secs(1));
|
||||||
assert!(stderr_lines.next().unwrap().contains("file_to_watch.js"));
|
assert_contains!(stderr_lines.next().unwrap(), "file_to_watch.js");
|
||||||
assert!(stderr_lines.next().unwrap().contains("mod6.bundle.js"));
|
assert_contains!(stderr_lines.next().unwrap(), "mod6.bundle.js");
|
||||||
let file = PathBuf::from(&bundle);
|
let file = PathBuf::from(&bundle);
|
||||||
assert!(file.is_file());
|
assert!(file.is_file());
|
||||||
wait_for_process_finished("Bundle", &mut stderr_lines);
|
wait_for("Bundle finished", &mut stderr_lines);
|
||||||
|
|
||||||
std::fs::write(&file_to_watch, "console.log('Hello world2');")
|
write(&file_to_watch, "console.log('Hello world2');").unwrap();
|
||||||
.expect("error writing file");
|
|
||||||
std::thread::sleep(std::time::Duration::from_secs(1));
|
std::thread::sleep(std::time::Duration::from_secs(1));
|
||||||
assert!(stderr_lines
|
assert_contains!(stderr_lines.next().unwrap(), "File change detected!");
|
||||||
.next()
|
assert_contains!(stderr_lines.next().unwrap(), "file_to_watch.js");
|
||||||
.unwrap()
|
assert_contains!(stderr_lines.next().unwrap(), "mod6.bundle.js");
|
||||||
.contains("File change detected!"));
|
|
||||||
assert!(stderr_lines.next().unwrap().contains("file_to_watch.js"));
|
|
||||||
assert!(stderr_lines.next().unwrap().contains("mod6.bundle.js"));
|
|
||||||
let file = PathBuf::from(&bundle);
|
let file = PathBuf::from(&bundle);
|
||||||
assert!(file.is_file());
|
assert!(file.is_file());
|
||||||
wait_for_process_finished("Bundle", &mut stderr_lines);
|
wait_for("Bundle finished", &mut stderr_lines);
|
||||||
|
|
||||||
// Confirm that the watcher keeps on working even if the file is updated and has invalid syntax
|
// Confirm that the watcher keeps on working even if the file is updated and has invalid syntax
|
||||||
std::fs::write(&file_to_watch, "syntax error ^^")
|
write(&file_to_watch, "syntax error ^^").unwrap();
|
||||||
.expect("error writing file");
|
|
||||||
std::thread::sleep(std::time::Duration::from_secs(1));
|
std::thread::sleep(std::time::Duration::from_secs(1));
|
||||||
assert!(stderr_lines
|
assert_contains!(stderr_lines.next().unwrap(), "File change detected!");
|
||||||
.next()
|
assert_contains!(stderr_lines.next().unwrap(), "error: ");
|
||||||
.unwrap()
|
wait_for("Bundle failed", &mut stderr_lines);
|
||||||
.contains("File change detected!"));
|
check_alive_then_kill(deno);
|
||||||
assert!(stderr_lines.next().unwrap().contains("error: "));
|
|
||||||
wait_for_process_failed("Bundle", &mut stderr_lines);
|
|
||||||
|
|
||||||
// the watcher process is still alive
|
|
||||||
assert!(deno.try_wait().unwrap().is_none());
|
|
||||||
|
|
||||||
deno.kill().unwrap();
|
|
||||||
drop(t);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Confirm that the watcher continues to work even if module resolution fails at the *first* attempt
|
/// Confirm that the watcher continues to work even if module resolution fails at the *first* attempt
|
||||||
#[test]
|
#[test]
|
||||||
fn bundle_watch_not_exit() {
|
fn bundle_watch_not_exit() {
|
||||||
let t = TempDir::new().expect("tempdir fail");
|
let t = TempDir::new().unwrap();
|
||||||
let file_to_watch = t.path().join("file_to_watch.js");
|
let file_to_watch = t.path().join("file_to_watch.js");
|
||||||
std::fs::write(&file_to_watch, "syntax error ^^")
|
write(&file_to_watch, "syntax error ^^").unwrap();
|
||||||
.expect("error writing file");
|
|
||||||
let target_file = t.path().join("target.js");
|
let target_file = t.path().join("target.js");
|
||||||
|
|
||||||
let mut deno = util::deno_cmd()
|
let mut deno = util::deno_cmd()
|
||||||
|
@ -184,45 +164,32 @@ fn bundle_watch_not_exit() {
|
||||||
.stdout(std::process::Stdio::piped())
|
.stdout(std::process::Stdio::piped())
|
||||||
.stderr(std::process::Stdio::piped())
|
.stderr(std::process::Stdio::piped())
|
||||||
.spawn()
|
.spawn()
|
||||||
.expect("failed to spawn script");
|
.unwrap();
|
||||||
|
let (_stdout_lines, mut stderr_lines) = child_lines(&mut deno);
|
||||||
let stderr = deno.stderr.as_mut().unwrap();
|
|
||||||
let mut stderr_lines =
|
|
||||||
std::io::BufReader::new(stderr).lines().map(|r| r.unwrap());
|
|
||||||
|
|
||||||
std::thread::sleep(std::time::Duration::from_secs(1));
|
std::thread::sleep(std::time::Duration::from_secs(1));
|
||||||
assert!(stderr_lines.next().unwrap().contains("error:"));
|
assert_contains!(stderr_lines.next().unwrap(), "error:");
|
||||||
assert!(stderr_lines.next().unwrap().contains("Bundle failed"));
|
assert_contains!(stderr_lines.next().unwrap(), "Bundle failed");
|
||||||
// the target file hasn't been created yet
|
// the target file hasn't been created yet
|
||||||
assert!(!target_file.is_file());
|
assert!(!target_file.is_file());
|
||||||
|
|
||||||
// Make sure the watcher actually restarts and works fine with the proper syntax
|
// Make sure the watcher actually restarts and works fine with the proper syntax
|
||||||
std::fs::write(&file_to_watch, "console.log(42);")
|
write(&file_to_watch, "console.log(42);").unwrap();
|
||||||
.expect("error writing file");
|
|
||||||
std::thread::sleep(std::time::Duration::from_secs(1));
|
std::thread::sleep(std::time::Duration::from_secs(1));
|
||||||
assert!(stderr_lines
|
assert_contains!(stderr_lines.next().unwrap(), "File change detected!");
|
||||||
.next()
|
assert_contains!(stderr_lines.next().unwrap(), "file_to_watch.js");
|
||||||
.unwrap()
|
assert_contains!(stderr_lines.next().unwrap(), "target.js");
|
||||||
.contains("File change detected!"));
|
wait_for("Bundle finished", &mut stderr_lines);
|
||||||
assert!(stderr_lines.next().unwrap().contains("file_to_watch.js"));
|
|
||||||
assert!(stderr_lines.next().unwrap().contains("target.js"));
|
|
||||||
wait_for_process_finished("Bundle", &mut stderr_lines);
|
|
||||||
// bundled file is created
|
// bundled file is created
|
||||||
assert!(target_file.is_file());
|
assert!(target_file.is_file());
|
||||||
|
check_alive_then_kill(deno);
|
||||||
// the watcher process is still alive
|
|
||||||
assert!(deno.try_wait().unwrap().is_none());
|
|
||||||
|
|
||||||
deno.kill().unwrap();
|
|
||||||
drop(t);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[flaky_test::flaky_test]
|
#[flaky_test::flaky_test]
|
||||||
fn run_watch() {
|
fn run_watch() {
|
||||||
let t = TempDir::new().expect("tempdir fail");
|
let t = TempDir::new().unwrap();
|
||||||
let file_to_watch = t.path().join("file_to_watch.js");
|
let file_to_watch = t.path().join("file_to_watch.js");
|
||||||
std::fs::write(&file_to_watch, "console.log('Hello world');")
|
write(&file_to_watch, "console.log('Hello world');").unwrap();
|
||||||
.expect("error writing file");
|
|
||||||
|
|
||||||
let mut child = util::deno_cmd()
|
let mut child = util::deno_cmd()
|
||||||
.current_dir(util::testdata_path())
|
.current_dir(util::testdata_path())
|
||||||
|
@ -234,99 +201,83 @@ fn run_watch() {
|
||||||
.stdout(std::process::Stdio::piped())
|
.stdout(std::process::Stdio::piped())
|
||||||
.stderr(std::process::Stdio::piped())
|
.stderr(std::process::Stdio::piped())
|
||||||
.spawn()
|
.spawn()
|
||||||
.expect("failed to spawn script");
|
.unwrap();
|
||||||
|
let (mut stdout_lines, mut stderr_lines) = child_lines(&mut child);
|
||||||
|
|
||||||
let stdout = child.stdout.as_mut().unwrap();
|
assert_contains!(stdout_lines.next().unwrap(), "Hello world");
|
||||||
let mut stdout_lines =
|
wait_for("Process finished", &mut stderr_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!(stdout_lines.next().unwrap().contains("Hello world"));
|
|
||||||
wait_for_process_finished("Process", &mut stderr_lines);
|
|
||||||
|
|
||||||
// TODO(lucacasonato): remove this timeout. It seems to be needed on Linux.
|
// TODO(lucacasonato): remove this timeout. It seems to be needed on Linux.
|
||||||
std::thread::sleep(std::time::Duration::from_secs(1));
|
std::thread::sleep(std::time::Duration::from_secs(1));
|
||||||
|
|
||||||
// Change content of the file
|
// Change content of the file
|
||||||
std::fs::write(&file_to_watch, "console.log('Hello world2');")
|
write(&file_to_watch, "console.log('Hello world2');").unwrap();
|
||||||
.expect("error writing file");
|
|
||||||
// Events from the file watcher is "debounced", so we need to wait for the next execution to start
|
// Events from the file watcher is "debounced", so we need to wait for the next execution to start
|
||||||
std::thread::sleep(std::time::Duration::from_secs(1));
|
std::thread::sleep(std::time::Duration::from_secs(1));
|
||||||
|
|
||||||
assert!(stderr_lines.next().unwrap().contains("Restarting"));
|
assert_contains!(stderr_lines.next().unwrap(), "Restarting");
|
||||||
assert!(stdout_lines.next().unwrap().contains("Hello world2"));
|
assert_contains!(stdout_lines.next().unwrap(), "Hello world2");
|
||||||
wait_for_process_finished("Process", &mut stderr_lines);
|
wait_for("Process finished", &mut stderr_lines);
|
||||||
|
|
||||||
// Add dependency
|
// Add dependency
|
||||||
let another_file = t.path().join("another_file.js");
|
let another_file = t.path().join("another_file.js");
|
||||||
std::fs::write(&another_file, "export const foo = 0;")
|
write(&another_file, "export const foo = 0;").unwrap();
|
||||||
.expect("error writing file");
|
write(
|
||||||
std::fs::write(
|
|
||||||
&file_to_watch,
|
&file_to_watch,
|
||||||
"import { foo } from './another_file.js'; console.log(foo);",
|
"import { foo } from './another_file.js'; console.log(foo);",
|
||||||
)
|
)
|
||||||
.expect("error writing file");
|
.unwrap();
|
||||||
std::thread::sleep(std::time::Duration::from_secs(1));
|
std::thread::sleep(std::time::Duration::from_secs(1));
|
||||||
assert!(stderr_lines.next().unwrap().contains("Restarting"));
|
assert_contains!(stderr_lines.next().unwrap(), "Restarting");
|
||||||
assert!(stdout_lines.next().unwrap().contains('0'));
|
assert_contains!(stdout_lines.next().unwrap(), '0');
|
||||||
wait_for_process_finished("Process", &mut stderr_lines);
|
wait_for("Process finished", &mut stderr_lines);
|
||||||
|
|
||||||
// Confirm that restarting occurs when a new file is updated
|
// Confirm that restarting occurs when a new file is updated
|
||||||
std::fs::write(&another_file, "export const foo = 42;")
|
write(&another_file, "export const foo = 42;").unwrap();
|
||||||
.expect("error writing file");
|
|
||||||
std::thread::sleep(std::time::Duration::from_secs(1));
|
std::thread::sleep(std::time::Duration::from_secs(1));
|
||||||
assert!(stderr_lines.next().unwrap().contains("Restarting"));
|
assert_contains!(stderr_lines.next().unwrap(), "Restarting");
|
||||||
assert!(stdout_lines.next().unwrap().contains("42"));
|
assert_contains!(stdout_lines.next().unwrap(), "42");
|
||||||
wait_for_process_finished("Process", &mut stderr_lines);
|
wait_for("Process finished", &mut stderr_lines);
|
||||||
|
|
||||||
// Confirm that the watcher keeps on working even if the file is updated and has invalid syntax
|
// Confirm that the watcher keeps on working even if the file is updated and has invalid syntax
|
||||||
std::fs::write(&file_to_watch, "syntax error ^^")
|
write(&file_to_watch, "syntax error ^^").unwrap();
|
||||||
.expect("error writing file");
|
|
||||||
std::thread::sleep(std::time::Duration::from_secs(1));
|
std::thread::sleep(std::time::Duration::from_secs(1));
|
||||||
assert!(stderr_lines.next().unwrap().contains("Restarting"));
|
assert_contains!(stderr_lines.next().unwrap(), "Restarting");
|
||||||
assert!(stderr_lines.next().unwrap().contains("error:"));
|
assert_contains!(stderr_lines.next().unwrap(), "error:");
|
||||||
wait_for_process_failed("Process", &mut stderr_lines);
|
wait_for("Process failed", &mut stderr_lines);
|
||||||
|
|
||||||
// Then restore the file
|
// Then restore the file
|
||||||
std::fs::write(
|
write(
|
||||||
&file_to_watch,
|
&file_to_watch,
|
||||||
"import { foo } from './another_file.js'; console.log(foo);",
|
"import { foo } from './another_file.js'; console.log(foo);",
|
||||||
)
|
)
|
||||||
.expect("error writing file");
|
.unwrap();
|
||||||
std::thread::sleep(std::time::Duration::from_secs(1));
|
std::thread::sleep(std::time::Duration::from_secs(1));
|
||||||
assert!(stderr_lines.next().unwrap().contains("Restarting"));
|
assert_contains!(stderr_lines.next().unwrap(), "Restarting");
|
||||||
assert!(stdout_lines.next().unwrap().contains("42"));
|
assert_contains!(stdout_lines.next().unwrap(), "42");
|
||||||
wait_for_process_finished("Process", &mut stderr_lines);
|
wait_for("Process finished", &mut stderr_lines);
|
||||||
|
|
||||||
// Update the content of the imported file with invalid syntax
|
// Update the content of the imported file with invalid syntax
|
||||||
std::fs::write(&another_file, "syntax error ^^").expect("error writing file");
|
write(&another_file, "syntax error ^^").unwrap();
|
||||||
std::thread::sleep(std::time::Duration::from_secs(1));
|
std::thread::sleep(std::time::Duration::from_secs(1));
|
||||||
assert!(stderr_lines.next().unwrap().contains("Restarting"));
|
assert_contains!(stderr_lines.next().unwrap(), "Restarting");
|
||||||
assert!(stderr_lines.next().unwrap().contains("error:"));
|
assert_contains!(stderr_lines.next().unwrap(), "error:");
|
||||||
wait_for_process_failed("Process", &mut stderr_lines);
|
wait_for("Process failed", &mut stderr_lines);
|
||||||
|
|
||||||
// Modify the imported file and make sure that restarting occurs
|
// Modify the imported file and make sure that restarting occurs
|
||||||
std::fs::write(&another_file, "export const foo = 'modified!';")
|
write(&another_file, "export const foo = 'modified!';").unwrap();
|
||||||
.expect("error writing file");
|
|
||||||
std::thread::sleep(std::time::Duration::from_secs(1));
|
std::thread::sleep(std::time::Duration::from_secs(1));
|
||||||
assert!(stderr_lines.next().unwrap().contains("Restarting"));
|
assert_contains!(stderr_lines.next().unwrap(), "Restarting");
|
||||||
assert!(stdout_lines.next().unwrap().contains("modified!"));
|
assert_contains!(stdout_lines.next().unwrap(), "modified!");
|
||||||
wait_for_process_finished("Process", &mut stderr_lines);
|
wait_for("Process finished", &mut stderr_lines);
|
||||||
|
check_alive_then_kill(child);
|
||||||
// the watcher process is still alive
|
|
||||||
assert!(child.try_wait().unwrap().is_none());
|
|
||||||
|
|
||||||
child.kill().unwrap();
|
|
||||||
drop(t);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn run_watch_load_unload_events() {
|
fn run_watch_load_unload_events() {
|
||||||
let t = TempDir::new().expect("tempdir fail");
|
let t = TempDir::new().unwrap();
|
||||||
let file_to_watch = t.path().join("file_to_watch.js");
|
let file_to_watch = t.path().join("file_to_watch.js");
|
||||||
std::fs::write(
|
write(
|
||||||
&file_to_watch,
|
&file_to_watch,
|
||||||
r#"
|
r#"
|
||||||
setInterval(() => {}, 0);
|
setInterval(() => {}, 0);
|
||||||
|
@ -339,7 +290,7 @@ fn run_watch_load_unload_events() {
|
||||||
});
|
});
|
||||||
"#,
|
"#,
|
||||||
)
|
)
|
||||||
.expect("error writing file");
|
.unwrap();
|
||||||
|
|
||||||
let mut child = util::deno_cmd()
|
let mut child = util::deno_cmd()
|
||||||
.current_dir(util::testdata_path())
|
.current_dir(util::testdata_path())
|
||||||
|
@ -351,20 +302,14 @@ fn run_watch_load_unload_events() {
|
||||||
.stdout(std::process::Stdio::piped())
|
.stdout(std::process::Stdio::piped())
|
||||||
.stderr(std::process::Stdio::piped())
|
.stderr(std::process::Stdio::piped())
|
||||||
.spawn()
|
.spawn()
|
||||||
.expect("failed to spawn script");
|
.unwrap();
|
||||||
|
let (mut stdout_lines, mut stderr_lines) = child_lines(&mut child);
|
||||||
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());
|
|
||||||
|
|
||||||
// Wait for the first load event to fire
|
// Wait for the first load event to fire
|
||||||
assert!(stdout_lines.next().unwrap().contains("load"));
|
assert_contains!(stdout_lines.next().unwrap(), "load");
|
||||||
|
|
||||||
// Change content of the file, this time without an interval to keep it alive.
|
// Change content of the file, this time without an interval to keep it alive.
|
||||||
std::fs::write(
|
write(
|
||||||
&file_to_watch,
|
&file_to_watch,
|
||||||
r#"
|
r#"
|
||||||
window.addEventListener("load", () => {
|
window.addEventListener("load", () => {
|
||||||
|
@ -376,34 +321,31 @@ fn run_watch_load_unload_events() {
|
||||||
});
|
});
|
||||||
"#,
|
"#,
|
||||||
)
|
)
|
||||||
.expect("error writing file");
|
.unwrap();
|
||||||
|
|
||||||
// Events from the file watcher is "debounced", so we need to wait for the next execution to start
|
// Events from the file watcher is "debounced", so we need to wait for the next execution to start
|
||||||
std::thread::sleep(std::time::Duration::from_secs(1));
|
std::thread::sleep(std::time::Duration::from_secs(1));
|
||||||
|
|
||||||
// Wait for the restart
|
// Wait for the restart
|
||||||
assert!(stderr_lines.next().unwrap().contains("Restarting"));
|
assert_contains!(stderr_lines.next().unwrap(), "Restarting");
|
||||||
|
|
||||||
// Confirm that the unload event was dispatched from the first run
|
// Confirm that the unload event was dispatched from the first run
|
||||||
assert!(stdout_lines.next().unwrap().contains("unload"));
|
assert_contains!(stdout_lines.next().unwrap(), "unload");
|
||||||
|
|
||||||
// Followed by the load event of the second run
|
// Followed by the load event of the second run
|
||||||
assert!(stdout_lines.next().unwrap().contains("load"));
|
assert_contains!(stdout_lines.next().unwrap(), "load");
|
||||||
|
|
||||||
// Which is then unloaded as there is nothing keeping it alive.
|
// Which is then unloaded as there is nothing keeping it alive.
|
||||||
assert!(stdout_lines.next().unwrap().contains("unload"));
|
assert_contains!(stdout_lines.next().unwrap(), "unload");
|
||||||
|
check_alive_then_kill(child);
|
||||||
child.kill().unwrap();
|
|
||||||
drop(t);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Confirm that the watcher continues to work even if module resolution fails at the *first* attempt
|
/// Confirm that the watcher continues to work even if module resolution fails at the *first* attempt
|
||||||
#[test]
|
#[test]
|
||||||
fn run_watch_not_exit() {
|
fn run_watch_not_exit() {
|
||||||
let t = TempDir::new().expect("tempdir fail");
|
let t = TempDir::new().unwrap();
|
||||||
let file_to_watch = t.path().join("file_to_watch.js");
|
let file_to_watch = t.path().join("file_to_watch.js");
|
||||||
std::fs::write(&file_to_watch, "syntax error ^^")
|
write(&file_to_watch, "syntax error ^^").unwrap();
|
||||||
.expect("error writing file");
|
|
||||||
|
|
||||||
let mut child = util::deno_cmd()
|
let mut child = util::deno_cmd()
|
||||||
.current_dir(util::testdata_path())
|
.current_dir(util::testdata_path())
|
||||||
|
@ -415,32 +357,20 @@ fn run_watch_not_exit() {
|
||||||
.stdout(std::process::Stdio::piped())
|
.stdout(std::process::Stdio::piped())
|
||||||
.stderr(std::process::Stdio::piped())
|
.stderr(std::process::Stdio::piped())
|
||||||
.spawn()
|
.spawn()
|
||||||
.expect("failed to spawn script");
|
.unwrap();
|
||||||
|
let (mut stdout_lines, mut stderr_lines) = child_lines(&mut child);
|
||||||
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());
|
|
||||||
|
|
||||||
std::thread::sleep(std::time::Duration::from_secs(1));
|
std::thread::sleep(std::time::Duration::from_secs(1));
|
||||||
assert!(stderr_lines.next().unwrap().contains("error:"));
|
assert_contains!(stderr_lines.next().unwrap(), "error:");
|
||||||
assert!(stderr_lines.next().unwrap().contains("Process failed"));
|
assert_contains!(stderr_lines.next().unwrap(), "Process failed");
|
||||||
|
|
||||||
// Make sure the watcher actually restarts and works fine with the proper syntax
|
// Make sure the watcher actually restarts and works fine with the proper syntax
|
||||||
std::fs::write(&file_to_watch, "console.log(42);")
|
write(&file_to_watch, "console.log(42);").unwrap();
|
||||||
.expect("error writing file");
|
|
||||||
std::thread::sleep(std::time::Duration::from_secs(1));
|
std::thread::sleep(std::time::Duration::from_secs(1));
|
||||||
assert!(stderr_lines.next().unwrap().contains("Restarting"));
|
assert_contains!(stderr_lines.next().unwrap(), "Restarting");
|
||||||
assert!(stdout_lines.next().unwrap().contains("42"));
|
assert_contains!(stdout_lines.next().unwrap(), "42");
|
||||||
wait_for_process_finished("Process", &mut stderr_lines);
|
wait_for("Process finished", &mut stderr_lines);
|
||||||
|
check_alive_then_kill(child);
|
||||||
// the watcher process is still alive
|
|
||||||
assert!(child.try_wait().unwrap().is_none());
|
|
||||||
|
|
||||||
child.kill().unwrap();
|
|
||||||
drop(t);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -451,16 +381,15 @@ fn run_watch_with_import_map_and_relative_paths() {
|
||||||
filecontent: &'static str,
|
filecontent: &'static str,
|
||||||
) -> std::path::PathBuf {
|
) -> std::path::PathBuf {
|
||||||
let absolute_path = directory.path().join(filename);
|
let absolute_path = directory.path().join(filename);
|
||||||
std::fs::write(&absolute_path, filecontent).expect("error writing file");
|
write(&absolute_path, filecontent).unwrap();
|
||||||
let relative_path = absolute_path
|
let relative_path = absolute_path
|
||||||
.strip_prefix(util::testdata_path())
|
.strip_prefix(util::testdata_path())
|
||||||
.expect("unable to create relative temporary file")
|
.unwrap()
|
||||||
.to_owned();
|
.to_owned();
|
||||||
assert!(relative_path.is_relative());
|
assert!(relative_path.is_relative());
|
||||||
relative_path
|
relative_path
|
||||||
}
|
}
|
||||||
let temp_directory =
|
let temp_directory = TempDir::new_in(util::testdata_path()).unwrap();
|
||||||
TempDir::new_in(util::testdata_path()).expect("tempdir fail");
|
|
||||||
let file_to_watch = create_relative_tmp_file(
|
let file_to_watch = create_relative_tmp_file(
|
||||||
&temp_directory,
|
&temp_directory,
|
||||||
"file_to_watch.js",
|
"file_to_watch.js",
|
||||||
|
@ -484,37 +413,18 @@ fn run_watch_with_import_map_and_relative_paths() {
|
||||||
.stdout(std::process::Stdio::piped())
|
.stdout(std::process::Stdio::piped())
|
||||||
.stderr(std::process::Stdio::piped())
|
.stderr(std::process::Stdio::piped())
|
||||||
.spawn()
|
.spawn()
|
||||||
.expect("failed to spawn script");
|
.unwrap();
|
||||||
|
let (mut stdout_lines, mut stderr_lines) = child_lines(&mut child);
|
||||||
|
|
||||||
let stdout = child.stdout.as_mut().unwrap();
|
assert_contains!(stderr_lines.next().unwrap(), "Process finished");
|
||||||
let mut stdout_lines =
|
assert_contains!(stdout_lines.next().unwrap(), "Hello world");
|
||||||
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!(stderr_lines.next().unwrap().contains("Process finished"));
|
check_alive_then_kill(child);
|
||||||
assert!(stdout_lines.next().unwrap().contains("Hello world"));
|
|
||||||
|
|
||||||
child.kill().unwrap();
|
|
||||||
|
|
||||||
drop(file_to_watch);
|
|
||||||
drop(import_map_path);
|
|
||||||
temp_directory.close().unwrap();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[flaky_test]
|
#[flaky_test]
|
||||||
fn test_watch() {
|
fn test_watch() {
|
||||||
macro_rules! assert_contains {
|
let t = TempDir::new().unwrap();
|
||||||
($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()
|
let mut child = util::deno_cmd()
|
||||||
.current_dir(util::testdata_path())
|
.current_dir(util::testdata_path())
|
||||||
|
@ -527,40 +437,32 @@ fn test_watch() {
|
||||||
.stdout(std::process::Stdio::piped())
|
.stdout(std::process::Stdio::piped())
|
||||||
.stderr(std::process::Stdio::piped())
|
.stderr(std::process::Stdio::piped())
|
||||||
.spawn()
|
.spawn()
|
||||||
.expect("failed to spawn script");
|
.unwrap();
|
||||||
|
let (mut stdout_lines, mut stderr_lines) = child_lines(&mut child);
|
||||||
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_eq!(stdout_lines.next().unwrap(), "");
|
assert_eq!(stdout_lines.next().unwrap(), "");
|
||||||
assert_contains!(
|
assert_contains!(
|
||||||
stdout_lines.next().unwrap(),
|
stdout_lines.next().unwrap(),
|
||||||
"0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out"
|
"0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out"
|
||||||
);
|
);
|
||||||
wait_for_process_finished("Test", &mut stderr_lines);
|
wait_for("Test finished", &mut stderr_lines);
|
||||||
|
|
||||||
let foo_file = t.path().join("foo.js");
|
let foo_file = t.path().join("foo.js");
|
||||||
let bar_file = t.path().join("bar.js");
|
let bar_file = t.path().join("bar.js");
|
||||||
let foo_test = t.path().join("foo_test.js");
|
let foo_test = t.path().join("foo_test.js");
|
||||||
let bar_test = t.path().join("bar_test.js");
|
let bar_test = t.path().join("bar_test.js");
|
||||||
std::fs::write(&foo_file, "export default function foo() { 1 + 1 }")
|
write(&foo_file, "export default function foo() { 1 + 1 }").unwrap();
|
||||||
.expect("error writing file");
|
write(&bar_file, "export default function bar() { 2 + 2 }").unwrap();
|
||||||
std::fs::write(&bar_file, "export default function bar() { 2 + 2 }")
|
write(
|
||||||
.expect("error writing file");
|
|
||||||
std::fs::write(
|
|
||||||
&foo_test,
|
&foo_test,
|
||||||
"import foo from './foo.js'; Deno.test('foo', foo);",
|
"import foo from './foo.js'; Deno.test('foo', foo);",
|
||||||
)
|
)
|
||||||
.expect("error writing file");
|
.unwrap();
|
||||||
std::fs::write(
|
write(
|
||||||
&bar_test,
|
&bar_test,
|
||||||
"import bar from './bar.js'; Deno.test('bar', bar);",
|
"import bar from './bar.js'; Deno.test('bar', bar);",
|
||||||
)
|
)
|
||||||
.expect("error writing file");
|
.unwrap();
|
||||||
|
|
||||||
assert_eq!(stdout_lines.next().unwrap(), "");
|
assert_eq!(stdout_lines.next().unwrap(), "");
|
||||||
assert_contains!(stdout_lines.next().unwrap(), "running 1 test");
|
assert_contains!(stdout_lines.next().unwrap(), "running 1 test");
|
||||||
|
@ -570,14 +472,14 @@ fn test_watch() {
|
||||||
stdout_lines.next();
|
stdout_lines.next();
|
||||||
stdout_lines.next();
|
stdout_lines.next();
|
||||||
stdout_lines.next();
|
stdout_lines.next();
|
||||||
wait_for_process_finished("Test", &mut stderr_lines);
|
wait_for("Test finished", &mut stderr_lines);
|
||||||
|
|
||||||
// Change content of the file
|
// Change content of the file
|
||||||
std::fs::write(
|
write(
|
||||||
&foo_test,
|
&foo_test,
|
||||||
"import foo from './foo.js'; Deno.test('foobar', foo);",
|
"import foo from './foo.js'; Deno.test('foobar', foo);",
|
||||||
)
|
)
|
||||||
.expect("error writing file");
|
.unwrap();
|
||||||
|
|
||||||
assert_contains!(stderr_lines.next().unwrap(), "Restarting");
|
assert_contains!(stderr_lines.next().unwrap(), "Restarting");
|
||||||
assert_contains!(stdout_lines.next().unwrap(), "running 1 test");
|
assert_contains!(stdout_lines.next().unwrap(), "running 1 test");
|
||||||
|
@ -585,23 +487,22 @@ fn test_watch() {
|
||||||
stdout_lines.next();
|
stdout_lines.next();
|
||||||
stdout_lines.next();
|
stdout_lines.next();
|
||||||
stdout_lines.next();
|
stdout_lines.next();
|
||||||
wait_for_process_finished("Test", &mut stderr_lines);
|
wait_for("Test finished", &mut stderr_lines);
|
||||||
|
|
||||||
// Add test
|
// Add test
|
||||||
let another_test = t.path().join("new_test.js");
|
let another_test = t.path().join("new_test.js");
|
||||||
std::fs::write(&another_test, "Deno.test('another one', () => 3 + 3)")
|
write(&another_test, "Deno.test('another one', () => 3 + 3)").unwrap();
|
||||||
.expect("error writing file");
|
|
||||||
assert_contains!(stderr_lines.next().unwrap(), "Restarting");
|
assert_contains!(stderr_lines.next().unwrap(), "Restarting");
|
||||||
assert_contains!(stdout_lines.next().unwrap(), "running 1 test");
|
assert_contains!(stdout_lines.next().unwrap(), "running 1 test");
|
||||||
assert_contains!(stdout_lines.next().unwrap(), "another one");
|
assert_contains!(stdout_lines.next().unwrap(), "another one");
|
||||||
stdout_lines.next();
|
stdout_lines.next();
|
||||||
stdout_lines.next();
|
stdout_lines.next();
|
||||||
stdout_lines.next();
|
stdout_lines.next();
|
||||||
wait_for_process_finished("Test", &mut stderr_lines);
|
wait_for("Test finished", &mut stderr_lines);
|
||||||
|
|
||||||
// Confirm that restarting occurs when a new file is updated
|
// Confirm that restarting occurs when a new file is updated
|
||||||
std::fs::write(&another_test, "Deno.test('another one', () => 3 + 3); Deno.test('another another one', () => 4 + 4)")
|
write(&another_test, "Deno.test('another one', () => 3 + 3); Deno.test('another another one', () => 4 + 4)")
|
||||||
.expect("error writing file");
|
.unwrap();
|
||||||
assert_contains!(stderr_lines.next().unwrap(), "Restarting");
|
assert_contains!(stderr_lines.next().unwrap(), "Restarting");
|
||||||
assert_contains!(stdout_lines.next().unwrap(), "running 2 tests");
|
assert_contains!(stdout_lines.next().unwrap(), "running 2 tests");
|
||||||
assert_contains!(stdout_lines.next().unwrap(), "another one");
|
assert_contains!(stdout_lines.next().unwrap(), "another one");
|
||||||
|
@ -609,81 +510,65 @@ fn test_watch() {
|
||||||
stdout_lines.next();
|
stdout_lines.next();
|
||||||
stdout_lines.next();
|
stdout_lines.next();
|
||||||
stdout_lines.next();
|
stdout_lines.next();
|
||||||
wait_for_process_finished("Test", &mut stderr_lines);
|
wait_for("Test finished", &mut stderr_lines);
|
||||||
|
|
||||||
// Confirm that the watcher keeps on working even if the file is updated and has invalid syntax
|
// Confirm that the watcher keeps on working even if the file is updated and has invalid syntax
|
||||||
std::fs::write(&another_test, "syntax error ^^").expect("error writing file");
|
write(&another_test, "syntax error ^^").unwrap();
|
||||||
assert_contains!(stderr_lines.next().unwrap(), "Restarting");
|
assert_contains!(stderr_lines.next().unwrap(), "Restarting");
|
||||||
assert_contains!(stderr_lines.next().unwrap(), "error:");
|
assert_contains!(stderr_lines.next().unwrap(), "error:");
|
||||||
assert_contains!(stderr_lines.next().unwrap(), "Test failed");
|
assert_contains!(stderr_lines.next().unwrap(), "Test failed");
|
||||||
|
|
||||||
// Then restore the file
|
// Then restore the file
|
||||||
std::fs::write(&another_test, "Deno.test('another one', () => 3 + 3)")
|
write(&another_test, "Deno.test('another one', () => 3 + 3)").unwrap();
|
||||||
.expect("error writing file");
|
|
||||||
assert_contains!(stderr_lines.next().unwrap(), "Restarting");
|
assert_contains!(stderr_lines.next().unwrap(), "Restarting");
|
||||||
assert_contains!(stdout_lines.next().unwrap(), "running 1 test");
|
assert_contains!(stdout_lines.next().unwrap(), "running 1 test");
|
||||||
assert_contains!(stdout_lines.next().unwrap(), "another one");
|
assert_contains!(stdout_lines.next().unwrap(), "another one");
|
||||||
stdout_lines.next();
|
stdout_lines.next();
|
||||||
stdout_lines.next();
|
stdout_lines.next();
|
||||||
stdout_lines.next();
|
stdout_lines.next();
|
||||||
wait_for_process_finished("Test", &mut stderr_lines);
|
wait_for("Test finished", &mut stderr_lines);
|
||||||
|
|
||||||
// Confirm that the watcher keeps on working even if the file is updated and the test fails
|
// Confirm that the watcher keeps on working even if the file is updated and the test fails
|
||||||
// This also confirms that it restarts when dependencies change
|
// This also confirms that it restarts when dependencies change
|
||||||
std::fs::write(
|
write(
|
||||||
&foo_file,
|
&foo_file,
|
||||||
"export default function foo() { throw new Error('Whoops!'); }",
|
"export default function foo() { throw new Error('Whoops!'); }",
|
||||||
)
|
)
|
||||||
.expect("error writing file");
|
.unwrap();
|
||||||
assert_contains!(stderr_lines.next().unwrap(), "Restarting");
|
assert_contains!(stderr_lines.next().unwrap(), "Restarting");
|
||||||
assert_contains!(stdout_lines.next().unwrap(), "running 1 test");
|
assert_contains!(stdout_lines.next().unwrap(), "running 1 test");
|
||||||
assert_contains!(stdout_lines.next().unwrap(), "FAILED");
|
assert_contains!(stdout_lines.next().unwrap(), "FAILED");
|
||||||
while !stdout_lines.next().unwrap().contains("test result") {}
|
wait_for("test result", &mut stdout_lines);
|
||||||
stdout_lines.next();
|
stdout_lines.next();
|
||||||
wait_for_process_finished("Test", &mut stderr_lines);
|
wait_for("Test finished", &mut stderr_lines);
|
||||||
|
|
||||||
// Then restore the file
|
// Then restore the file
|
||||||
std::fs::write(&foo_file, "export default function foo() { 1 + 1 }")
|
write(&foo_file, "export default function foo() { 1 + 1 }").unwrap();
|
||||||
.expect("error writing file");
|
|
||||||
assert_contains!(stderr_lines.next().unwrap(), "Restarting");
|
assert_contains!(stderr_lines.next().unwrap(), "Restarting");
|
||||||
assert_contains!(stdout_lines.next().unwrap(), "running 1 test");
|
assert_contains!(stdout_lines.next().unwrap(), "running 1 test");
|
||||||
assert_contains!(stdout_lines.next().unwrap(), "foo");
|
assert_contains!(stdout_lines.next().unwrap(), "foo");
|
||||||
stdout_lines.next();
|
stdout_lines.next();
|
||||||
stdout_lines.next();
|
stdout_lines.next();
|
||||||
stdout_lines.next();
|
stdout_lines.next();
|
||||||
wait_for_process_finished("Test", &mut stderr_lines);
|
wait_for("Test finished", &mut stderr_lines);
|
||||||
|
|
||||||
// Test that circular dependencies work fine
|
// Test that circular dependencies work fine
|
||||||
std::fs::write(
|
write(
|
||||||
&foo_file,
|
&foo_file,
|
||||||
"import './bar.js'; export default function foo() { 1 + 1 }",
|
"import './bar.js'; export default function foo() { 1 + 1 }",
|
||||||
)
|
)
|
||||||
.expect("error writing file");
|
.unwrap();
|
||||||
std::fs::write(
|
write(
|
||||||
&bar_file,
|
&bar_file,
|
||||||
"import './foo.js'; export default function bar() { 2 + 2 }",
|
"import './foo.js'; export default function bar() { 2 + 2 }",
|
||||||
)
|
)
|
||||||
.expect("error writing file");
|
.unwrap();
|
||||||
|
check_alive_then_kill(child);
|
||||||
// the watcher process is still alive
|
|
||||||
assert!(child.try_wait().unwrap().is_none());
|
|
||||||
|
|
||||||
child.kill().unwrap();
|
|
||||||
drop(t);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[flaky_test]
|
#[flaky_test]
|
||||||
fn test_watch_doc() {
|
fn test_watch_doc() {
|
||||||
macro_rules! assert_contains {
|
let t = TempDir::new().unwrap();
|
||||||
($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()
|
let mut child = util::deno_cmd()
|
||||||
.current_dir(util::testdata_path())
|
.current_dir(util::testdata_path())
|
||||||
|
@ -696,32 +581,26 @@ fn test_watch_doc() {
|
||||||
.stdout(std::process::Stdio::piped())
|
.stdout(std::process::Stdio::piped())
|
||||||
.stderr(std::process::Stdio::piped())
|
.stderr(std::process::Stdio::piped())
|
||||||
.spawn()
|
.spawn()
|
||||||
.expect("failed to spawn script");
|
.unwrap();
|
||||||
|
let (mut stdout_lines, mut stderr_lines) = child_lines(&mut child);
|
||||||
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_eq!(stdout_lines.next().unwrap(), "");
|
assert_eq!(stdout_lines.next().unwrap(), "");
|
||||||
assert_contains!(
|
assert_contains!(
|
||||||
stdout_lines.next().unwrap(),
|
stdout_lines.next().unwrap(),
|
||||||
"0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out"
|
"0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out"
|
||||||
);
|
);
|
||||||
wait_for_process_finished("Test", &mut stderr_lines);
|
wait_for("Test finished", &mut stderr_lines);
|
||||||
|
|
||||||
let foo_file = t.path().join("foo.ts");
|
let foo_file = t.path().join("foo.ts");
|
||||||
std::fs::write(
|
write(
|
||||||
&foo_file,
|
&foo_file,
|
||||||
r#"
|
r#"
|
||||||
export default function foo() {}
|
export default function foo() {}
|
||||||
"#,
|
"#,
|
||||||
)
|
)
|
||||||
.expect("error writing file");
|
.unwrap();
|
||||||
|
|
||||||
std::fs::write(
|
write(
|
||||||
&foo_file,
|
&foo_file,
|
||||||
r#"
|
r#"
|
||||||
/**
|
/**
|
||||||
|
@ -732,14 +611,10 @@ fn test_watch_doc() {
|
||||||
export default function foo() {}
|
export default function foo() {}
|
||||||
"#,
|
"#,
|
||||||
)
|
)
|
||||||
.expect("error writing file");
|
.unwrap();
|
||||||
|
|
||||||
// We only need to scan for a Check file://.../foo.ts$3-6 line that
|
// We only need to scan for a Check file://.../foo.ts$3-6 line that
|
||||||
// corresponds to the documentation block being type-checked.
|
// corresponds to the documentation block being type-checked.
|
||||||
assert_contains!(skip_restarting_line(stderr_lines), "foo.ts$3-6");
|
assert_contains!(skip_restarting_line(stderr_lines), "foo.ts$3-6");
|
||||||
|
check_alive_then_kill(child);
|
||||||
assert!(child.try_wait().unwrap().is_none());
|
|
||||||
child.kill().unwrap();
|
|
||||||
|
|
||||||
drop(t);
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue