From 95563476f604c33e91d66e164e7a804c356c0802 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartek=20Iwa=C5=84czuk?= Date: Mon, 17 Feb 2020 19:11:45 +0100 Subject: [PATCH] fix(deno test): support directories as arguments (#4011) --- Cargo.lock | 21 ++++++++++++++ cli/Cargo.toml | 1 + cli/fmt.rs | 30 ++++---------------- cli/fs.rs | 15 ++++++++++ cli/lib.rs | 2 +- cli/test_runner.rs | 71 ++++++++++++++++++++++++++++++++++++++++++---- 6 files changed, 110 insertions(+), 30 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7e67d6e372..0c0e639cfe 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -385,6 +385,7 @@ dependencies = [ "tokio-rustls 0.12.2 (registry+https://github.com/rust-lang/crates.io-index)", "url 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "utime 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "walkdir 2.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "webpki 0.21.0 (registry+https://github.com/rust-lang/crates.io-index)", "webpki-roots 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1556,6 +1557,14 @@ name = "ryu" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "schannel" version = "0.1.16" @@ -2116,6 +2125,16 @@ name = "void" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "walkdir" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "same-file 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "want" version = "0.3.0" @@ -2478,6 +2497,7 @@ dependencies = [ "checksum rusty_v8 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8ed9530934df58a5be648916e142858b473558a0df6356b59e083c1c3c2f7d32" "checksum rustyline 5.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "a23cb19702a8d6afb6edb3c842386e680d4883760e0df74e6848e23c2a87a635" "checksum ryu 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bfa8506c1de11c9c4e4c38863ccbe02a305c8188e85a05a784c9e11e1c3910c8" +"checksum same-file 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" "checksum schannel 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "87f550b06b6cba9c8b8be3ee73f391990116bf527450d2556e9b9ce263b9a021" "checksum scoped-tls 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ea6a9290e3c9cf0f18145ef7ffa62d68ee0bf5fcd651017e586dc7fd5da448c2" "checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27" @@ -2542,6 +2562,7 @@ dependencies = [ "checksum version_check 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "078775d0255232fb988e6fccf26ddc9d1ac274299aaedcedce21c6f72cc533ce" "checksum vlq 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "65dd7eed29412da847b0f78bcec0ac98588165988a8cfe41d4ea1d429f8ccfff" "checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" +"checksum walkdir 2.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "777182bc735b6424e1a57516d35ed72cb8019d85c8c9bf536dccb3445c1a2f7d" "checksum want 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0" "checksum wasi 0.9.0+wasi-snapshot-preview1 (registry+https://github.com/rust-lang/crates.io-index)" = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" "checksum wasm-bindgen 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)" = "5205e9afdf42282b192e2310a5b463a6d1c1d774e30dc3c791ac37ab42d2616c" diff --git a/cli/Cargo.toml b/cli/Cargo.toml index a8f2e1dd31..a9b79dbbcf 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -62,6 +62,7 @@ url = "2.1.0" utime = "0.2.1" webpki = "0.21.0" webpki-roots = "0.17.0" +walkdir = "2.3.1" [target.'cfg(windows)'.dependencies] winapi = "0.3.8" diff --git a/cli/fmt.rs b/cli/fmt.rs index c9b0ef8266..a71c411025 100644 --- a/cli/fmt.rs +++ b/cli/fmt.rs @@ -7,9 +7,9 @@ //! the future it can be easily extended to provide //! the same functions as ops available in JS runtime. +use crate::fs::files_in_subtree; use deno_core::ErrBox; use dprint_plugin_typescript as dprint; -use glob; use std::fs; use std::io::stdin; use std::io::stdout; @@ -135,26 +135,6 @@ fn format_source_files( ); } -pub fn source_files_in_subtree(root: PathBuf) -> Vec { - assert!(root.is_dir()); - // TODO(ry) Use WalkDir instead of globs. - let g = root.join("**/*"); - glob::glob(&g.into_os_string().into_string().unwrap()) - .expect("Failed to execute glob.") - .filter_map(|result| { - if let Ok(p) = result { - if is_supported(&p) { - Some(p) - } else { - None - } - } else { - None - } - }) - .collect() -} - /// Format JavaScript/TypeScript files. /// /// First argument supports globs, and if it is `None` @@ -168,13 +148,15 @@ pub fn format_files(args: Vec, check: bool) -> Result<(), ErrBox> { let mut target_files: Vec = vec![]; if args.is_empty() { - target_files - .extend(source_files_in_subtree(std::env::current_dir().unwrap())); + target_files.extend(files_in_subtree( + std::env::current_dir().unwrap(), + is_supported, + )); } else { for arg in args { let p = PathBuf::from(arg); if p.is_dir() { - target_files.extend(source_files_in_subtree(p)); + target_files.extend(files_in_subtree(p, is_supported)); } else { target_files.push(p); }; diff --git a/cli/fs.rs b/cli/fs.rs index 8d3a31bb5b..521b996ac3 100644 --- a/cli/fs.rs +++ b/cli/fs.rs @@ -9,6 +9,7 @@ use deno_core::ErrBox; use rand; use rand::Rng; use url::Url; +use walkdir::WalkDir; #[cfg(unix)] use nix::unistd::{chown as unix_chown, Gid, Uid}; @@ -188,3 +189,17 @@ mod tests { assert_eq!(resolve_from_cwd(expected).unwrap(), expected); } } + +pub fn files_in_subtree(root: PathBuf, filter: F) -> Vec +where + F: Fn(&Path) -> bool, +{ + assert!(root.is_dir()); + + WalkDir::new(root) + .into_iter() + .filter_map(|e| e.ok()) + .map(|e| e.path().to_owned()) + .filter(|p| if p.is_dir() { false } else { filter(&p) }) + .collect() +} diff --git a/cli/lib.rs b/cli/lib.rs index e646c41999..81fd8810e1 100644 --- a/cli/lib.rs +++ b/cli/lib.rs @@ -429,7 +429,7 @@ async fn test_command( let global_state = create_global_state(flags.clone()); let cwd = std::env::current_dir().expect("No current directory"); let include = include.unwrap_or_else(|| vec![".".to_string()]); - let res = test_runner::prepare_test_modules_urls(include, cwd.clone()); + let res = test_runner::prepare_test_modules_urls(include, &cwd); let test_modules = match res { Ok(modules) => modules, diff --git a/cli/test_runner.rs b/cli/test_runner.rs index e05013889d..3d177f60e5 100644 --- a/cli/test_runner.rs +++ b/cli/test_runner.rs @@ -3,12 +3,28 @@ use crate::installer::is_remote_url; use deno_core::ErrBox; use std; +use std::path::Path; use std::path::PathBuf; use url::Url; +fn is_supported(p: &Path) -> bool { + use std::path::Component; + if let Some(Component::Normal(basename_os_str)) = p.components().next_back() { + let basename = basename_os_str.to_string_lossy(); + basename.ends_with("_test.ts") + || basename.ends_with("_test.js") + || basename.ends_with(".test.ts") + || basename.ends_with(".test.js") + || basename == "test.ts" + || basename == "test.js" + } else { + false + } +} + pub fn prepare_test_modules_urls( include: Vec, - root_path: PathBuf, + root_path: &PathBuf, ) -> Result, ErrBox> { let (include_paths, include_urls): (Vec, Vec) = include.into_iter().partition(|n| !is_remote_url(n)); @@ -16,9 +32,19 @@ pub fn prepare_test_modules_urls( let mut prepared = vec![]; for path in include_paths { - let p = root_path.join(path).canonicalize()?; - let url = Url::from_file_path(p).unwrap(); - prepared.push(url); + let q = root_path.join(path); + let p = q.canonicalize()?; + if p.is_dir() { + let test_files = crate::fs::files_in_subtree(p, is_supported); + let test_files_as_urls = test_files + .iter() + .map(|f| Url::from_file_path(f).unwrap()) + .collect::>(); + prepared.extend(test_files_as_urls); + } else { + let url = Url::from_file_path(p).unwrap(); + prepared.push(url); + } } for remote_url in include_urls { @@ -59,7 +85,7 @@ mod tests { "subdir2/mod2.ts".to_string(), "http://example.com/printf_test.ts".to_string(), ], - test_data_path.clone(), + &test_data_path, ) .unwrap(); let test_data_url = @@ -78,4 +104,39 @@ mod tests { matched_urls.sort(); assert_eq!(matched_urls, expected); } + + #[test] + fn test_is_supported() { + assert!(is_supported(Path::new("tests/subdir/foo_test.ts"))); + assert!(is_supported(Path::new("tests/subdir/foo_test.js"))); + assert!(is_supported(Path::new("bar/foo.test.ts"))); + assert!(is_supported(Path::new("bar/foo.test.js"))); + assert!(is_supported(Path::new("foo/bar/test.js"))); + assert!(is_supported(Path::new("foo/bar/test.ts"))); + assert!(!is_supported(Path::new("README.md"))); + assert!(!is_supported(Path::new("lib/typescript.d.ts"))); + assert!(!is_supported(Path::new("notatest.js"))); + assert!(!is_supported(Path::new("NotAtest.ts"))); + } + + #[test] + fn supports_dirs() { + let root = test_util::root_path().join("std").join("http"); + println!("root {:?}", root); + let mut matched_urls = + prepare_test_modules_urls(vec![".".to_string()], &root).unwrap(); + matched_urls.sort(); + let root_url = Url::from_file_path(root).unwrap().to_string(); + println!("root_url {}", root_url); + let expected: Vec = vec![ + format!("{}/cookie_test.ts", root_url), + format!("{}/file_server_test.ts", root_url), + format!("{}/racing_server_test.ts", root_url), + format!("{}/server_test.ts", root_url), + ] + .into_iter() + .map(|f| Url::parse(&f).unwrap()) + .collect(); + assert_eq!(matched_urls, expected); + } }