From 8207afe2a797aa586d88a4ba62e44d98a3f66270 Mon Sep 17 00:00:00 2001 From: "T. Hopia" <25904171+tuomohopia@users.noreply.github.com> Date: Thu, 16 Nov 2023 14:35:48 +0200 Subject: [PATCH] Minor fixes (#8) --- README.md | 2 +- lib/mix/mutate.ex | 11 +++++++++-- lib/mutix/report.ex | 5 +++-- test/mutix/report_test.exs | 18 +++++++++++++++++- 4 files changed, 30 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 86ea39c..214e5ff 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ Add `:mutix` to your test dependencies in your `mix.exs` file: ```elixir def deps do [ - {:mutix, git: "https://github.com/tuomohopia/mutix.git", tag: "v0.1.0", only: :test} + {:mutix, git: "https://github.com/tuomohopia/mutix.git", tag: "v0.1.0", only: [:dev, :test]} ] end ``` diff --git a/lib/mix/mutate.ex b/lib/mix/mutate.ex index d3f8f45..f1592a4 100644 --- a/lib/mix/mutate.ex +++ b/lib/mix/mutate.ex @@ -83,7 +83,7 @@ defmodule Mix.Tasks.Mutate do if source_file_count == 0, do: Mix.raise( - "Please provide path to the source file to mutate, e.g. `mix mutate lib/my_app/transformer.ex`. Other options unsupported at this time." + "Please provide path to the source file to mutate, e.g. `mix mutate lib/my_app/transformer.ex`." ) if source_file_count > 1, @@ -96,7 +96,10 @@ defmodule Mix.Tasks.Mutate do end if Mix.Task.recursing?(), do: Mix.raise("Umbrella apps not supported yet.") - unless File.exists?(source_file), do: Mix.raise("Source module file must exist.") + + unless File.exists?(source_file), + do: Mix.raise("Source module file #{source_file} does not exist.") + _ = Mix.Project.get!() project = Mix.Project.config() @@ -137,6 +140,10 @@ defmodule Mix.Tasks.Mutate do # One clean run first to assert all tests pass ExUnit.CaptureIO.with_io(fn -> case ExUnit.run() do + %{failures: 0, total: total, excluded: excluded, skipped: skipped} + when excluded + skipped == total -> + Mix.raise("No tests to run detected. Exited without running a mutation test suite.") + %{failures: 0} -> :ok diff --git a/lib/mutix/report.ex b/lib/mutix/report.ex index 47e91ad..45f0240 100644 --- a/lib/mutix/report.ex +++ b/lib/mutix/report.ex @@ -15,7 +15,8 @@ defmodule Mutix.Report do def mutation(test_results, source_file_path, operator_mutation) do {from, to} = operator_mutation score = mutation_score(test_results) - percentage = score.survived_count / score.mutant_count * 100 + + percentage = (score.mutant_count - score.survived_count) / score.mutant_count * 100 survived = score.survived survived_report = @@ -32,7 +33,7 @@ defmodule Mutix.Report do #{score.killed_count} / #{score.mutant_count} mutants killed by the test suite. - Mutation score: #{percentage} % + Mutation score: #{Float.round(percentage, 1)} % #{survived_report} """ end diff --git a/test/mutix/report_test.exs b/test/mutix/report_test.exs index c90ce17..6e04c3b 100644 --- a/test/mutix/report_test.exs +++ b/test/mutix/report_test.exs @@ -14,7 +14,7 @@ defmodule Mutix.ReportTest do 0 / 1 mutants killed by the test suite. - Mutation score: 100.0 % + Mutation score: 0.0 % Surviving mutants (no test failed with these injections): @@ -36,5 +36,21 @@ defmodule Mutix.ReportTest do result = Report.mutation(test_results, source_file_path, operator_mutation) assert result == String.replace_trailing(@single_operator_result, "\n\n\n", "\n\n") end + + test "reports mutation score correctly" do + test_results = [ + {%{total: 5, failures: 0, excluded: 0, skipped: 0}, [index_on_line: 0, line: 3], ""}, + {%{total: 5, failures: 1, excluded: 0, skipped: 0}, [index_on_line: 0, line: 5], ""}, + {%{total: 5, failures: 5, excluded: 0, skipped: 0}, [index_on_line: 0, line: 8], ""} + ] + + source_file_path = "test/support/single_operator_source.ex" + operator_mutation = {:>, :<} + + result = Report.mutation(test_results, source_file_path, operator_mutation) + assert result =~ "5 tests were run for each mutant." + assert result =~ "2 / 3 mutants killed by the test suite." + assert result =~ "Mutation score: 66.7 %" + end end end