// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. use crate::fs_util; use crate::tools::installer::is_remote_url; use deno_core::error::AnyError; use deno_core::serde_json::json; use deno_core::url::Url; use std::path::Path; use std::path::PathBuf; 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.tsx") || basename.ends_with("_test.js") || basename.ends_with("_test.mjs") || basename.ends_with("_test.jsx") || basename.ends_with(".test.ts") || basename.ends_with(".test.tsx") || basename.ends_with(".test.js") || basename.ends_with(".test.mjs") || basename.ends_with(".test.jsx") || basename == "test.ts" || basename == "test.tsx" || basename == "test.js" || basename == "test.mjs" || basename == "test.jsx" } else { false } } pub fn prepare_test_modules_urls( include: Vec, root_path: &PathBuf, ) -> Result, AnyError> { let (include_paths, include_urls): (Vec, Vec) = include.into_iter().partition(|n| !is_remote_url(n)); let mut prepared = vec![]; for path in include_paths { let p = fs_util::normalize_path(&root_path.join(path)); if p.is_dir() { let test_files = fs_util::collect_files(&[p], &[], is_supported).unwrap(); 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 { let url = Url::parse(&remote_url)?; prepared.push(url); } Ok(prepared) } pub fn render_test_file( modules: Vec, fail_fast: bool, quiet: bool, filter: Option, ) -> String { let mut test_file = "".to_string(); for module in modules { test_file.push_str(&format!("import \"{}\";\n", module.to_string())); } let options = if let Some(filter) = filter { json!({ "failFast": fail_fast, "reportToConsole": !quiet, "disableLog": quiet, "filter": filter }) } else { json!({ "failFast": fail_fast, "reportToConsole": !quiet, "disableLog": quiet }) }; test_file.push_str("// @ts-ignore\n"); test_file.push_str(&format!( "await Deno[Deno.internal].runTests({});\n", options )); test_file } #[cfg(test)] mod tests { use super::*; #[test] fn test_prepare_test_modules_urls() { let test_data_path = test_util::root_path().join("cli/tests/subdir"); let mut matched_urls = prepare_test_modules_urls( vec![ "https://example.com/colors_test.ts".to_string(), "./mod1.ts".to_string(), "./mod3.js".to_string(), "subdir2/mod2.ts".to_string(), "http://example.com/printf_test.ts".to_string(), ], &test_data_path, ) .unwrap(); let test_data_url = Url::from_file_path(test_data_path).unwrap().to_string(); let expected: Vec = vec![ format!("{}/mod1.ts", test_data_url), format!("{}/mod3.js", test_data_url), format!("{}/subdir2/mod2.ts", test_data_url), "http://example.com/printf_test.ts".to_string(), "https://example.com/colors_test.ts".to_string(), ] .into_iter() .map(|f| Url::parse(&f).unwrap()) .collect(); 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.tsx"))); assert!(is_supported(Path::new("tests/subdir/foo_test.js"))); assert!(is_supported(Path::new("tests/subdir/foo_test.jsx"))); assert!(is_supported(Path::new("bar/foo.test.ts"))); assert!(is_supported(Path::new("bar/foo.test.tsx"))); assert!(is_supported(Path::new("bar/foo.test.js"))); assert!(is_supported(Path::new("bar/foo.test.jsx"))); assert!(is_supported(Path::new("foo/bar/test.js"))); assert!(is_supported(Path::new("foo/bar/test.jsx"))); assert!(is_supported(Path::new("foo/bar/test.ts"))); assert!(is_supported(Path::new("foo/bar/test.tsx"))); 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() { // TODO(caspervonb) generate some fixtures in a temporary directory instead, there's no need // for this to rely on external fixtures. let root = test_util::root_path() .join("test_util") .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!("{}/_io_test.ts", root_url), 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), format!("{}/test.ts", root_url), ] .into_iter() .map(|f| Url::parse(&f).unwrap()) .collect(); assert_eq!(matched_urls, expected); } }