diff --git a/NEWS.md b/NEWS.md index ed5bd2bb..2003a1d1 100644 --- a/NEWS.md +++ b/NEWS.md @@ -6,6 +6,8 @@ - Fixed: `#[mutants::skip]` (and `#[cfg_attr(..., mutants::skip)]`) is now honoured when placed on `const` and `static` items, including associated constants in `impl` and `trait` blocks. Previously the attribute was silently ignored on these items and operator mutants inside the initializer expression were still generated ([#508](https://github.com/sourcefrog/cargo-mutants/issues/508)). +- Fixed: Apply `--re` and `--exclude-re` name filters to struct-field deletion mutants. + - Fixed: Shorter temporary directory names on Windows, to reduce the risk of running into the 260-character path limit. - Fixed: Support for Illumos, by updating to `fs4`. diff --git a/src/visit.rs b/src/visit.rs index d3d9fa8a..ce039d72 100644 --- a/src/visit.rs +++ b/src/visit.rs @@ -442,6 +442,10 @@ impl DiscoveryVisitor<'_> { genre, None, ); + self.push_mutant_if_allowed(mutant); + } + + fn push_mutant_if_allowed(&mut self, mutant: Mutant) { if self.excluded_by_attr_re(&mutant.name) { trace!( name = mutant.name(false), @@ -964,9 +968,7 @@ impl<'ast> Visit<'ast> for DiscoveryVisitor<'_> { struct_name: struct_name.clone(), }), ); - if !v.excluded_by_attr_re(&mutant.name) { - v.mutants.push(mutant); - } + v.push_mutant_if_allowed(mutant); } } } @@ -1997,6 +1999,60 @@ mod test { ); } + fn struct_field_mutant_names(options: &Options) -> Vec { + mutate_source_str( + indoc! {" + fn settings() -> Settings { + Settings { + enabled: true, + count: 1 + 2, + ..Default::default() + } + } + "}, + options, + ) + .unwrap() + .into_iter() + .filter(|mutant| mutant.genre == Genre::StructField) + .map(|mutant| mutant.name(false)) + .collect() + } + + #[test] + fn re_filters_struct_field_mutants() { + let options = Options::from_arg_strs(["mutants", "--re", "delete field enabled"]); + + assert_eq!( + struct_field_mutant_names(&options), + ["src/main.rs: delete field enabled from struct Settings expression in settings"] + ); + } + + #[test] + fn exclude_re_filters_struct_field_mutants() { + let options = Options::from_arg_strs(["mutants", "--exclude-re", "delete field enabled"]); + + assert_eq!( + struct_field_mutant_names(&options), + ["src/main.rs: delete field count from struct Settings expression in settings"] + ); + } + + #[test] + fn nonmatching_exclude_re_doesnt_filter_struct_field_mutants() { + let options = + Options::from_arg_strs(["mutants", "--exclude-re", "this pattern matches no mutant"]); + + assert_eq!( + struct_field_mutant_names(&options), + [ + "src/main.rs: delete field enabled from struct Settings expression in settings", + "src/main.rs: delete field count from struct Settings expression in settings", + ] + ); + } + #[test] fn exclude_re_attr_filters_specific_mutants() { let options = Options::default();