diff --git a/cmd/go-mutesting/main.go b/cmd/go-mutesting/main.go index 5749905..116e909 100644 --- a/cmd/go-mutesting/main.go +++ b/cmd/go-mutesting/main.go @@ -109,6 +109,22 @@ type mutatorItem struct { Mutator mutator.Mutator } +// mutatorDisabled reports whether name matches any entry in patterns. +// An entry ending in '*' is treated as a prefix: "branch*" disables any +// mutator whose name starts with "branch". +func mutatorDisabled(name string, patterns []string) bool { + for _, d := range patterns { + if strings.HasSuffix(d, "*") { + if strings.HasPrefix(name, d[:len(d)-1]) { + return true + } + } else if name == d { + return true + } + } + return false +} + func mainCmd(args []string) int { var opts = &models.Options{} var mutationBlackList = map[string]struct{}{} @@ -170,14 +186,8 @@ func mainCmd(args []string) int { MUTATOR: for _, name := range mutator.List() { - if len(opts.Mutator.DisableMutators) > 0 { - for _, d := range opts.Mutator.DisableMutators { - pattern := strings.HasSuffix(d, "*") - - if (pattern && strings.HasPrefix(name, d[:len(d)-2])) || (!pattern && name == d) { - continue MUTATOR - } - } + if mutatorDisabled(name, opts.Mutator.DisableMutators) { + continue MUTATOR } console.Verbose(opts, "Enable mutator %q", name) diff --git a/cmd/go-mutesting/main_test.go b/cmd/go-mutesting/main_test.go index fc5fc61..d514e9f 100644 --- a/cmd/go-mutesting/main_test.go +++ b/cmd/go-mutesting/main_test.go @@ -167,3 +167,30 @@ func testMain(t *testing.T, root string, exec []string, expectedExitCode int, co assert.Equal(t, expectedExitCode, exitCode) assert.Contains(t, out, contains) } + +func TestMutatorDisabled(t *testing.T) { + for _, tc := range []struct { + name string + patterns []string + want bool + }{ + // exact match + {"branch/if", []string{"branch/if"}, true}, + {"branch/else", []string{"branch/if"}, false}, + // wildcard prefix + {"branch/if", []string{"branch*"}, true}, + {"branch/else", []string{"branch*"}, true}, + {"arithmetic/base", []string{"branch*"}, false}, + // The old bug: len(d)-2 on a 2-char pattern like "b*" produced an empty + // prefix "", which matched every mutator name. len(d)-1 correctly gives "b". + {"arithmetic/base", []string{"b*"}, false}, + {"branch/if", []string{"b*"}, true}, + // empty patterns + {"branch/if", []string{}, false}, + // multiple patterns, first miss second hit + {"arithmetic/base", []string{"branch*", "arithmetic*"}, true}, + } { + got := mutatorDisabled(tc.name, tc.patterns) + assert.Equal(t, tc.want, got, "mutatorDisabled(%q, %v)", tc.name, tc.patterns) + } +}