1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-11-25 15:29:32 -05:00

feat(cli): support configuring the test tool in the config file (#15079)

This commit is contained in:
Roj 2022-07-18 22:12:19 +03:00 committed by GitHub
parent 1f04cea160
commit 70d1ecaeaa
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 145 additions and 18 deletions

View file

@ -397,6 +397,28 @@ pub struct FmtConfig {
pub files: FilesConfig, pub files: FilesConfig,
} }
#[derive(Clone, Debug, Default, Deserialize)]
#[serde(default, deny_unknown_fields)]
struct SerializedTestConfig {
pub files: SerializedFilesConfig,
}
impl SerializedTestConfig {
pub fn into_resolved(
self,
config_file_specifier: &ModuleSpecifier,
) -> Result<TestConfig, AnyError> {
Ok(TestConfig {
files: self.files.into_resolved(config_file_specifier)?,
})
}
}
#[derive(Clone, Debug, Default)]
pub struct TestConfig {
pub files: FilesConfig,
}
#[derive(Clone, Debug, Deserialize)] #[derive(Clone, Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct ConfigFileJson { pub struct ConfigFileJson {
@ -405,6 +427,7 @@ pub struct ConfigFileJson {
pub lint: Option<Value>, pub lint: Option<Value>,
pub fmt: Option<Value>, pub fmt: Option<Value>,
pub tasks: Option<Value>, pub tasks: Option<Value>,
pub test: Option<Value>,
} }
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
@ -583,6 +606,16 @@ impl ConfigFile {
} }
} }
pub fn to_test_config(&self) -> Result<Option<TestConfig>, AnyError> {
if let Some(config) = self.json.test.clone() {
let lint_config: SerializedTestConfig = serde_json::from_value(config)
.context("Failed to parse \"test\" configuration")?;
Ok(Some(lint_config.into_resolved(&self.specifier)?))
} else {
Ok(None)
}
}
/// Return any tasks that are defined in the configuration file as a sequence /// Return any tasks that are defined in the configuration file as a sequence
/// of JSON objects providing the name of the task and the arguments of the /// of JSON objects providing the name of the task and the arguments of the
/// task in a detail field. /// task in a detail field.

View file

