From d65b7f163eaf8371bdae2dd88df1a5952ca2afd9 Mon Sep 17 00:00:00 2001 From: Martin Pool Date: Sun, 17 Dec 2023 11:35:47 +1000 Subject: [PATCH 01/11] More binary op mutants --- ..._expected_mutants_for_own_source_tree.snap | 23 + src/visit.rs | 5 + testdata/error_value/src/lib.rs | 10 +- testdata/override_dependency/tests/api.rs | 5 + testdata/patch_dependency/tests/api.rs | 5 + testdata/replace_dependency/tests/api.rs | 5 + .../with_child_directories/src/methods.rs | 3 +- .../src/module/module_methods.rs | 2 + tests/cli/config.rs | 38 +- tests/cli/error_value.rs | 14 +- tests/cli/main.rs | 9 +- ...ts_in_override_dependency_tree_passes.snap | 4 +- ...tants_in_patch_dependency_tree_passes.snap | 4 +- ...ts_in_relative_dependency_tree_passes.snap | 4 +- ...nts_in_replace_dependency_tree_passes.snap | 4 +- .../cli__check_tree_with_mutants_skip.snap | 6 +- ..._error_value_catches_untested_ok_case.snap | 6 +- ...th_error_value_from_command_line_list.snap | 8 +- ..._file_so_error_value_is_not_generated.snap | 6 +- ...est_source_is_not_mutated__caught.txt.snap | 2 + ...li__list_mutants_in_all_trees_as_json.snap | 1736 +++++++++++++++-- ...li__list_mutants_in_all_trees_as_text.snap | 56 +- ...i__list_mutants_in_cfg_attr_test_skip.snap | 2 + ...st_mutants_in_cfg_attr_test_skip_json.snap | 60 + .../cli__list_mutants_json_well_tested.snap | 274 +++ .../cli__list_mutants_regex_filters.snap | 2 + .../cli__list_mutants_regex_filters_json.snap | 60 + .../cli__list_mutants_well_tested.snap | 10 + ...mine_and_exclude_name_filter_combined.snap | 2 + ...tants_well_tested_examine_name_filter.snap | 2 + ...nts_well_tested_exclude_folder_filter.snap | 2 + ...tants_well_tested_exclude_name_filter.snap | 8 + ...de_name_filter_with_files_and_folders.snap | 2 + 33 files changed, 2157 insertions(+), 222 deletions(-) diff --git a/src/snapshots/cargo_mutants__visit__test__expected_mutants_for_own_source_tree.snap b/src/snapshots/cargo_mutants__visit__test__expected_mutants_for_own_source_tree.snap index 8e7577f2..c2e37c07 100644 --- a/src/snapshots/cargo_mutants__visit__test__expected_mutants_for_own_source_tree.snap +++ b/src/snapshots/cargo_mutants__visit__test__expected_mutants_for_own_source_tree.snap @@ -88,8 +88,19 @@ src/console.rs: replace > with == in ::render src/console.rs: replace > with < in ::render src/console.rs: replace > with == in ::render src/console.rs: replace > with < in ::render +src/console.rs: replace - with + in ::render +src/console.rs: replace / with % in ::render +src/console.rs: replace / with * in ::render +src/console.rs: replace * with + in ::render +src/console.rs: replace * with / in ::render src/console.rs: replace > with == in ::render src/console.rs: replace > with < in ::render +src/console.rs: replace * with + in ::render +src/console.rs: replace * with / in ::render +src/console.rs: replace / with % in ::render +src/console.rs: replace / with * in ::render +src/console.rs: replace + with - in ::render +src/console.rs: replace + with * in ::render src/console.rs: replace LabModel::find_scenario_mut -> &mut ScenarioModel with Box::leak(Box::new(Default::default())) src/console.rs: replace == with != in LabModel::find_scenario_mut src/console.rs: replace LabModel::remove_scenario with () @@ -183,6 +194,7 @@ src/in_diff.rs: replace diff_filter -> Result> with Ok(vec![Default: src/in_diff.rs: replace diff_filter -> Result> with Err(::anyhow::anyhow!("mutated!")) src/in_diff.rs: replace check_diff_new_text_matches -> Result<()> with Ok(()) src/in_diff.rs: replace check_diff_new_text_matches -> Result<()> with Err(::anyhow::anyhow!("mutated!")) +src/in_diff.rs: replace - with + in check_diff_new_text_matches src/in_diff.rs: replace != with == in check_diff_new_text_matches src/in_diff.rs: replace strip_patch_path -> &Utf8Path with &Default::default() src/in_diff.rs: replace affected_lines -> Vec with vec![] @@ -197,6 +209,8 @@ src/in_diff.rs: replace > with == in affected_lines src/in_diff.rs: replace > with < in affected_lines src/in_diff.rs: replace < with == in affected_lines src/in_diff.rs: replace < with > in affected_lines +src/in_diff.rs: replace - with + in affected_lines +src/in_diff.rs: replace - with + in affected_lines src/in_diff.rs: replace partial_new_file -> Vec<(usize, &'d str)> with vec![] src/in_diff.rs: replace partial_new_file -> Vec<(usize, &'d str)> with vec![(0, "")] src/in_diff.rs: replace partial_new_file -> Vec<(usize, &'d str)> with vec![(0, "xyzzy")] @@ -206,6 +220,7 @@ src/interrupt.rs: replace install_handler with () src/lab.rs: replace test_mutants -> Result with Ok(Default::default()) src/lab.rs: replace test_mutants -> Result with Err(::anyhow::anyhow!("mutated!")) src/lab.rs: replace == with != in test_mutants +src/lab.rs: replace - with + in test_mutants src/lab.rs: replace == with != in test_mutants src/lab.rs: replace == with != in test_mutants src/lab.rs: replace test_scenario -> Result with Ok(Default::default()) @@ -299,6 +314,8 @@ src/mutate.rs: replace ::serialize -> Result Vec with vec![] src/options.rs: replace join_slices -> Vec with vec![String::new()] src/options.rs: replace join_slices -> Vec with vec!["xyzzy".into()] +src/options.rs: replace + with - in join_slices +src/options.rs: replace + with * in join_slices src/options.rs: replace or_slices -> &'c[T] with Vec::leak(Vec::new()) src/options.rs: replace or_slices -> &'c[T] with Vec::leak(vec![Default::default()]) src/options.rs: replace build_glob_set -> Result> with Ok(None) @@ -462,6 +479,8 @@ src/source.rs: replace SourceFile::path -> &Utf8Path with &Default::default() src/source.rs: replace SourceFile::code -> &str with "" src/source.rs: replace SourceFile::code -> &str with "xyzzy" src/span.rs: replace ::from -> Self with Default::default() +src/span.rs: replace + with - in ::from +src/span.rs: replace + with * in ::from src/span.rs: replace ::fmt -> fmt::Result with Ok(Default::default()) src/span.rs: replace ::fmt -> fmt::Result with Err(::anyhow::anyhow!("mutated!")) src/span.rs: replace Span::quad -> Self with Default::default() @@ -502,6 +521,8 @@ src/span.rs: replace == with != in Span::extract src/span.rs: replace >= with < in Span::extract src/span.rs: replace Span::replace -> String with String::new() src/span.rs: replace Span::replace -> String with "xyzzy".into() +src/span.rs: replace + with - in Span::replace +src/span.rs: replace + with * in Span::replace src/span.rs: replace && with || in Span::replace src/span.rs: replace && with == in Span::replace src/span.rs: replace && with != in Span::replace @@ -611,6 +632,8 @@ src/visit.rs: replace find_mod_source -> Result> with Err(:: src/visit.rs: replace || with && in find_mod_source src/visit.rs: replace || with == in find_mod_source src/visit.rs: replace || with != in find_mod_source +src/visit.rs: replace + with - in find_mod_source +src/visit.rs: replace + with * in find_mod_source src/visit.rs: replace fn_sig_excluded -> bool with true src/visit.rs: replace fn_sig_excluded -> bool with false src/visit.rs: replace attrs_excluded -> bool with true diff --git a/src/visit.rs b/src/visit.rs index 80bc933d..6951cd1d 100644 --- a/src/visit.rs +++ b/src/visit.rs @@ -367,6 +367,11 @@ impl<'ast> Visit<'ast> for DiscoveryVisitor<'_> { BinOp::Gt(_) => vec![quote! { == }, quote! {<}], BinOp::Le(_) => vec![quote! {>}], BinOp::Ge(_) => vec![quote! {<}], + BinOp::Add(_) => vec![quote! {-}, quote! {*}], + BinOp::Sub(_) => vec![quote! {+}], + BinOp::Mul(_) => vec![quote! {+}, quote! {/}], + BinOp::Div(_) => vec![quote! {%}, quote! {*}], + BinOp::Rem(_) => vec![quote! {/}, quote! {+}], _ => { trace!( op = i.op.to_pretty_string(), diff --git a/testdata/error_value/src/lib.rs b/testdata/error_value/src/lib.rs index 8f98395e..0695af16 100644 --- a/testdata/error_value/src/lib.rs +++ b/testdata/error_value/src/lib.rs @@ -1,10 +1,10 @@ use std::result::Result; -pub fn even_is_ok(n: u32) -> Result { - if n % 2 == 0 { +pub fn zero_is_ok(n: u32) -> Result { + if n == 0 { Ok(n) } else { - Err("number is odd") + Err("not zero") } } @@ -30,7 +30,7 @@ mod test { fn bad_test_ignores_error_results() { // A bit contrived but does the job: never checks that // the code passes on values that it should accept. - assert!(even_is_ok(1).is_err()); - assert!(even_is_ok(3).is_err()); + assert!(zero_is_ok(1).is_err()); + assert!(zero_is_ok(3).is_err()); } } diff --git a/testdata/override_dependency/tests/api.rs b/testdata/override_dependency/tests/api.rs index 2a910942..4a56f7cf 100644 --- a/testdata/override_dependency/tests/api.rs +++ b/testdata/override_dependency/tests/api.rs @@ -9,3 +9,8 @@ fn zero_is_even() { fn three_is_not_even() { assert_eq!(is_even(3), false); } + +#[test] +fn two_is_even() { + assert!(is_even(2)); +} diff --git a/testdata/patch_dependency/tests/api.rs b/testdata/patch_dependency/tests/api.rs index 62ccc000..e042487f 100644 --- a/testdata/patch_dependency/tests/api.rs +++ b/testdata/patch_dependency/tests/api.rs @@ -9,3 +9,8 @@ fn zero_is_even() { fn three_is_not_even() { assert_eq!(is_even(3), false); } + +#[test] +fn two_is_even() { + assert!(is_even(2)); +} diff --git a/testdata/replace_dependency/tests/api.rs b/testdata/replace_dependency/tests/api.rs index 663e4b77..094b1efa 100644 --- a/testdata/replace_dependency/tests/api.rs +++ b/testdata/replace_dependency/tests/api.rs @@ -9,3 +9,8 @@ fn zero_is_even() { fn three_is_not_even() { assert_eq!(is_even(3), false); } + +#[test] +fn two_is_even() { + assert!(is_even(2)); +} diff --git a/testdata/with_child_directories/src/methods.rs b/testdata/with_child_directories/src/methods.rs index 5fc756b8..f3de6087 100644 --- a/testdata/with_child_directories/src/methods.rs +++ b/testdata/with_child_directories/src/methods.rs @@ -5,7 +5,8 @@ pub fn double(x: usize) -> usize { #[cfg(test)] mod test { #[test] - fn double() { + fn test_double() { assert_eq!(super::double(2), 4); + assert_eq!(super::double(8), 16); } } diff --git a/testdata/with_child_directories/src/module/module_methods.rs b/testdata/with_child_directories/src/module/module_methods.rs index 5fc756b8..d3c531a5 100644 --- a/testdata/with_child_directories/src/module/module_methods.rs +++ b/testdata/with_child_directories/src/module/module_methods.rs @@ -7,5 +7,7 @@ mod test { #[test] fn double() { assert_eq!(super::double(2), 4); + assert_eq!(super::double(0), 0); + assert_eq!(super::double(6), 12); } } diff --git a/tests/cli/config.rs b/tests/cli/config.rs index 9feb6d95..ba72a970 100644 --- a/tests/cli/config.rs +++ b/tests/cli/config.rs @@ -5,6 +5,7 @@ use std::fs::{create_dir, write}; use indoc::indoc; +use insta::assert_snapshot; use predicates::prelude::*; use tempfile::TempDir; @@ -163,15 +164,20 @@ fn list_with_config_file_regexps() { exclude_re = ["-> bool with true"] "#, ); - run() + let cmd = run() .args(["mutants", "--list", "--line-col=false", "-d"]) .arg(testdata.path()) .assert() - .success() - .stdout(predicates::str::diff(indoc! {"\ - src/simple_fns.rs: replace divisible_by_three -> bool with false - src/simple_fns.rs: replace == with != in divisible_by_three - "})); + .success(); + assert_snapshot!( + String::from_utf8_lossy(&cmd.get_output().stdout), + @r###" + src/simple_fns.rs: replace divisible_by_three -> bool with false + src/simple_fns.rs: replace == with != in divisible_by_three + src/simple_fns.rs: replace % with / in divisible_by_three + src/simple_fns.rs: replace % with + in divisible_by_three + "### + ); } #[test] @@ -180,8 +186,8 @@ fn exclude_re_overrides_config() { write_config_file( &testdata, r#" -exclude_re = [".*"] # would exclude everything -"#, + exclude_re = [".*"] # would exclude everything + "#, ); run() .args(["mutants", "--list", "-d"]) @@ -190,17 +196,21 @@ exclude_re = [".*"] # would exclude everything .success() .stdout(predicates::str::is_empty()); // Also tests that the alias --exclude-regex is accepted - run() + let cmd = run() .args(["mutants", "--list", "--line-col=false", "-d"]) .arg(testdata.path()) .args(["--exclude-regex", " -> "]) .args(["-f", "src/simple_fns.rs"]) .assert() - .success() - .stdout(indoc! {" - src/simple_fns.rs: replace returns_unit with () - src/simple_fns.rs: replace == with != in divisible_by_three - "}); + .success(); + assert_snapshot!( + String::from_utf8_lossy(&cmd.get_output().stdout), + @r###" + src/simple_fns.rs: replace returns_unit with () + src/simple_fns.rs: replace == with != in divisible_by_three + src/simple_fns.rs: replace % with / in divisible_by_three + src/simple_fns.rs: replace % with + in divisible_by_three + "###); } #[test] diff --git a/tests/cli/error_value.rs b/tests/cli/error_value.rs index 8ece316e..306dda01 100644 --- a/tests/cli/error_value.rs +++ b/tests/cli/error_value.rs @@ -22,11 +22,7 @@ fn error_value_catches_untested_ok_case() { .arg(tmp_src_dir.path()) .assert() .code(2) - .stderr("") - .stdout(predicate::function(|stdout| { - insta::assert_snapshot!(stdout); - true - })); + .stderr(""); } #[test] @@ -94,13 +90,7 @@ fn warn_if_error_value_starts_with_err() { .code(0) .stderr(predicate::str::contains( "error_value option gives the value of the error, and probably should not start with Err(: got Err(anyhow!(\"mutant\"))" - )) - .stdout(indoc! { "\ - src/lib.rs:4:5: replace even_is_ok -> Result with Ok(0) - src/lib.rs:4:5: replace even_is_ok -> Result with Ok(1) - src/lib.rs:4:5: replace even_is_ok -> Result with Err(Err(anyhow!(\"mutant\"))) - src/lib.rs:4:14: replace == with != in even_is_ok - " }); + )); } #[test] diff --git a/tests/cli/main.rs b/tests/cli/main.rs index 76d7891c..629cfd9d 100644 --- a/tests/cli/main.rs +++ b/tests/cli/main.rs @@ -908,8 +908,7 @@ fn already_failing_doctests_can_be_skipped_with_cargo_arg() { .current_dir(tmp_src_dir.path()) .env_remove("RUST_BACKTRACE") .assert() - .code(0) - .stdout(contains("Found 2 mutants to test")); + .code(0); } #[test] @@ -1269,8 +1268,7 @@ fn strict_warnings_about_unused_variables_are_disabled_so_mutants_compile() { .current_dir(tmp_src_dir.path()) .env_remove("RUST_BACKTRACE") .assert() - .success() - .stdout(contains("2 mutants tested: 2 succeeded")); + .success(); run() .arg("mutants") @@ -1278,8 +1276,7 @@ fn strict_warnings_about_unused_variables_are_disabled_so_mutants_compile() { .current_dir(tmp_src_dir.path()) .env_remove("RUST_BACKTRACE") .assert() - .success() - .stdout(contains("2 mutants tested: 2 caught")); + .success(); } /// `INSTA_UPDATE=always` in the environment will cause Insta to update diff --git a/tests/cli/snapshots/cli__cargo_mutants_in_override_dependency_tree_passes.snap b/tests/cli/snapshots/cli__cargo_mutants_in_override_dependency_tree_passes.snap index 89489340..ee59c929 100644 --- a/tests/cli/snapshots/cli__cargo_mutants_in_override_dependency_tree_passes.snap +++ b/tests/cli/snapshots/cli__cargo_mutants_in_override_dependency_tree_passes.snap @@ -2,7 +2,7 @@ source: tests/cli/main.rs expression: stdout --- -Found 3 mutants to test +Found 5 mutants to test ok Unmutated baseline -3 mutants tested: 3 caught +5 mutants tested: 5 caught diff --git a/tests/cli/snapshots/cli__cargo_mutants_in_patch_dependency_tree_passes.snap b/tests/cli/snapshots/cli__cargo_mutants_in_patch_dependency_tree_passes.snap index 89489340..ee59c929 100644 --- a/tests/cli/snapshots/cli__cargo_mutants_in_patch_dependency_tree_passes.snap +++ b/tests/cli/snapshots/cli__cargo_mutants_in_patch_dependency_tree_passes.snap @@ -2,7 +2,7 @@ source: tests/cli/main.rs expression: stdout --- -Found 3 mutants to test +Found 5 mutants to test ok Unmutated baseline -3 mutants tested: 3 caught +5 mutants tested: 5 caught diff --git a/tests/cli/snapshots/cli__cargo_mutants_in_relative_dependency_tree_passes.snap b/tests/cli/snapshots/cli__cargo_mutants_in_relative_dependency_tree_passes.snap index 30953faf..fe39b9fd 100644 --- a/tests/cli/snapshots/cli__cargo_mutants_in_relative_dependency_tree_passes.snap +++ b/tests/cli/snapshots/cli__cargo_mutants_in_relative_dependency_tree_passes.snap @@ -2,7 +2,7 @@ source: tests/cli/main.rs expression: stdout --- -Found 4 mutants to test +Found 6 mutants to test ok Unmutated baseline -4 mutants tested: 4 caught +6 mutants tested: 6 caught diff --git a/tests/cli/snapshots/cli__cargo_mutants_in_replace_dependency_tree_passes.snap b/tests/cli/snapshots/cli__cargo_mutants_in_replace_dependency_tree_passes.snap index 89489340..ee59c929 100644 --- a/tests/cli/snapshots/cli__cargo_mutants_in_replace_dependency_tree_passes.snap +++ b/tests/cli/snapshots/cli__cargo_mutants_in_replace_dependency_tree_passes.snap @@ -2,7 +2,7 @@ source: tests/cli/main.rs expression: stdout --- -Found 3 mutants to test +Found 5 mutants to test ok Unmutated baseline -3 mutants tested: 3 caught +5 mutants tested: 5 caught diff --git a/tests/cli/snapshots/cli__check_tree_with_mutants_skip.snap b/tests/cli/snapshots/cli__check_tree_with_mutants_skip.snap index aa44dbcc..ce12f6d2 100644 --- a/tests/cli/snapshots/cli__check_tree_with_mutants_skip.snap +++ b/tests/cli/snapshots/cli__check_tree_with_mutants_skip.snap @@ -2,10 +2,12 @@ source: tests/cli/main.rs expression: stdout --- -Found 3 mutants to test +Found 5 mutants to test ok Unmutated baseline ok src/lib.rs:15:5: replace controlled_loop with () ok src/lib.rs:21:28: replace > with == in controlled_loop ok src/lib.rs:21:28: replace > with < in controlled_loop -3 mutants tested: 3 succeeded +ok src/lib.rs:21:53: replace * with + in controlled_loop +ok src/lib.rs:21:53: replace * with / in controlled_loop +5 mutants tested: 5 succeeded diff --git a/tests/cli/snapshots/cli__error_value__error_value_catches_untested_ok_case.snap b/tests/cli/snapshots/cli__error_value__error_value_catches_untested_ok_case.snap index 1bd7aaa5..9cf18e24 100644 --- a/tests/cli/snapshots/cli__error_value__error_value_catches_untested_ok_case.snap +++ b/tests/cli/snapshots/cli__error_value__error_value_catches_untested_ok_case.snap @@ -2,11 +2,13 @@ source: tests/cli/error_value.rs expression: stdout --- -Found 4 mutants to test +Found 6 mutants to test ok Unmutated baseline caught src/lib.rs:4:5: replace even_is_ok -> Result with Ok(0) caught src/lib.rs:4:5: replace even_is_ok -> Result with Ok(1) MISSED src/lib.rs:4:5: replace even_is_ok -> Result with Err("injected") caught src/lib.rs:4:14: replace == with != in even_is_ok -4 mutants tested: 1 missed, 3 caught +caught src/lib.rs:4:10: replace % with / in even_is_ok +MISSED src/lib.rs:4:10: replace % with + in even_is_ok +6 mutants tested: 2 missed, 4 caught diff --git a/tests/cli/snapshots/cli__error_value__list_mutants_with_error_value_from_command_line_list.snap b/tests/cli/snapshots/cli__error_value__list_mutants_with_error_value_from_command_line_list.snap index 424d11c0..810adde9 100644 --- a/tests/cli/snapshots/cli__error_value__list_mutants_with_error_value_from_command_line_list.snap +++ b/tests/cli/snapshots/cli__error_value__list_mutants_with_error_value_from_command_line_list.snap @@ -2,8 +2,8 @@ source: tests/cli/error_value.rs expression: stdout --- -src/lib.rs:4:5: replace even_is_ok -> Result with Ok(0) -src/lib.rs:4:5: replace even_is_ok -> Result with Ok(1) -src/lib.rs:4:5: replace even_is_ok -> Result with Err(::eyre::eyre!("mutant")) -src/lib.rs:4:14: replace == with != in even_is_ok +src/lib.rs:4:5: replace zero_is_ok -> Result with Ok(0) +src/lib.rs:4:5: replace zero_is_ok -> Result with Ok(1) +src/lib.rs:4:5: replace zero_is_ok -> Result with Err(::eyre::eyre!("mutant")) +src/lib.rs:4:10: replace == with != in zero_is_ok diff --git a/tests/cli/snapshots/cli__error_value__no_config_option_disables_config_file_so_error_value_is_not_generated.snap b/tests/cli/snapshots/cli__error_value__no_config_option_disables_config_file_so_error_value_is_not_generated.snap index 9a56eda8..246223e8 100644 --- a/tests/cli/snapshots/cli__error_value__no_config_option_disables_config_file_so_error_value_is_not_generated.snap +++ b/tests/cli/snapshots/cli__error_value__no_config_option_disables_config_file_so_error_value_is_not_generated.snap @@ -4,8 +4,8 @@ expression: stdout --- Found 3 mutants to test ok Unmutated baseline -caught src/lib.rs:4:5: replace even_is_ok -> Result with Ok(0) -caught src/lib.rs:4:5: replace even_is_ok -> Result with Ok(1) -caught src/lib.rs:4:14: replace == with != in even_is_ok +caught src/lib.rs:4:5: replace zero_is_ok -> Result with Ok(0) +caught src/lib.rs:4:5: replace zero_is_ok -> Result with Ok(1) +caught src/lib.rs:4:10: replace == with != in zero_is_ok 3 mutants tested: 3 caught diff --git a/tests/cli/snapshots/cli__integration_test_source_is_not_mutated__caught.txt.snap b/tests/cli/snapshots/cli__integration_test_source_is_not_mutated__caught.txt.snap index 22db05b6..bb26175f 100644 --- a/tests/cli/snapshots/cli__integration_test_source_is_not_mutated__caught.txt.snap +++ b/tests/cli/snapshots/cli__integration_test_source_is_not_mutated__caught.txt.snap @@ -4,4 +4,6 @@ expression: content --- src/lib.rs:2:5: replace double -> u32 with 0 src/lib.rs:2:5: replace double -> u32 with 1 +src/lib.rs:2:7: replace * with + in double +src/lib.rs:2:7: replace * with / in double diff --git a/tests/cli/snapshots/cli__list_mutants_in_all_trees_as_json.snap b/tests/cli/snapshots/cli__list_mutants_in_all_trees_as_json.snap index 3e77f81b..8500ee5c 100644 --- a/tests/cli/snapshots/cli__list_mutants_in_all_trees_as_json.snap +++ b/tests/cli/snapshots/cli__list_mutants_in_all_trees_as_json.snap @@ -65,6 +65,66 @@ expression: buf "line": 10 } } + }, + { + "file": "src/lib.rs", + "function": { + "function_name": "takes_one_arg", + "return_type": "-> usize", + "span": { + "end": { + "column": 2, + "line": 11 + }, + "start": { + "column": 1, + "line": 1 + } + } + }, + "genre": "BinaryOperator", + "package": "mutants-testdata-already-failing-doctests", + "replacement": "-", + "span": { + "end": { + "column": 8, + "line": 10 + }, + "start": { + "column": 7, + "line": 10 + } + } + }, + { + "file": "src/lib.rs", + "function": { + "function_name": "takes_one_arg", + "return_type": "-> usize", + "span": { + "end": { + "column": 2, + "line": 11 + }, + "start": { + "column": 1, + "line": 1 + } + } + }, + "genre": "BinaryOperator", + "package": "mutants-testdata-already-failing-doctests", + "replacement": "*", + "span": { + "end": { + "column": 8, + "line": 10 + }, + "start": { + "column": 7, + "line": 10 + } + } } ] ``` @@ -309,6 +369,66 @@ expression: buf "line": 18 } } + }, + { + "file": "src/lib.rs", + "function": { + "function_name": "double", + "return_type": "-> usize", + "span": { + "end": { + "column": 2, + "line": 19 + }, + "start": { + "column": 1, + "line": 16 + } + } + }, + "genre": "BinaryOperator", + "package": "cargo-mutants-testdata-cfg-attr-test-skip", + "replacement": "+", + "span": { + "end": { + "column": 8, + "line": 18 + }, + "start": { + "column": 7, + "line": 18 + } + } + }, + { + "file": "src/lib.rs", + "function": { + "function_name": "double", + "return_type": "-> usize", + "span": { + "end": { + "column": 2, + "line": 19 + }, + "start": { + "column": 1, + "line": 16 + } + } + }, + "genre": "BinaryOperator", + "package": "cargo-mutants-testdata-cfg-attr-test-skip", + "replacement": "/", + "span": { + "end": { + "column": 8, + "line": 18 + }, + "start": { + "column": 7, + "line": 18 + } + } } ] ``` @@ -406,6 +526,66 @@ expression: buf "line": 2 } } + }, + { + "file": "src/custom_top.rs", + "function": { + "function_name": "is_even", + "return_type": "-> bool", + "span": { + "end": { + "column": 2, + "line": 3 + }, + "start": { + "column": 1, + "line": 1 + } + } + }, + "genre": "BinaryOperator", + "package": "cargo-mutants-testdata-custom-top-file", + "replacement": "/", + "span": { + "end": { + "column": 8, + "line": 2 + }, + "start": { + "column": 7, + "line": 2 + } + } + }, + { + "file": "src/custom_top.rs", + "function": { + "function_name": "is_even", + "return_type": "-> bool", + "span": { + "end": { + "column": 2, + "line": 3 + }, + "start": { + "column": 1, + "line": 1 + } + } + }, + "genre": "BinaryOperator", + "package": "cargo-mutants-testdata-custom-top-file", + "replacement": "+", + "span": { + "end": { + "column": 8, + "line": 2 + }, + "start": { + "column": 7, + "line": 2 + } + } } ] ``` @@ -678,7 +858,7 @@ expression: buf { "file": "src/lib.rs", "function": { - "function_name": "even_is_ok", + "function_name": "zero_is_ok", "return_type": "-> Result", "span": { "end": { @@ -708,7 +888,7 @@ expression: buf { "file": "src/lib.rs", "function": { - "function_name": "even_is_ok", + "function_name": "zero_is_ok", "return_type": "-> Result", "span": { "end": { @@ -738,7 +918,7 @@ expression: buf { "file": "src/lib.rs", "function": { - "function_name": "even_is_ok", + "function_name": "zero_is_ok", "return_type": "-> Result", "span": { "end": { @@ -768,7 +948,7 @@ expression: buf { "file": "src/lib.rs", "function": { - "function_name": "even_is_ok", + "function_name": "zero_is_ok", "return_type": "-> Result", "span": { "end": { @@ -786,11 +966,11 @@ expression: buf "replacement": "!=", "span": { "end": { - "column": 16, + "column": 12, "line": 4 }, "start": { - "column": 14, + "column": 10, "line": 4 } } @@ -1061,6 +1241,66 @@ expression: buf "line": 21 } } + }, + { + "file": "src/lib.rs", + "function": { + "function_name": "controlled_loop", + "return_type": "", + "span": { + "end": { + "column": 2, + "line": 25 + }, + "start": { + "column": 1, + "line": 14 + } + } + }, + "genre": "BinaryOperator", + "package": "cargo-mutants-testdata-hang-avoided-by-attr", + "replacement": "+", + "span": { + "end": { + "column": 54, + "line": 21 + }, + "start": { + "column": 53, + "line": 21 + } + } + }, + { + "file": "src/lib.rs", + "function": { + "function_name": "controlled_loop", + "return_type": "", + "span": { + "end": { + "column": 2, + "line": 25 + }, + "start": { + "column": 1, + "line": 14 + } + } + }, + "genre": "BinaryOperator", + "package": "cargo-mutants-testdata-hang-avoided-by-attr", + "replacement": "/", + "span": { + "end": { + "column": 54, + "line": 21 + }, + "start": { + "column": 53, + "line": 21 + } + } } ] ``` @@ -1248,49 +1488,109 @@ expression: buf "line": 33 } } - } -] -``` - -## testdata/insta - -```json -[ + }, { "file": "src/lib.rs", "function": { - "function_name": "say_hello", - "return_type": "-> String", + "function_name": "controlled_loop", + "return_type": "-> usize", "span": { "end": { "column": 2, - "line": 3 + "line": 38 }, "start": { "column": 1, - "line": 1 + "line": 20 } } }, - "genre": "FnValue", - "package": "cargo-mutants-testdata-insta", - "replacement": "String::new()", + "genre": "BinaryOperator", + "package": "cargo-mutants-testdata-hang-when-mutated", + "replacement": "+", "span": { "end": { - "column": 30, - "line": 2 + "column": 54, + "line": 33 }, "start": { - "column": 5, - "line": 2 + "column": 53, + "line": 33 } } }, { "file": "src/lib.rs", "function": { - "function_name": "say_hello", - "return_type": "-> String", + "function_name": "controlled_loop", + "return_type": "-> usize", + "span": { + "end": { + "column": 2, + "line": 38 + }, + "start": { + "column": 1, + "line": 20 + } + } + }, + "genre": "BinaryOperator", + "package": "cargo-mutants-testdata-hang-when-mutated", + "replacement": "/", + "span": { + "end": { + "column": 54, + "line": 33 + }, + "start": { + "column": 53, + "line": 33 + } + } + } +] +``` + +## testdata/insta + +```json +[ + { + "file": "src/lib.rs", + "function": { + "function_name": "say_hello", + "return_type": "-> String", + "span": { + "end": { + "column": 2, + "line": 3 + }, + "start": { + "column": 1, + "line": 1 + } + } + }, + "genre": "FnValue", + "package": "cargo-mutants-testdata-insta", + "replacement": "String::new()", + "span": { + "end": { + "column": 30, + "line": 2 + }, + "start": { + "column": 5, + "line": 2 + } + } + }, + { + "file": "src/lib.rs", + "function": { + "function_name": "say_hello", + "return_type": "-> String", "span": { "end": { "column": 2, @@ -1382,6 +1682,66 @@ expression: buf "line": 2 } } + }, + { + "file": "src/lib.rs", + "function": { + "function_name": "double", + "return_type": "-> u32", + "span": { + "end": { + "column": 2, + "line": 3 + }, + "start": { + "column": 1, + "line": 1 + } + } + }, + "genre": "BinaryOperator", + "package": "cargo-mutants-testdata-integration-tests", + "replacement": "+", + "span": { + "end": { + "column": 8, + "line": 2 + }, + "start": { + "column": 7, + "line": 2 + } + } + }, + { + "file": "src/lib.rs", + "function": { + "function_name": "double", + "return_type": "-> u32", + "span": { + "end": { + "column": 2, + "line": 3 + }, + "start": { + "column": 1, + "line": 1 + } + } + }, + "genre": "BinaryOperator", + "package": "cargo-mutants-testdata-integration-tests", + "replacement": "/", + "span": { + "end": { + "column": 8, + "line": 2 + }, + "start": { + "column": 7, + "line": 2 + } + } } ] ``` @@ -1746,6 +2106,66 @@ expression: buf "line": 7 } } + }, + { + "file": "src/lib.rs", + "function": { + "function_name": "is_even", + "return_type": "-> bool", + "span": { + "end": { + "column": 2, + "line": 8 + }, + "start": { + "column": 1, + "line": 6 + } + } + }, + "genre": "BinaryOperator", + "package": "cargo-mutants-testdata-override-dependency", + "replacement": "/", + "span": { + "end": { + "column": 8, + "line": 7 + }, + "start": { + "column": 7, + "line": 7 + } + } + }, + { + "file": "src/lib.rs", + "function": { + "function_name": "is_even", + "return_type": "-> bool", + "span": { + "end": { + "column": 2, + "line": 8 + }, + "start": { + "column": 1, + "line": 6 + } + } + }, + "genre": "BinaryOperator", + "package": "cargo-mutants-testdata-override-dependency", + "replacement": "+", + "span": { + "end": { + "column": 8, + "line": 7 + }, + "start": { + "column": 7, + "line": 7 + } + } } ] ``` @@ -1815,7 +2235,7 @@ expression: buf } }, { - "file": "passing/src/lib.rs", + "file": "failing/src/lib.rs", "function": { "function_name": "triple", "return_type": "-> usize", @@ -1830,22 +2250,22 @@ expression: buf } } }, - "genre": "FnValue", - "package": "cargo-mutants-testdata-package-fails-passing", - "replacement": "0", + "genre": "BinaryOperator", + "package": "cargo-mutants-testdata-package-fails-failing", + "replacement": "+", "span": { "end": { - "column": 10, + "column": 8, "line": 2 }, "start": { - "column": 5, + "column": 7, "line": 2 } } }, { - "file": "passing/src/lib.rs", + "file": "failing/src/lib.rs", "function": { "function_name": "triple", "return_type": "-> usize", @@ -1860,100 +2280,220 @@ expression: buf } } }, - "genre": "FnValue", - "package": "cargo-mutants-testdata-package-fails-passing", - "replacement": "1", + "genre": "BinaryOperator", + "package": "cargo-mutants-testdata-package-fails-failing", + "replacement": "/", "span": { "end": { - "column": 10, + "column": 8, "line": 2 }, "start": { - "column": 5, + "column": 7, "line": 2 } } - } -] -``` - -## testdata/patch_dependency - -```json -[ + }, { - "file": "src/lib.rs", + "file": "passing/src/lib.rs", "function": { - "function_name": "is_even", - "return_type": "-> bool", + "function_name": "triple", + "return_type": "-> usize", "span": { "end": { "column": 2, - "line": 8 + "line": 3 }, "start": { "column": 1, - "line": 6 + "line": 1 } } }, "genre": "FnValue", - "package": "cargo-mutants-testdata-patch-dependency", - "replacement": "true", + "package": "cargo-mutants-testdata-package-fails-passing", + "replacement": "0", "span": { "end": { - "column": 15, - "line": 7 + "column": 10, + "line": 2 }, "start": { "column": 5, - "line": 7 + "line": 2 } } }, { - "file": "src/lib.rs", + "file": "passing/src/lib.rs", "function": { - "function_name": "is_even", - "return_type": "-> bool", + "function_name": "triple", + "return_type": "-> usize", "span": { "end": { "column": 2, - "line": 8 + "line": 3 }, "start": { "column": 1, - "line": 6 + "line": 1 } } }, "genre": "FnValue", - "package": "cargo-mutants-testdata-patch-dependency", - "replacement": "false", + "package": "cargo-mutants-testdata-package-fails-passing", + "replacement": "1", "span": { "end": { - "column": 15, - "line": 7 + "column": 10, + "line": 2 }, "start": { "column": 5, - "line": 7 + "line": 2 } } }, { - "file": "src/lib.rs", + "file": "passing/src/lib.rs", "function": { - "function_name": "is_even", - "return_type": "-> bool", + "function_name": "triple", + "return_type": "-> usize", "span": { "end": { "column": 2, - "line": 8 + "line": 3 }, "start": { "column": 1, - "line": 6 + "line": 1 + } + } + }, + "genre": "BinaryOperator", + "package": "cargo-mutants-testdata-package-fails-passing", + "replacement": "+", + "span": { + "end": { + "column": 8, + "line": 2 + }, + "start": { + "column": 7, + "line": 2 + } + } + }, + { + "file": "passing/src/lib.rs", + "function": { + "function_name": "triple", + "return_type": "-> usize", + "span": { + "end": { + "column": 2, + "line": 3 + }, + "start": { + "column": 1, + "line": 1 + } + } + }, + "genre": "BinaryOperator", + "package": "cargo-mutants-testdata-package-fails-passing", + "replacement": "/", + "span": { + "end": { + "column": 8, + "line": 2 + }, + "start": { + "column": 7, + "line": 2 + } + } + } +] +``` + +## testdata/patch_dependency + +```json +[ + { + "file": "src/lib.rs", + "function": { + "function_name": "is_even", + "return_type": "-> bool", + "span": { + "end": { + "column": 2, + "line": 8 + }, + "start": { + "column": 1, + "line": 6 + } + } + }, + "genre": "FnValue", + "package": "cargo-mutants-testdata-patch-dependency", + "replacement": "true", + "span": { + "end": { + "column": 15, + "line": 7 + }, + "start": { + "column": 5, + "line": 7 + } + } + }, + { + "file": "src/lib.rs", + "function": { + "function_name": "is_even", + "return_type": "-> bool", + "span": { + "end": { + "column": 2, + "line": 8 + }, + "start": { + "column": 1, + "line": 6 + } + } + }, + "genre": "FnValue", + "package": "cargo-mutants-testdata-patch-dependency", + "replacement": "false", + "span": { + "end": { + "column": 15, + "line": 7 + }, + "start": { + "column": 5, + "line": 7 + } + } + }, + { + "file": "src/lib.rs", + "function": { + "function_name": "is_even", + "return_type": "-> bool", + "span": { + "end": { + "column": 2, + "line": 8 + }, + "start": { + "column": 1, + "line": 6 } } }, @@ -1970,6 +2510,66 @@ expression: buf "line": 7 } } + }, + { + "file": "src/lib.rs", + "function": { + "function_name": "is_even", + "return_type": "-> bool", + "span": { + "end": { + "column": 2, + "line": 8 + }, + "start": { + "column": 1, + "line": 6 + } + } + }, + "genre": "BinaryOperator", + "package": "cargo-mutants-testdata-patch-dependency", + "replacement": "/", + "span": { + "end": { + "column": 8, + "line": 7 + }, + "start": { + "column": 7, + "line": 7 + } + } + }, + { + "file": "src/lib.rs", + "function": { + "function_name": "is_even", + "return_type": "-> bool", + "span": { + "end": { + "column": 2, + "line": 8 + }, + "start": { + "column": 1, + "line": 6 + } + } + }, + "genre": "BinaryOperator", + "package": "cargo-mutants-testdata-patch-dependency", + "replacement": "+", + "span": { + "end": { + "column": 8, + "line": 7 + }, + "start": { + "column": 7, + "line": 7 + } + } } ] ``` @@ -2097,6 +2697,66 @@ expression: buf "line": 6 } } + }, + { + "file": "src/lib.rs", + "function": { + "function_name": "double_factorial", + "return_type": "-> u32", + "span": { + "end": { + "column": 2, + "line": 10 + }, + "start": { + "column": 1, + "line": 5 + } + } + }, + "genre": "BinaryOperator", + "package": "cargo-mutants-testdata-relative-dependency", + "replacement": "+", + "span": { + "end": { + "column": 8, + "line": 9 + }, + "start": { + "column": 7, + "line": 9 + } + } + }, + { + "file": "src/lib.rs", + "function": { + "function_name": "double_factorial", + "return_type": "-> u32", + "span": { + "end": { + "column": 2, + "line": 10 + }, + "start": { + "column": 1, + "line": 5 + } + } + }, + "genre": "BinaryOperator", + "package": "cargo-mutants-testdata-relative-dependency", + "replacement": "/", + "span": { + "end": { + "column": 8, + "line": 9 + }, + "start": { + "column": 7, + "line": 9 + } + } } ] ``` @@ -2194,6 +2854,66 @@ expression: buf "line": 7 } } + }, + { + "file": "src/lib.rs", + "function": { + "function_name": "is_even", + "return_type": "-> bool", + "span": { + "end": { + "column": 2, + "line": 8 + }, + "start": { + "column": 1, + "line": 6 + } + } + }, + "genre": "BinaryOperator", + "package": "cargo-mutants-testdata-replace-dependency", + "replacement": "/", + "span": { + "end": { + "column": 8, + "line": 7 + }, + "start": { + "column": 7, + "line": 7 + } + } + }, + { + "file": "src/lib.rs", + "function": { + "function_name": "is_even", + "return_type": "-> bool", + "span": { + "end": { + "column": 2, + "line": 8 + }, + "start": { + "column": 1, + "line": 6 + } + } + }, + "genre": "BinaryOperator", + "package": "cargo-mutants-testdata-replace-dependency", + "replacement": "+", + "span": { + "end": { + "column": 8, + "line": 7 + }, + "start": { + "column": 7, + "line": 7 + } + } } ] ``` @@ -2261,14 +2981,74 @@ expression: buf "line": 5 } } - } -] -``` - -## testdata/strict_warnings - -```json -[ + } +] +``` + +## testdata/strict_warnings + +```json +[ + { + "file": "src/lib.rs", + "function": { + "function_name": "some_fn", + "return_type": "-> usize", + "span": { + "end": { + "column": 2, + "line": 7 + }, + "start": { + "column": 1, + "line": 5 + } + } + }, + "genre": "FnValue", + "package": "cargo-mutants-testdata-strict-warnings", + "replacement": "0", + "span": { + "end": { + "column": 10, + "line": 6 + }, + "start": { + "column": 5, + "line": 6 + } + } + }, + { + "file": "src/lib.rs", + "function": { + "function_name": "some_fn", + "return_type": "-> usize", + "span": { + "end": { + "column": 2, + "line": 7 + }, + "start": { + "column": 1, + "line": 5 + } + } + }, + "genre": "FnValue", + "package": "cargo-mutants-testdata-strict-warnings", + "replacement": "1", + "span": { + "end": { + "column": 10, + "line": 6 + }, + "start": { + "column": 5, + "line": 6 + } + } + }, { "file": "src/lib.rs", "function": { @@ -2285,16 +3065,16 @@ expression: buf } } }, - "genre": "FnValue", + "genre": "BinaryOperator", "package": "cargo-mutants-testdata-strict-warnings", - "replacement": "0", + "replacement": "-", "span": { "end": { - "column": 10, + "column": 8, "line": 6 }, "start": { - "column": 5, + "column": 7, "line": 6 } } @@ -2315,16 +3095,16 @@ expression: buf } } }, - "genre": "FnValue", + "genre": "BinaryOperator", "package": "cargo-mutants-testdata-strict-warnings", - "replacement": "1", + "replacement": "*", "span": { "end": { - "column": 10, + "column": 8, "line": 6 }, "start": { - "column": 5, + "column": 7, "line": 6 } } @@ -2499,6 +3279,66 @@ expression: buf "line": 6 } } + }, + { + "file": "src/lib.rs", + "function": { + "function_name": "try_value_coercion", + "return_type": "-> String", + "span": { + "end": { + "column": 2, + "line": 7 + }, + "start": { + "column": 1, + "line": 5 + } + } + }, + "genre": "BinaryOperator", + "package": "mutants-testdata-typecheck-fails", + "replacement": "-", + "span": { + "end": { + "column": 10, + "line": 6 + }, + "start": { + "column": 9, + "line": 6 + } + } + }, + { + "file": "src/lib.rs", + "function": { + "function_name": "try_value_coercion", + "return_type": "-> String", + "span": { + "end": { + "column": 2, + "line": 7 + }, + "start": { + "column": 1, + "line": 5 + } + } + }, + "genre": "BinaryOperator", + "package": "mutants-testdata-typecheck-fails", + "replacement": "*", + "span": { + "end": { + "column": 10, + "line": 6 + }, + "start": { + "column": 9, + "line": 6 + } + } } ] ``` @@ -3030,6 +3870,66 @@ expression: buf } } }, + { + "file": "src/nested_function.rs", + "function": { + "function_name": "has_nested", + "return_type": "-> u32", + "span": { + "end": { + "column": 2, + "line": 6 + }, + "start": { + "column": 1, + "line": 1 + } + } + }, + "genre": "BinaryOperator", + "package": "cargo-mutants-testdata-well-tested", + "replacement": "+", + "span": { + "end": { + "column": 14, + "line": 5 + }, + "start": { + "column": 13, + "line": 5 + } + } + }, + { + "file": "src/nested_function.rs", + "function": { + "function_name": "has_nested", + "return_type": "-> u32", + "span": { + "end": { + "column": 2, + "line": 6 + }, + "start": { + "column": 1, + "line": 1 + } + } + }, + "genre": "BinaryOperator", + "package": "cargo-mutants-testdata-well-tested", + "replacement": "/", + "span": { + "end": { + "column": 14, + "line": 5 + }, + "start": { + "column": 13, + "line": 5 + } + } + }, { "file": "src/numbers.rs", "function": { @@ -3072,51 +3972,171 @@ expression: buf }, "start": { "column": 1, - "line": 1 + "line": 1 + } + } + }, + "genre": "FnValue", + "package": "cargo-mutants-testdata-well-tested", + "replacement": "1.0", + "span": { + "end": { + "column": 12, + "line": 2 + }, + "start": { + "column": 5, + "line": 2 + } + } + }, + { + "file": "src/numbers.rs", + "function": { + "function_name": "double_float", + "return_type": "-> f32", + "span": { + "end": { + "column": 2, + "line": 3 + }, + "start": { + "column": 1, + "line": 1 + } + } + }, + "genre": "FnValue", + "package": "cargo-mutants-testdata-well-tested", + "replacement": "-1.0", + "span": { + "end": { + "column": 12, + "line": 2 + }, + "start": { + "column": 5, + "line": 2 + } + } + }, + { + "file": "src/numbers.rs", + "function": { + "function_name": "double_float", + "return_type": "-> f32", + "span": { + "end": { + "column": 2, + "line": 3 + }, + "start": { + "column": 1, + "line": 1 + } + } + }, + "genre": "BinaryOperator", + "package": "cargo-mutants-testdata-well-tested", + "replacement": "+", + "span": { + "end": { + "column": 10, + "line": 2 + }, + "start": { + "column": 9, + "line": 2 + } + } + }, + { + "file": "src/numbers.rs", + "function": { + "function_name": "double_float", + "return_type": "-> f32", + "span": { + "end": { + "column": 2, + "line": 3 + }, + "start": { + "column": 1, + "line": 1 + } + } + }, + "genre": "BinaryOperator", + "package": "cargo-mutants-testdata-well-tested", + "replacement": "/", + "span": { + "end": { + "column": 10, + "line": 2 + }, + "start": { + "column": 9, + "line": 2 + } + } + }, + { + "file": "src/numbers.rs", + "function": { + "function_name": "is_double", + "return_type": "-> bool", + "span": { + "end": { + "column": 2, + "line": 7 + }, + "start": { + "column": 1, + "line": 5 } } }, "genre": "FnValue", "package": "cargo-mutants-testdata-well-tested", - "replacement": "1.0", + "replacement": "true", "span": { "end": { - "column": 12, - "line": 2 + "column": 15, + "line": 6 }, "start": { "column": 5, - "line": 2 + "line": 6 } } }, { "file": "src/numbers.rs", "function": { - "function_name": "double_float", - "return_type": "-> f32", + "function_name": "is_double", + "return_type": "-> bool", "span": { "end": { "column": 2, - "line": 3 + "line": 7 }, "start": { "column": 1, - "line": 1 + "line": 5 } } }, "genre": "FnValue", "package": "cargo-mutants-testdata-well-tested", - "replacement": "-1.0", + "replacement": "false", "span": { "end": { - "column": 12, - "line": 2 + "column": 15, + "line": 6 }, "start": { "column": 5, - "line": 2 + "line": 6 } } }, @@ -3136,16 +4156,16 @@ expression: buf } } }, - "genre": "FnValue", + "genre": "BinaryOperator", "package": "cargo-mutants-testdata-well-tested", - "replacement": "true", + "replacement": "!=", "span": { "end": { - "column": 15, + "column": 9, "line": 6 }, "start": { - "column": 5, + "column": 7, "line": 6 } } @@ -3166,16 +4186,16 @@ expression: buf } } }, - "genre": "FnValue", + "genre": "BinaryOperator", "package": "cargo-mutants-testdata-well-tested", - "replacement": "false", + "replacement": "+", "span": { "end": { - "column": 15, + "column": 13, "line": 6 }, "start": { - "column": 5, + "column": 12, "line": 6 } } @@ -3198,14 +4218,14 @@ expression: buf }, "genre": "BinaryOperator", "package": "cargo-mutants-testdata-well-tested", - "replacement": "!=", + "replacement": "/", "span": { "end": { - "column": 9, + "column": 13, "line": 6 }, "start": { - "column": 7, + "column": 12, "line": 6 } } @@ -3660,6 +4680,66 @@ expression: buf } } }, + { + "file": "src/simple_fns.rs", + "function": { + "function_name": "divisible_by_three", + "return_type": "-> bool", + "span": { + "end": { + "column": 2, + "line": 19 + }, + "start": { + "column": 1, + "line": 16 + } + } + }, + "genre": "BinaryOperator", + "package": "cargo-mutants-testdata-well-tested", + "replacement": "/", + "span": { + "end": { + "column": 8, + "line": 18 + }, + "start": { + "column": 7, + "line": 18 + } + } + }, + { + "file": "src/simple_fns.rs", + "function": { + "function_name": "divisible_by_three", + "return_type": "-> bool", + "span": { + "end": { + "column": 2, + "line": 19 + }, + "start": { + "column": 1, + "line": 16 + } + } + }, + "genre": "BinaryOperator", + "package": "cargo-mutants-testdata-well-tested", + "replacement": "+", + "span": { + "end": { + "column": 8, + "line": 18 + }, + "start": { + "column": 7, + "line": 18 + } + } + }, { "file": "src/simple_fns.rs", "function": { @@ -4037,6 +5117,40 @@ expression: buf } } }, + { + "file": "src/static_item.rs", + "function": null, + "genre": "BinaryOperator", + "package": "cargo-mutants-testdata-well-tested", + "replacement": "-", + "span": { + "end": { + "column": 40, + "line": 1 + }, + "start": { + "column": 39, + "line": 1 + } + } + }, + { + "file": "src/static_item.rs", + "function": null, + "genre": "BinaryOperator", + "package": "cargo-mutants-testdata-well-tested", + "replacement": "*", + "span": { + "end": { + "column": 40, + "line": 1 + }, + "start": { + "column": 39, + "line": 1 + } + } + }, { "file": "src/struct_with_lifetime.rs", "function": { @@ -4118,84 +5232,204 @@ expression: buf "replacement": "true", "span": { "end": { - "column": 15, - "line": 5 + "column": 15, + "line": 5 + }, + "start": { + "column": 9, + "line": 5 + } + } + }, + { + "file": "src/traits.rs", + "function": { + "function_name": "Something::is_three", + "return_type": "-> bool", + "span": { + "end": { + "column": 6, + "line": 6 + }, + "start": { + "column": 5, + "line": 4 + } + } + }, + "genre": "FnValue", + "package": "cargo-mutants-testdata-well-tested", + "replacement": "false", + "span": { + "end": { + "column": 15, + "line": 5 + }, + "start": { + "column": 9, + "line": 5 + } + } + }, + { + "file": "src/traits.rs", + "function": { + "function_name": "Something::is_three", + "return_type": "-> bool", + "span": { + "end": { + "column": 6, + "line": 6 + }, + "start": { + "column": 5, + "line": 4 + } + } + }, + "genre": "BinaryOperator", + "package": "cargo-mutants-testdata-well-tested", + "replacement": "!=", + "span": { + "end": { + "column": 13, + "line": 5 + }, + "start": { + "column": 11, + "line": 5 + } + } + } +] +``` + +## testdata/with_child_directories + +```json +[ + { + "file": "src/methods.rs", + "function": { + "function_name": "double", + "return_type": "-> usize", + "span": { + "end": { + "column": 2, + "line": 3 + }, + "start": { + "column": 1, + "line": 1 + } + } + }, + "genre": "FnValue", + "package": "cargo-mutants-testdata-with-child-directories", + "replacement": "0", + "span": { + "end": { + "column": 10, + "line": 2 + }, + "start": { + "column": 5, + "line": 2 + } + } + }, + { + "file": "src/methods.rs", + "function": { + "function_name": "double", + "return_type": "-> usize", + "span": { + "end": { + "column": 2, + "line": 3 + }, + "start": { + "column": 1, + "line": 1 + } + } + }, + "genre": "FnValue", + "package": "cargo-mutants-testdata-with-child-directories", + "replacement": "1", + "span": { + "end": { + "column": 10, + "line": 2 }, "start": { - "column": 9, - "line": 5 + "column": 5, + "line": 2 } } }, { - "file": "src/traits.rs", + "file": "src/methods.rs", "function": { - "function_name": "Something::is_three", - "return_type": "-> bool", + "function_name": "double", + "return_type": "-> usize", "span": { "end": { - "column": 6, - "line": 6 + "column": 2, + "line": 3 }, "start": { - "column": 5, - "line": 4 + "column": 1, + "line": 1 } } }, - "genre": "FnValue", - "package": "cargo-mutants-testdata-well-tested", - "replacement": "false", + "genre": "BinaryOperator", + "package": "cargo-mutants-testdata-with-child-directories", + "replacement": "+", "span": { "end": { - "column": 15, - "line": 5 + "column": 8, + "line": 2 }, "start": { - "column": 9, - "line": 5 + "column": 7, + "line": 2 } } }, { - "file": "src/traits.rs", + "file": "src/methods.rs", "function": { - "function_name": "Something::is_three", - "return_type": "-> bool", + "function_name": "double", + "return_type": "-> usize", "span": { "end": { - "column": 6, - "line": 6 + "column": 2, + "line": 3 }, "start": { - "column": 5, - "line": 4 + "column": 1, + "line": 1 } } }, "genre": "BinaryOperator", - "package": "cargo-mutants-testdata-well-tested", - "replacement": "!=", + "package": "cargo-mutants-testdata-with-child-directories", + "replacement": "/", "span": { "end": { - "column": 13, - "line": 5 + "column": 8, + "line": 2 }, "start": { - "column": 11, - "line": 5 + "column": 7, + "line": 2 } } - } -] -``` - -## testdata/with_child_directories - -```json -[ + }, { - "file": "src/methods.rs", + "file": "src/module/module_methods.rs", "function": { "function_name": "double", "return_type": "-> usize", @@ -4225,7 +5459,7 @@ expression: buf } }, { - "file": "src/methods.rs", + "file": "src/module/module_methods.rs", "function": { "function_name": "double", "return_type": "-> usize", @@ -4270,16 +5504,16 @@ expression: buf } } }, - "genre": "FnValue", + "genre": "BinaryOperator", "package": "cargo-mutants-testdata-with-child-directories", - "replacement": "0", + "replacement": "+", "span": { "end": { - "column": 10, + "column": 8, "line": 2 }, "start": { - "column": 5, + "column": 7, "line": 2 } } @@ -4300,16 +5534,16 @@ expression: buf } } }, - "genre": "FnValue", + "genre": "BinaryOperator", "package": "cargo-mutants-testdata-with-child-directories", - "replacement": "1", + "replacement": "/", "span": { "end": { - "column": 10, + "column": 8, "line": 2 }, "start": { - "column": 5, + "column": 7, "line": 2 } } @@ -4494,6 +5728,66 @@ expression: buf } } }, + { + "file": "src/module/utils/nested_function.rs", + "function": { + "function_name": "has_nested", + "return_type": "-> u32", + "span": { + "end": { + "column": 2, + "line": 6 + }, + "start": { + "column": 1, + "line": 1 + } + } + }, + "genre": "BinaryOperator", + "package": "cargo-mutants-testdata-with-child-directories", + "replacement": "+", + "span": { + "end": { + "column": 14, + "line": 5 + }, + "start": { + "column": 13, + "line": 5 + } + } + }, + { + "file": "src/module/utils/nested_function.rs", + "function": { + "function_name": "has_nested", + "return_type": "-> u32", + "span": { + "end": { + "column": 2, + "line": 6 + }, + "start": { + "column": 1, + "line": 1 + } + } + }, + "genre": "BinaryOperator", + "package": "cargo-mutants-testdata-with-child-directories", + "replacement": "/", + "span": { + "end": { + "column": 14, + "line": 5 + }, + "start": { + "column": 13, + "line": 5 + } + } + }, { "file": "src/module/utils/sub_utils/subutils_nested_function.rs", "function": { @@ -4613,6 +5907,66 @@ expression: buf "line": 3 } } + }, + { + "file": "src/module/utils/sub_utils/subutils_nested_function.rs", + "function": { + "function_name": "has_nested", + "return_type": "-> u32", + "span": { + "end": { + "column": 2, + "line": 6 + }, + "start": { + "column": 1, + "line": 1 + } + } + }, + "genre": "BinaryOperator", + "package": "cargo-mutants-testdata-with-child-directories", + "replacement": "+", + "span": { + "end": { + "column": 14, + "line": 5 + }, + "start": { + "column": 13, + "line": 5 + } + } + }, + { + "file": "src/module/utils/sub_utils/subutils_nested_function.rs", + "function": { + "function_name": "has_nested", + "return_type": "-> u32", + "span": { + "end": { + "column": 2, + "line": 6 + }, + "start": { + "column": 1, + "line": 1 + } + } + }, + "genre": "BinaryOperator", + "package": "cargo-mutants-testdata-with-child-directories", + "replacement": "/", + "span": { + "end": { + "column": 14, + "line": 5 + }, + "start": { + "column": 13, + "line": 5 + } + } } ] ``` @@ -4711,6 +6065,66 @@ expression: buf } } }, + { + "file": "utils/src/lib.rs", + "function": { + "function_name": "triple", + "return_type": "-> i32", + "span": { + "end": { + "column": 2, + "line": 3 + }, + "start": { + "column": 1, + "line": 1 + } + } + }, + "genre": "BinaryOperator", + "package": "cargo_mutants_testdata_workspace_utils", + "replacement": "+", + "span": { + "end": { + "column": 8, + "line": 2 + }, + "start": { + "column": 7, + "line": 2 + } + } + }, + { + "file": "utils/src/lib.rs", + "function": { + "function_name": "triple", + "return_type": "-> i32", + "span": { + "end": { + "column": 2, + "line": 3 + }, + "start": { + "column": 1, + "line": 1 + } + } + }, + "genre": "BinaryOperator", + "package": "cargo_mutants_testdata_workspace_utils", + "replacement": "/", + "span": { + "end": { + "column": 8, + "line": 2 + }, + "start": { + "column": 7, + "line": 2 + } + } + }, { "file": "main/src/main.rs", "function": { diff --git a/tests/cli/snapshots/cli__list_mutants_in_all_trees_as_text.snap b/tests/cli/snapshots/cli__list_mutants_in_all_trees_as_text.snap index 428dc601..c09d1a0a 100644 --- a/tests/cli/snapshots/cli__list_mutants_in_all_trees_as_text.snap +++ b/tests/cli/snapshots/cli__list_mutants_in_all_trees_as_text.snap @@ -7,6 +7,8 @@ expression: buf ``` src/lib.rs:10:5: replace takes_one_arg -> usize with 0 src/lib.rs:10:5: replace takes_one_arg -> usize with 1 +src/lib.rs:10:7: replace + with - in takes_one_arg +src/lib.rs:10:7: replace + with * in takes_one_arg ``` ## testdata/already_failing_tests @@ -39,6 +41,8 @@ src/entry.rs:2:5: replace factorial -> u32 with 1 ``` src/lib.rs:18:5: replace double -> usize with 0 src/lib.rs:18:5: replace double -> usize with 1 +src/lib.rs:18:7: replace * with + in double +src/lib.rs:18:7: replace * with / in double ``` ## testdata/custom_top_file @@ -47,6 +51,8 @@ src/lib.rs:18:5: replace double -> usize with 1 src/custom_top.rs:2:5: replace is_even -> bool with true src/custom_top.rs:2:5: replace is_even -> bool with false src/custom_top.rs:2:11: replace == with != in is_even +src/custom_top.rs:2:7: replace % with / in is_even +src/custom_top.rs:2:7: replace % with + in is_even ``` ## testdata/dependency @@ -75,10 +81,10 @@ src/lib.rs:6:5: replace two -> String with "xyzzy".into() ## testdata/error_value ``` -src/lib.rs:4:5: replace even_is_ok -> Result with Ok(0) -src/lib.rs:4:5: replace even_is_ok -> Result with Ok(1) -src/lib.rs:4:5: replace even_is_ok -> Result with Err("injected") -src/lib.rs:4:14: replace == with != in even_is_ok +src/lib.rs:4:5: replace zero_is_ok -> Result with Ok(0) +src/lib.rs:4:5: replace zero_is_ok -> Result with Ok(1) +src/lib.rs:4:5: replace zero_is_ok -> Result with Err("injected") +src/lib.rs:4:10: replace == with != in zero_is_ok ``` ## testdata/everything_skipped @@ -107,6 +113,8 @@ src/bin/factorial.rs:10:5: replace factorial -> u32 with 1 src/lib.rs:15:5: replace controlled_loop with () src/lib.rs:21:28: replace > with == in controlled_loop src/lib.rs:21:28: replace > with < in controlled_loop +src/lib.rs:21:53: replace * with + in controlled_loop +src/lib.rs:21:53: replace * with / in controlled_loop ``` ## testdata/hang_when_mutated @@ -118,6 +126,8 @@ src/lib.rs:26:5: replace controlled_loop -> usize with 0 src/lib.rs:26:5: replace controlled_loop -> usize with 1 src/lib.rs:33:28: replace > with == in controlled_loop src/lib.rs:33:28: replace > with < in controlled_loop +src/lib.rs:33:53: replace * with + in controlled_loop +src/lib.rs:33:53: replace * with / in controlled_loop ``` ## testdata/insta @@ -132,6 +142,8 @@ src/lib.rs:2:5: replace say_hello -> String with "xyzzy".into() ``` src/lib.rs:2:5: replace double -> u32 with 0 src/lib.rs:2:5: replace double -> u32 with 1 +src/lib.rs:2:7: replace * with + in double +src/lib.rs:2:7: replace * with / in double ``` ## testdata/missing_test @@ -168,6 +180,8 @@ src/lib.rs:3:5: replace box_an_int -> Box with Box::new(-1) src/lib.rs:7:5: replace is_even -> bool with true src/lib.rs:7:5: replace is_even -> bool with false src/lib.rs:7:11: replace == with != in is_even +src/lib.rs:7:7: replace % with / in is_even +src/lib.rs:7:7: replace % with + in is_even ``` ## testdata/package_fails @@ -175,8 +189,12 @@ src/lib.rs:7:11: replace == with != in is_even ``` failing/src/lib.rs:2:5: replace triple -> usize with 0 failing/src/lib.rs:2:5: replace triple -> usize with 1 +failing/src/lib.rs:2:7: replace * with + in triple +failing/src/lib.rs:2:7: replace * with / in triple passing/src/lib.rs:2:5: replace triple -> usize with 0 passing/src/lib.rs:2:5: replace triple -> usize with 1 +passing/src/lib.rs:2:7: replace * with + in triple +passing/src/lib.rs:2:7: replace * with / in triple ``` ## testdata/patch_dependency @@ -185,6 +203,8 @@ passing/src/lib.rs:2:5: replace triple -> usize with 1 src/lib.rs:7:5: replace is_even -> bool with true src/lib.rs:7:5: replace is_even -> bool with false src/lib.rs:7:11: replace == with != in is_even +src/lib.rs:7:7: replace % with / in is_even +src/lib.rs:7:7: replace % with + in is_even ``` ## testdata/relative_dependency @@ -194,6 +214,8 @@ src/lib.rs:6:5: replace double_factorial -> u32 with 0 src/lib.rs:6:5: replace double_factorial -> u32 with 1 src/lib.rs:6:10: replace < with == in double_factorial src/lib.rs:6:10: replace < with > in double_factorial +src/lib.rs:9:7: replace * with + in double_factorial +src/lib.rs:9:7: replace * with / in double_factorial ``` ## testdata/replace_dependency @@ -202,6 +224,8 @@ src/lib.rs:6:10: replace < with > in double_factorial src/lib.rs:7:5: replace is_even -> bool with true src/lib.rs:7:5: replace is_even -> bool with false src/lib.rs:7:11: replace == with != in is_even +src/lib.rs:7:7: replace % with / in is_even +src/lib.rs:7:7: replace % with + in is_even ``` ## testdata/small_well_tested @@ -216,6 +240,8 @@ src/lib.rs:5:5: replace factorial -> u32 with 1 ``` src/lib.rs:6:5: replace some_fn -> usize with 0 src/lib.rs:6:5: replace some_fn -> usize with 1 +src/lib.rs:6:7: replace + with - in some_fn +src/lib.rs:6:7: replace + with * in some_fn ``` ## testdata/struct_with_no_default @@ -236,6 +262,8 @@ src/lib.rs:4:5: replace read_through_symlink -> String with "xyzzy".into() ``` src/lib.rs:6:5: replace try_value_coercion -> String with String::new() src/lib.rs:6:5: replace try_value_coercion -> String with "xyzzy".into() +src/lib.rs:6:9: replace + with - in try_value_coercion +src/lib.rs:6:9: replace + with * in try_value_coercion ``` ## testdata/unapply @@ -268,12 +296,18 @@ src/nested_function.rs:2:5: replace has_nested -> u32 with 0 src/nested_function.rs:2:5: replace has_nested -> u32 with 1 src/nested_function.rs:3:9: replace has_nested::inner -> u32 with 0 src/nested_function.rs:3:9: replace has_nested::inner -> u32 with 1 +src/nested_function.rs:5:13: replace * with + in has_nested +src/nested_function.rs:5:13: replace * with / in has_nested src/numbers.rs:2:5: replace double_float -> f32 with 0.0 src/numbers.rs:2:5: replace double_float -> f32 with 1.0 src/numbers.rs:2:5: replace double_float -> f32 with -1.0 +src/numbers.rs:2:9: replace * with + in double_float +src/numbers.rs:2:9: replace * with / in double_float src/numbers.rs:6:5: replace is_double -> bool with true src/numbers.rs:6:5: replace is_double -> bool with false src/numbers.rs:6:7: replace == with != in is_double +src/numbers.rs:6:12: replace * with + in is_double +src/numbers.rs:6:12: replace * with / in is_double src/result.rs:6:5: replace simple_result -> Result<&'static str, ()> with Ok("") src/result.rs:6:5: replace simple_result -> Result<&'static str, ()> with Ok("xyzzy") src/result.rs:10:5: replace error_if_negative -> Result<(), ()> with Ok(()) @@ -289,6 +323,8 @@ src/simple_fns.rs:13:5: replace returns_42u32 -> u32 with 1 src/simple_fns.rs:18:5: replace divisible_by_three -> bool with true src/simple_fns.rs:18:5: replace divisible_by_three -> bool with false src/simple_fns.rs:18:11: replace == with != in divisible_by_three +src/simple_fns.rs:18:7: replace % with / in divisible_by_three +src/simple_fns.rs:18:7: replace % with + in divisible_by_three src/simple_fns.rs:27:5: replace double_string -> String with String::new() src/simple_fns.rs:27:5: replace double_string -> String with "xyzzy".into() src/slices.rs:4:5: replace pad -> &'a[Cow<'static, str>] with Vec::leak(Vec::new()) @@ -302,6 +338,8 @@ src/slices.rs:13:5: replace return_mut_slice -> &mut[usize] with Vec::leak(Vec:: src/slices.rs:13:5: replace return_mut_slice -> &mut[usize] with Vec::leak(vec![0]) src/slices.rs:13:5: replace return_mut_slice -> &mut[usize] with Vec::leak(vec![1]) src/static_item.rs:1:33: replace == with != +src/static_item.rs:1:39: replace + with - +src/static_item.rs:1:39: replace + with * src/struct_with_lifetime.rs:15:9: replace Lex<'buf>::buf_len -> usize with 0 src/struct_with_lifetime.rs:15:9: replace Lex<'buf>::buf_len -> usize with 1 src/traits.rs:5:9: replace Something::is_three -> bool with true @@ -314,18 +352,26 @@ src/traits.rs:5:11: replace == with != in Something::is_three ``` src/methods.rs:2:5: replace double -> usize with 0 src/methods.rs:2:5: replace double -> usize with 1 +src/methods.rs:2:7: replace * with + in double +src/methods.rs:2:7: replace * with / in double src/module/module_methods.rs:2:5: replace double -> usize with 0 src/module/module_methods.rs:2:5: replace double -> usize with 1 +src/module/module_methods.rs:2:7: replace * with + in double +src/module/module_methods.rs:2:7: replace * with / in double src/module/utils/inside_mod.rs:4:13: replace outer::inner::name -> &'static str with "" src/module/utils/inside_mod.rs:4:13: replace outer::inner::name -> &'static str with "xyzzy" src/module/utils/nested_function.rs:2:5: replace has_nested -> u32 with 0 src/module/utils/nested_function.rs:2:5: replace has_nested -> u32 with 1 src/module/utils/nested_function.rs:3:9: replace has_nested::inner -> u32 with 0 src/module/utils/nested_function.rs:3:9: replace has_nested::inner -> u32 with 1 +src/module/utils/nested_function.rs:5:13: replace * with + in has_nested +src/module/utils/nested_function.rs:5:13: replace * with / in has_nested src/module/utils/sub_utils/subutils_nested_function.rs:2:5: replace has_nested -> u32 with 0 src/module/utils/sub_utils/subutils_nested_function.rs:2:5: replace has_nested -> u32 with 1 src/module/utils/sub_utils/subutils_nested_function.rs:3:9: replace has_nested::inner -> u32 with 0 src/module/utils/sub_utils/subutils_nested_function.rs:3:9: replace has_nested::inner -> u32 with 1 +src/module/utils/sub_utils/subutils_nested_function.rs:5:13: replace * with + in has_nested +src/module/utils/sub_utils/subutils_nested_function.rs:5:13: replace * with / in has_nested ``` ## testdata/workspace @@ -334,6 +380,8 @@ src/module/utils/sub_utils/subutils_nested_function.rs:3:9: replace has_nested:: utils/src/lib.rs:2:5: replace triple -> i32 with 0 utils/src/lib.rs:2:5: replace triple -> i32 with 1 utils/src/lib.rs:2:5: replace triple -> i32 with -1 +utils/src/lib.rs:2:7: replace * with + in triple +utils/src/lib.rs:2:7: replace * with / in triple main/src/main.rs:12:5: replace factorial -> u32 with 0 main/src/main.rs:12:5: replace factorial -> u32 with 1 main2/src/main.rs:10:5: replace triple_3 -> i32 with 0 diff --git a/tests/cli/snapshots/cli__list_mutants_in_cfg_attr_test_skip.snap b/tests/cli/snapshots/cli__list_mutants_in_cfg_attr_test_skip.snap index 6d042382..baf5677c 100644 --- a/tests/cli/snapshots/cli__list_mutants_in_cfg_attr_test_skip.snap +++ b/tests/cli/snapshots/cli__list_mutants_in_cfg_attr_test_skip.snap @@ -4,4 +4,6 @@ expression: "String::from_utf8_lossy(&output.stdout)" --- src/lib.rs:18:5: replace double -> usize with 0 src/lib.rs:18:5: replace double -> usize with 1 +src/lib.rs:18:7: replace * with + in double +src/lib.rs:18:7: replace * with / in double diff --git a/tests/cli/snapshots/cli__list_mutants_in_cfg_attr_test_skip_json.snap b/tests/cli/snapshots/cli__list_mutants_in_cfg_attr_test_skip_json.snap index b8ebc631..86f39f6f 100644 --- a/tests/cli/snapshots/cli__list_mutants_in_cfg_attr_test_skip_json.snap +++ b/tests/cli/snapshots/cli__list_mutants_in_cfg_attr_test_skip_json.snap @@ -62,5 +62,65 @@ expression: "String::from_utf8_lossy(&output.stdout)" "line": 18 } } + }, + { + "file": "src/lib.rs", + "function": { + "function_name": "double", + "return_type": "-> usize", + "span": { + "end": { + "column": 2, + "line": 19 + }, + "start": { + "column": 1, + "line": 16 + } + } + }, + "genre": "BinaryOperator", + "package": "cargo-mutants-testdata-cfg-attr-test-skip", + "replacement": "+", + "span": { + "end": { + "column": 8, + "line": 18 + }, + "start": { + "column": 7, + "line": 18 + } + } + }, + { + "file": "src/lib.rs", + "function": { + "function_name": "double", + "return_type": "-> usize", + "span": { + "end": { + "column": 2, + "line": 19 + }, + "start": { + "column": 1, + "line": 16 + } + } + }, + "genre": "BinaryOperator", + "package": "cargo-mutants-testdata-cfg-attr-test-skip", + "replacement": "/", + "span": { + "end": { + "column": 8, + "line": 18 + }, + "start": { + "column": 7, + "line": 18 + } + } } ] diff --git a/tests/cli/snapshots/cli__list_mutants_json_well_tested.snap b/tests/cli/snapshots/cli__list_mutants_json_well_tested.snap index 3528be69..917e3a56 100644 --- a/tests/cli/snapshots/cli__list_mutants_json_well_tested.snap +++ b/tests/cli/snapshots/cli__list_mutants_json_well_tested.snap @@ -333,6 +333,66 @@ expression: "String::from_utf8_lossy(&output.stdout)" } } }, + { + "file": "src/nested_function.rs", + "function": { + "function_name": "has_nested", + "return_type": "-> u32", + "span": { + "end": { + "column": 2, + "line": 6 + }, + "start": { + "column": 1, + "line": 1 + } + } + }, + "genre": "BinaryOperator", + "package": "cargo-mutants-testdata-well-tested", + "replacement": "+", + "span": { + "end": { + "column": 14, + "line": 5 + }, + "start": { + "column": 13, + "line": 5 + } + } + }, + { + "file": "src/nested_function.rs", + "function": { + "function_name": "has_nested", + "return_type": "-> u32", + "span": { + "end": { + "column": 2, + "line": 6 + }, + "start": { + "column": 1, + "line": 1 + } + } + }, + "genre": "BinaryOperator", + "package": "cargo-mutants-testdata-well-tested", + "replacement": "/", + "span": { + "end": { + "column": 14, + "line": 5 + }, + "start": { + "column": 13, + "line": 5 + } + } + }, { "file": "src/numbers.rs", "function": { @@ -423,6 +483,66 @@ expression: "String::from_utf8_lossy(&output.stdout)" } } }, + { + "file": "src/numbers.rs", + "function": { + "function_name": "double_float", + "return_type": "-> f32", + "span": { + "end": { + "column": 2, + "line": 3 + }, + "start": { + "column": 1, + "line": 1 + } + } + }, + "genre": "BinaryOperator", + "package": "cargo-mutants-testdata-well-tested", + "replacement": "+", + "span": { + "end": { + "column": 10, + "line": 2 + }, + "start": { + "column": 9, + "line": 2 + } + } + }, + { + "file": "src/numbers.rs", + "function": { + "function_name": "double_float", + "return_type": "-> f32", + "span": { + "end": { + "column": 2, + "line": 3 + }, + "start": { + "column": 1, + "line": 1 + } + } + }, + "genre": "BinaryOperator", + "package": "cargo-mutants-testdata-well-tested", + "replacement": "/", + "span": { + "end": { + "column": 10, + "line": 2 + }, + "start": { + "column": 9, + "line": 2 + } + } + }, { "file": "src/numbers.rs", "function": { @@ -513,6 +633,66 @@ expression: "String::from_utf8_lossy(&output.stdout)" } } }, + { + "file": "src/numbers.rs", + "function": { + "function_name": "is_double", + "return_type": "-> bool", + "span": { + "end": { + "column": 2, + "line": 7 + }, + "start": { + "column": 1, + "line": 5 + } + } + }, + "genre": "BinaryOperator", + "package": "cargo-mutants-testdata-well-tested", + "replacement": "+", + "span": { + "end": { + "column": 13, + "line": 6 + }, + "start": { + "column": 12, + "line": 6 + } + } + }, + { + "file": "src/numbers.rs", + "function": { + "function_name": "is_double", + "return_type": "-> bool", + "span": { + "end": { + "column": 2, + "line": 7 + }, + "start": { + "column": 1, + "line": 5 + } + } + }, + "genre": "BinaryOperator", + "package": "cargo-mutants-testdata-well-tested", + "replacement": "/", + "span": { + "end": { + "column": 13, + "line": 6 + }, + "start": { + "column": 12, + "line": 6 + } + } + }, { "file": "src/result.rs", "function": { @@ -963,6 +1143,66 @@ expression: "String::from_utf8_lossy(&output.stdout)" } } }, + { + "file": "src/simple_fns.rs", + "function": { + "function_name": "divisible_by_three", + "return_type": "-> bool", + "span": { + "end": { + "column": 2, + "line": 19 + }, + "start": { + "column": 1, + "line": 16 + } + } + }, + "genre": "BinaryOperator", + "package": "cargo-mutants-testdata-well-tested", + "replacement": "/", + "span": { + "end": { + "column": 8, + "line": 18 + }, + "start": { + "column": 7, + "line": 18 + } + } + }, + { + "file": "src/simple_fns.rs", + "function": { + "function_name": "divisible_by_three", + "return_type": "-> bool", + "span": { + "end": { + "column": 2, + "line": 19 + }, + "start": { + "column": 1, + "line": 16 + } + } + }, + "genre": "BinaryOperator", + "package": "cargo-mutants-testdata-well-tested", + "replacement": "+", + "span": { + "end": { + "column": 8, + "line": 18 + }, + "start": { + "column": 7, + "line": 18 + } + } + }, { "file": "src/simple_fns.rs", "function": { @@ -1340,6 +1580,40 @@ expression: "String::from_utf8_lossy(&output.stdout)" } } }, + { + "file": "src/static_item.rs", + "function": null, + "genre": "BinaryOperator", + "package": "cargo-mutants-testdata-well-tested", + "replacement": "-", + "span": { + "end": { + "column": 40, + "line": 1 + }, + "start": { + "column": 39, + "line": 1 + } + } + }, + { + "file": "src/static_item.rs", + "function": null, + "genre": "BinaryOperator", + "package": "cargo-mutants-testdata-well-tested", + "replacement": "*", + "span": { + "end": { + "column": 40, + "line": 1 + }, + "start": { + "column": 39, + "line": 1 + } + } + }, { "file": "src/struct_with_lifetime.rs", "function": { diff --git a/tests/cli/snapshots/cli__list_mutants_regex_filters.snap b/tests/cli/snapshots/cli__list_mutants_regex_filters.snap index 4b559bf6..fc9621ea 100644 --- a/tests/cli/snapshots/cli__list_mutants_regex_filters.snap +++ b/tests/cli/snapshots/cli__list_mutants_regex_filters.snap @@ -5,4 +5,6 @@ expression: "String::from_utf8_lossy(&output.stdout)" src/simple_fns.rs:18:5: replace divisible_by_three -> bool with true src/simple_fns.rs:18:5: replace divisible_by_three -> bool with false src/simple_fns.rs:18:11: replace == with != in divisible_by_three +src/simple_fns.rs:18:7: replace % with / in divisible_by_three +src/simple_fns.rs:18:7: replace % with + in divisible_by_three diff --git a/tests/cli/snapshots/cli__list_mutants_regex_filters_json.snap b/tests/cli/snapshots/cli__list_mutants_regex_filters_json.snap index f907131b..82e8cbbf 100644 --- a/tests/cli/snapshots/cli__list_mutants_regex_filters_json.snap +++ b/tests/cli/snapshots/cli__list_mutants_regex_filters_json.snap @@ -62,5 +62,65 @@ expression: "String::from_utf8_lossy(&output.stdout)" "line": 18 } } + }, + { + "file": "src/simple_fns.rs", + "function": { + "function_name": "divisible_by_three", + "return_type": "-> bool", + "span": { + "end": { + "column": 2, + "line": 19 + }, + "start": { + "column": 1, + "line": 16 + } + } + }, + "genre": "BinaryOperator", + "package": "cargo-mutants-testdata-well-tested", + "replacement": "/", + "span": { + "end": { + "column": 8, + "line": 18 + }, + "start": { + "column": 7, + "line": 18 + } + } + }, + { + "file": "src/simple_fns.rs", + "function": { + "function_name": "divisible_by_three", + "return_type": "-> bool", + "span": { + "end": { + "column": 2, + "line": 19 + }, + "start": { + "column": 1, + "line": 16 + } + } + }, + "genre": "BinaryOperator", + "package": "cargo-mutants-testdata-well-tested", + "replacement": "+", + "span": { + "end": { + "column": 8, + "line": 18 + }, + "start": { + "column": 7, + "line": 18 + } + } } ] diff --git a/tests/cli/snapshots/cli__list_mutants_well_tested.snap b/tests/cli/snapshots/cli__list_mutants_well_tested.snap index d9c0a8b4..70639ea8 100644 --- a/tests/cli/snapshots/cli__list_mutants_well_tested.snap +++ b/tests/cli/snapshots/cli__list_mutants_well_tested.snap @@ -13,12 +13,18 @@ src/nested_function.rs:2:5: replace has_nested -> u32 with 0 src/nested_function.rs:2:5: replace has_nested -> u32 with 1 src/nested_function.rs:3:9: replace has_nested::inner -> u32 with 0 src/nested_function.rs:3:9: replace has_nested::inner -> u32 with 1 +src/nested_function.rs:5:13: replace * with + in has_nested +src/nested_function.rs:5:13: replace * with / in has_nested src/numbers.rs:2:5: replace double_float -> f32 with 0.0 src/numbers.rs:2:5: replace double_float -> f32 with 1.0 src/numbers.rs:2:5: replace double_float -> f32 with -1.0 +src/numbers.rs:2:9: replace * with + in double_float +src/numbers.rs:2:9: replace * with / in double_float src/numbers.rs:6:5: replace is_double -> bool with true src/numbers.rs:6:5: replace is_double -> bool with false src/numbers.rs:6:7: replace == with != in is_double +src/numbers.rs:6:12: replace * with + in is_double +src/numbers.rs:6:12: replace * with / in is_double src/result.rs:6:5: replace simple_result -> Result<&'static str, ()> with Ok("") src/result.rs:6:5: replace simple_result -> Result<&'static str, ()> with Ok("xyzzy") src/result.rs:10:5: replace error_if_negative -> Result<(), ()> with Ok(()) @@ -34,6 +40,8 @@ src/simple_fns.rs:13:5: replace returns_42u32 -> u32 with 1 src/simple_fns.rs:18:5: replace divisible_by_three -> bool with true src/simple_fns.rs:18:5: replace divisible_by_three -> bool with false src/simple_fns.rs:18:11: replace == with != in divisible_by_three +src/simple_fns.rs:18:7: replace % with / in divisible_by_three +src/simple_fns.rs:18:7: replace % with + in divisible_by_three src/simple_fns.rs:27:5: replace double_string -> String with String::new() src/simple_fns.rs:27:5: replace double_string -> String with "xyzzy".into() src/slices.rs:4:5: replace pad -> &'a[Cow<'static, str>] with Vec::leak(Vec::new()) @@ -47,6 +55,8 @@ src/slices.rs:13:5: replace return_mut_slice -> &mut[usize] with Vec::leak(Vec:: src/slices.rs:13:5: replace return_mut_slice -> &mut[usize] with Vec::leak(vec![0]) src/slices.rs:13:5: replace return_mut_slice -> &mut[usize] with Vec::leak(vec![1]) src/static_item.rs:1:33: replace == with != +src/static_item.rs:1:39: replace + with - +src/static_item.rs:1:39: replace + with * src/struct_with_lifetime.rs:15:9: replace Lex<'buf>::buf_len -> usize with 0 src/struct_with_lifetime.rs:15:9: replace Lex<'buf>::buf_len -> usize with 1 src/traits.rs:5:9: replace Something::is_three -> bool with true diff --git a/tests/cli/snapshots/cli__list_mutants_well_tested_examine_and_exclude_name_filter_combined.snap b/tests/cli/snapshots/cli__list_mutants_well_tested_examine_and_exclude_name_filter_combined.snap index b24667ef..af4ad2b3 100644 --- a/tests/cli/snapshots/cli__list_mutants_well_tested_examine_and_exclude_name_filter_combined.snap +++ b/tests/cli/snapshots/cli__list_mutants_well_tested_examine_and_exclude_name_filter_combined.snap @@ -8,4 +8,6 @@ src/module/utils/sub_utils/subutils_nested_function.rs:2:5: replace has_nested - src/module/utils/sub_utils/subutils_nested_function.rs:2:5: replace has_nested -> u32 with 1 src/module/utils/sub_utils/subutils_nested_function.rs:3:9: replace has_nested::inner -> u32 with 0 src/module/utils/sub_utils/subutils_nested_function.rs:3:9: replace has_nested::inner -> u32 with 1 +src/module/utils/sub_utils/subutils_nested_function.rs:5:13: replace * with + in has_nested +src/module/utils/sub_utils/subutils_nested_function.rs:5:13: replace * with / in has_nested diff --git a/tests/cli/snapshots/cli__list_mutants_well_tested_examine_name_filter.snap b/tests/cli/snapshots/cli__list_mutants_well_tested_examine_name_filter.snap index 11f92044..c125b6eb 100644 --- a/tests/cli/snapshots/cli__list_mutants_well_tested_examine_name_filter.snap +++ b/tests/cli/snapshots/cli__list_mutants_well_tested_examine_name_filter.snap @@ -6,4 +6,6 @@ src/nested_function.rs:2:5: replace has_nested -> u32 with 0 src/nested_function.rs:2:5: replace has_nested -> u32 with 1 src/nested_function.rs:3:9: replace has_nested::inner -> u32 with 0 src/nested_function.rs:3:9: replace has_nested::inner -> u32 with 1 +src/nested_function.rs:5:13: replace * with + in has_nested +src/nested_function.rs:5:13: replace * with / in has_nested diff --git a/tests/cli/snapshots/cli__list_mutants_well_tested_exclude_folder_filter.snap b/tests/cli/snapshots/cli__list_mutants_well_tested_exclude_folder_filter.snap index c79cddac..4631c68a 100644 --- a/tests/cli/snapshots/cli__list_mutants_well_tested_exclude_folder_filter.snap +++ b/tests/cli/snapshots/cli__list_mutants_well_tested_exclude_folder_filter.snap @@ -4,4 +4,6 @@ expression: "String::from_utf8_lossy(&output.stdout)" --- src/methods.rs:2:5: replace double -> usize with 0 src/methods.rs:2:5: replace double -> usize with 1 +src/methods.rs:2:7: replace * with + in double +src/methods.rs:2:7: replace * with / in double diff --git a/tests/cli/snapshots/cli__list_mutants_well_tested_exclude_name_filter.snap b/tests/cli/snapshots/cli__list_mutants_well_tested_exclude_name_filter.snap index 83ccafc4..143b5be8 100644 --- a/tests/cli/snapshots/cli__list_mutants_well_tested_exclude_name_filter.snap +++ b/tests/cli/snapshots/cli__list_mutants_well_tested_exclude_name_filter.snap @@ -13,12 +13,18 @@ src/nested_function.rs:2:5: replace has_nested -> u32 with 0 src/nested_function.rs:2:5: replace has_nested -> u32 with 1 src/nested_function.rs:3:9: replace has_nested::inner -> u32 with 0 src/nested_function.rs:3:9: replace has_nested::inner -> u32 with 1 +src/nested_function.rs:5:13: replace * with + in has_nested +src/nested_function.rs:5:13: replace * with / in has_nested src/numbers.rs:2:5: replace double_float -> f32 with 0.0 src/numbers.rs:2:5: replace double_float -> f32 with 1.0 src/numbers.rs:2:5: replace double_float -> f32 with -1.0 +src/numbers.rs:2:9: replace * with + in double_float +src/numbers.rs:2:9: replace * with / in double_float src/numbers.rs:6:5: replace is_double -> bool with true src/numbers.rs:6:5: replace is_double -> bool with false src/numbers.rs:6:7: replace == with != in is_double +src/numbers.rs:6:12: replace * with + in is_double +src/numbers.rs:6:12: replace * with / in is_double src/result.rs:6:5: replace simple_result -> Result<&'static str, ()> with Ok("") src/result.rs:6:5: replace simple_result -> Result<&'static str, ()> with Ok("xyzzy") src/result.rs:10:5: replace error_if_negative -> Result<(), ()> with Ok(()) @@ -39,6 +45,8 @@ src/slices.rs:13:5: replace return_mut_slice -> &mut[usize] with Vec::leak(Vec:: src/slices.rs:13:5: replace return_mut_slice -> &mut[usize] with Vec::leak(vec![0]) src/slices.rs:13:5: replace return_mut_slice -> &mut[usize] with Vec::leak(vec![1]) src/static_item.rs:1:33: replace == with != +src/static_item.rs:1:39: replace + with - +src/static_item.rs:1:39: replace + with * src/struct_with_lifetime.rs:15:9: replace Lex<'buf>::buf_len -> usize with 0 src/struct_with_lifetime.rs:15:9: replace Lex<'buf>::buf_len -> usize with 1 src/traits.rs:5:9: replace Something::is_three -> bool with true diff --git a/tests/cli/snapshots/cli__list_mutants_well_tested_multiple_examine_and_exclude_name_filter_with_files_and_folders.snap b/tests/cli/snapshots/cli__list_mutants_well_tested_multiple_examine_and_exclude_name_filter_with_files_and_folders.snap index 0d175630..9c7fd953 100644 --- a/tests/cli/snapshots/cli__list_mutants_well_tested_multiple_examine_and_exclude_name_filter_with_files_and_folders.snap +++ b/tests/cli/snapshots/cli__list_mutants_well_tested_multiple_examine_and_exclude_name_filter_with_files_and_folders.snap @@ -4,6 +4,8 @@ expression: "String::from_utf8_lossy(&output.stdout)" --- src/module/module_methods.rs:2:5: replace double -> usize with 0 src/module/module_methods.rs:2:5: replace double -> usize with 1 +src/module/module_methods.rs:2:7: replace * with + in double +src/module/module_methods.rs:2:7: replace * with / in double src/module/utils/inside_mod.rs:4:13: replace outer::inner::name -> &'static str with "" src/module/utils/inside_mod.rs:4:13: replace outer::inner::name -> &'static str with "xyzzy" From eee229b5489eaf1f36b3751f3bf76bcfe1c450fb Mon Sep 17 00:00:00 2001 From: Martin Pool Date: Sun, 17 Dec 2023 11:36:53 +1000 Subject: [PATCH 02/11] News --- NEWS.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/NEWS.md b/NEWS.md index 1b29c32c..2c7b8c5f 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,5 +1,9 @@ # cargo-mutants changelog +## Unreleased + +- Mutate `+, -, *, /, %` binary ops. + ## 23.12.1 - Improved progress bars and console output, including putting the outcome of each mutant on the left, and the overall progress bar at the bottom. Improved display of estimated remaining time, and other times. From 531035cb62c665378510a3c9f88cbafbf32364e7 Mon Sep 17 00:00:00 2001 From: Martin Pool Date: Sun, 17 Dec 2023 11:39:00 +1000 Subject: [PATCH 03/11] Run full mutants after PR mutants --- .github/workflows/tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index d4e64991..0a11a725 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -75,7 +75,7 @@ jobs: cargo-mutants: runs-on: ubuntu-latest - # needs: [build, incremental-mutants] + needs: [build, pr-mutants] steps: - uses: actions/checkout@v3 - uses: dtolnay/rust-toolchain@master From 7cbf18e8b98bdae658ce449cdd807107638d1feb Mon Sep 17 00:00:00 2001 From: Martin Pool Date: Sun, 17 Dec 2023 11:47:29 +1000 Subject: [PATCH 04/11] Fix tests --- src/mutate.rs | 2 ++ .../cli__well_tested_tree_check_only.snap | 14 ++++++-- ...i__well_tested_tree_finds_no_problems.snap | 14 ++++++-- ...ed_tree_finds_no_problems__caught.txt.snap | 10 ++++++ tests/cli/workspace.rs | 33 +++++++++++-------- 5 files changed, 55 insertions(+), 18 deletions(-) diff --git a/src/mutate.rs b/src/mutate.rs index 9fef9eb6..25ebb7b2 100644 --- a/src/mutate.rs +++ b/src/mutate.rs @@ -318,6 +318,8 @@ mod test { replace controlled_loop with () replace > with == in controlled_loop replace > with < in controlled_loop + replace * with + in controlled_loop + replace * with / in controlled_loop "### ); } diff --git a/tests/cli/snapshots/cli__well_tested_tree_check_only.snap b/tests/cli/snapshots/cli__well_tested_tree_check_only.snap index b460e210..0b560c42 100644 --- a/tests/cli/snapshots/cli__well_tested_tree_check_only.snap +++ b/tests/cli/snapshots/cli__well_tested_tree_check_only.snap @@ -2,7 +2,7 @@ source: tests/cli/main.rs expression: stdout --- -Found 50 mutants to test +Found 60 mutants to test ok Unmutated baseline ok src/arc.rs:4:5: replace return_arc -> Arc with Arc::new(String::new()) ok src/arc.rs:4:5: replace return_arc -> Arc with Arc::new("xyzzy".into()) @@ -15,12 +15,18 @@ ok src/nested_function.rs:2:5: replace has_nested -> u32 with 0 ok src/nested_function.rs:2:5: replace has_nested -> u32 with 1 ok src/nested_function.rs:3:9: replace has_nested::inner -> u32 with 0 ok src/nested_function.rs:3:9: replace has_nested::inner -> u32 with 1 +ok src/nested_function.rs:5:13: replace * with + in has_nested +ok src/nested_function.rs:5:13: replace * with / in has_nested ok src/numbers.rs:2:5: replace double_float -> f32 with 0.0 ok src/numbers.rs:2:5: replace double_float -> f32 with 1.0 ok src/numbers.rs:2:5: replace double_float -> f32 with -1.0 +ok src/numbers.rs:2:9: replace * with + in double_float +ok src/numbers.rs:2:9: replace * with / in double_float ok src/numbers.rs:6:5: replace is_double -> bool with true ok src/numbers.rs:6:5: replace is_double -> bool with false ok src/numbers.rs:6:7: replace == with != in is_double +ok src/numbers.rs:6:12: replace * with + in is_double +ok src/numbers.rs:6:12: replace * with / in is_double ok src/result.rs:6:5: replace simple_result -> Result<&'static str, ()> with Ok("") ok src/result.rs:6:5: replace simple_result -> Result<&'static str, ()> with Ok("xyzzy") ok src/result.rs:10:5: replace error_if_negative -> Result<(), ()> with Ok(()) @@ -36,6 +42,8 @@ ok src/simple_fns.rs:13:5: replace returns_42u32 -> u32 with 1 ok src/simple_fns.rs:18:5: replace divisible_by_three -> bool with true ok src/simple_fns.rs:18:5: replace divisible_by_three -> bool with false ok src/simple_fns.rs:18:11: replace == with != in divisible_by_three +ok src/simple_fns.rs:18:7: replace % with / in divisible_by_three +ok src/simple_fns.rs:18:7: replace % with + in divisible_by_three ok src/simple_fns.rs:27:5: replace double_string -> String with String::new() ok src/simple_fns.rs:27:5: replace double_string -> String with "xyzzy".into() ok src/slices.rs:4:5: replace pad -> &'a[Cow<'static, str>] with Vec::leak(Vec::new()) @@ -49,10 +57,12 @@ ok src/slices.rs:13:5: replace return_mut_slice -> &mut[usize] with Vec::l ok src/slices.rs:13:5: replace return_mut_slice -> &mut[usize] with Vec::leak(vec![0]) ok src/slices.rs:13:5: replace return_mut_slice -> &mut[usize] with Vec::leak(vec![1]) ok src/static_item.rs:1:33: replace == with != +ok src/static_item.rs:1:39: replace + with - +ok src/static_item.rs:1:39: replace + with * ok src/struct_with_lifetime.rs:15:9: replace Lex<'buf>::buf_len -> usize with 0 ok src/struct_with_lifetime.rs:15:9: replace Lex<'buf>::buf_len -> usize with 1 ok src/traits.rs:5:9: replace Something::is_three -> bool with true ok src/traits.rs:5:9: replace Something::is_three -> bool with false ok src/traits.rs:5:11: replace == with != in Something::is_three -50 mutants tested: 50 succeeded +60 mutants tested: 60 succeeded diff --git a/tests/cli/snapshots/cli__well_tested_tree_finds_no_problems.snap b/tests/cli/snapshots/cli__well_tested_tree_finds_no_problems.snap index d794cb73..547ee2f0 100644 --- a/tests/cli/snapshots/cli__well_tested_tree_finds_no_problems.snap +++ b/tests/cli/snapshots/cli__well_tested_tree_finds_no_problems.snap @@ -2,7 +2,7 @@ source: tests/cli/main.rs expression: stdout --- -Found 50 mutants to test +Found 60 mutants to test ok Unmutated baseline caught src/arc.rs:4:5: replace return_arc -> Arc with Arc::new(String::new()) caught src/arc.rs:4:5: replace return_arc -> Arc with Arc::new("xyzzy".into()) @@ -15,12 +15,18 @@ caught src/nested_function.rs:2:5: replace has_nested -> u32 with 0 caught src/nested_function.rs:2:5: replace has_nested -> u32 with 1 caught src/nested_function.rs:3:9: replace has_nested::inner -> u32 with 0 caught src/nested_function.rs:3:9: replace has_nested::inner -> u32 with 1 +caught src/nested_function.rs:5:13: replace * with + in has_nested +caught src/nested_function.rs:5:13: replace * with / in has_nested caught src/numbers.rs:2:5: replace double_float -> f32 with 0.0 caught src/numbers.rs:2:5: replace double_float -> f32 with 1.0 caught src/numbers.rs:2:5: replace double_float -> f32 with -1.0 +caught src/numbers.rs:2:9: replace * with + in double_float +caught src/numbers.rs:2:9: replace * with / in double_float caught src/numbers.rs:6:5: replace is_double -> bool with true caught src/numbers.rs:6:5: replace is_double -> bool with false caught src/numbers.rs:6:7: replace == with != in is_double +caught src/numbers.rs:6:12: replace * with + in is_double +caught src/numbers.rs:6:12: replace * with / in is_double caught src/result.rs:6:5: replace simple_result -> Result<&'static str, ()> with Ok("") caught src/result.rs:6:5: replace simple_result -> Result<&'static str, ()> with Ok("xyzzy") caught src/result.rs:10:5: replace error_if_negative -> Result<(), ()> with Ok(()) @@ -36,6 +42,8 @@ caught src/simple_fns.rs:13:5: replace returns_42u32 -> u32 with 1 caught src/simple_fns.rs:18:5: replace divisible_by_three -> bool with true caught src/simple_fns.rs:18:5: replace divisible_by_three -> bool with false caught src/simple_fns.rs:18:11: replace == with != in divisible_by_three +caught src/simple_fns.rs:18:7: replace % with / in divisible_by_three +caught src/simple_fns.rs:18:7: replace % with + in divisible_by_three caught src/simple_fns.rs:27:5: replace double_string -> String with String::new() caught src/simple_fns.rs:27:5: replace double_string -> String with "xyzzy".into() caught src/slices.rs:4:5: replace pad -> &'a[Cow<'static, str>] with Vec::leak(Vec::new()) @@ -49,10 +57,12 @@ caught src/slices.rs:13:5: replace return_mut_slice -> &mut[usize] with Vec::l caught src/slices.rs:13:5: replace return_mut_slice -> &mut[usize] with Vec::leak(vec![0]) caught src/slices.rs:13:5: replace return_mut_slice -> &mut[usize] with Vec::leak(vec![1]) caught src/static_item.rs:1:33: replace == with != +caught src/static_item.rs:1:39: replace + with - +caught src/static_item.rs:1:39: replace + with * caught src/struct_with_lifetime.rs:15:9: replace Lex<'buf>::buf_len -> usize with 0 caught src/struct_with_lifetime.rs:15:9: replace Lex<'buf>::buf_len -> usize with 1 caught src/traits.rs:5:9: replace Something::is_three -> bool with true caught src/traits.rs:5:9: replace Something::is_three -> bool with false caught src/traits.rs:5:11: replace == with != in Something::is_three -50 mutants tested: 50 caught +60 mutants tested: 60 caught diff --git a/tests/cli/snapshots/cli__well_tested_tree_finds_no_problems__caught.txt.snap b/tests/cli/snapshots/cli__well_tested_tree_finds_no_problems__caught.txt.snap index a9b1d723..5d5cdfc4 100644 --- a/tests/cli/snapshots/cli__well_tested_tree_finds_no_problems__caught.txt.snap +++ b/tests/cli/snapshots/cli__well_tested_tree_finds_no_problems__caught.txt.snap @@ -13,12 +13,18 @@ src/nested_function.rs:2:5: replace has_nested -> u32 with 0 src/nested_function.rs:2:5: replace has_nested -> u32 with 1 src/nested_function.rs:3:9: replace has_nested::inner -> u32 with 0 src/nested_function.rs:3:9: replace has_nested::inner -> u32 with 1 +src/nested_function.rs:5:13: replace * with + in has_nested +src/nested_function.rs:5:13: replace * with / in has_nested src/numbers.rs:2:5: replace double_float -> f32 with 0.0 src/numbers.rs:2:5: replace double_float -> f32 with 1.0 src/numbers.rs:2:5: replace double_float -> f32 with -1.0 +src/numbers.rs:2:9: replace * with + in double_float +src/numbers.rs:2:9: replace * with / in double_float src/numbers.rs:6:5: replace is_double -> bool with true src/numbers.rs:6:5: replace is_double -> bool with false src/numbers.rs:6:7: replace == with != in is_double +src/numbers.rs:6:12: replace * with + in is_double +src/numbers.rs:6:12: replace * with / in is_double src/result.rs:6:5: replace simple_result -> Result<&'static str, ()> with Ok("") src/result.rs:6:5: replace simple_result -> Result<&'static str, ()> with Ok("xyzzy") src/result.rs:10:5: replace error_if_negative -> Result<(), ()> with Ok(()) @@ -34,6 +40,8 @@ src/simple_fns.rs:13:5: replace returns_42u32 -> u32 with 1 src/simple_fns.rs:18:5: replace divisible_by_three -> bool with true src/simple_fns.rs:18:5: replace divisible_by_three -> bool with false src/simple_fns.rs:18:11: replace == with != in divisible_by_three +src/simple_fns.rs:18:7: replace % with / in divisible_by_three +src/simple_fns.rs:18:7: replace % with + in divisible_by_three src/simple_fns.rs:27:5: replace double_string -> String with String::new() src/simple_fns.rs:27:5: replace double_string -> String with "xyzzy".into() src/slices.rs:4:5: replace pad -> &'a[Cow<'static, str>] with Vec::leak(Vec::new()) @@ -47,6 +55,8 @@ src/slices.rs:13:5: replace return_mut_slice -> &mut[usize] with Vec::leak(Vec:: src/slices.rs:13:5: replace return_mut_slice -> &mut[usize] with Vec::leak(vec![0]) src/slices.rs:13:5: replace return_mut_slice -> &mut[usize] with Vec::leak(vec![1]) src/static_item.rs:1:33: replace == with != +src/static_item.rs:1:39: replace + with - +src/static_item.rs:1:39: replace + with * src/struct_with_lifetime.rs:15:9: replace Lex<'buf>::buf_len -> usize with 0 src/struct_with_lifetime.rs:15:9: replace Lex<'buf>::buf_len -> usize with 1 src/traits.rs:5:9: replace Something::is_three -> bool with true diff --git a/tests/cli/workspace.rs b/tests/cli/workspace.rs index 95b5e98a..d622367b 100644 --- a/tests/cli/workspace.rs +++ b/tests/cli/workspace.rs @@ -5,6 +5,7 @@ use std::fs::{self, read_to_string}; use indoc::indoc; +use insta::assert_snapshot; use itertools::Itertools; use serde_json::json; @@ -117,8 +118,9 @@ fn workspace_tree_is_well_tested() { fs::read_to_string(tmp_src_dir.path().join("mutants.out/outcomes.json")).unwrap(); println!("outcomes.json:\n{json_str}"); let json: serde_json::Value = json_str.parse().unwrap(); - assert_eq!(json["total_mutants"].as_u64().unwrap(), 8); - assert_eq!(json["caught"].as_u64().unwrap(), 8); + let total = json["total_mutants"].as_u64().unwrap(); + assert!(total > 8); + assert_eq!(json["caught"].as_u64().unwrap(), total); assert_eq!(json["missed"].as_u64().unwrap(), 0); assert_eq!(json["timeout"].as_u64().unwrap(), 0); let outcomes = json["outcomes"].as_array().unwrap(); @@ -148,7 +150,7 @@ fn workspace_tree_is_well_tested() { ); } - assert_eq!(outcomes.len(), 9); + assert!(outcomes.len() > 9); for outcome in &outcomes[1..] { let mutant = &outcome["scenario"]["Mutant"]; let package_name = mutant["package"].as_str().unwrap(); @@ -200,13 +202,14 @@ fn in_workspace_only_relevant_packages_included_in_baseline_tests_by_file_filter .arg(tmp.path()) .assert() .success(); - assert_eq!( + assert_snapshot!( read_to_string(tmp.path().join("mutants.out/caught.txt")).unwrap(), - indoc! { "\ - passing/src/lib.rs:2:5: replace triple -> usize with 0 - passing/src/lib.rs:2:5: replace triple -> usize with 1 - "} - ); + @r###" + passing/src/lib.rs:2:5: replace triple -> usize with 0 + passing/src/lib.rs:2:5: replace triple -> usize with 1 + passing/src/lib.rs:2:7: replace * with + in triple + passing/src/lib.rs:2:7: replace * with / in triple + "###); assert_eq!( read_to_string(tmp.path().join("mutants.out/timeout.txt")).unwrap(), "" @@ -237,12 +240,14 @@ fn baseline_test_respects_package_options() { .arg(tmp.path()) .assert() .success(); - assert_eq!( + assert_snapshot!( read_to_string(tmp.path().join("mutants.out/caught.txt")).unwrap(), - indoc! { "\ - passing/src/lib.rs:2:5: replace triple -> usize with 0 - passing/src/lib.rs:2:5: replace triple -> usize with 1 - "} + @r###" + passing/src/lib.rs:2:5: replace triple -> usize with 0 + passing/src/lib.rs:2:5: replace triple -> usize with 1 + passing/src/lib.rs:2:7: replace * with + in triple + passing/src/lib.rs:2:7: replace * with / in triple + "### ); assert_eq!( read_to_string(tmp.path().join("mutants.out/timeout.txt")).unwrap(), From 5ccdcd26333bbb9081d5e7267aa7f5fa0b132d62 Mon Sep 17 00:00:00 2001 From: Martin Pool Date: Sun, 17 Dec 2023 19:55:27 +1000 Subject: [PATCH 05/11] Update expected own mutants --- ...ants__visit__test__expected_mutants_for_own_source_tree.snap | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/snapshots/cargo_mutants__visit__test__expected_mutants_for_own_source_tree.snap b/src/snapshots/cargo_mutants__visit__test__expected_mutants_for_own_source_tree.snap index 880f19aa..34b62da0 100644 --- a/src/snapshots/cargo_mutants__visit__test__expected_mutants_for_own_source_tree.snap +++ b/src/snapshots/cargo_mutants__visit__test__expected_mutants_for_own_source_tree.snap @@ -476,6 +476,8 @@ src/scenario.rs: replace Scenario::log_file_name_base -> String with "xyzzy".int src/shard.rs: replace Shard::select -> Vec with vec![] src/shard.rs: replace Shard::select -> Vec with vec![Default::default()] src/shard.rs: replace == with != in Shard::select +src/shard.rs: replace % with / in Shard::select +src/shard.rs: replace % with + in Shard::select src/shard.rs: replace ::from_str -> Result with Ok(Default::default()) src/shard.rs: replace ::from_str -> Result with Err(::anyhow::anyhow!("mutated!")) src/source.rs: replace SourceFile::tree_relative_slashes -> String with String::new() From eb9c3bfa367f5132921c51171df904745138b44a Mon Sep 17 00:00:00 2001 From: Martin Pool Date: Mon, 18 Dec 2023 07:17:30 +1000 Subject: [PATCH 06/11] More binary operators --- ..._expected_mutants_for_own_source_tree.snap | 5 ++ src/visit.rs | 7 ++- ...li__list_mutants_in_all_trees_as_json.snap | 60 +++++++++++++++++++ ...li__list_mutants_in_all_trees_as_text.snap | 2 + 4 files changed, 73 insertions(+), 1 deletion(-) diff --git a/src/snapshots/cargo_mutants__visit__test__expected_mutants_for_own_source_tree.snap b/src/snapshots/cargo_mutants__visit__test__expected_mutants_for_own_source_tree.snap index 34b62da0..15e2451d 100644 --- a/src/snapshots/cargo_mutants__visit__test__expected_mutants_for_own_source_tree.snap +++ b/src/snapshots/cargo_mutants__visit__test__expected_mutants_for_own_source_tree.snap @@ -89,6 +89,7 @@ src/console.rs: replace > with < in ::render src/console.rs: replace > with == in ::render src/console.rs: replace > with < in ::render src/console.rs: replace - with + in ::render +src/console.rs: replace - with / in ::render src/console.rs: replace / with % in ::render src/console.rs: replace / with * in ::render src/console.rs: replace * with + in ::render @@ -195,6 +196,7 @@ src/in_diff.rs: replace diff_filter -> Result> with Err(::anyhow::an src/in_diff.rs: replace check_diff_new_text_matches -> Result<()> with Ok(()) src/in_diff.rs: replace check_diff_new_text_matches -> Result<()> with Err(::anyhow::anyhow!("mutated!")) src/in_diff.rs: replace - with + in check_diff_new_text_matches +src/in_diff.rs: replace - with / in check_diff_new_text_matches src/in_diff.rs: replace != with == in check_diff_new_text_matches src/in_diff.rs: replace strip_patch_path -> &Utf8Path with &Default::default() src/in_diff.rs: replace affected_lines -> Vec with vec![] @@ -210,7 +212,9 @@ src/in_diff.rs: replace > with < in affected_lines src/in_diff.rs: replace < with == in affected_lines src/in_diff.rs: replace < with > in affected_lines src/in_diff.rs: replace - with + in affected_lines +src/in_diff.rs: replace - with / in affected_lines src/in_diff.rs: replace - with + in affected_lines +src/in_diff.rs: replace - with / in affected_lines src/in_diff.rs: replace partial_new_file -> Vec<(usize, &'d str)> with vec![] src/in_diff.rs: replace partial_new_file -> Vec<(usize, &'d str)> with vec![(0, "")] src/in_diff.rs: replace partial_new_file -> Vec<(usize, &'d str)> with vec![(0, "xyzzy")] @@ -221,6 +225,7 @@ src/lab.rs: replace test_mutants -> Result with Ok(Default::default( src/lab.rs: replace test_mutants -> Result with Err(::anyhow::anyhow!("mutated!")) src/lab.rs: replace == with != in test_mutants src/lab.rs: replace - with + in test_mutants +src/lab.rs: replace - with / in test_mutants src/lab.rs: replace == with != in test_mutants src/lab.rs: replace == with != in test_mutants src/lab.rs: replace test_scenario -> Result with Ok(Default::default()) diff --git a/src/visit.rs b/src/visit.rs index 6951cd1d..524febcf 100644 --- a/src/visit.rs +++ b/src/visit.rs @@ -368,10 +368,15 @@ impl<'ast> Visit<'ast> for DiscoveryVisitor<'_> { BinOp::Le(_) => vec![quote! {>}], BinOp::Ge(_) => vec![quote! {<}], BinOp::Add(_) => vec![quote! {-}, quote! {*}], - BinOp::Sub(_) => vec![quote! {+}], + BinOp::Sub(_) => vec![quote! {+}, quote! {/}], BinOp::Mul(_) => vec![quote! {+}, quote! {/}], BinOp::Div(_) => vec![quote! {%}, quote! {*}], BinOp::Rem(_) => vec![quote! {/}, quote! {+}], + BinOp::Shl(_) => vec![quote! {>>}], + BinOp::Shr(_) => vec![quote! {<<}], + BinOp::BitAnd(_) => vec![quote! {|}, quote! {^}], + BinOp::BitOr(_) => vec![quote! {&}, quote! {^}], + BinOp::BitXor(_) => vec![quote! {|}, quote! {&}], _ => { trace!( op = i.op.to_pretty_string(), diff --git a/tests/cli/snapshots/cli__list_mutants_in_all_trees_as_json.snap b/tests/cli/snapshots/cli__list_mutants_in_all_trees_as_json.snap index 8500ee5c..7c73d9a6 100644 --- a/tests/cli/snapshots/cli__list_mutants_in_all_trees_as_json.snap +++ b/tests/cli/snapshots/cli__list_mutants_in_all_trees_as_json.snap @@ -1839,6 +1839,66 @@ expression: buf "line": 2 } } + }, + { + "file": "src/lib.rs", + "function": { + "function_name": "is_symlink", + "return_type": "-> bool", + "span": { + "end": { + "column": 2, + "line": 3 + }, + "start": { + "column": 1, + "line": 1 + } + } + }, + "genre": "BinaryOperator", + "package": "cargo-mutants-testdata-missing-test", + "replacement": "|", + "span": { + "end": { + "column": 16, + "line": 2 + }, + "start": { + "column": 15, + "line": 2 + } + } + }, + { + "file": "src/lib.rs", + "function": { + "function_name": "is_symlink", + "return_type": "-> bool", + "span": { + "end": { + "column": 2, + "line": 3 + }, + "start": { + "column": 1, + "line": 1 + } + } + }, + "genre": "BinaryOperator", + "package": "cargo-mutants-testdata-missing-test", + "replacement": "^", + "span": { + "end": { + "column": 16, + "line": 2 + }, + "start": { + "column": 15, + "line": 2 + } + } } ] ``` diff --git a/tests/cli/snapshots/cli__list_mutants_in_all_trees_as_text.snap b/tests/cli/snapshots/cli__list_mutants_in_all_trees_as_text.snap index c09d1a0a..b9530da4 100644 --- a/tests/cli/snapshots/cli__list_mutants_in_all_trees_as_text.snap +++ b/tests/cli/snapshots/cli__list_mutants_in_all_trees_as_text.snap @@ -152,6 +152,8 @@ src/lib.rs:2:7: replace * with / in double src/lib.rs:2:5: replace is_symlink -> bool with true src/lib.rs:2:5: replace is_symlink -> bool with false src/lib.rs:2:26: replace != with == in is_symlink +src/lib.rs:2:15: replace & with | in is_symlink +src/lib.rs:2:15: replace & with ^ in is_symlink ``` ## testdata/mut_ref From dbf18c93ded42e71efe47fadad86bd84245f5454 Mon Sep 17 00:00:00 2001 From: Martin Pool Date: Mon, 18 Dec 2023 07:38:03 +1000 Subject: [PATCH 07/11] Mutate assignment ops --- NEWS.md | 2 +- src/mutate.rs | 4 +- ..._expected_mutants_for_own_source_tree.snap | 54 ++ src/visit.rs | 11 + tests/cli/config.rs | 12 +- tests/cli/main.rs | 2 +- .../cli__cdylib_tree_is_well_tested.snap | 6 +- ...s_in_tree_that_builds_but_fails_tests.snap | 6 +- .../snapshots/cli__factorial__log_names.snap | 2 + ...cli__factorial_mutants_no_copy_target.snap | 4 +- ...li__list_mutants_in_all_trees_as_json.snap | 624 +++++++++++++++++- ...li__list_mutants_in_all_trees_as_text.snap | 20 + .../cli__list_mutants_in_factorial.snap | 2 + .../cli__list_mutants_in_factorial_json.snap | 60 ++ .../cli__list_mutants_json_well_tested.snap | 180 +++++ .../cli__list_mutants_well_tested.snap | 6 + ...tants_well_tested_exclude_name_filter.snap | 4 + ..._list_mutants_with_diffs_in_factorial.snap | 46 ++ .../cli__list_mutants_with_dir_option.snap | 2 + tests/cli/snapshots/cli__mutants.json.snap | 60 ++ ...tested_mutants_with_cargo_arg_release.snap | 4 +- .../cli__small_well_tested_tree_is_clean.snap | 6 +- .../cli__uncaught_mutant_in_factorial.snap | 4 +- ...aught_mutant_in_factorial__caught.txt.snap | 2 + .../cli__well_tested_tree_check_only.snap | 10 +- ...i__well_tested_tree_finds_no_problems.snap | 10 +- ...ed_tree_finds_no_problems__caught.txt.snap | 6 + tests/cli/workspace.rs | 9 +- 28 files changed, 1112 insertions(+), 46 deletions(-) diff --git a/NEWS.md b/NEWS.md index 036712a3..c55c7e0d 100644 --- a/NEWS.md +++ b/NEWS.md @@ -6,7 +6,7 @@ - Improved: Better documentation about `-j`, with stronger recommendations not to set it too high. -- Mutate `+, -, *, /, %` binary ops. +- New: Mutate `+, -, *, /, %, &, ^, |, <<, >>` binary ops, and their corresponding assignment ops like `+=`. ## 23.12.1 diff --git a/src/mutate.rs b/src/mutate.rs index 25ebb7b2..a3fc32e1 100644 --- a/src/mutate.rs +++ b/src/mutate.rs @@ -250,7 +250,7 @@ mod test { let mutants = workspace .mutants(&PackageFilter::All, &options, &Console::new()) .unwrap(); - assert_eq!(mutants.len(), 3); + assert_eq!(mutants.len(), 5); assert_eq!( format!("{:#?}", mutants[0]), indoc! { @@ -332,7 +332,7 @@ mod test { &Options::default(), &Console::new(), )?; - assert_eq!(mutants.len(), 3); + assert_eq!(mutants.len(), 5); let mutated_code = mutants[0].mutated_code(); assert_eq!(mutants[0].function.as_ref().unwrap().function_name, "main"); diff --git a/src/snapshots/cargo_mutants__visit__test__expected_mutants_for_own_source_tree.snap b/src/snapshots/cargo_mutants__visit__test__expected_mutants_for_own_source_tree.snap index 15e2451d..ae85c470 100644 --- a/src/snapshots/cargo_mutants__visit__test__expected_mutants_for_own_source_tree.snap +++ b/src/snapshots/cargo_mutants__visit__test__expected_mutants_for_own_source_tree.snap @@ -33,6 +33,20 @@ src/console.rs: replace Console::walk_tree_done with () src/console.rs: replace Console::scenario_started -> Result<()> with Ok(()) src/console.rs: replace Console::scenario_started -> Result<()> with Err(::anyhow::anyhow!("mutated!")) src/console.rs: replace Console::scenario_finished with () +src/console.rs: replace += with -= in Console::scenario_finished +src/console.rs: replace += with *= in Console::scenario_finished +src/console.rs: replace += with -= in Console::scenario_finished +src/console.rs: replace += with *= in Console::scenario_finished +src/console.rs: replace += with -= in Console::scenario_finished +src/console.rs: replace += with *= in Console::scenario_finished +src/console.rs: replace += with -= in Console::scenario_finished +src/console.rs: replace += with *= in Console::scenario_finished +src/console.rs: replace += with -= in Console::scenario_finished +src/console.rs: replace += with *= in Console::scenario_finished +src/console.rs: replace += with -= in Console::scenario_finished +src/console.rs: replace += with *= in Console::scenario_finished +src/console.rs: replace += with -= in Console::scenario_finished +src/console.rs: replace += with *= in Console::scenario_finished src/console.rs: replace || with && in Console::scenario_finished src/console.rs: replace || with == in Console::scenario_finished src/console.rs: replace || with != in Console::scenario_finished @@ -78,6 +92,8 @@ src/console.rs: replace ::flush -> io::Result<()> src/console.rs: replace ::flush -> io::Result<()> with Err(::anyhow::anyhow!("mutated!")) src/console.rs: replace ::render -> String with String::new() src/console.rs: replace ::render -> String with "xyzzy".into() +src/console.rs: replace += with -= in ::render +src/console.rs: replace += with *= in ::render src/console.rs: replace > with == in ::render src/console.rs: replace > with < in ::render src/console.rs: replace > with == in ::render @@ -146,6 +162,10 @@ src/console.rs: replace plural -> String with "xyzzy".into() src/console.rs: replace == with != in plural src/copy_tree.rs: replace copy_tree -> Result with Ok(Default::default()) src/copy_tree.rs: replace copy_tree -> Result with Err(::anyhow::anyhow!("mutated!")) +src/copy_tree.rs: replace += with -= in copy_tree +src/copy_tree.rs: replace += with *= in copy_tree +src/copy_tree.rs: replace += with -= in copy_tree +src/copy_tree.rs: replace += with *= in copy_tree src/copy_tree.rs: replace copy_symlink -> Result<()> with Ok(()) src/copy_tree.rs: replace copy_symlink -> Result<()> with Err(::anyhow::anyhow!("mutated!")) src/fnvalue.rs: replace return_type_replacements -> Vec with vec![] @@ -202,8 +222,12 @@ src/in_diff.rs: replace strip_patch_path -> &Utf8Path with &Default::default() src/in_diff.rs: replace affected_lines -> Vec with vec![] src/in_diff.rs: replace affected_lines -> Vec with vec![0] src/in_diff.rs: replace affected_lines -> Vec with vec![1] +src/in_diff.rs: replace += with -= in affected_lines +src/in_diff.rs: replace += with *= in affected_lines src/in_diff.rs: replace < with == in affected_lines src/in_diff.rs: replace < with > in affected_lines +src/in_diff.rs: replace += with -= in affected_lines +src/in_diff.rs: replace += with *= in affected_lines src/in_diff.rs: replace && with || in affected_lines src/in_diff.rs: replace && with == in affected_lines src/in_diff.rs: replace && with != in affected_lines @@ -220,6 +244,8 @@ src/in_diff.rs: replace partial_new_file -> Vec<(usize, &'d str)> with vec![(0, src/in_diff.rs: replace partial_new_file -> Vec<(usize, &'d str)> with vec![(0, "xyzzy")] src/in_diff.rs: replace partial_new_file -> Vec<(usize, &'d str)> with vec![(1, "")] src/in_diff.rs: replace partial_new_file -> Vec<(usize, &'d str)> with vec![(1, "xyzzy")] +src/in_diff.rs: replace += with -= in partial_new_file +src/in_diff.rs: replace += with *= in partial_new_file src/interrupt.rs: replace install_handler with () src/lab.rs: replace test_mutants -> Result with Ok(Default::default()) src/lab.rs: replace test_mutants -> Result with Err(::anyhow::anyhow!("mutated!")) @@ -334,6 +360,20 @@ src/outcome.rs: replace Phase::name -> &'static str with "xyzzy" src/outcome.rs: replace ::fmt -> fmt::Result with Ok(Default::default()) src/outcome.rs: replace ::fmt -> fmt::Result with Err(::anyhow::anyhow!("mutated!")) src/outcome.rs: replace LabOutcome::add with () +src/outcome.rs: replace += with -= in LabOutcome::add +src/outcome.rs: replace += with *= in LabOutcome::add +src/outcome.rs: replace += with -= in LabOutcome::add +src/outcome.rs: replace += with *= in LabOutcome::add +src/outcome.rs: replace += with -= in LabOutcome::add +src/outcome.rs: replace += with *= in LabOutcome::add +src/outcome.rs: replace += with -= in LabOutcome::add +src/outcome.rs: replace += with *= in LabOutcome::add +src/outcome.rs: replace += with -= in LabOutcome::add +src/outcome.rs: replace += with *= in LabOutcome::add +src/outcome.rs: replace += with -= in LabOutcome::add +src/outcome.rs: replace += with *= in LabOutcome::add +src/outcome.rs: replace += with -= in LabOutcome::add +src/outcome.rs: replace += with *= in LabOutcome::add src/outcome.rs: replace LabOutcome::exit_code -> i32 with 0 src/outcome.rs: replace LabOutcome::exit_code -> i32 with 1 src/outcome.rs: replace LabOutcome::exit_code -> i32 with -1 @@ -427,7 +467,11 @@ src/path.rs: replace ascent -> isize with 0 src/path.rs: replace ascent -> isize with 1 src/path.rs: replace ascent -> isize with -1 src/path.rs: replace == with != in ascent +src/path.rs: replace += with -= in ascent +src/path.rs: replace += with *= in ascent src/path.rs: replace != with == in ascent +src/path.rs: replace -= with += in ascent +src/path.rs: replace -= with /= in ascent src/path.rs: replace > with == in ascent src/path.rs: replace > with < in ascent src/path.rs: replace ::to_slash_path -> String with String::new() @@ -453,6 +497,8 @@ src/pretty.rs: replace == with != in ::to_pretty_stri src/pretty.rs: replace || with && in ::to_pretty_string src/pretty.rs: replace || with == in ::to_pretty_string src/pretty.rs: replace || with != in ::to_pretty_string +src/pretty.rs: replace += with -= in ::to_pretty_string +src/pretty.rs: replace += with *= in ::to_pretty_string src/process.rs: replace Process::run -> Result with Ok(Default::default()) src/process.rs: replace Process::run -> Result with Err(::anyhow::anyhow!("mutated!")) src/process.rs: replace Process::start -> Result with Ok(Default::default()) @@ -523,9 +569,13 @@ src/span.rs: replace == with != in Span::extract src/span.rs: replace < with == in Span::extract src/span.rs: replace < with > in Span::extract src/span.rs: replace == with != in Span::extract +src/span.rs: replace += with -= in Span::extract +src/span.rs: replace += with *= in Span::extract src/span.rs: replace > with == in Span::extract src/span.rs: replace > with < in Span::extract src/span.rs: replace == with != in Span::extract +src/span.rs: replace += with -= in Span::extract +src/span.rs: replace += with *= in Span::extract src/span.rs: replace && with || in Span::extract src/span.rs: replace && with == in Span::extract src/span.rs: replace && with != in Span::extract @@ -565,7 +615,11 @@ src/span.rs: replace && with != in Span::replace src/span.rs: replace == with != in Span::replace src/span.rs: replace >= with < in Span::replace src/span.rs: replace == with != in Span::replace +src/span.rs: replace += with -= in Span::replace +src/span.rs: replace += with *= in Span::replace src/span.rs: replace == with != in Span::replace +src/span.rs: replace += with -= in Span::replace +src/span.rs: replace += with *= in Span::replace src/span.rs: replace && with || in Span::replace src/span.rs: replace && with == in Span::replace src/span.rs: replace && with != in Span::replace diff --git a/src/visit.rs b/src/visit.rs index 524febcf..7cffa92b 100644 --- a/src/visit.rs +++ b/src/visit.rs @@ -9,6 +9,7 @@ use std::collections::VecDeque; use std::sync::Arc; +use std::vec; use anyhow::Context; use proc_macro2::{Ident, TokenStream}; @@ -368,15 +369,25 @@ impl<'ast> Visit<'ast> for DiscoveryVisitor<'_> { BinOp::Le(_) => vec![quote! {>}], BinOp::Ge(_) => vec![quote! {<}], BinOp::Add(_) => vec![quote! {-}, quote! {*}], + BinOp::AddAssign(_) => vec![quote! {-=}, quote! {*=}], BinOp::Sub(_) => vec![quote! {+}, quote! {/}], + BinOp::SubAssign(_) => vec![quote! {+=}, quote! {/=}], BinOp::Mul(_) => vec![quote! {+}, quote! {/}], + BinOp::MulAssign(_) => vec![quote! {+=}, quote! {/=}], BinOp::Div(_) => vec![quote! {%}, quote! {*}], + BinOp::DivAssign(_) => vec![quote! {%=}, quote! {*=}], BinOp::Rem(_) => vec![quote! {/}, quote! {+}], + BinOp::RemAssign(_) => vec![quote! {/=}, quote! {+=}], BinOp::Shl(_) => vec![quote! {>>}], + BinOp::ShlAssign(_) => vec![quote! {>>=}], BinOp::Shr(_) => vec![quote! {<<}], + BinOp::ShrAssign(_) => vec![quote! {<<=}], BinOp::BitAnd(_) => vec![quote! {|}, quote! {^}], + BinOp::BitAndAssign(_) => vec![quote! {|=}, quote! {^=}], BinOp::BitOr(_) => vec![quote! {&}, quote! {^}], + BinOp::BitOrAssign(_) => vec![quote! {&=}, quote! {^=}], BinOp::BitXor(_) => vec![quote! {|}, quote! {&}], + BinOp::BitXorAssign(_) => vec![quote! {|=}, quote! {&=}], _ => { trace!( op = i.op.to_pretty_string(), diff --git a/tests/cli/config.rs b/tests/cli/config.rs index ba72a970..1b2d2296 100644 --- a/tests/cli/config.rs +++ b/tests/cli/config.rs @@ -207,6 +207,8 @@ fn exclude_re_overrides_config() { String::from_utf8_lossy(&cmd.get_output().stdout), @r###" src/simple_fns.rs: replace returns_unit with () + src/simple_fns.rs: replace += with -= in returns_unit + src/simple_fns.rs: replace += with *= in returns_unit src/simple_fns.rs: replace == with != in divisible_by_three src/simple_fns.rs: replace % with / in divisible_by_three src/simple_fns.rs: replace % with + in divisible_by_three @@ -230,8 +232,6 @@ fn tree_fails_without_needed_feature() { #[test] fn additional_cargo_args() { - // The point of this tree is to check that Cargo features can be turned on, - // but let's make sure it does fail as intended if they're not. let testdata = copy_of_testdata("fails_without_feature"); write_config_file( &testdata, @@ -243,14 +243,11 @@ fn additional_cargo_args() { .args(["mutants", "-d"]) .arg(testdata.path()) .assert() - .success() - .stdout(predicates::str::contains("2 caught")); + .success(); } #[test] fn additional_cargo_test_args() { - // The point of this tree is to check that Cargo features can be turned on, - // but let's make sure it does fail as intended if they're not. let testdata = copy_of_testdata("fails_without_feature"); write_config_file( &testdata, @@ -262,6 +259,5 @@ fn additional_cargo_test_args() { .args(["mutants", "-d"]) .arg(testdata.path()) .assert() - .success() - .stdout(predicates::str::contains("2 caught")); + .success(); } diff --git a/tests/cli/main.rs b/tests/cli/main.rs index f3febe3c..d217bd08 100644 --- a/tests/cli/main.rs +++ b/tests/cli/main.rs @@ -170,7 +170,7 @@ fn list_diff_json_contains_diffs() { println!("{}", String::from_utf8_lossy(&out.stdout)); let out_json = serde_json::from_slice::(&out.stdout).unwrap(); let mutants_json = out_json.as_array().expect("json output is array"); - assert_eq!(mutants_json.len(), 3); + assert_eq!(mutants_json.len(), 5); assert!(mutants_json.iter().all(|e| e.as_object().unwrap()["diff"] .as_str() .unwrap() diff --git a/tests/cli/snapshots/cli__cdylib_tree_is_well_tested.snap b/tests/cli/snapshots/cli__cdylib_tree_is_well_tested.snap index b73706a7..7a9305e3 100644 --- a/tests/cli/snapshots/cli__cdylib_tree_is_well_tested.snap +++ b/tests/cli/snapshots/cli__cdylib_tree_is_well_tested.snap @@ -2,9 +2,11 @@ source: tests/cli/main.rs expression: stdout --- -Found 2 mutants to test +Found 4 mutants to test ok Unmutated baseline caught src/entry.rs:2:5: replace factorial -> u32 with 0 caught src/entry.rs:2:5: replace factorial -> u32 with 1 -2 mutants tested: 2 caught +caught src/entry.rs:4:11: replace *= with += in factorial +caught src/entry.rs:4:11: replace *= with /= in factorial +4 mutants tested: 4 caught diff --git a/tests/cli/snapshots/cli__check_succeeds_in_tree_that_builds_but_fails_tests.snap b/tests/cli/snapshots/cli__check_succeeds_in_tree_that_builds_but_fails_tests.snap index b7b0fd03..827b6f03 100644 --- a/tests/cli/snapshots/cli__check_succeeds_in_tree_that_builds_but_fails_tests.snap +++ b/tests/cli/snapshots/cli__check_succeeds_in_tree_that_builds_but_fails_tests.snap @@ -2,9 +2,11 @@ source: tests/cli/main.rs expression: stdout --- -Found 2 mutants to test +Found 4 mutants to test ok Unmutated baseline ok src/lib.rs:2:5: replace factorial -> u32 with 0 ok src/lib.rs:2:5: replace factorial -> u32 with 1 -2 mutants tested: 2 succeeded +ok src/lib.rs:4:11: replace *= with += in factorial +ok src/lib.rs:4:11: replace *= with /= in factorial +4 mutants tested: 4 succeeded diff --git a/tests/cli/snapshots/cli__factorial__log_names.snap b/tests/cli/snapshots/cli__factorial__log_names.snap index fff4f17b..a0b3f34f 100644 --- a/tests/cli/snapshots/cli__factorial__log_names.snap +++ b/tests/cli/snapshots/cli__factorial__log_names.snap @@ -4,6 +4,8 @@ expression: "&names" --- [ "baseline.log", + "src__bin__factorial.rs_line_10_col_11.log", + "src__bin__factorial.rs_line_10_col_11_001.log", "src__bin__factorial.rs_line_2_col_5.log", "src__bin__factorial.rs_line_8_col_5.log", "src__bin__factorial.rs_line_8_col_5_001.log", diff --git a/tests/cli/snapshots/cli__factorial_mutants_no_copy_target.snap b/tests/cli/snapshots/cli__factorial_mutants_no_copy_target.snap index 75d3521f..cc9fc1c1 100644 --- a/tests/cli/snapshots/cli__factorial_mutants_no_copy_target.snap +++ b/tests/cli/snapshots/cli__factorial_mutants_no_copy_target.snap @@ -2,8 +2,8 @@ source: tests/cli/main.rs expression: stdout --- -Found 3 mutants to test +Found 5 mutants to test ok Unmutated baseline MISSED src/bin/factorial.rs:2:5: replace main with () -3 mutants tested: 1 missed, 2 caught +5 mutants tested: 1 missed, 4 caught diff --git a/tests/cli/snapshots/cli__list_mutants_in_all_trees_as_json.snap b/tests/cli/snapshots/cli__list_mutants_in_all_trees_as_json.snap index 7c73d9a6..4f339b91 100644 --- a/tests/cli/snapshots/cli__list_mutants_in_all_trees_as_json.snap +++ b/tests/cli/snapshots/cli__list_mutants_in_all_trees_as_json.snap @@ -192,6 +192,66 @@ expression: buf "line": 2 } } + }, + { + "file": "src/lib.rs", + "function": { + "function_name": "factorial", + "return_type": "-> u32", + "span": { + "end": { + "column": 2, + "line": 7 + }, + "start": { + "column": 1, + "line": 1 + } + } + }, + "genre": "BinaryOperator", + "package": "mutants-testdata-already-failing-tests", + "replacement": "+=", + "span": { + "end": { + "column": 13, + "line": 4 + }, + "start": { + "column": 11, + "line": 4 + } + } + }, + { + "file": "src/lib.rs", + "function": { + "function_name": "factorial", + "return_type": "-> u32", + "span": { + "end": { + "column": 2, + "line": 7 + }, + "start": { + "column": 1, + "line": 1 + } + } + }, + "genre": "BinaryOperator", + "package": "mutants-testdata-already-failing-tests", + "replacement": "/=", + "span": { + "end": { + "column": 13, + "line": 4 + }, + "start": { + "column": 11, + "line": 4 + } + } } ] ``` @@ -296,6 +356,66 @@ expression: buf "line": 2 } } + }, + { + "file": "src/entry.rs", + "function": { + "function_name": "factorial", + "return_type": "-> u32", + "span": { + "end": { + "column": 2, + "line": 7 + }, + "start": { + "column": 1, + "line": 1 + } + } + }, + "genre": "BinaryOperator", + "package": "cargo-mutants-testdata-cdylib", + "replacement": "+=", + "span": { + "end": { + "column": 13, + "line": 4 + }, + "start": { + "column": 11, + "line": 4 + } + } + }, + { + "file": "src/entry.rs", + "function": { + "function_name": "factorial", + "return_type": "-> u32", + "span": { + "end": { + "column": 2, + "line": 7 + }, + "start": { + "column": 1, + "line": 1 + } + } + }, + "genre": "BinaryOperator", + "package": "cargo-mutants-testdata-cdylib", + "replacement": "/=", + "span": { + "end": { + "column": 13, + "line": 4 + }, + "start": { + "column": 11, + "line": 4 + } + } } ] ``` @@ -653,6 +773,66 @@ expression: buf "line": 2 } } + }, + { + "file": "src/lib.rs", + "function": { + "function_name": "factorial", + "return_type": "-> u32", + "span": { + "end": { + "column": 2, + "line": 7 + }, + "start": { + "column": 1, + "line": 1 + } + } + }, + "genre": "BinaryOperator", + "package": "cargo-mutants-testdata-dependency", + "replacement": "+=", + "span": { + "end": { + "column": 13, + "line": 4 + }, + "start": { + "column": 11, + "line": 4 + } + } + }, + { + "file": "src/lib.rs", + "function": { + "function_name": "factorial", + "return_type": "-> u32", + "span": { + "end": { + "column": 2, + "line": 7 + }, + "start": { + "column": 1, + "line": 1 + } + } + }, + "genre": "BinaryOperator", + "package": "cargo-mutants-testdata-dependency", + "replacement": "/=", + "span": { + "end": { + "column": 13, + "line": 4 + }, + "start": { + "column": 11, + "line": 4 + } + } } ] ``` @@ -1077,6 +1257,66 @@ expression: buf "line": 8 } } + }, + { + "file": "src/bin/factorial.rs", + "function": { + "function_name": "factorial", + "return_type": "-> u32", + "span": { + "end": { + "column": 2, + "line": 13 + }, + "start": { + "column": 1, + "line": 7 + } + } + }, + "genre": "BinaryOperator", + "package": "cargo-mutants-testdata-factorial", + "replacement": "+=", + "span": { + "end": { + "column": 13, + "line": 10 + }, + "start": { + "column": 11, + "line": 10 + } + } + }, + { + "file": "src/bin/factorial.rs", + "function": { + "function_name": "factorial", + "return_type": "-> u32", + "span": { + "end": { + "column": 2, + "line": 13 + }, + "start": { + "column": 1, + "line": 7 + } + } + }, + "genre": "BinaryOperator", + "package": "cargo-mutants-testdata-factorial", + "replacement": "/=", + "span": { + "end": { + "column": 13, + "line": 10 + }, + "start": { + "column": 11, + "line": 10 + } + } } ] ``` @@ -1144,6 +1384,66 @@ expression: buf "line": 10 } } + }, + { + "file": "src/bin/factorial.rs", + "function": { + "function_name": "factorial", + "return_type": "-> u32", + "span": { + "end": { + "column": 2, + "line": 15 + }, + "start": { + "column": 1, + "line": 8 + } + } + }, + "genre": "BinaryOperator", + "package": "cargo-mutants-testdata-fails-without-feature", + "replacement": "+=", + "span": { + "end": { + "column": 13, + "line": 12 + }, + "start": { + "column": 11, + "line": 12 + } + } + }, + { + "file": "src/bin/factorial.rs", + "function": { + "function_name": "factorial", + "return_type": "-> u32", + "span": { + "end": { + "column": 2, + "line": 15 + }, + "start": { + "column": 1, + "line": 8 + } + } + }, + "genre": "BinaryOperator", + "package": "cargo-mutants-testdata-fails-without-feature", + "replacement": "/=", + "span": { + "end": { + "column": 13, + "line": 12 + }, + "start": { + "column": 11, + "line": 12 + } + } } ] ``` @@ -2998,17 +3298,77 @@ expression: buf } } }, - "genre": "FnValue", + "genre": "FnValue", + "package": "cargo-mutants-testdata-small-well-tested", + "replacement": "0", + "span": { + "end": { + "column": 6, + "line": 9 + }, + "start": { + "column": 5, + "line": 5 + } + } + }, + { + "file": "src/lib.rs", + "function": { + "function_name": "factorial", + "return_type": "-> u32", + "span": { + "end": { + "column": 2, + "line": 10 + }, + "start": { + "column": 1, + "line": 4 + } + } + }, + "genre": "FnValue", + "package": "cargo-mutants-testdata-small-well-tested", + "replacement": "1", + "span": { + "end": { + "column": 6, + "line": 9 + }, + "start": { + "column": 5, + "line": 5 + } + } + }, + { + "file": "src/lib.rs", + "function": { + "function_name": "factorial", + "return_type": "-> u32", + "span": { + "end": { + "column": 2, + "line": 10 + }, + "start": { + "column": 1, + "line": 4 + } + } + }, + "genre": "BinaryOperator", "package": "cargo-mutants-testdata-small-well-tested", - "replacement": "0", + "replacement": "+=", "span": { "end": { - "column": 6, - "line": 9 + "column": 13, + "line": 7 }, "start": { - "column": 5, - "line": 5 + "column": 11, + "line": 7 } } }, @@ -3028,17 +3388,17 @@ expression: buf } } }, - "genre": "FnValue", + "genre": "BinaryOperator", "package": "cargo-mutants-testdata-small-well-tested", - "replacement": "1", + "replacement": "/=", "span": { "end": { - "column": 6, - "line": 9 + "column": 13, + "line": 7 }, "start": { - "column": 5, - "line": 5 + "column": 11, + "line": 7 } } } @@ -3750,6 +4110,66 @@ expression: buf } } }, + { + "file": "src/methods.rs", + "function": { + "function_name": "Foo::double", + "return_type": "", + "span": { + "end": { + "column": 6, + "line": 18 + }, + "start": { + "column": 5, + "line": 16 + } + } + }, + "genre": "BinaryOperator", + "package": "cargo-mutants-testdata-well-tested", + "replacement": "+=", + "span": { + "end": { + "column": 18, + "line": 17 + }, + "start": { + "column": 16, + "line": 17 + } + } + }, + { + "file": "src/methods.rs", + "function": { + "function_name": "Foo::double", + "return_type": "", + "span": { + "end": { + "column": 6, + "line": 18 + }, + "start": { + "column": 5, + "line": 16 + } + } + }, + "genre": "BinaryOperator", + "package": "cargo-mutants-testdata-well-tested", + "replacement": "/=", + "span": { + "end": { + "column": 18, + "line": 17 + }, + "start": { + "column": 16, + "line": 17 + } + } + }, { "file": "src/methods.rs", "function": { @@ -4590,6 +5010,66 @@ expression: buf } } }, + { + "file": "src/simple_fns.rs", + "function": { + "function_name": "returns_unit", + "return_type": "", + "span": { + "end": { + "column": 2, + "line": 9 + }, + "start": { + "column": 1, + "line": 7 + } + } + }, + "genre": "BinaryOperator", + "package": "cargo-mutants-testdata-well-tested", + "replacement": "-=", + "span": { + "end": { + "column": 10, + "line": 8 + }, + "start": { + "column": 8, + "line": 8 + } + } + }, + { + "file": "src/simple_fns.rs", + "function": { + "function_name": "returns_unit", + "return_type": "", + "span": { + "end": { + "column": 2, + "line": 9 + }, + "start": { + "column": 1, + "line": 7 + } + } + }, + "genre": "BinaryOperator", + "package": "cargo-mutants-testdata-well-tested", + "replacement": "*=", + "span": { + "end": { + "column": 10, + "line": 8 + }, + "start": { + "column": 8, + "line": 8 + } + } + }, { "file": "src/simple_fns.rs", "function": { @@ -5160,6 +5640,66 @@ expression: buf } } }, + { + "file": "src/slices.rs", + "function": { + "function_name": "return_mut_slice", + "return_type": "-> &mut[usize]", + "span": { + "end": { + "column": 2, + "line": 17 + }, + "start": { + "column": 1, + "line": 12 + } + } + }, + "genre": "BinaryOperator", + "package": "cargo-mutants-testdata-well-tested", + "replacement": "+=", + "span": { + "end": { + "column": 14, + "line": 14 + }, + "start": { + "column": 12, + "line": 14 + } + } + }, + { + "file": "src/slices.rs", + "function": { + "function_name": "return_mut_slice", + "return_type": "-> &mut[usize]", + "span": { + "end": { + "column": 2, + "line": 17 + }, + "start": { + "column": 1, + "line": 12 + } + } + }, + "genre": "BinaryOperator", + "package": "cargo-mutants-testdata-well-tested", + "replacement": "/=", + "span": { + "end": { + "column": 14, + "line": 14 + }, + "start": { + "column": 12, + "line": 14 + } + } + }, { "file": "src/static_item.rs", "function": null, @@ -6245,6 +6785,66 @@ expression: buf } } }, + { + "file": "main/src/main.rs", + "function": { + "function_name": "factorial", + "return_type": "-> u32", + "span": { + "end": { + "column": 2, + "line": 17 + }, + "start": { + "column": 1, + "line": 11 + } + } + }, + "genre": "BinaryOperator", + "package": "main", + "replacement": "+=", + "span": { + "end": { + "column": 13, + "line": 14 + }, + "start": { + "column": 11, + "line": 14 + } + } + }, + { + "file": "main/src/main.rs", + "function": { + "function_name": "factorial", + "return_type": "-> u32", + "span": { + "end": { + "column": 2, + "line": 17 + }, + "start": { + "column": 1, + "line": 11 + } + } + }, + "genre": "BinaryOperator", + "package": "main", + "replacement": "/=", + "span": { + "end": { + "column": 13, + "line": 14 + }, + "start": { + "column": 11, + "line": 14 + } + } + }, { "file": "main2/src/main.rs", "function": { diff --git a/tests/cli/snapshots/cli__list_mutants_in_all_trees_as_text.snap b/tests/cli/snapshots/cli__list_mutants_in_all_trees_as_text.snap index b9530da4..ca4fb2dd 100644 --- a/tests/cli/snapshots/cli__list_mutants_in_all_trees_as_text.snap +++ b/tests/cli/snapshots/cli__list_mutants_in_all_trees_as_text.snap @@ -16,6 +16,8 @@ src/lib.rs:10:7: replace + with * in takes_one_arg ``` src/lib.rs:2:5: replace factorial -> u32 with 0 src/lib.rs:2:5: replace factorial -> u32 with 1 +src/lib.rs:4:11: replace *= with += in factorial +src/lib.rs:4:11: replace *= with /= in factorial ``` ## testdata/already_hangs @@ -29,6 +31,8 @@ src/lib.rs:12:5: replace infinite_loop with () ``` src/entry.rs:2:5: replace factorial -> u32 with 0 src/entry.rs:2:5: replace factorial -> u32 with 1 +src/entry.rs:4:11: replace *= with += in factorial +src/entry.rs:4:11: replace *= with /= in factorial ``` ## testdata/cfg_attr_mutants_skip @@ -60,6 +64,8 @@ src/custom_top.rs:2:7: replace % with + in is_even ``` src/lib.rs:2:5: replace factorial -> u32 with 0 src/lib.rs:2:5: replace factorial -> u32 with 1 +src/lib.rs:4:11: replace *= with += in factorial +src/lib.rs:4:11: replace *= with /= in factorial ``` ## testdata/diff0 @@ -98,6 +104,8 @@ src/lib.rs:4:10: replace == with != in zero_is_ok src/bin/factorial.rs:2:5: replace main with () src/bin/factorial.rs:8:5: replace factorial -> u32 with 0 src/bin/factorial.rs:8:5: replace factorial -> u32 with 1 +src/bin/factorial.rs:10:11: replace *= with += in factorial +src/bin/factorial.rs:10:11: replace *= with /= in factorial ``` ## testdata/fails_without_feature @@ -105,6 +113,8 @@ src/bin/factorial.rs:8:5: replace factorial -> u32 with 1 ``` src/bin/factorial.rs:10:5: replace factorial -> u32 with 0 src/bin/factorial.rs:10:5: replace factorial -> u32 with 1 +src/bin/factorial.rs:12:11: replace *= with += in factorial +src/bin/factorial.rs:12:11: replace *= with /= in factorial ``` ## testdata/hang_avoided_by_attr @@ -235,6 +245,8 @@ src/lib.rs:7:7: replace % with + in is_even ``` src/lib.rs:5:5: replace factorial -> u32 with 0 src/lib.rs:5:5: replace factorial -> u32 with 1 +src/lib.rs:7:11: replace *= with += in factorial +src/lib.rs:7:11: replace *= with /= in factorial ``` ## testdata/strict_warnings @@ -292,6 +304,8 @@ src/arc.rs:4:5: replace return_arc -> Arc with Arc::new("xyzzy".into()) src/inside_mod.rs:4:13: replace outer::inner::name -> &'static str with "" src/inside_mod.rs:4:13: replace outer::inner::name -> &'static str with "xyzzy" src/methods.rs:17:9: replace Foo::double with () +src/methods.rs:17:16: replace *= with += in Foo::double +src/methods.rs:17:16: replace *= with /= in Foo::double src/methods.rs:23:9: replace ::fmt -> fmt::Result with Ok(Default::default()) src/methods.rs:29:9: replace ::fmt -> fmt::Result with Ok(Default::default()) src/nested_function.rs:2:5: replace has_nested -> u32 with 0 @@ -320,6 +334,8 @@ src/sets.rs:4:5: replace make_a_set -> BTreeSet with BTreeSet::new() src/sets.rs:4:5: replace make_a_set -> BTreeSet with BTreeSet::from_iter([String::new()]) src/sets.rs:4:5: replace make_a_set -> BTreeSet with BTreeSet::from_iter(["xyzzy".into()]) src/simple_fns.rs:8:5: replace returns_unit with () +src/simple_fns.rs:8:8: replace += with -= in returns_unit +src/simple_fns.rs:8:8: replace += with *= in returns_unit src/simple_fns.rs:13:5: replace returns_42u32 -> u32 with 0 src/simple_fns.rs:13:5: replace returns_42u32 -> u32 with 1 src/simple_fns.rs:18:5: replace divisible_by_three -> bool with true @@ -339,6 +355,8 @@ src/slices.rs:5:20: replace < with > in pad src/slices.rs:13:5: replace return_mut_slice -> &mut[usize] with Vec::leak(Vec::new()) src/slices.rs:13:5: replace return_mut_slice -> &mut[usize] with Vec::leak(vec![0]) src/slices.rs:13:5: replace return_mut_slice -> &mut[usize] with Vec::leak(vec![1]) +src/slices.rs:14:12: replace *= with += in return_mut_slice +src/slices.rs:14:12: replace *= with /= in return_mut_slice src/static_item.rs:1:33: replace == with != src/static_item.rs:1:39: replace + with - src/static_item.rs:1:39: replace + with * @@ -386,6 +404,8 @@ utils/src/lib.rs:2:7: replace * with + in triple utils/src/lib.rs:2:7: replace * with / in triple main/src/main.rs:12:5: replace factorial -> u32 with 0 main/src/main.rs:12:5: replace factorial -> u32 with 1 +main/src/main.rs:14:11: replace *= with += in factorial +main/src/main.rs:14:11: replace *= with /= in factorial main2/src/main.rs:10:5: replace triple_3 -> i32 with 0 main2/src/main.rs:10:5: replace triple_3 -> i32 with 1 main2/src/main.rs:10:5: replace triple_3 -> i32 with -1 diff --git a/tests/cli/snapshots/cli__list_mutants_in_factorial.snap b/tests/cli/snapshots/cli__list_mutants_in_factorial.snap index 87e22a11..da04bcd4 100644 --- a/tests/cli/snapshots/cli__list_mutants_in_factorial.snap +++ b/tests/cli/snapshots/cli__list_mutants_in_factorial.snap @@ -5,4 +5,6 @@ expression: "String::from_utf8_lossy(&output.stdout)" src/bin/factorial.rs:2:5: replace main with () src/bin/factorial.rs:8:5: replace factorial -> u32 with 0 src/bin/factorial.rs:8:5: replace factorial -> u32 with 1 +src/bin/factorial.rs:10:11: replace *= with += in factorial +src/bin/factorial.rs:10:11: replace *= with /= in factorial diff --git a/tests/cli/snapshots/cli__list_mutants_in_factorial_json.snap b/tests/cli/snapshots/cli__list_mutants_in_factorial_json.snap index 593a4d9f..513013a2 100644 --- a/tests/cli/snapshots/cli__list_mutants_in_factorial_json.snap +++ b/tests/cli/snapshots/cli__list_mutants_in_factorial_json.snap @@ -92,5 +92,65 @@ expression: "String::from_utf8_lossy(&output.stdout)" "line": 8 } } + }, + { + "file": "src/bin/factorial.rs", + "function": { + "function_name": "factorial", + "return_type": "-> u32", + "span": { + "end": { + "column": 2, + "line": 13 + }, + "start": { + "column": 1, + "line": 7 + } + } + }, + "genre": "BinaryOperator", + "package": "cargo-mutants-testdata-factorial", + "replacement": "+=", + "span": { + "end": { + "column": 13, + "line": 10 + }, + "start": { + "column": 11, + "line": 10 + } + } + }, + { + "file": "src/bin/factorial.rs", + "function": { + "function_name": "factorial", + "return_type": "-> u32", + "span": { + "end": { + "column": 2, + "line": 13 + }, + "start": { + "column": 1, + "line": 7 + } + } + }, + "genre": "BinaryOperator", + "package": "cargo-mutants-testdata-factorial", + "replacement": "/=", + "span": { + "end": { + "column": 13, + "line": 10 + }, + "start": { + "column": 11, + "line": 10 + } + } } ] diff --git a/tests/cli/snapshots/cli__list_mutants_json_well_tested.snap b/tests/cli/snapshots/cli__list_mutants_json_well_tested.snap index 917e3a56..68c282ca 100644 --- a/tests/cli/snapshots/cli__list_mutants_json_well_tested.snap +++ b/tests/cli/snapshots/cli__list_mutants_json_well_tested.snap @@ -153,6 +153,66 @@ expression: "String::from_utf8_lossy(&output.stdout)" } } }, + { + "file": "src/methods.rs", + "function": { + "function_name": "Foo::double", + "return_type": "", + "span": { + "end": { + "column": 6, + "line": 18 + }, + "start": { + "column": 5, + "line": 16 + } + } + }, + "genre": "BinaryOperator", + "package": "cargo-mutants-testdata-well-tested", + "replacement": "+=", + "span": { + "end": { + "column": 18, + "line": 17 + }, + "start": { + "column": 16, + "line": 17 + } + } + }, + { + "file": "src/methods.rs", + "function": { + "function_name": "Foo::double", + "return_type": "", + "span": { + "end": { + "column": 6, + "line": 18 + }, + "start": { + "column": 5, + "line": 16 + } + } + }, + "genre": "BinaryOperator", + "package": "cargo-mutants-testdata-well-tested", + "replacement": "/=", + "span": { + "end": { + "column": 18, + "line": 17 + }, + "start": { + "column": 16, + "line": 17 + } + } + }, { "file": "src/methods.rs", "function": { @@ -993,6 +1053,66 @@ expression: "String::from_utf8_lossy(&output.stdout)" } } }, + { + "file": "src/simple_fns.rs", + "function": { + "function_name": "returns_unit", + "return_type": "", + "span": { + "end": { + "column": 2, + "line": 9 + }, + "start": { + "column": 1, + "line": 7 + } + } + }, + "genre": "BinaryOperator", + "package": "cargo-mutants-testdata-well-tested", + "replacement": "-=", + "span": { + "end": { + "column": 10, + "line": 8 + }, + "start": { + "column": 8, + "line": 8 + } + } + }, + { + "file": "src/simple_fns.rs", + "function": { + "function_name": "returns_unit", + "return_type": "", + "span": { + "end": { + "column": 2, + "line": 9 + }, + "start": { + "column": 1, + "line": 7 + } + } + }, + "genre": "BinaryOperator", + "package": "cargo-mutants-testdata-well-tested", + "replacement": "*=", + "span": { + "end": { + "column": 10, + "line": 8 + }, + "start": { + "column": 8, + "line": 8 + } + } + }, { "file": "src/simple_fns.rs", "function": { @@ -1563,6 +1683,66 @@ expression: "String::from_utf8_lossy(&output.stdout)" } } }, + { + "file": "src/slices.rs", + "function": { + "function_name": "return_mut_slice", + "return_type": "-> &mut[usize]", + "span": { + "end": { + "column": 2, + "line": 17 + }, + "start": { + "column": 1, + "line": 12 + } + } + }, + "genre": "BinaryOperator", + "package": "cargo-mutants-testdata-well-tested", + "replacement": "+=", + "span": { + "end": { + "column": 14, + "line": 14 + }, + "start": { + "column": 12, + "line": 14 + } + } + }, + { + "file": "src/slices.rs", + "function": { + "function_name": "return_mut_slice", + "return_type": "-> &mut[usize]", + "span": { + "end": { + "column": 2, + "line": 17 + }, + "start": { + "column": 1, + "line": 12 + } + } + }, + "genre": "BinaryOperator", + "package": "cargo-mutants-testdata-well-tested", + "replacement": "/=", + "span": { + "end": { + "column": 14, + "line": 14 + }, + "start": { + "column": 12, + "line": 14 + } + } + }, { "file": "src/static_item.rs", "function": null, diff --git a/tests/cli/snapshots/cli__list_mutants_well_tested.snap b/tests/cli/snapshots/cli__list_mutants_well_tested.snap index 70639ea8..cd6ae9ac 100644 --- a/tests/cli/snapshots/cli__list_mutants_well_tested.snap +++ b/tests/cli/snapshots/cli__list_mutants_well_tested.snap @@ -7,6 +7,8 @@ src/arc.rs:4:5: replace return_arc -> Arc with Arc::new("xyzzy".into()) src/inside_mod.rs:4:13: replace outer::inner::name -> &'static str with "" src/inside_mod.rs:4:13: replace outer::inner::name -> &'static str with "xyzzy" src/methods.rs:17:9: replace Foo::double with () +src/methods.rs:17:16: replace *= with += in Foo::double +src/methods.rs:17:16: replace *= with /= in Foo::double src/methods.rs:23:9: replace ::fmt -> fmt::Result with Ok(Default::default()) src/methods.rs:29:9: replace ::fmt -> fmt::Result with Ok(Default::default()) src/nested_function.rs:2:5: replace has_nested -> u32 with 0 @@ -35,6 +37,8 @@ src/sets.rs:4:5: replace make_a_set -> BTreeSet with BTreeSet::new() src/sets.rs:4:5: replace make_a_set -> BTreeSet with BTreeSet::from_iter([String::new()]) src/sets.rs:4:5: replace make_a_set -> BTreeSet with BTreeSet::from_iter(["xyzzy".into()]) src/simple_fns.rs:8:5: replace returns_unit with () +src/simple_fns.rs:8:8: replace += with -= in returns_unit +src/simple_fns.rs:8:8: replace += with *= in returns_unit src/simple_fns.rs:13:5: replace returns_42u32 -> u32 with 0 src/simple_fns.rs:13:5: replace returns_42u32 -> u32 with 1 src/simple_fns.rs:18:5: replace divisible_by_three -> bool with true @@ -54,6 +58,8 @@ src/slices.rs:5:20: replace < with > in pad src/slices.rs:13:5: replace return_mut_slice -> &mut[usize] with Vec::leak(Vec::new()) src/slices.rs:13:5: replace return_mut_slice -> &mut[usize] with Vec::leak(vec![0]) src/slices.rs:13:5: replace return_mut_slice -> &mut[usize] with Vec::leak(vec![1]) +src/slices.rs:14:12: replace *= with += in return_mut_slice +src/slices.rs:14:12: replace *= with /= in return_mut_slice src/static_item.rs:1:33: replace == with != src/static_item.rs:1:39: replace + with - src/static_item.rs:1:39: replace + with * diff --git a/tests/cli/snapshots/cli__list_mutants_well_tested_exclude_name_filter.snap b/tests/cli/snapshots/cli__list_mutants_well_tested_exclude_name_filter.snap index 143b5be8..158373a5 100644 --- a/tests/cli/snapshots/cli__list_mutants_well_tested_exclude_name_filter.snap +++ b/tests/cli/snapshots/cli__list_mutants_well_tested_exclude_name_filter.snap @@ -7,6 +7,8 @@ src/arc.rs:4:5: replace return_arc -> Arc with Arc::new("xyzzy".into()) src/inside_mod.rs:4:13: replace outer::inner::name -> &'static str with "" src/inside_mod.rs:4:13: replace outer::inner::name -> &'static str with "xyzzy" src/methods.rs:17:9: replace Foo::double with () +src/methods.rs:17:16: replace *= with += in Foo::double +src/methods.rs:17:16: replace *= with /= in Foo::double src/methods.rs:23:9: replace ::fmt -> fmt::Result with Ok(Default::default()) src/methods.rs:29:9: replace ::fmt -> fmt::Result with Ok(Default::default()) src/nested_function.rs:2:5: replace has_nested -> u32 with 0 @@ -44,6 +46,8 @@ src/slices.rs:5:20: replace < with > in pad src/slices.rs:13:5: replace return_mut_slice -> &mut[usize] with Vec::leak(Vec::new()) src/slices.rs:13:5: replace return_mut_slice -> &mut[usize] with Vec::leak(vec![0]) src/slices.rs:13:5: replace return_mut_slice -> &mut[usize] with Vec::leak(vec![1]) +src/slices.rs:14:12: replace *= with += in return_mut_slice +src/slices.rs:14:12: replace *= with /= in return_mut_slice src/static_item.rs:1:33: replace == with != src/static_item.rs:1:39: replace + with - src/static_item.rs:1:39: replace + with * diff --git a/tests/cli/snapshots/cli__list_mutants_with_diffs_in_factorial.snap b/tests/cli/snapshots/cli__list_mutants_with_diffs_in_factorial.snap index 9c059f4a..a85cf17c 100644 --- a/tests/cli/snapshots/cli__list_mutants_with_diffs_in_factorial.snap +++ b/tests/cli/snapshots/cli__list_mutants_with_diffs_in_factorial.snap @@ -70,4 +70,50 @@ src/bin/factorial.rs:8:5: replace factorial -> u32 with 1 assert_eq!(factorial(6), 720); } +src/bin/factorial.rs:10:11: replace *= with += in factorial +--- src/bin/factorial.rs ++++ replace *= with += in factorial +@@ -2,17 +2,17 @@ + for i in 1..=6 { + println!("{}! = {}", i, factorial(i)); + } + } + + fn factorial(n: u32) -> u32 { + let mut a = 1; + for i in 2..=n { +- a *= i; ++ a += /* ~ changed by cargo-mutants ~ */ i; + } + a + } + + #[test] + fn test_factorial() { + println!("factorial({}) = {}", 6, factorial(6)); // This line is here so we can see it in --nocapture + assert_eq!(factorial(6), 720); + +src/bin/factorial.rs:10:11: replace *= with /= in factorial +--- src/bin/factorial.rs ++++ replace *= with /= in factorial +@@ -2,17 +2,17 @@ + for i in 1..=6 { + println!("{}! = {}", i, factorial(i)); + } + } + + fn factorial(n: u32) -> u32 { + let mut a = 1; + for i in 2..=n { +- a *= i; ++ a /= /* ~ changed by cargo-mutants ~ */ i; + } + a + } + + #[test] + fn test_factorial() { + println!("factorial({}) = {}", 6, factorial(6)); // This line is here so we can see it in --nocapture + assert_eq!(factorial(6), 720); + diff --git a/tests/cli/snapshots/cli__list_mutants_with_dir_option.snap b/tests/cli/snapshots/cli__list_mutants_with_dir_option.snap index 87e22a11..da04bcd4 100644 --- a/tests/cli/snapshots/cli__list_mutants_with_dir_option.snap +++ b/tests/cli/snapshots/cli__list_mutants_with_dir_option.snap @@ -5,4 +5,6 @@ expression: "String::from_utf8_lossy(&output.stdout)" src/bin/factorial.rs:2:5: replace main with () src/bin/factorial.rs:8:5: replace factorial -> u32 with 0 src/bin/factorial.rs:8:5: replace factorial -> u32 with 1 +src/bin/factorial.rs:10:11: replace *= with += in factorial +src/bin/factorial.rs:10:11: replace *= with /= in factorial diff --git a/tests/cli/snapshots/cli__mutants.json.snap b/tests/cli/snapshots/cli__mutants.json.snap index 9ea1afcc..55b8a8cb 100644 --- a/tests/cli/snapshots/cli__mutants.json.snap +++ b/tests/cli/snapshots/cli__mutants.json.snap @@ -92,5 +92,65 @@ expression: mutants_json }, "replacement": "1", "genre": "FnValue" + }, + { + "package": "cargo-mutants-testdata-factorial", + "file": "src/bin/factorial.rs", + "function": { + "function_name": "factorial", + "return_type": "-> u32", + "span": { + "start": { + "line": 7, + "column": 1 + }, + "end": { + "line": 13, + "column": 2 + } + } + }, + "span": { + "start": { + "line": 10, + "column": 11 + }, + "end": { + "line": 10, + "column": 13 + } + }, + "replacement": "+=", + "genre": "BinaryOperator" + }, + { + "package": "cargo-mutants-testdata-factorial", + "file": "src/bin/factorial.rs", + "function": { + "function_name": "factorial", + "return_type": "-> u32", + "span": { + "start": { + "line": 7, + "column": 1 + }, + "end": { + "line": 13, + "column": 2 + } + } + }, + "span": { + "start": { + "line": 10, + "column": 11 + }, + "end": { + "line": 10, + "column": 13 + } + }, + "replacement": "/=", + "genre": "BinaryOperator" } ] diff --git a/tests/cli/snapshots/cli__small_well_tested_mutants_with_cargo_arg_release.snap b/tests/cli/snapshots/cli__small_well_tested_mutants_with_cargo_arg_release.snap index 05cd8a21..30953faf 100644 --- a/tests/cli/snapshots/cli__small_well_tested_mutants_with_cargo_arg_release.snap +++ b/tests/cli/snapshots/cli__small_well_tested_mutants_with_cargo_arg_release.snap @@ -2,7 +2,7 @@ source: tests/cli/main.rs expression: stdout --- -Found 2 mutants to test +Found 4 mutants to test ok Unmutated baseline -2 mutants tested: 2 caught +4 mutants tested: 4 caught diff --git a/tests/cli/snapshots/cli__small_well_tested_tree_is_clean.snap b/tests/cli/snapshots/cli__small_well_tested_tree_is_clean.snap index 9b6c34b5..c51d3dcd 100644 --- a/tests/cli/snapshots/cli__small_well_tested_tree_is_clean.snap +++ b/tests/cli/snapshots/cli__small_well_tested_tree_is_clean.snap @@ -2,9 +2,11 @@ source: tests/cli/main.rs expression: stdout --- -Found 2 mutants to test +Found 4 mutants to test ok Unmutated baseline caught src/lib.rs:5:5: replace factorial -> u32 with 0 caught src/lib.rs:5:5: replace factorial -> u32 with 1 -2 mutants tested: 2 caught +caught src/lib.rs:7:11: replace *= with += in factorial +caught src/lib.rs:7:11: replace *= with /= in factorial +4 mutants tested: 4 caught diff --git a/tests/cli/snapshots/cli__uncaught_mutant_in_factorial.snap b/tests/cli/snapshots/cli__uncaught_mutant_in_factorial.snap index 75d3521f..cc9fc1c1 100644 --- a/tests/cli/snapshots/cli__uncaught_mutant_in_factorial.snap +++ b/tests/cli/snapshots/cli__uncaught_mutant_in_factorial.snap @@ -2,8 +2,8 @@ source: tests/cli/main.rs expression: stdout --- -Found 3 mutants to test +Found 5 mutants to test ok Unmutated baseline MISSED src/bin/factorial.rs:2:5: replace main with () -3 mutants tested: 1 missed, 2 caught +5 mutants tested: 1 missed, 4 caught diff --git a/tests/cli/snapshots/cli__uncaught_mutant_in_factorial__caught.txt.snap b/tests/cli/snapshots/cli__uncaught_mutant_in_factorial__caught.txt.snap index 8051ebf6..03ad2a0f 100644 --- a/tests/cli/snapshots/cli__uncaught_mutant_in_factorial__caught.txt.snap +++ b/tests/cli/snapshots/cli__uncaught_mutant_in_factorial__caught.txt.snap @@ -4,4 +4,6 @@ expression: content --- src/bin/factorial.rs:8:5: replace factorial -> u32 with 0 src/bin/factorial.rs:8:5: replace factorial -> u32 with 1 +src/bin/factorial.rs:10:11: replace *= with += in factorial +src/bin/factorial.rs:10:11: replace *= with /= in factorial diff --git a/tests/cli/snapshots/cli__well_tested_tree_check_only.snap b/tests/cli/snapshots/cli__well_tested_tree_check_only.snap index 0b560c42..46445571 100644 --- a/tests/cli/snapshots/cli__well_tested_tree_check_only.snap +++ b/tests/cli/snapshots/cli__well_tested_tree_check_only.snap @@ -2,13 +2,15 @@ source: tests/cli/main.rs expression: stdout --- -Found 60 mutants to test +Found 66 mutants to test ok Unmutated baseline ok src/arc.rs:4:5: replace return_arc -> Arc with Arc::new(String::new()) ok src/arc.rs:4:5: replace return_arc -> Arc with Arc::new("xyzzy".into()) ok src/inside_mod.rs:4:13: replace outer::inner::name -> &'static str with "" ok src/inside_mod.rs:4:13: replace outer::inner::name -> &'static str with "xyzzy" ok src/methods.rs:17:9: replace Foo::double with () +ok src/methods.rs:17:16: replace *= with += in Foo::double +ok src/methods.rs:17:16: replace *= with /= in Foo::double ok src/methods.rs:23:9: replace ::fmt -> fmt::Result with Ok(Default::default()) ok src/methods.rs:29:9: replace ::fmt -> fmt::Result with Ok(Default::default()) ok src/nested_function.rs:2:5: replace has_nested -> u32 with 0 @@ -37,6 +39,8 @@ ok src/sets.rs:4:5: replace make_a_set -> BTreeSet with BTreeSet:: ok src/sets.rs:4:5: replace make_a_set -> BTreeSet with BTreeSet::from_iter([String::new()]) ok src/sets.rs:4:5: replace make_a_set -> BTreeSet with BTreeSet::from_iter(["xyzzy".into()]) ok src/simple_fns.rs:8:5: replace returns_unit with () +ok src/simple_fns.rs:8:8: replace += with -= in returns_unit +ok src/simple_fns.rs:8:8: replace += with *= in returns_unit ok src/simple_fns.rs:13:5: replace returns_42u32 -> u32 with 0 ok src/simple_fns.rs:13:5: replace returns_42u32 -> u32 with 1 ok src/simple_fns.rs:18:5: replace divisible_by_three -> bool with true @@ -56,6 +60,8 @@ ok src/slices.rs:5:20: replace < with > in pad ok src/slices.rs:13:5: replace return_mut_slice -> &mut[usize] with Vec::leak(Vec::new()) ok src/slices.rs:13:5: replace return_mut_slice -> &mut[usize] with Vec::leak(vec![0]) ok src/slices.rs:13:5: replace return_mut_slice -> &mut[usize] with Vec::leak(vec![1]) +ok src/slices.rs:14:12: replace *= with += in return_mut_slice +ok src/slices.rs:14:12: replace *= with /= in return_mut_slice ok src/static_item.rs:1:33: replace == with != ok src/static_item.rs:1:39: replace + with - ok src/static_item.rs:1:39: replace + with * @@ -64,5 +70,5 @@ ok src/struct_with_lifetime.rs:15:9: replace Lex<'buf>::buf_len -> usize w ok src/traits.rs:5:9: replace Something::is_three -> bool with true ok src/traits.rs:5:9: replace Something::is_three -> bool with false ok src/traits.rs:5:11: replace == with != in Something::is_three -60 mutants tested: 60 succeeded +66 mutants tested: 66 succeeded diff --git a/tests/cli/snapshots/cli__well_tested_tree_finds_no_problems.snap b/tests/cli/snapshots/cli__well_tested_tree_finds_no_problems.snap index 547ee2f0..7d1f3026 100644 --- a/tests/cli/snapshots/cli__well_tested_tree_finds_no_problems.snap +++ b/tests/cli/snapshots/cli__well_tested_tree_finds_no_problems.snap @@ -2,13 +2,15 @@ source: tests/cli/main.rs expression: stdout --- -Found 60 mutants to test +Found 66 mutants to test ok Unmutated baseline caught src/arc.rs:4:5: replace return_arc -> Arc with Arc::new(String::new()) caught src/arc.rs:4:5: replace return_arc -> Arc with Arc::new("xyzzy".into()) caught src/inside_mod.rs:4:13: replace outer::inner::name -> &'static str with "" caught src/inside_mod.rs:4:13: replace outer::inner::name -> &'static str with "xyzzy" caught src/methods.rs:17:9: replace Foo::double with () +caught src/methods.rs:17:16: replace *= with += in Foo::double +caught src/methods.rs:17:16: replace *= with /= in Foo::double caught src/methods.rs:23:9: replace ::fmt -> fmt::Result with Ok(Default::default()) caught src/methods.rs:29:9: replace ::fmt -> fmt::Result with Ok(Default::default()) caught src/nested_function.rs:2:5: replace has_nested -> u32 with 0 @@ -37,6 +39,8 @@ caught src/sets.rs:4:5: replace make_a_set -> BTreeSet with BTreeSet:: caught src/sets.rs:4:5: replace make_a_set -> BTreeSet with BTreeSet::from_iter([String::new()]) caught src/sets.rs:4:5: replace make_a_set -> BTreeSet with BTreeSet::from_iter(["xyzzy".into()]) caught src/simple_fns.rs:8:5: replace returns_unit with () +caught src/simple_fns.rs:8:8: replace += with -= in returns_unit +caught src/simple_fns.rs:8:8: replace += with *= in returns_unit caught src/simple_fns.rs:13:5: replace returns_42u32 -> u32 with 0 caught src/simple_fns.rs:13:5: replace returns_42u32 -> u32 with 1 caught src/simple_fns.rs:18:5: replace divisible_by_three -> bool with true @@ -56,6 +60,8 @@ caught src/slices.rs:5:20: replace < with > in pad caught src/slices.rs:13:5: replace return_mut_slice -> &mut[usize] with Vec::leak(Vec::new()) caught src/slices.rs:13:5: replace return_mut_slice -> &mut[usize] with Vec::leak(vec![0]) caught src/slices.rs:13:5: replace return_mut_slice -> &mut[usize] with Vec::leak(vec![1]) +caught src/slices.rs:14:12: replace *= with += in return_mut_slice +caught src/slices.rs:14:12: replace *= with /= in return_mut_slice caught src/static_item.rs:1:33: replace == with != caught src/static_item.rs:1:39: replace + with - caught src/static_item.rs:1:39: replace + with * @@ -64,5 +70,5 @@ caught src/struct_with_lifetime.rs:15:9: replace Lex<'buf>::buf_len -> usize w caught src/traits.rs:5:9: replace Something::is_three -> bool with true caught src/traits.rs:5:9: replace Something::is_three -> bool with false caught src/traits.rs:5:11: replace == with != in Something::is_three -60 mutants tested: 60 caught +66 mutants tested: 66 caught diff --git a/tests/cli/snapshots/cli__well_tested_tree_finds_no_problems__caught.txt.snap b/tests/cli/snapshots/cli__well_tested_tree_finds_no_problems__caught.txt.snap index 5d5cdfc4..3588e959 100644 --- a/tests/cli/snapshots/cli__well_tested_tree_finds_no_problems__caught.txt.snap +++ b/tests/cli/snapshots/cli__well_tested_tree_finds_no_problems__caught.txt.snap @@ -7,6 +7,8 @@ src/arc.rs:4:5: replace return_arc -> Arc with Arc::new("xyzzy".into()) src/inside_mod.rs:4:13: replace outer::inner::name -> &'static str with "" src/inside_mod.rs:4:13: replace outer::inner::name -> &'static str with "xyzzy" src/methods.rs:17:9: replace Foo::double with () +src/methods.rs:17:16: replace *= with += in Foo::double +src/methods.rs:17:16: replace *= with /= in Foo::double src/methods.rs:23:9: replace ::fmt -> fmt::Result with Ok(Default::default()) src/methods.rs:29:9: replace ::fmt -> fmt::Result with Ok(Default::default()) src/nested_function.rs:2:5: replace has_nested -> u32 with 0 @@ -35,6 +37,8 @@ src/sets.rs:4:5: replace make_a_set -> BTreeSet with BTreeSet::new() src/sets.rs:4:5: replace make_a_set -> BTreeSet with BTreeSet::from_iter([String::new()]) src/sets.rs:4:5: replace make_a_set -> BTreeSet with BTreeSet::from_iter(["xyzzy".into()]) src/simple_fns.rs:8:5: replace returns_unit with () +src/simple_fns.rs:8:8: replace += with -= in returns_unit +src/simple_fns.rs:8:8: replace += with *= in returns_unit src/simple_fns.rs:13:5: replace returns_42u32 -> u32 with 0 src/simple_fns.rs:13:5: replace returns_42u32 -> u32 with 1 src/simple_fns.rs:18:5: replace divisible_by_three -> bool with true @@ -54,6 +58,8 @@ src/slices.rs:5:20: replace < with > in pad src/slices.rs:13:5: replace return_mut_slice -> &mut[usize] with Vec::leak(Vec::new()) src/slices.rs:13:5: replace return_mut_slice -> &mut[usize] with Vec::leak(vec![0]) src/slices.rs:13:5: replace return_mut_slice -> &mut[usize] with Vec::leak(vec![1]) +src/slices.rs:14:12: replace *= with += in return_mut_slice +src/slices.rs:14:12: replace *= with /= in return_mut_slice src/static_item.rs:1:33: replace == with != src/static_item.rs:1:39: replace + with - src/static_item.rs:1:39: replace + with * diff --git a/tests/cli/workspace.rs b/tests/cli/workspace.rs index d622367b..93ef72f0 100644 --- a/tests/cli/workspace.rs +++ b/tests/cli/workspace.rs @@ -4,7 +4,6 @@ use std::fs::{self, read_to_string}; -use indoc::indoc; use insta::assert_snapshot; use itertools::Itertools; use serde_json::json; @@ -23,11 +22,9 @@ fn open_by_manifest_path() { ]) .assert() .success() - .stdout(indoc! {" - src/bin/factorial.rs: replace main with () - src/bin/factorial.rs: replace factorial -> u32 with 0 - src/bin/factorial.rs: replace factorial -> u32 with 1 - "}); + .stdout(predicates::str::contains( + "src/bin/factorial.rs: replace main with ()", + )); } #[test] From 53fb59a03a1cd88aa05428b58fe442d6bfe0c3c9 Mon Sep 17 00:00:00 2001 From: Martin Pool Date: Mon, 1 Jan 2024 12:59:22 -0800 Subject: [PATCH 08/11] Stop mutating || to != --- NEWS.md | 2 ++ src/visit.rs | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/NEWS.md b/NEWS.md index c55c7e0d..8761c374 100644 --- a/NEWS.md +++ b/NEWS.md @@ -8,6 +8,8 @@ - New: Mutate `+, -, *, /, %, &, ^, |, <<, >>` binary ops, and their corresponding assignment ops like `+=`. +- Changed: Stop generating mutations of `||` to `!=`, because it seems to raise too many low-value false positives, where the program does not need to care about the case where both operands are true. + ## 23.12.1 - Improved progress bars and console output, including putting the outcome of each mutant on the left, and the overall progress bar at the bottom. Improved display of estimated remaining time, and other times. diff --git a/src/visit.rs b/src/visit.rs index 7cffa92b..d827ac4f 100644 --- a/src/visit.rs +++ b/src/visit.rs @@ -362,8 +362,8 @@ impl<'ast> Visit<'ast> for DiscoveryVisitor<'_> { // because they require parenthesis for disambiguation in many expressions. BinOp::Eq(_) => vec![quote! { != }], BinOp::Ne(_) => vec![quote! { == }], - BinOp::And(_) => vec![quote! { || }, quote! {==}, quote! {!=}], - BinOp::Or(_) => vec![quote! { && }, quote! {==}, quote! {!=}], + BinOp::And(_) => vec![quote! { || }, quote! {!=}], + BinOp::Or(_) => vec![quote! { && }, quote! {==}], BinOp::Lt(_) => vec![quote! { == }, quote! {>}], BinOp::Gt(_) => vec![quote! { == }, quote! {<}], BinOp::Le(_) => vec![quote! {>}], From 49387557fbb8518a6b25e7ca2f28fccb585d25d0 Mon Sep 17 00:00:00 2001 From: Martin Pool Date: Mon, 1 Jan 2024 13:12:55 -0800 Subject: [PATCH 09/11] Drop other mutations of && and || --- NEWS.md | 2 +- ..._expected_mutants_for_own_source_tree.snap | 102 ------------------ src/visit.rs | 4 +- 3 files changed, 3 insertions(+), 105 deletions(-) diff --git a/NEWS.md b/NEWS.md index 8761c374..9198d2d4 100644 --- a/NEWS.md +++ b/NEWS.md @@ -8,7 +8,7 @@ - New: Mutate `+, -, *, /, %, &, ^, |, <<, >>` binary ops, and their corresponding assignment ops like `+=`. -- Changed: Stop generating mutations of `||` to `!=`, because it seems to raise too many low-value false positives, where the program does not need to care about the case where both operands are true. +- Changed: Stop generating mutations of `||` and `&&` to `!=` and `||`, because it seems to raise too many low-value false positives that may be hard to test. ## 23.12.1 diff --git a/src/snapshots/cargo_mutants__visit__test__expected_mutants_for_own_source_tree.snap b/src/snapshots/cargo_mutants__visit__test__expected_mutants_for_own_source_tree.snap index ae85c470..8767d363 100644 --- a/src/snapshots/cargo_mutants__visit__test__expected_mutants_for_own_source_tree.snap +++ b/src/snapshots/cargo_mutants__visit__test__expected_mutants_for_own_source_tree.snap @@ -15,8 +15,6 @@ src/cargo.rs: replace cargo_argv -> Vec with vec![] src/cargo.rs: replace cargo_argv -> Vec with vec![String::new()] src/cargo.rs: replace cargo_argv -> Vec with vec!["xyzzy".into()] src/cargo.rs: replace || with && in cargo_argv -src/cargo.rs: replace || with == in cargo_argv -src/cargo.rs: replace || with != in cargo_argv src/cargo.rs: replace == with != in cargo_argv src/cargo.rs: replace == with != in cargo_argv src/cargo.rs: replace == with != in cargo_argv @@ -48,20 +46,10 @@ src/console.rs: replace += with *= in Console::scenario_finished src/console.rs: replace += with -= in Console::scenario_finished src/console.rs: replace += with *= in Console::scenario_finished src/console.rs: replace || with && in Console::scenario_finished -src/console.rs: replace || with == in Console::scenario_finished -src/console.rs: replace || with != in Console::scenario_finished src/console.rs: replace && with || in Console::scenario_finished -src/console.rs: replace && with == in Console::scenario_finished -src/console.rs: replace && with != in Console::scenario_finished src/console.rs: replace && with || in Console::scenario_finished -src/console.rs: replace && with == in Console::scenario_finished -src/console.rs: replace && with != in Console::scenario_finished src/console.rs: replace && with || in Console::scenario_finished -src/console.rs: replace && with == in Console::scenario_finished -src/console.rs: replace && with != in Console::scenario_finished src/console.rs: replace || with && in Console::scenario_finished -src/console.rs: replace || with == in Console::scenario_finished -src/console.rs: replace || with != in Console::scenario_finished src/console.rs: replace Console::autoset_timeout with () src/console.rs: replace Console::start_copy with () src/console.rs: replace Console::finish_copy with () @@ -178,8 +166,6 @@ src/fnvalue.rs: replace == with != in path_ends_with src/fnvalue.rs: replace match_impl_iterator -> Option<&Type> with None src/fnvalue.rs: replace match_impl_iterator -> Option<&Type> with Some(&Default::default()) src/fnvalue.rs: replace && with || in match_impl_iterator -src/fnvalue.rs: replace && with == in match_impl_iterator -src/fnvalue.rs: replace && with != in match_impl_iterator src/fnvalue.rs: replace == with != in match_impl_iterator src/fnvalue.rs: replace == with != in match_impl_iterator src/fnvalue.rs: replace == with != in match_impl_iterator @@ -229,8 +215,6 @@ src/in_diff.rs: replace < with > in affected_lines src/in_diff.rs: replace += with -= in affected_lines src/in_diff.rs: replace += with *= in affected_lines src/in_diff.rs: replace && with || in affected_lines -src/in_diff.rs: replace && with == in affected_lines -src/in_diff.rs: replace && with != in affected_lines src/in_diff.rs: replace > with == in affected_lines src/in_diff.rs: replace > with < in affected_lines src/in_diff.rs: replace < with == in affected_lines @@ -257,11 +241,7 @@ src/lab.rs: replace == with != in test_mutants src/lab.rs: replace test_scenario -> Result with Ok(Default::default()) src/lab.rs: replace test_scenario -> Result with Err(::anyhow::anyhow!("mutated!")) src/lab.rs: replace || with && in test_scenario -src/lab.rs: replace || with == in test_scenario -src/lab.rs: replace || with != in test_scenario src/lab.rs: replace && with || in test_scenario -src/lab.rs: replace && with == in test_scenario -src/lab.rs: replace && with != in test_scenario src/lab.rs: replace == with != in test_scenario src/list.rs: replace >::write_str -> Result<(), fmt::Error> with Ok(()) src/list.rs: replace >::write_str -> Result<(), fmt::Error> with Err(::anyhow::anyhow!("mutated!")) @@ -296,8 +276,6 @@ src/manifest.rs: replace fix_path -> Option with None src/manifest.rs: replace fix_path -> Option with Some(String::new()) src/manifest.rs: replace fix_path -> Option with Some("xyzzy".into()) src/manifest.rs: replace || with && in fix_path -src/manifest.rs: replace || with == in fix_path -src/manifest.rs: replace || with != in fix_path src/manifest.rs: replace == with != in fix_path src/mutate.rs: replace Mutant::mutated_code -> String with String::new() src/mutate.rs: replace Mutant::mutated_code -> String with "xyzzy".into() @@ -353,8 +331,6 @@ src/options.rs: replace build_glob_set -> Result> with Ok(None) src/options.rs: replace build_glob_set -> Result> with Ok(Some(Default::default())) src/options.rs: replace build_glob_set -> Result> with Err(::anyhow::anyhow!("mutated!")) src/options.rs: replace || with && in build_glob_set -src/options.rs: replace || with == in build_glob_set -src/options.rs: replace || with != in build_glob_set src/outcome.rs: replace Phase::name -> &'static str with "" src/outcome.rs: replace Phase::name -> &'static str with "xyzzy" src/outcome.rs: replace ::fmt -> fmt::Result with Ok(Default::default()) @@ -378,8 +354,6 @@ src/outcome.rs: replace LabOutcome::exit_code -> i32 with 0 src/outcome.rs: replace LabOutcome::exit_code -> i32 with 1 src/outcome.rs: replace LabOutcome::exit_code -> i32 with -1 src/outcome.rs: replace && with || in LabOutcome::exit_code -src/outcome.rs: replace && with == in LabOutcome::exit_code -src/outcome.rs: replace && with != in LabOutcome::exit_code src/outcome.rs: replace > with == in LabOutcome::exit_code src/outcome.rs: replace > with < in LabOutcome::exit_code src/outcome.rs: replace > with == in LabOutcome::exit_code @@ -411,8 +385,6 @@ src/outcome.rs: replace ScenarioOutcome::phase_results -> &[PhaseResult] with Ve src/outcome.rs: replace ScenarioOutcome::should_show_logs -> bool with true src/outcome.rs: replace ScenarioOutcome::should_show_logs -> bool with false src/outcome.rs: replace && with || in ScenarioOutcome::should_show_logs -src/outcome.rs: replace && with == in ScenarioOutcome::should_show_logs -src/outcome.rs: replace && with != in ScenarioOutcome::should_show_logs src/outcome.rs: replace ScenarioOutcome::success -> bool with true src/outcome.rs: replace ScenarioOutcome::success -> bool with false src/outcome.rs: replace ScenarioOutcome::has_timeout -> bool with true @@ -420,28 +392,18 @@ src/outcome.rs: replace ScenarioOutcome::has_timeout -> bool with false src/outcome.rs: replace ScenarioOutcome::check_or_build_failed -> bool with true src/outcome.rs: replace ScenarioOutcome::check_or_build_failed -> bool with false src/outcome.rs: replace && with || in ScenarioOutcome::check_or_build_failed -src/outcome.rs: replace && with == in ScenarioOutcome::check_or_build_failed -src/outcome.rs: replace && with != in ScenarioOutcome::check_or_build_failed src/outcome.rs: replace != with == in ScenarioOutcome::check_or_build_failed src/outcome.rs: replace == with != in ScenarioOutcome::check_or_build_failed src/outcome.rs: replace ScenarioOutcome::mutant_caught -> bool with true src/outcome.rs: replace ScenarioOutcome::mutant_caught -> bool with false src/outcome.rs: replace && with || in ScenarioOutcome::mutant_caught -src/outcome.rs: replace && with == in ScenarioOutcome::mutant_caught -src/outcome.rs: replace && with != in ScenarioOutcome::mutant_caught src/outcome.rs: replace && with || in ScenarioOutcome::mutant_caught -src/outcome.rs: replace && with == in ScenarioOutcome::mutant_caught -src/outcome.rs: replace && with != in ScenarioOutcome::mutant_caught src/outcome.rs: replace == with != in ScenarioOutcome::mutant_caught src/outcome.rs: replace == with != in ScenarioOutcome::mutant_caught src/outcome.rs: replace ScenarioOutcome::mutant_missed -> bool with true src/outcome.rs: replace ScenarioOutcome::mutant_missed -> bool with false src/outcome.rs: replace && with || in ScenarioOutcome::mutant_missed -src/outcome.rs: replace && with == in ScenarioOutcome::mutant_missed -src/outcome.rs: replace && with != in ScenarioOutcome::mutant_missed src/outcome.rs: replace && with || in ScenarioOutcome::mutant_missed -src/outcome.rs: replace && with == in ScenarioOutcome::mutant_missed -src/outcome.rs: replace && with != in ScenarioOutcome::mutant_missed src/outcome.rs: replace == with != in ScenarioOutcome::mutant_missed src/outcome.rs: replace ScenarioOutcome::summary -> SummaryOutcome with Default::default() src/outcome.rs: replace PhaseResult::is_success -> bool with true @@ -477,26 +439,16 @@ src/path.rs: replace > with < in ascent src/path.rs: replace ::to_slash_path -> String with String::new() src/path.rs: replace ::to_slash_path -> String with "xyzzy".into() src/path.rs: replace || with && in ::to_slash_path -src/path.rs: replace || with == in ::to_slash_path -src/path.rs: replace || with != in ::to_slash_path src/path.rs: replace == with != in ::to_slash_path src/path.rs: replace == with != in ::to_slash_path src/pretty.rs: replace ::to_pretty_string -> String with String::new() src/pretty.rs: replace ::to_pretty_string -> String with "xyzzy".into() src/pretty.rs: replace && with || in ::to_pretty_string -src/pretty.rs: replace && with == in ::to_pretty_string -src/pretty.rs: replace && with != in ::to_pretty_string src/pretty.rs: replace || with && in ::to_pretty_string -src/pretty.rs: replace || with == in ::to_pretty_string -src/pretty.rs: replace || with != in ::to_pretty_string src/pretty.rs: replace || with && in ::to_pretty_string -src/pretty.rs: replace || with == in ::to_pretty_string -src/pretty.rs: replace || with != in ::to_pretty_string src/pretty.rs: replace == with != in ::to_pretty_string src/pretty.rs: replace == with != in ::to_pretty_string src/pretty.rs: replace || with && in ::to_pretty_string -src/pretty.rs: replace || with == in ::to_pretty_string -src/pretty.rs: replace || with != in ::to_pretty_string src/pretty.rs: replace += with -= in ::to_pretty_string src/pretty.rs: replace += with *= in ::to_pretty_string src/process.rs: replace Process::run -> Result with Ok(Default::default()) @@ -545,26 +497,16 @@ src/span.rs: replace Span::quad -> Self with Default::default() src/span.rs: replace Span::extract -> String with String::new() src/span.rs: replace Span::extract -> String with "xyzzy".into() src/span.rs: replace && with || in Span::extract -src/span.rs: replace && with == in Span::extract -src/span.rs: replace && with != in Span::extract src/span.rs: replace || with && in Span::extract -src/span.rs: replace || with == in Span::extract -src/span.rs: replace || with != in Span::extract src/span.rs: replace && with || in Span::extract -src/span.rs: replace && with == in Span::extract -src/span.rs: replace && with != in Span::extract src/span.rs: replace == with != in Span::extract src/span.rs: replace >= with < in Span::extract src/span.rs: replace > with == in Span::extract src/span.rs: replace > with < in Span::extract src/span.rs: replace || with && in Span::extract -src/span.rs: replace || with == in Span::extract -src/span.rs: replace || with != in Span::extract src/span.rs: replace < with == in Span::extract src/span.rs: replace < with > in Span::extract src/span.rs: replace && with || in Span::extract -src/span.rs: replace && with == in Span::extract -src/span.rs: replace && with != in Span::extract src/span.rs: replace == with != in Span::extract src/span.rs: replace < with == in Span::extract src/span.rs: replace < with > in Span::extract @@ -577,8 +519,6 @@ src/span.rs: replace == with != in Span::extract src/span.rs: replace += with -= in Span::extract src/span.rs: replace += with *= in Span::extract src/span.rs: replace && with || in Span::extract -src/span.rs: replace && with == in Span::extract -src/span.rs: replace && with != in Span::extract src/span.rs: replace == with != in Span::extract src/span.rs: replace >= with < in Span::extract src/span.rs: replace Span::replace -> String with String::new() @@ -586,32 +526,20 @@ src/span.rs: replace Span::replace -> String with "xyzzy".into() src/span.rs: replace + with - in Span::replace src/span.rs: replace + with * in Span::replace src/span.rs: replace && with || in Span::replace -src/span.rs: replace && with == in Span::replace -src/span.rs: replace && with != in Span::replace src/span.rs: replace == with != in Span::replace src/span.rs: replace == with != in Span::replace src/span.rs: replace || with && in Span::replace -src/span.rs: replace || with == in Span::replace -src/span.rs: replace || with != in Span::replace src/span.rs: replace || with && in Span::replace -src/span.rs: replace || with == in Span::replace -src/span.rs: replace || with != in Span::replace src/span.rs: replace || with && in Span::replace -src/span.rs: replace || with == in Span::replace -src/span.rs: replace || with != in Span::replace src/span.rs: replace < with == in Span::replace src/span.rs: replace < with > in Span::replace src/span.rs: replace > with == in Span::replace src/span.rs: replace > with < in Span::replace src/span.rs: replace && with || in Span::replace -src/span.rs: replace && with == in Span::replace -src/span.rs: replace && with != in Span::replace src/span.rs: replace == with != in Span::replace src/span.rs: replace < with == in Span::replace src/span.rs: replace < with > in Span::replace src/span.rs: replace && with || in Span::replace -src/span.rs: replace && with == in Span::replace -src/span.rs: replace && with != in Span::replace src/span.rs: replace == with != in Span::replace src/span.rs: replace >= with < in Span::replace src/span.rs: replace == with != in Span::replace @@ -621,8 +549,6 @@ src/span.rs: replace == with != in Span::replace src/span.rs: replace += with -= in Span::replace src/span.rs: replace += with *= in Span::replace src/span.rs: replace && with || in Span::replace -src/span.rs: replace && with == in Span::replace -src/span.rs: replace && with != in Span::replace src/span.rs: replace == with != in Span::replace src/span.rs: replace == with != in Span::replace src/span.rs: replace ::from -> Self with Default::default() @@ -638,14 +564,8 @@ src/tail_file.rs: replace > with < in TailFile::last_line src/visit.rs: replace walk_tree -> Result with Ok(Default::default()) src/visit.rs: replace walk_tree -> Result with Err(::anyhow::anyhow!("mutated!")) src/visit.rs: replace && with || in walk_tree -src/visit.rs: replace && with == in walk_tree -src/visit.rs: replace && with != in walk_tree src/visit.rs: replace || with && in walk_tree -src/visit.rs: replace || with == in walk_tree -src/visit.rs: replace || with != in walk_tree src/visit.rs: replace || with && in walk_tree -src/visit.rs: replace || with == in walk_tree -src/visit.rs: replace || with != in walk_tree src/visit.rs: replace walk_file -> Result<(Vec, Vec)> with Ok((vec![], vec![])) src/visit.rs: replace walk_file -> Result<(Vec, Vec)> with Ok((vec![], vec![String::new()])) src/visit.rs: replace walk_file -> Result<(Vec, Vec)> with Ok((vec![], vec!["xyzzy".into()])) @@ -661,29 +581,15 @@ src/visit.rs: replace == with != in DiscoveryVisitor<'o>::collect_fn_mutants src/visit.rs: replace DiscoveryVisitor<'o>::in_namespace -> T with Default::default() src/visit.rs: replace >::visit_item_fn with () src/visit.rs: replace || with && in >::visit_item_fn -src/visit.rs: replace || with == in >::visit_item_fn -src/visit.rs: replace || with != in >::visit_item_fn src/visit.rs: replace || with && in >::visit_item_fn -src/visit.rs: replace || with == in >::visit_item_fn -src/visit.rs: replace || with != in >::visit_item_fn src/visit.rs: replace >::visit_impl_item_fn with () src/visit.rs: replace || with && in >::visit_impl_item_fn -src/visit.rs: replace || with == in >::visit_impl_item_fn -src/visit.rs: replace || with != in >::visit_impl_item_fn src/visit.rs: replace || with && in >::visit_impl_item_fn -src/visit.rs: replace || with == in >::visit_impl_item_fn -src/visit.rs: replace || with != in >::visit_impl_item_fn src/visit.rs: replace || with && in >::visit_impl_item_fn -src/visit.rs: replace || with == in >::visit_impl_item_fn -src/visit.rs: replace || with != in >::visit_impl_item_fn src/visit.rs: replace == with != in >::visit_impl_item_fn src/visit.rs: replace >::visit_trait_item_fn with () src/visit.rs: replace || with && in >::visit_trait_item_fn -src/visit.rs: replace || with == in >::visit_trait_item_fn -src/visit.rs: replace || with != in >::visit_trait_item_fn src/visit.rs: replace || with && in >::visit_trait_item_fn -src/visit.rs: replace || with == in >::visit_trait_item_fn -src/visit.rs: replace || with != in >::visit_trait_item_fn src/visit.rs: replace == with != in >::visit_trait_item_fn src/visit.rs: replace >::visit_item_impl with () src/visit.rs: replace == with != in >::visit_item_impl @@ -696,8 +602,6 @@ src/visit.rs: replace find_mod_source -> Result> with Ok(Non src/visit.rs: replace find_mod_source -> Result> with Ok(Some(Default::default())) src/visit.rs: replace find_mod_source -> Result> with Err(::anyhow::anyhow!("mutated!")) src/visit.rs: replace || with && in find_mod_source -src/visit.rs: replace || with == in find_mod_source -src/visit.rs: replace || with != in find_mod_source src/visit.rs: replace + with - in find_mod_source src/visit.rs: replace + with * in find_mod_source src/visit.rs: replace fn_sig_excluded -> bool with true @@ -705,11 +609,7 @@ src/visit.rs: replace fn_sig_excluded -> bool with false src/visit.rs: replace attrs_excluded -> bool with true src/visit.rs: replace attrs_excluded -> bool with false src/visit.rs: replace || with && in attrs_excluded -src/visit.rs: replace || with == in attrs_excluded -src/visit.rs: replace || with != in attrs_excluded src/visit.rs: replace || with && in attrs_excluded -src/visit.rs: replace || with == in attrs_excluded -src/visit.rs: replace || with != in attrs_excluded src/visit.rs: replace block_is_empty -> bool with true src/visit.rs: replace block_is_empty -> bool with false src/visit.rs: replace attr_is_cfg_test -> bool with true @@ -747,8 +647,6 @@ src/workspace.rs: replace direct_package_sources -> Result> wit src/workspace.rs: replace should_mutate_target -> bool with true src/workspace.rs: replace should_mutate_target -> bool with false src/workspace.rs: replace || with && in should_mutate_target -src/workspace.rs: replace || with == in should_mutate_target -src/workspace.rs: replace || with != in should_mutate_target src/workspace.rs: replace == with != in should_mutate_target src/workspace.rs: replace locate_project -> Result with Ok(Default::default()) src/workspace.rs: replace locate_project -> Result with Err(::anyhow::anyhow!("mutated!")) diff --git a/src/visit.rs b/src/visit.rs index d827ac4f..19a4c4aa 100644 --- a/src/visit.rs +++ b/src/visit.rs @@ -362,8 +362,8 @@ impl<'ast> Visit<'ast> for DiscoveryVisitor<'_> { // because they require parenthesis for disambiguation in many expressions. BinOp::Eq(_) => vec![quote! { != }], BinOp::Ne(_) => vec![quote! { == }], - BinOp::And(_) => vec![quote! { || }, quote! {!=}], - BinOp::Or(_) => vec![quote! { && }, quote! {==}], + BinOp::And(_) => vec![quote! { || }], + BinOp::Or(_) => vec![quote! { && }], BinOp::Lt(_) => vec![quote! { == }, quote! {>}], BinOp::Gt(_) => vec![quote! { == }, quote! {<}], BinOp::Le(_) => vec![quote! {>}], From 96d59f8e8d3f8ae77b0de816348bcb0b5b223f9f Mon Sep 17 00:00:00 2001 From: Martin Pool Date: Wed, 10 Jan 2024 21:46:56 -0800 Subject: [PATCH 10/11] Test tree for new binops patterns --- Cargo.toml | 1 + testdata/many_patterns/Cargo.toml | 8 + testdata/many_patterns/README.md | 5 + testdata/many_patterns/src/binops.rs | 19 + testdata/many_patterns/src/lib.rs | 1 + ...li__list_mutants_in_all_trees_as_json.snap | 1087 +++++++++++++++++ ...li__list_mutants_in_all_trees_as_text.snap | 41 + 7 files changed, 1162 insertions(+) create mode 100644 testdata/many_patterns/Cargo.toml create mode 100644 testdata/many_patterns/README.md create mode 100644 testdata/many_patterns/src/binops.rs create mode 100644 testdata/many_patterns/src/lib.rs diff --git a/Cargo.toml b/Cargo.toml index 4907edae..425d2ae2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -115,6 +115,7 @@ exclude = [ "testdata/hang_when_mutated", "testdata/insta", "testdata/integration_tests", + "testdata/many_patterns", "testdata/missing_test", "testdata/mut_ref", "testdata/never_type", diff --git a/testdata/many_patterns/Cargo.toml b/testdata/many_patterns/Cargo.toml new file mode 100644 index 00000000..06614b8b --- /dev/null +++ b/testdata/many_patterns/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "cargo-mutants-testdata-many-patterns" +version = "0.0.0" +edition = "2021" +authors = ["Martin Pool"] +publish = false + +[lib] diff --git a/testdata/many_patterns/README.md b/testdata/many_patterns/README.md new file mode 100644 index 00000000..1c097727 --- /dev/null +++ b/testdata/many_patterns/README.md @@ -0,0 +1,5 @@ +# `many_patterns` testdata tree + +This tree contains code that generates many different mutants, to exercise code that matches these patterns. + +This tree is not tested from the test suite, because it may eventually generate many mutants and get slow, and there is in fact no test coverage. diff --git a/testdata/many_patterns/src/binops.rs b/testdata/many_patterns/src/binops.rs new file mode 100644 index 00000000..4a5ae69e --- /dev/null +++ b/testdata/many_patterns/src/binops.rs @@ -0,0 +1,19 @@ +pub fn binops() { + let _ = 1 + 2 * 3 / 4 % 5; + let _ = 1 & 2 | 3 ^ 4 << 5 >> 6; + let mut a = 0isize; + a += 1; + a -= 2; + a *= 3; + a /= 2; +} + +pub fn bin_assign() -> i32 { + let mut a = 0; + a |= 0xfff7; + a ^= 0xffff; + a &= 0x0f; + a >>= 4; + a <<= 1; + a +} diff --git a/testdata/many_patterns/src/lib.rs b/testdata/many_patterns/src/lib.rs new file mode 100644 index 00000000..20adc0eb --- /dev/null +++ b/testdata/many_patterns/src/lib.rs @@ -0,0 +1 @@ +pub mod binops; diff --git a/tests/cli/snapshots/cli__list_mutants_in_all_trees_as_json.snap b/tests/cli/snapshots/cli__list_mutants_in_all_trees_as_json.snap index 4f339b91..baa0fbab 100644 --- a/tests/cli/snapshots/cli__list_mutants_in_all_trees_as_json.snap +++ b/tests/cli/snapshots/cli__list_mutants_in_all_trees_as_json.snap @@ -2046,6 +2046,1093 @@ expression: buf ] ``` +## testdata/many_patterns + +```json +[ + { + "file": "src/binops.rs", + "function": { + "function_name": "binops", + "return_type": "", + "span": { + "end": { + "column": 2, + "line": 9 + }, + "start": { + "column": 1, + "line": 1 + } + } + }, + "genre": "FnValue", + "package": "cargo-mutants-testdata-many-patterns", + "replacement": "()", + "span": { + "end": { + "column": 12, + "line": 8 + }, + "start": { + "column": 5, + "line": 2 + } + } + }, + { + "file": "src/binops.rs", + "function": { + "function_name": "binops", + "return_type": "", + "span": { + "end": { + "column": 2, + "line": 9 + }, + "start": { + "column": 1, + "line": 1 + } + } + }, + "genre": "BinaryOperator", + "package": "cargo-mutants-testdata-many-patterns", + "replacement": "-", + "span": { + "end": { + "column": 16, + "line": 2 + }, + "start": { + "column": 15, + "line": 2 + } + } + }, + { + "file": "src/binops.rs", + "function": { + "function_name": "binops", + "return_type": "", + "span": { + "end": { + "column": 2, + "line": 9 + }, + "start": { + "column": 1, + "line": 1 + } + } + }, + "genre": "BinaryOperator", + "package": "cargo-mutants-testdata-many-patterns", + "replacement": "*", + "span": { + "end": { + "column": 16, + "line": 2 + }, + "start": { + "column": 15, + "line": 2 + } + } + }, + { + "file": "src/binops.rs", + "function": { + "function_name": "binops", + "return_type": "", + "span": { + "end": { + "column": 2, + "line": 9 + }, + "start": { + "column": 1, + "line": 1 + } + } + }, + "genre": "BinaryOperator", + "package": "cargo-mutants-testdata-many-patterns", + "replacement": "/", + "span": { + "end": { + "column": 28, + "line": 2 + }, + "start": { + "column": 27, + "line": 2 + } + } + }, + { + "file": "src/binops.rs", + "function": { + "function_name": "binops", + "return_type": "", + "span": { + "end": { + "column": 2, + "line": 9 + }, + "start": { + "column": 1, + "line": 1 + } + } + }, + "genre": "BinaryOperator", + "package": "cargo-mutants-testdata-many-patterns", + "replacement": "+", + "span": { + "end": { + "column": 28, + "line": 2 + }, + "start": { + "column": 27, + "line": 2 + } + } + }, + { + "file": "src/binops.rs", + "function": { + "function_name": "binops", + "return_type": "", + "span": { + "end": { + "column": 2, + "line": 9 + }, + "start": { + "column": 1, + "line": 1 + } + } + }, + "genre": "BinaryOperator", + "package": "cargo-mutants-testdata-many-patterns", + "replacement": "%", + "span": { + "end": { + "column": 24, + "line": 2 + }, + "start": { + "column": 23, + "line": 2 + } + } + }, + { + "file": "src/binops.rs", + "function": { + "function_name": "binops", + "return_type": "", + "span": { + "end": { + "column": 2, + "line": 9 + }, + "start": { + "column": 1, + "line": 1 + } + } + }, + "genre": "BinaryOperator", + "package": "cargo-mutants-testdata-many-patterns", + "replacement": "*", + "span": { + "end": { + "column": 24, + "line": 2 + }, + "start": { + "column": 23, + "line": 2 + } + } + }, + { + "file": "src/binops.rs", + "function": { + "function_name": "binops", + "return_type": "", + "span": { + "end": { + "column": 2, + "line": 9 + }, + "start": { + "column": 1, + "line": 1 + } + } + }, + "genre": "BinaryOperator", + "package": "cargo-mutants-testdata-many-patterns", + "replacement": "+", + "span": { + "end": { + "column": 20, + "line": 2 + }, + "start": { + "column": 19, + "line": 2 + } + } + }, + { + "file": "src/binops.rs", + "function": { + "function_name": "binops", + "return_type": "", + "span": { + "end": { + "column": 2, + "line": 9 + }, + "start": { + "column": 1, + "line": 1 + } + } + }, + "genre": "BinaryOperator", + "package": "cargo-mutants-testdata-many-patterns", + "replacement": "/", + "span": { + "end": { + "column": 20, + "line": 2 + }, + "start": { + "column": 19, + "line": 2 + } + } + }, + { + "file": "src/binops.rs", + "function": { + "function_name": "binops", + "return_type": "", + "span": { + "end": { + "column": 2, + "line": 9 + }, + "start": { + "column": 1, + "line": 1 + } + } + }, + "genre": "BinaryOperator", + "package": "cargo-mutants-testdata-many-patterns", + "replacement": "&", + "span": { + "end": { + "column": 20, + "line": 3 + }, + "start": { + "column": 19, + "line": 3 + } + } + }, + { + "file": "src/binops.rs", + "function": { + "function_name": "binops", + "return_type": "", + "span": { + "end": { + "column": 2, + "line": 9 + }, + "start": { + "column": 1, + "line": 1 + } + } + }, + "genre": "BinaryOperator", + "package": "cargo-mutants-testdata-many-patterns", + "replacement": "^", + "span": { + "end": { + "column": 20, + "line": 3 + }, + "start": { + "column": 19, + "line": 3 + } + } + }, + { + "file": "src/binops.rs", + "function": { + "function_name": "binops", + "return_type": "", + "span": { + "end": { + "column": 2, + "line": 9 + }, + "start": { + "column": 1, + "line": 1 + } + } + }, + "genre": "BinaryOperator", + "package": "cargo-mutants-testdata-many-patterns", + "replacement": "|", + "span": { + "end": { + "column": 16, + "line": 3 + }, + "start": { + "column": 15, + "line": 3 + } + } + }, + { + "file": "src/binops.rs", + "function": { + "function_name": "binops", + "return_type": "", + "span": { + "end": { + "column": 2, + "line": 9 + }, + "start": { + "column": 1, + "line": 1 + } + } + }, + "genre": "BinaryOperator", + "package": "cargo-mutants-testdata-many-patterns", + "replacement": "^", + "span": { + "end": { + "column": 16, + "line": 3 + }, + "start": { + "column": 15, + "line": 3 + } + } + }, + { + "file": "src/binops.rs", + "function": { + "function_name": "binops", + "return_type": "", + "span": { + "end": { + "column": 2, + "line": 9 + }, + "start": { + "column": 1, + "line": 1 + } + } + }, + "genre": "BinaryOperator", + "package": "cargo-mutants-testdata-many-patterns", + "replacement": "|", + "span": { + "end": { + "column": 24, + "line": 3 + }, + "start": { + "column": 23, + "line": 3 + } + } + }, + { + "file": "src/binops.rs", + "function": { + "function_name": "binops", + "return_type": "", + "span": { + "end": { + "column": 2, + "line": 9 + }, + "start": { + "column": 1, + "line": 1 + } + } + }, + "genre": "BinaryOperator", + "package": "cargo-mutants-testdata-many-patterns", + "replacement": "&", + "span": { + "end": { + "column": 24, + "line": 3 + }, + "start": { + "column": 23, + "line": 3 + } + } + }, + { + "file": "src/binops.rs", + "function": { + "function_name": "binops", + "return_type": "", + "span": { + "end": { + "column": 2, + "line": 9 + }, + "start": { + "column": 1, + "line": 1 + } + } + }, + "genre": "BinaryOperator", + "package": "cargo-mutants-testdata-many-patterns", + "replacement": "<<", + "span": { + "end": { + "column": 34, + "line": 3 + }, + "start": { + "column": 32, + "line": 3 + } + } + }, + { + "file": "src/binops.rs", + "function": { + "function_name": "binops", + "return_type": "", + "span": { + "end": { + "column": 2, + "line": 9 + }, + "start": { + "column": 1, + "line": 1 + } + } + }, + "genre": "BinaryOperator", + "package": "cargo-mutants-testdata-many-patterns", + "replacement": ">>", + "span": { + "end": { + "column": 29, + "line": 3 + }, + "start": { + "column": 27, + "line": 3 + } + } + }, + { + "file": "src/binops.rs", + "function": { + "function_name": "binops", + "return_type": "", + "span": { + "end": { + "column": 2, + "line": 9 + }, + "start": { + "column": 1, + "line": 1 + } + } + }, + "genre": "BinaryOperator", + "package": "cargo-mutants-testdata-many-patterns", + "replacement": "-=", + "span": { + "end": { + "column": 9, + "line": 5 + }, + "start": { + "column": 7, + "line": 5 + } + } + }, + { + "file": "src/binops.rs", + "function": { + "function_name": "binops", + "return_type": "", + "span": { + "end": { + "column": 2, + "line": 9 + }, + "start": { + "column": 1, + "line": 1 + } + } + }, + "genre": "BinaryOperator", + "package": "cargo-mutants-testdata-many-patterns", + "replacement": "*=", + "span": { + "end": { + "column": 9, + "line": 5 + }, + "start": { + "column": 7, + "line": 5 + } + } + }, + { + "file": "src/binops.rs", + "function": { + "function_name": "binops", + "return_type": "", + "span": { + "end": { + "column": 2, + "line": 9 + }, + "start": { + "column": 1, + "line": 1 + } + } + }, + "genre": "BinaryOperator", + "package": "cargo-mutants-testdata-many-patterns", + "replacement": "+=", + "span": { + "end": { + "column": 9, + "line": 6 + }, + "start": { + "column": 7, + "line": 6 + } + } + }, + { + "file": "src/binops.rs", + "function": { + "function_name": "binops", + "return_type": "", + "span": { + "end": { + "column": 2, + "line": 9 + }, + "start": { + "column": 1, + "line": 1 + } + } + }, + "genre": "BinaryOperator", + "package": "cargo-mutants-testdata-many-patterns", + "replacement": "/=", + "span": { + "end": { + "column": 9, + "line": 6 + }, + "start": { + "column": 7, + "line": 6 + } + } + }, + { + "file": "src/binops.rs", + "function": { + "function_name": "binops", + "return_type": "", + "span": { + "end": { + "column": 2, + "line": 9 + }, + "start": { + "column": 1, + "line": 1 + } + } + }, + "genre": "BinaryOperator", + "package": "cargo-mutants-testdata-many-patterns", + "replacement": "+=", + "span": { + "end": { + "column": 9, + "line": 7 + }, + "start": { + "column": 7, + "line": 7 + } + } + }, + { + "file": "src/binops.rs", + "function": { + "function_name": "binops", + "return_type": "", + "span": { + "end": { + "column": 2, + "line": 9 + }, + "start": { + "column": 1, + "line": 1 + } + } + }, + "genre": "BinaryOperator", + "package": "cargo-mutants-testdata-many-patterns", + "replacement": "/=", + "span": { + "end": { + "column": 9, + "line": 7 + }, + "start": { + "column": 7, + "line": 7 + } + } + }, + { + "file": "src/binops.rs", + "function": { + "function_name": "binops", + "return_type": "", + "span": { + "end": { + "column": 2, + "line": 9 + }, + "start": { + "column": 1, + "line": 1 + } + } + }, + "genre": "BinaryOperator", + "package": "cargo-mutants-testdata-many-patterns", + "replacement": "%=", + "span": { + "end": { + "column": 9, + "line": 8 + }, + "start": { + "column": 7, + "line": 8 + } + } + }, + { + "file": "src/binops.rs", + "function": { + "function_name": "binops", + "return_type": "", + "span": { + "end": { + "column": 2, + "line": 9 + }, + "start": { + "column": 1, + "line": 1 + } + } + }, + "genre": "BinaryOperator", + "package": "cargo-mutants-testdata-many-patterns", + "replacement": "*=", + "span": { + "end": { + "column": 9, + "line": 8 + }, + "start": { + "column": 7, + "line": 8 + } + } + }, + { + "file": "src/binops.rs", + "function": { + "function_name": "bin_assign", + "return_type": "-> i32", + "span": { + "end": { + "column": 2, + "line": 19 + }, + "start": { + "column": 1, + "line": 11 + } + } + }, + "genre": "FnValue", + "package": "cargo-mutants-testdata-many-patterns", + "replacement": "0", + "span": { + "end": { + "column": 6, + "line": 18 + }, + "start": { + "column": 5, + "line": 12 + } + } + }, + { + "file": "src/binops.rs", + "function": { + "function_name": "bin_assign", + "return_type": "-> i32", + "span": { + "end": { + "column": 2, + "line": 19 + }, + "start": { + "column": 1, + "line": 11 + } + } + }, + "genre": "FnValue", + "package": "cargo-mutants-testdata-many-patterns", + "replacement": "1", + "span": { + "end": { + "column": 6, + "line": 18 + }, + "start": { + "column": 5, + "line": 12 + } + } + }, + { + "file": "src/binops.rs", + "function": { + "function_name": "bin_assign", + "return_type": "-> i32", + "span": { + "end": { + "column": 2, + "line": 19 + }, + "start": { + "column": 1, + "line": 11 + } + } + }, + "genre": "FnValue", + "package": "cargo-mutants-testdata-many-patterns", + "replacement": "-1", + "span": { + "end": { + "column": 6, + "line": 18 + }, + "start": { + "column": 5, + "line": 12 + } + } + }, + { + "file": "src/binops.rs", + "function": { + "function_name": "bin_assign", + "return_type": "-> i32", + "span": { + "end": { + "column": 2, + "line": 19 + }, + "start": { + "column": 1, + "line": 11 + } + } + }, + "genre": "BinaryOperator", + "package": "cargo-mutants-testdata-many-patterns", + "replacement": "&=", + "span": { + "end": { + "column": 9, + "line": 13 + }, + "start": { + "column": 7, + "line": 13 + } + } + }, + { + "file": "src/binops.rs", + "function": { + "function_name": "bin_assign", + "return_type": "-> i32", + "span": { + "end": { + "column": 2, + "line": 19 + }, + "start": { + "column": 1, + "line": 11 + } + } + }, + "genre": "BinaryOperator", + "package": "cargo-mutants-testdata-many-patterns", + "replacement": "^=", + "span": { + "end": { + "column": 9, + "line": 13 + }, + "start": { + "column": 7, + "line": 13 + } + } + }, + { + "file": "src/binops.rs", + "function": { + "function_name": "bin_assign", + "return_type": "-> i32", + "span": { + "end": { + "column": 2, + "line": 19 + }, + "start": { + "column": 1, + "line": 11 + } + } + }, + "genre": "BinaryOperator", + "package": "cargo-mutants-testdata-many-patterns", + "replacement": "|=", + "span": { + "end": { + "column": 9, + "line": 14 + }, + "start": { + "column": 7, + "line": 14 + } + } + }, + { + "file": "src/binops.rs", + "function": { + "function_name": "bin_assign", + "return_type": "-> i32", + "span": { + "end": { + "column": 2, + "line": 19 + }, + "start": { + "column": 1, + "line": 11 + } + } + }, + "genre": "BinaryOperator", + "package": "cargo-mutants-testdata-many-patterns", + "replacement": "&=", + "span": { + "end": { + "column": 9, + "line": 14 + }, + "start": { + "column": 7, + "line": 14 + } + } + }, + { + "file": "src/binops.rs", + "function": { + "function_name": "bin_assign", + "return_type": "-> i32", + "span": { + "end": { + "column": 2, + "line": 19 + }, + "start": { + "column": 1, + "line": 11 + } + } + }, + "genre": "BinaryOperator", + "package": "cargo-mutants-testdata-many-patterns", + "replacement": "|=", + "span": { + "end": { + "column": 9, + "line": 15 + }, + "start": { + "column": 7, + "line": 15 + } + } + }, + { + "file": "src/binops.rs", + "function": { + "function_name": "bin_assign", + "return_type": "-> i32", + "span": { + "end": { + "column": 2, + "line": 19 + }, + "start": { + "column": 1, + "line": 11 + } + } + }, + "genre": "BinaryOperator", + "package": "cargo-mutants-testdata-many-patterns", + "replacement": "^=", + "span": { + "end": { + "column": 9, + "line": 15 + }, + "start": { + "column": 7, + "line": 15 + } + } + }, + { + "file": "src/binops.rs", + "function": { + "function_name": "bin_assign", + "return_type": "-> i32", + "span": { + "end": { + "column": 2, + "line": 19 + }, + "start": { + "column": 1, + "line": 11 + } + } + }, + "genre": "BinaryOperator", + "package": "cargo-mutants-testdata-many-patterns", + "replacement": "<<=", + "span": { + "end": { + "column": 10, + "line": 16 + }, + "start": { + "column": 7, + "line": 16 + } + } + }, + { + "file": "src/binops.rs", + "function": { + "function_name": "bin_assign", + "return_type": "-> i32", + "span": { + "end": { + "column": 2, + "line": 19 + }, + "start": { + "column": 1, + "line": 11 + } + } + }, + "genre": "BinaryOperator", + "package": "cargo-mutants-testdata-many-patterns", + "replacement": ">>=", + "span": { + "end": { + "column": 10, + "line": 17 + }, + "start": { + "column": 7, + "line": 17 + } + } + } +] +``` + ## testdata/missing_test ```json diff --git a/tests/cli/snapshots/cli__list_mutants_in_all_trees_as_text.snap b/tests/cli/snapshots/cli__list_mutants_in_all_trees_as_text.snap index ca4fb2dd..82468777 100644 --- a/tests/cli/snapshots/cli__list_mutants_in_all_trees_as_text.snap +++ b/tests/cli/snapshots/cli__list_mutants_in_all_trees_as_text.snap @@ -156,6 +156,47 @@ src/lib.rs:2:7: replace * with + in double src/lib.rs:2:7: replace * with / in double ``` +## testdata/many_patterns + +``` +src/binops.rs:2:5: replace binops with () +src/binops.rs:2:15: replace + with - in binops +src/binops.rs:2:15: replace + with * in binops +src/binops.rs:2:27: replace % with / in binops +src/binops.rs:2:27: replace % with + in binops +src/binops.rs:2:23: replace / with % in binops +src/binops.rs:2:23: replace / with * in binops +src/binops.rs:2:19: replace * with + in binops +src/binops.rs:2:19: replace * with / in binops +src/binops.rs:3:19: replace | with & in binops +src/binops.rs:3:19: replace | with ^ in binops +src/binops.rs:3:15: replace & with | in binops +src/binops.rs:3:15: replace & with ^ in binops +src/binops.rs:3:23: replace ^ with | in binops +src/binops.rs:3:23: replace ^ with & in binops +src/binops.rs:3:32: replace >> with << in binops +src/binops.rs:3:27: replace << with >> in binops +src/binops.rs:5:7: replace += with -= in binops +src/binops.rs:5:7: replace += with *= in binops +src/binops.rs:6:7: replace -= with += in binops +src/binops.rs:6:7: replace -= with /= in binops +src/binops.rs:7:7: replace *= with += in binops +src/binops.rs:7:7: replace *= with /= in binops +src/binops.rs:8:7: replace /= with %= in binops +src/binops.rs:8:7: replace /= with *= in binops +src/binops.rs:12:5: replace bin_assign -> i32 with 0 +src/binops.rs:12:5: replace bin_assign -> i32 with 1 +src/binops.rs:12:5: replace bin_assign -> i32 with -1 +src/binops.rs:13:7: replace |= with &= in bin_assign +src/binops.rs:13:7: replace |= with ^= in bin_assign +src/binops.rs:14:7: replace ^= with |= in bin_assign +src/binops.rs:14:7: replace ^= with &= in bin_assign +src/binops.rs:15:7: replace &= with |= in bin_assign +src/binops.rs:15:7: replace &= with ^= in bin_assign +src/binops.rs:16:7: replace >>= with <<= in bin_assign +src/binops.rs:17:7: replace <<= with >>= in bin_assign +``` + ## testdata/missing_test ``` From 3fcf6248d4aa5506019988b6ebee7845f456172a Mon Sep 17 00:00:00 2001 From: Martin Pool Date: Wed, 10 Jan 2024 21:53:41 -0800 Subject: [PATCH 11/11] Document new mutation patterns --- book/src/mutants.md | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/book/src/mutants.md b/book/src/mutants.md index 727cae45..86b4c32e 100644 --- a/book/src/mutants.md +++ b/book/src/mutants.md @@ -64,16 +64,24 @@ like `a == 0`. | -------- | ------------------ | | `==` | `!=` | | `!=` | `==` | -| `&&` | `\|\|`, `==`, `!=` | -| `\|\|` | `&&`, `==`, `!=` | +| `&&` | `\|\|` | +| `\|\|` | `&&`, | | `<` | `==`, `>` | | `>` | `==`, `<` | -| `<=` | `==`, `>=` | -| `>=` | `==`, `<=` | +| `<=` | `>` | +| `>=` | `<` | +| `+` | `-`, `*` | +| `-` | `+`, `/` | +| `*` | `+`, `/` | +| `/` | `%`, `*` | +| `%` | `/`, `+` | +| `<<` | `>>` | +| `>>` | `<<` | +| `&` | `\|`,`^` | +| `\|` | `&`, `^` | +| `^` | `&`, `\|` | +| `+=` and similar assignments | assignment corresponding to the line above | Equality operators are not currently replaced with comparisons like `<` or `<=` because they are too prone to generate false positives, for example when unsigned integers are compared to 0. - -Logical `&&` and `||` are replaced with `==` and `!=` which function as XNOR and XOR respectively, -although they are fairly often unviable due to needing parenthesis when the original operator does not.