Skip to content

Commit

Permalink
Mutator to empty cases of switches
Browse files Browse the repository at this point in the history
  • Loading branch information
zimmski committed Jan 3, 2015
1 parent 9730be1 commit 62261da
Show file tree
Hide file tree
Showing 9 changed files with 187 additions and 2 deletions.
2 changes: 1 addition & 1 deletion cmd/go-mutesting/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,5 +44,5 @@ func TestMain(t *testing.T) {
out := <-bufChannel

assert.Equal(t, returnOk, exitCode)
assert.Contains(t, out, "The mutation score is 0.750000 (6 passed, 2 failed, 0 skipped, total is 8)")
assert.Contains(t, out, "The mutation score is 0.636364 (7 passed, 4 failed, 0 skipped, total is 11)")
}
9 changes: 9 additions & 0 deletions example/example.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,15 @@ func foo() int {
bar()
bar()

switch {
case n < 20:
n++
case n > 20:
n--
default:
n = 0
}

return n
}

Expand Down
2 changes: 1 addition & 1 deletion example/example_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@ import (
)

func TestFoo(t *testing.T) {
Equal(t, foo(), 15)
Equal(t, foo(), 16)
}
64 changes: 64 additions & 0 deletions mutator/branch/mutatecase.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package branch

import (
"go/ast"

"github.com/zimmski/go-mutesting/mutator"
)

// MutatorCase implements a mutator for case
type MutatorCase struct{}

// NewMutatorCase returns a new instance of a MutatorCase mutator
func NewMutatorCase() *MutatorCase {
return &MutatorCase{}
}

func init() {
mutator.Register(MutatorCase{}.String(), func() mutator.Mutator {
return NewMutatorCase()
})
}

func (m *MutatorCase) check(node ast.Node) (*ast.CaseClause, bool) {
n, ok := node.(*ast.CaseClause)

return n, ok
}

// Check validates how often a node can be mutated by a mutator
func (m *MutatorCase) Check(node ast.Node) uint {
_, ok := m.check(node)
if !ok {
return 0
}

return 1
}

// Mutate mutates a given node if it can be mutated by the mutator.
// 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.
func (m *MutatorCase) Mutate(node ast.Node, changed chan bool) {
n, ok := m.check(node)
if !ok {
changed <- false

return
}

old := n.Body
n.Body = make([]ast.Stmt, 0)

changed <- true
<-changed

n.Body = old

changed <- true
<-changed
}

// String implements the String method of the Stringer interface
func (m MutatorCase) String() string {
return "branch/case"
}
16 changes: 16 additions & 0 deletions mutator/branch/mutatecase_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package branch

import (
"testing"

"github.com/zimmski/go-mutesting/test"
)

func TestMutatorCase(t *testing.T) {
test.Mutator(
t,
NewMutatorCase(),
"../../testdata/branch/mutatecase.go",
3,
)
}
24 changes: 24 additions & 0 deletions testdata/branch/mutatecase.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// +build example-main

package main

import (
"fmt"
)

func main() {
i := 1

for i != 4 {
switch {
case i == 1:
fmt.Println(i)
case i == 2:
fmt.Println(i * 2)
default:
fmt.Println(i * 3)
}

i++
}
}
24 changes: 24 additions & 0 deletions testdata/branch/mutatecase.go.0.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// +build example-main

package main

import (
"fmt"
)

func main() {
i := 1

for i != 4 {
switch {
case i == 1:

case i == 2:
fmt.Println(i * 2)
default:
fmt.Println(i * 3)
}

i++
}
}
24 changes: 24 additions & 0 deletions testdata/branch/mutatecase.go.1.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// +build example-main

package main

import (
"fmt"
)

func main() {
i := 1

for i != 4 {
switch {
case i == 1:
fmt.Println(i)
case i == 2:

default:
fmt.Println(i * 3)
}

i++
}
}
24 changes: 24 additions & 0 deletions testdata/branch/mutatecase.go.2.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// +build example-main

package main

import (
"fmt"
)

func main() {
i := 1

for i != 4 {
switch {
case i == 1:
fmt.Println(i)
case i == 2:
fmt.Println(i * 2)
default:

}

i++
}
}

0 comments on commit 62261da

Please sign in to comment.