From 9981568ab3143bfdceca0f30c61702a919d87ef8 Mon Sep 17 00:00:00 2001
From: "Mikhail f. Shiryaev" <mr.felixoid@gmail.com>
Date: Mon, 28 Jun 2021 00:45:30 +0200
Subject: [PATCH] Add --score flag to set a minimal acceptance

---
 cmd/go-mutesting/main.go      | 11 ++++++++---
 cmd/go-mutesting/main_test.go | 10 ++++++++++
 2 files changed, 18 insertions(+), 3 deletions(-)

diff --git a/cmd/go-mutesting/main.go b/cmd/go-mutesting/main.go
index ee786f5..cfafe0d 100644
--- a/cmd/go-mutesting/main.go
+++ b/cmd/go-mutesting/main.go
@@ -67,7 +67,8 @@ type options struct {
 	} `group:"Exec options"`
 
 	Test struct {
-		Recursive bool `long:"test-recursive" description:"Defines if the executer should test recursively"`
+		Recursive bool    `long:"test-recursive" description:"Defines if the executer should test recursively"`
+		Score     float64 `long:"score" description:"Minimal acceptable scores value. If result is less than given, exit code will be non-zero" default:"0"`
 	} `group:"Test options"`
 
 	Remaining struct {
@@ -111,7 +112,7 @@ func checkArguments(args []string, opts *options) (bool, int) {
 		opts.General.Verbose = true
 	}
 
-	return false, 0
+	return false, returnOk
 }
 
 func debug(opts *options, format string, args ...interface{}) {
@@ -299,13 +300,17 @@ MUTATOR:
 		debug(opts, "Remove %q", tmpDir)
 	}
 
+	exitCode := returnOk
 	if !opts.Exec.NoExec {
 		fmt.Printf("The mutation score is %f (%d passed, %d failed, %d duplicated, %d skipped, total is %d)\n", stats.Score(), stats.passed, stats.failed, stats.duplicated, stats.skipped, stats.Total())
+		if stats.Score() < opts.Test.Score {
+			exitCode = returnError
+		}
 	} else {
 		fmt.Println("Cannot do a mutation testing summary since no exec command was executed.")
 	}
 
-	return returnOk
+	return exitCode
 }
 
 func mutate(opts *options, mutators []mutatorItem, mutationBlackList map[string]struct{}, mutationID int, pkg *types.Package, info *types.Info, file string, fset *token.FileSet, src ast.Node, node ast.Node, tmpFile string, execs []string, stats *mutationStats) int {
diff --git a/cmd/go-mutesting/main_test.go b/cmd/go-mutesting/main_test.go
index 7727851..8b55cb1 100644
--- a/cmd/go-mutesting/main_test.go
+++ b/cmd/go-mutesting/main_test.go
@@ -49,6 +49,16 @@ func TestMainMatch(t *testing.T) {
 	)
 }
 
+func TestMainScore(t *testing.T) {
+	testMain(
+		t,
+		"../../example",
+		[]string{"--debug", "--exec-timeout", "1", "--score", "0.46"},
+		returnError,
+		"The mutation score is 0.450000 (9 passed, 11 failed, 8 duplicated, 0 skipped, total is 20)",
+	)
+}
+
 func testMain(t *testing.T, root string, exec []string, expectedExitCode int, contains string) {
 	saveStderr := os.Stderr
 	saveStdout := os.Stdout