@ -175,7 +175,7 @@ pub struct TestFlags {
pub no_run: bool, pub no_run: bool,
pub fail_fast: Option<NonZeroUsize>, pub fail_fast: Option<NonZeroUsize>,
pub allow_none: bool, pub allow_none: bool,
pub include: Option<Vec<String>>, pub include: Vec<String>,
pub filter: Option<String>, pub filter: Option<String>,
pub shuffle: Option<u64>, pub shuffle: Option<u64>,
pub concurrent_jobs: NonZeroUsize, pub concurrent_jobs: NonZeroUsize,
@ -2682,15 +2682,14 @@ fn test_parse(flags: &mut Flags, matches: &clap::ArgMatches) {
NonZeroUsize::new(1).unwrap() NonZeroUsize::new(1).unwrap()
}; };
let include = if matches.is_present("files") { let include: Vec<String> = if matches.is_present("files") {
let files: Vec<String> = matches matches
.values_of("files") .values_of("files")
.unwrap() .unwrap()
.map(String::from) .map(String::from)
.collect(); .collect::<Vec<_>>()
Some(files)
} else { } else {
None Vec::new()
}; };
flags.coverage_dir = matches.value_of("coverage").map(String::from); flags.coverage_dir = matches.value_of("coverage").map(String::from);
@ -4995,7 +4994,7 @@ mod tests {
fail_fast: None, fail_fast: None,
filter: Some("- foo".to_string()), filter: Some("- foo".to_string()),
allow_none: true, allow_none: true,
include: Some(svec!["dir1/", "dir2/"]), include: svec!["dir1/", "dir2/"],
ignore: vec![], ignore: vec![],
shuffle: None, shuffle: None,
concurrent_jobs: NonZeroUsize::new(1).unwrap(), concurrent_jobs: NonZeroUsize::new(1).unwrap(),
@ -5067,7 +5066,7 @@ mod tests {
filter: None, filter: None,
allow_none: false, allow_none: false,
shuffle: None, shuffle: None,
include: None, include: vec![],
ignore: vec![], ignore: vec![],
concurrent_jobs: NonZeroUsize::new(4).unwrap(), concurrent_jobs: NonZeroUsize::new(4).unwrap(),
trace_ops: false, trace_ops: false,
@ -5095,7 +5094,7 @@ mod tests {
filter: None, filter: None,
allow_none: false, allow_none: false,
shuffle: None, shuffle: None,
include: None, include: vec![],
ignore: vec![], ignore: vec![],
concurrent_jobs: NonZeroUsize::new(1).unwrap(), concurrent_jobs: NonZeroUsize::new(1).unwrap(),
trace_ops: false, trace_ops: false,
@ -5127,7 +5126,7 @@ mod tests {
filter: None, filter: None,
allow_none: false, allow_none: false,
shuffle: None, shuffle: None,
include: None, include: vec![],
ignore: vec![], ignore: vec![],
concurrent_jobs: NonZeroUsize::new(1).unwrap(), concurrent_jobs: NonZeroUsize::new(1).unwrap(),
trace_ops: false, trace_ops: false,
@ -5153,7 +5152,7 @@ mod tests {
filter: None, filter: None,
allow_none: false, allow_none: false,
shuffle: Some(1), shuffle: Some(1),
include: None, include: vec![],
ignore: vec![], ignore: vec![],
concurrent_jobs: NonZeroUsize::new(1).unwrap(), concurrent_jobs: NonZeroUsize::new(1).unwrap(),
trace_ops: false, trace_ops: false,
@ -5179,7 +5178,7 @@ mod tests {
filter: None, filter: None,
allow_none: false, allow_none: false,
shuffle: None, shuffle: None,
include: None, include: vec![],
ignore: vec![], ignore: vec![],
concurrent_jobs: NonZeroUsize::new(1).unwrap(), concurrent_jobs: NonZeroUsize::new(1).unwrap(),
trace_ops: false, trace_ops: false,
@ -5206,7 +5205,7 @@ mod tests {
filter: None, filter: None,
allow_none: false, allow_none: false,
shuffle: None, shuffle: None,
include: None, include: vec![],
ignore: vec![], ignore: vec![],
concurrent_jobs: NonZeroUsize::new(1).unwrap(), concurrent_jobs: NonZeroUsize::new(1).unwrap(),
trace_ops: false, trace_ops: false,

View file

@ -14,6 +14,7 @@ pub use config_file::LintConfig;
pub use config_file::LintRulesConfig; pub use config_file::LintRulesConfig;
pub use config_file::MaybeImportsResult; pub use config_file::MaybeImportsResult;
pub use config_file::ProseWrap; pub use config_file::ProseWrap;
pub use config_file::TestConfig;
pub use config_file::TsConfig; pub use config_file::TsConfig;
pub use flags::*; pub use flags::*;
@ -244,6 +245,14 @@ impl CliOptions {
} }
} }
pub fn to_test_config(&self) -> Result<Option<TestConfig>, AnyError> {
if let Some(config_file) = &self.maybe_config_file {
config_file.to_test_config()
} else {
Ok(None)
}
}
pub fn to_fmt_config(&self) -> Result<Option<FmtConfig>, AnyError> { pub fn to_fmt_config(&self) -> Result<Option<FmtConfig>, AnyError> {
if let Some(config) = &self.maybe_config_file { if let Some(config) = &self.maybe_config_file {
config.to_fmt_config() config.to_fmt_config()

View file

@ -62,6 +62,24 @@ itest!(collect {
output: "test/collect.out", output: "test/collect.out",
}); });
itest!(test_with_config {
args: "test --config test/collect/deno.jsonc test/collect",
exit_code: 0,
output: "test/collect.out",
});
itest!(test_with_config2 {
args: "test --config test/collect/deno2.jsonc test/collect",
exit_code: 0,
output: "test/collect2.out",
});
itest!(test_with_malformed_config {
args: "test --config test/collect/deno.malformed.jsonc",
exit_code: 1,
output: "test/collect_with_malformed_config.out",
});
itest!(jobs_flag { itest!(jobs_flag {
args: "test test/short-pass.ts --jobs", args: "test test/short-pass.ts --jobs",
exit_code: 0, exit_code: 0,

View file

@ -1,4 +1,8 @@
Check [WILDCARD]/test/collect/include/2_test.ts
Check [WILDCARD]/test/collect/include/test.ts
Check [WILDCARD]/test/collect/test.ts Check [WILDCARD]/test/collect/test.ts
running 0 tests from ./test/collect/include/2_test.ts
running 0 tests from ./test/collect/include/test.ts
running 0 tests from ./test/collect/test.ts running 0 tests from ./test/collect/test.ts
ok | 0 passed | 0 failed ([WILDCARD]) ok | 0 passed | 0 failed ([WILDCARD])

View file

@ -0,0 +1,7 @@
{
"test": {
"files": {
"exclude": ["./ignore"]
}
}
}

View file

@ -0,0 +1,5 @@
{
"test": {
"dont_know_this_field": {}
}
}

View file

@ -0,0 +1,8 @@
{
"test": {
"files": {
"include": ["./include/"],
"exclude": ["./ignore", "./include/2_test.ts"]
}
}
}

View file

View file

View file

7
cli/tests/testdata/test/collect2.out vendored Normal file
View file

@ -0,0 +1,7 @@
Check [WILDCARD]/test/collect/include/test.ts
Check [WILDCARD]/test/collect/test.ts
running 0 tests from ./test/collect/include/test.ts
running 0 tests from ./test/collect/test.ts
ok | 0 passed | 0 failed ([WILDCARD])

View file

@ -0,0 +1,4 @@
error: Failed to parse "test" configuration
Caused by:
unknown field `dont_know_this_field`, expected `files`

View file

@ -70,7 +70,7 @@ pub async fn lint(flags: Flags, lint_flags: LintFlags) -> Result<(), AnyError> {
} = lint_flags; } = lint_flags;
// First, prepare final configuration. // First, prepare final configuration.
// Collect included and ignored files. CLI flags take precendence // Collect included and ignored files. CLI flags take precendence
// over config file, ie. if there's `files.ignore` in config file // over config file, i.e. if there's `files.ignore` in config file
// and `--ignore` CLI flag, only the flag value is taken into account. // and `--ignore` CLI flag, only the flag value is taken into account.
let mut include_files = args.clone(); let mut include_files = args.clone();
let mut exclude_files = ignore.clone(); let mut exclude_files = ignore.clone();

View file

@ -15,6 +15,7 @@ use crate::fmt_errors::format_js_error;
use crate::fs_util::collect_specifiers; use crate::fs_util::collect_specifiers;
use crate::fs_util::is_supported_test_ext; use crate::fs_util::is_supported_test_ext;
use crate::fs_util::is_supported_test_path; use crate::fs_util::is_supported_test_path;
use crate::fs_util::specifier_to_file_path;
use crate::graph_util::contains_specifier; use crate::graph_util::contains_specifier;
use crate::graph_util::graph_valid; use crate::graph_util::graph_valid;
use crate::located_script_name; use crate::located_script_name;
@ -1363,8 +1364,40 @@ async fn fetch_specifiers_with_test_mode(
ignore: Vec<PathBuf>, ignore: Vec<PathBuf>,
include_inline: bool, include_inline: bool,
) -> Result<Vec<(ModuleSpecifier, TestMode)>, AnyError> { ) -> Result<Vec<(ModuleSpecifier, TestMode)>, AnyError> {
let mut specifiers_with_mode = let maybe_test_config = ps.options.to_test_config()?;
collect_specifiers_with_test_mode(include, ignore, include_inline)?;
let mut include_files = include.clone();
let mut exclude_files = ignore.clone();
if let Some(test_config) = maybe_test_config.as_ref() {
if include_files.is_empty() {
include_files = test_config
.files
.include
.iter()
.map(|s| s.to_string())
.collect::<Vec<_>>();
}
if exclude_files.is_empty() {
exclude_files = test_config
.files
.exclude
.iter()
.filter_map(|s| specifier_to_file_path(s).ok())
.collect::<Vec<_>>();
}
}
if include_files.is_empty() {
include_files.push(".".to_string());
}
let mut specifiers_with_mode = collect_specifiers_with_test_mode(
include_files,
exclude_files,
include_inline,
)?;
for (specifier, mode) in &mut specifiers_with_mode { for (specifier, mode) in &mut specifiers_with_mode {
let file = ps let file = ps
.file_fetcher .file_fetcher
@ -1390,7 +1423,7 @@ pub async fn run_tests(
Permissions::from_options(&ps.options.permissions_options()); Permissions::from_options(&ps.options.permissions_options());
let specifiers_with_mode = fetch_specifiers_with_test_mode( let specifiers_with_mode = fetch_specifiers_with_test_mode(
&ps, &ps,
test_flags.include.unwrap_or_else(|| vec![".".to_string()]), test_flags.include,
test_flags.ignore.clone(), test_flags.ignore.clone(),
test_flags.doc, test_flags.doc,
) )
@ -1434,7 +1467,7 @@ pub async fn run_tests_with_watch(
let permissions = let permissions =
Permissions::from_options(&ps.options.permissions_options()); Permissions::from_options(&ps.options.permissions_options());
let include = test_flags.include.unwrap_or_else(|| vec![".".to_string()]); let include = test_flags.include;
let ignore = test_flags.ignore.clone(); let ignore = test_flags.ignore.clone();
let paths_to_watch: Vec<_> = include.iter().map(PathBuf::from).collect(); let paths_to_watch: Vec<_> = include.iter().map(PathBuf::from).collect();
let no_check = ps.options.type_check_mode() == TypeCheckMode::None; let no_check = ps.options.type_check_mode() == TypeCheckMode::None;