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:
parent
1f04cea160
commit
70d1ecaeaa
15 changed files with 145 additions and 18 deletions
|
@ -397,6 +397,28 @@ pub struct FmtConfig {
|
|||
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)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct ConfigFileJson {
|
||||
|
@ -405,6 +427,7 @@ pub struct ConfigFileJson {
|
|||
pub lint: Option<Value>,
|
||||
pub fmt: Option<Value>,
|
||||
pub tasks: Option<Value>,
|
||||
pub test: Option<Value>,
|
||||
}
|
||||
|
||||
#[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
|
||||
/// of JSON objects providing the name of the task and the arguments of the
|
||||
/// task in a detail field.
|
||||
|
|
|
@ -175,7 +175,7 @@ pub struct TestFlags {
|
|||
pub no_run: bool,
|
||||
pub fail_fast: Option<NonZeroUsize>,
|
||||
pub allow_none: bool,
|
||||
pub include: Option<Vec<String>>,
|
||||
pub include: Vec<String>,
|
||||
pub filter: Option<String>,
|
||||
pub shuffle: Option<u64>,
|
||||
pub concurrent_jobs: NonZeroUsize,
|
||||
|
@ -2682,15 +2682,14 @@ fn test_parse(flags: &mut Flags, matches: &clap::ArgMatches) {
|
|||
NonZeroUsize::new(1).unwrap()
|
||||
};
|
||||
|
||||
let include = if matches.is_present("files") {
|
||||
let files: Vec<String> = matches
|
||||
let include: Vec<String> = if matches.is_present("files") {
|
||||
matches
|
||||
.values_of("files")
|
||||
.unwrap()
|
||||
.map(String::from)
|
||||
.collect();
|
||||
Some(files)
|
||||
.collect::<Vec<_>>()
|
||||
} else {
|
||||
None
|
||||
Vec::new()
|
||||
};
|
||||
|
||||
flags.coverage_dir = matches.value_of("coverage").map(String::from);
|
||||
|
@ -4995,7 +4994,7 @@ mod tests {
|
|||
fail_fast: None,
|
||||
filter: Some("- foo".to_string()),
|
||||
allow_none: true,
|
||||
include: Some(svec!["dir1/", "dir2/"]),
|
||||
include: svec!["dir1/", "dir2/"],
|
||||
ignore: vec![],
|
||||
shuffle: None,
|
||||
concurrent_jobs: NonZeroUsize::new(1).unwrap(),
|
||||
|
@ -5067,7 +5066,7 @@ mod tests {
|
|||
filter: None,
|
||||
allow_none: false,
|
||||
shuffle: None,
|
||||
include: None,
|
||||
include: vec![],
|
||||
ignore: vec![],
|
||||
concurrent_jobs: NonZeroUsize::new(4).unwrap(),
|
||||
trace_ops: false,
|
||||
|
@ -5095,7 +5094,7 @@ mod tests {
|
|||
filter: None,
|
||||
allow_none: false,
|
||||
shuffle: None,
|
||||
include: None,
|
||||
include: vec![],
|
||||
ignore: vec![],
|
||||
concurrent_jobs: NonZeroUsize::new(1).unwrap(),
|
||||
trace_ops: false,
|
||||
|
@ -5127,7 +5126,7 @@ mod tests {
|
|||
filter: None,
|
||||
allow_none: false,
|
||||
shuffle: None,
|
||||
include: None,
|
||||
include: vec![],
|
||||
ignore: vec![],
|
||||
concurrent_jobs: NonZeroUsize::new(1).unwrap(),
|
||||
trace_ops: false,
|
||||
|
@ -5153,7 +5152,7 @@ mod tests {
|
|||
filter: None,
|
||||
allow_none: false,
|
||||
shuffle: Some(1),
|
||||
include: None,
|
||||
include: vec![],
|
||||
ignore: vec![],
|
||||
concurrent_jobs: NonZeroUsize::new(1).unwrap(),
|
||||
trace_ops: false,
|
||||
|
@ -5179,7 +5178,7 @@ mod tests {
|
|||
filter: None,
|
||||
allow_none: false,
|
||||
shuffle: None,
|
||||
include: None,
|
||||
include: vec![],
|
||||
ignore: vec![],
|
||||
concurrent_jobs: NonZeroUsize::new(1).unwrap(),
|
||||
trace_ops: false,
|
||||
|
@ -5206,7 +5205,7 @@ mod tests {
|
|||
filter: None,
|
||||
allow_none: false,
|
||||
shuffle: None,
|
||||
include: None,
|
||||
include: vec![],
|
||||
ignore: vec![],
|
||||
concurrent_jobs: NonZeroUsize::new(1).unwrap(),
|
||||
trace_ops: false,
|
||||
|
|
|
@ -14,6 +14,7 @@ pub use config_file::LintConfig;
|
|||
pub use config_file::LintRulesConfig;
|
||||
pub use config_file::MaybeImportsResult;
|
||||
pub use config_file::ProseWrap;
|
||||
pub use config_file::TestConfig;
|
||||
pub use config_file::TsConfig;
|
||||
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> {
|
||||
if let Some(config) = &self.maybe_config_file {
|
||||
config.to_fmt_config()
|
||||
|
|
|
@ -62,6 +62,24 @@ itest!(collect {
|
|||
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 {
|
||||
args: "test test/short-pass.ts --jobs",
|
||||
exit_code: 0,
|
||||
|
|
4
cli/tests/testdata/test/collect.out
vendored
4
cli/tests/testdata/test/collect.out
vendored
|
@ -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
|
||||
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
|
||||
|
||||
ok | 0 passed | 0 failed ([WILDCARD])
|
||||
|
|
7
cli/tests/testdata/test/collect/deno.jsonc
vendored
Normal file
7
cli/tests/testdata/test/collect/deno.jsonc
vendored
Normal file
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"test": {
|
||||
"files": {
|
||||
"exclude": ["./ignore"]
|
||||
}
|
||||
}
|
||||
}
|
5
cli/tests/testdata/test/collect/deno.malformed.jsonc
vendored
Normal file
5
cli/tests/testdata/test/collect/deno.malformed.jsonc
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"test": {
|
||||
"dont_know_this_field": {}
|
||||
}
|
||||
}
|
8
cli/tests/testdata/test/collect/deno2.jsonc
vendored
Normal file
8
cli/tests/testdata/test/collect/deno2.jsonc
vendored
Normal file
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"test": {
|
||||
"files": {
|
||||
"include": ["./include/"],
|
||||
"exclude": ["./ignore", "./include/2_test.ts"]
|
||||
}
|
||||
}
|
||||
}
|
0
cli/tests/testdata/test/collect/include.ts
vendored
Normal file
0
cli/tests/testdata/test/collect/include.ts
vendored
Normal file
0
cli/tests/testdata/test/collect/include/2_test.ts
vendored
Normal file
0
cli/tests/testdata/test/collect/include/2_test.ts
vendored
Normal file
0
cli/tests/testdata/test/collect/include/test.ts
vendored
Normal file
0
cli/tests/testdata/test/collect/include/test.ts
vendored
Normal file
7
cli/tests/testdata/test/collect2.out
vendored
Normal file
7
cli/tests/testdata/test/collect2.out
vendored
Normal 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])
|
||||
|
4
cli/tests/testdata/test/collect_with_malformed_config.out
vendored
Normal file
4
cli/tests/testdata/test/collect_with_malformed_config.out
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
error: Failed to parse "test" configuration
|
||||
|
||||
Caused by:
|
||||
unknown field `dont_know_this_field`, expected `files`
|
|
@ -70,7 +70,7 @@ pub async fn lint(flags: Flags, lint_flags: LintFlags) -> Result<(), AnyError> {
|
|||
} = lint_flags;
|
||||
// First, prepare final configuration.
|
||||
// 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.
|
||||
let mut include_files = args.clone();
|
||||
let mut exclude_files = ignore.clone();
|
||||
|
|
|
@ -15,6 +15,7 @@ use crate::fmt_errors::format_js_error;
|
|||
use crate::fs_util::collect_specifiers;
|
||||
use crate::fs_util::is_supported_test_ext;
|
||||
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::graph_valid;
|
||||
use crate::located_script_name;
|
||||
|
@ -1363,8 +1364,40 @@ async fn fetch_specifiers_with_test_mode(
|
|||
ignore: Vec<PathBuf>,
|
||||
include_inline: bool,
|
||||
) -> Result<Vec<(ModuleSpecifier, TestMode)>, AnyError> {
|
||||
let mut specifiers_with_mode =
|
||||
collect_specifiers_with_test_mode(include, ignore, include_inline)?;
|
||||
let maybe_test_config = ps.options.to_test_config()?;
|
||||
|
||||
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 {
|
||||
let file = ps
|
||||
.file_fetcher
|
||||
|
@ -1390,7 +1423,7 @@ pub async fn run_tests(
|
|||
Permissions::from_options(&ps.options.permissions_options());
|
||||
let specifiers_with_mode = fetch_specifiers_with_test_mode(
|
||||
&ps,
|
||||
test_flags.include.unwrap_or_else(|| vec![".".to_string()]),
|
||||
test_flags.include,
|
||||
test_flags.ignore.clone(),
|
||||
test_flags.doc,
|
||||
)
|
||||
|
@ -1434,7 +1467,7 @@ pub async fn run_tests_with_watch(
|
|||
let permissions =
|
||||
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 paths_to_watch: Vec<_> = include.iter().map(PathBuf::from).collect();
|
||||
let no_check = ps.options.type_check_mode() == TypeCheckMode::None;
|
||||
|
|
Loading…
Reference in a new issue