Skip to content

Commit 62261da

Browse files
committed
Mutator to empty cases of switches
1 parent 9730be1 commit 62261da

File tree

9 files changed

+187
-2
lines changed

9 files changed

+187
-2
lines changed

cmd/go-mutesting/main_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -44,5 +44,5 @@ func TestMain(t *testing.T) {
4444
out := <-bufChannel
4545

4646
assert.Equal(t, returnOk, exitCode)
47-
assert.Contains(t, out, "The mutation score is 0.750000 (6 passed, 2 failed, 0 skipped, total is 8)")
47+
assert.Contains(t, out, "The mutation score is 0.636364 (7 passed, 4 failed, 0 skipped, total is 11)")
4848
}

example/example.go

+9
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,15 @@ func foo() int {
2626
bar()
2727
bar()
2828

29+
switch {
30+
case n < 20:
31+
n++
32+
case n > 20:
33+
n--
34+
default:
35+
n = 0
36+
}
37+
2938
return n
3039
}
3140

example/example_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,5 @@ import (
77
)
88

99
func TestFoo(t *testing.T) {
10-
Equal(t, foo(), 15)
10+
Equal(t, foo(), 16)
1111
}

mutator/branch/mutatecase.go

+64
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
package branch
2+
3+
import (
4+
"go/ast"
5+
6+
"github.com/zimmski/go-mutesting/mutator"
7+
)
8+
9+
// MutatorCase implements a mutator for case
10+
type MutatorCase struct{}
11+
12+
// NewMutatorCase returns a new instance of a MutatorCase mutator
13+
func NewMutatorCase() *MutatorCase {
14+
return &MutatorCase{}
15+
}
16+
17+
func init() {
18+
mutator.Register(MutatorCase{}.String(), func() mutator.Mutator {
19+
return NewMutatorCase()
20+
})
21+
}
22+
23+
func (m *MutatorCase) check(node ast.Node) (*ast.CaseClause, bool) {
24+
n, ok := node.(*ast.CaseClause)
25+
26+
return n, ok
27+
}
28+
29+
// Check validates how often a node can be mutated by a mutator
30+
func (m *MutatorCase) Check(node ast.Node) uint {
31+
_, ok := m.check(node)
32+
if !ok {
33+
return 0
34+
}
35+
36+
return 1
37+
}
38+
39+
// Mutate mutates a given node if it can be mutated by the mutator.
40+
// It first checks if the given node can be mutated by the mutator. If the node cannot be mutated, false is send into the given control channel and the method returns. If the node can be mutated, the current state of the node is saved. Afterwards the node is mutated, true is send into the given control channel and the method waits on the channel to continue the process. After receiving a value from the channel the original state of the node is restored, true is send into the given control channel and the method waits on the channel to continue the process. After receiving a value from the channel the method returns which finishes the mutation process.
41+
func (m *MutatorCase) Mutate(node ast.Node, changed chan bool) {
42+
n, ok := m.check(node)
43+
if !ok {
44+
changed <- false
45+
46+
return
47+
}
48+
49+
old := n.Body
50+
n.Body = make([]ast.Stmt, 0)
51+
52+
changed <- true
53+
<-changed
54+
55+
n.Body = old
56+
57+
changed <- true
58+
<-changed
59+
}
60+
61+
// String implements the String method of the Stringer interface
62+
func (m MutatorCase) String() string {
63+
return "branch/case"
64+
}

mutator/branch/mutatecase_test.go

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package branch
2+
3+
import (
4+
"testing"
5+
6+
"github.com/zimmski/go-mutesting/test"
7+
)
8+
9+
func TestMutatorCase(t *testing.T) {
10+
test.Mutator(
11+
t,
12+
NewMutatorCase(),
13+
"../../testdata/branch/mutatecase.go",
14+
3,
15+
)
16+
}

testdata/branch/mutatecase.go

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// +build example-main
2+
3+
package main
4+
5+
import (
6+
"fmt"
7+
)
8+
9+
func main() {
10+
i := 1
11+
12+
for i != 4 {
13+
switch {
14+
case i == 1:
15+
fmt.Println(i)
16+
case i == 2:
17+
fmt.Println(i * 2)
18+
default:
19+
fmt.Println(i * 3)
20+
}
21+
22+
i++
23+
}
24+
}

testdata/branch/mutatecase.go.0.go

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// +build example-main
2+
3+
package main
4+
5+
import (
6+
"fmt"
7+
)
8+
9+
func main() {
10+
i := 1
11+
12+
for i != 4 {
13+
switch {
14+
case i == 1:
15+
16+
case i == 2:
17+
fmt.Println(i * 2)
18+
default:
19+
fmt.Println(i * 3)
20+
}
21+
22+
i++
23+
}
24+
}

testdata/branch/mutatecase.go.1.go

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// +build example-main
2+
3+
package main
4+
5+
import (
6+
"fmt"
7+
)
8+
9+
func main() {
10+
i := 1
11+
12+
for i != 4 {
13+
switch {
14+
case i == 1:
15+
fmt.Println(i)
16+
case i == 2:
17+
18+
default:
19+
fmt.Println(i * 3)
20+
}
21+
22+
i++
23+
}
24+
}

testdata/branch/mutatecase.go.2.go

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// +build example-main
2+
3+
package main
4+
5+
import (
6+
"fmt"
7+
)
8+
9+
func main() {
10+
i := 1
11+
12+
for i != 4 {
13+
switch {
14+
case i == 1:
15+
fmt.Println(i)
16+
case i == 2:
17+
fmt.Println(i * 2)
18+
default:
19+
20+
}
21+
22+
i++
23+
}
24+
}

0 commit comments

Comments
 (0)