diff --git a/book/src/workspaces.md b/book/src/workspaces.md index b70cf40d..d049ec68 100644 --- a/book/src/workspaces.md +++ b/book/src/workspaces.md @@ -2,11 +2,12 @@ cargo-mutants supports testing Cargo workspaces that contain multiple packages. The entire workspace tree is copied. -By default, all source files in all packages in the workspace are tested. +By default, cargo-mutants has [the same behavior as Cargo](https://doc.rust-lang.org/cargo/reference/workspaces.html): -**NOTE: This behavior is likely to change in future: see .** - -With the `--package` option, only mutants from the package with the given name are testeg. The effect can be seen in `--list`, etc. This option can be repeated. +* If `--workspace` is given, all packages in the workspace are tested. +* If `--package` is given, the named packages are tested. +* If the starting directory (or `-d` directory) is in a package, that package is tested. +* Otherwise, the starting directory must be in a virtual workspace. If it specifies default members, they are tested. Otherwise, all packages are tested. You can use the `--file` options to restrict cargo-mutants to testing only files from some subdirectory, e.g. with `-f "utils/**/*.rs"`. (Remember to quote globs diff --git a/src/main.rs b/src/main.rs index 17b8d202..dafe78b8 100644 --- a/src/main.rs +++ b/src/main.rs @@ -191,6 +191,10 @@ struct Args { #[arg(long, action = clap::ArgAction::SetTrue)] version: bool, + /// test every package in the workspace. + #[arg(long)] + workspace: bool, + /// additional args for all cargo invocations. #[arg(long, short = 'C', allow_hyphen_values = true)] cargo_arg: Vec, @@ -237,8 +241,9 @@ fn main() -> Result<()> { debug!(?options); let package_filter = if !args.mutate_packages.is_empty() { PackageFilter::explicit(&args.mutate_packages) + } else if args.workspace { + PackageFilter::All } else { - // TODO: --workspace to ::All PackageFilter::Auto(start_dir.to_owned()) }; let discovered = workspace.discover(&package_filter, &options, &console)?; diff --git a/src/workspace.rs b/src/workspace.rs index e9147d82..27fa05d3 100644 --- a/src/workspace.rs +++ b/src/workspace.rs @@ -350,10 +350,38 @@ mod test { ); } + #[test] + fn package_filter_all_from_subdir_gets_everything() { + let subdir_path = Utf8Path::new("testdata/tree/workspace/main"); + let workspace = Workspace::open(subdir_path).expect("Find workspace root"); + let packages = workspace.packages(&PackageFilter::All).unwrap(); + assert_eq!( + packages.iter().map(|p| &p.name).collect_vec(), + ["cargo_mutants_testdata_workspace_utils", "main", "main2"] + ); + } + #[test] fn auto_packages_in_workspace_subdir_finds_single_package() { - let workspace = - Workspace::open("testdata/tree/workspace/main").expect("Find workspace root"); + let subdir_path = Utf8Path::new("testdata/tree/workspace/main"); + let workspace = Workspace::open(subdir_path).expect("Find workspace root"); + let packages = workspace + .packages(&PackageFilter::Auto(subdir_path.to_owned())) + .unwrap(); + assert_eq!(packages.iter().map(|p| &p.name).collect_vec(), ["main"]); + } + + #[test] + fn auto_packages_in_virtual_workspace_gets_everything() { + let path = Utf8Path::new("testdata/tree/workspace"); + let workspace = Workspace::open(path).expect("Find workspace root"); + let packages = workspace + .packages(&PackageFilter::Auto(path.to_owned())) + .unwrap(); + assert_eq!( + packages.iter().map(|p| &p.name).collect_vec(), + ["cargo_mutants_testdata_workspace_utils", "main", "main2"] + ); } #[test] diff --git a/tests/cli/workspace.rs b/tests/cli/workspace.rs index 3765d037..4393f65a 100644 --- a/tests/cli/workspace.rs +++ b/tests/cli/workspace.rs @@ -39,7 +39,7 @@ fn list_files_json_workspace() { #[test] fn list_files_as_json_in_workspace_subdir() { run() - .args(["mutants", "--list-files", "--json"]) + .args(["mutants", "--list-files", "--json", "--workspace"]) .current_dir("testdata/tree/workspace/main2") .assert() .stdout(indoc! {r#"