Skip to content

Commit

Permalink
mutator for term removal
Browse files Browse the repository at this point in the history
  • Loading branch information
zimmski committed Dec 29, 2014
1 parent 8fe3825 commit 854b834
Show file tree
Hide file tree
Showing 11 changed files with 283 additions and 2 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ DONE- Wir wollen folgendes unterstützen
* Also rein nur Zuweisungen und Aufrüfe
DONE + Blöcke löschen, daher
DONE * if, else if und else branches leeren
+ Condition Terme löschen vom ersten Condition level wenn mehr als ein Term da ist, für
* ifs und elseifs
DONE + Condition Terme löschen vom ersten Condition level wenn mehr als ein Term da ist, für
DONE * ifs und elseifs
DONE - Jede Art von "Mutator" ist ein "Plugin"
DONE- CMD
DONE + Kann wie Golint auf alles mögliche angewendet werden: einzelne Dateien, Ordner, Packages, mit Patterns
Expand Down
1 change: 1 addition & 0 deletions cmd/go-mutesting/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"github.com/zimmski/go-mutesting/importing"
"github.com/zimmski/go-mutesting/mutator"
_ "github.com/zimmski/go-mutesting/mutator/branch"
_ "github.com/zimmski/go-mutesting/mutator/expression"
)

const (
Expand Down
97 changes: 97 additions & 0 deletions mutator/expression/remove.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
package expression

import (
"go/ast"
"go/token"

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

// MutatorRemoveTerm implements a mutator to remove expression terms
type MutatorRemoveTerm struct{}

// NewMutatorRemoveTerm returns a new instance of a MutatorRemoveTerm mutator
func NewMutatorRemoveTerm() *MutatorRemoveTerm {
return &MutatorRemoveTerm{}
}

func init() {
mutator.Register(MutatorRemoveTerm{}.String(), func() mutator.Mutator {
return NewMutatorRemoveTerm()
})
}

func (m *MutatorRemoveTerm) check(node ast.Node) (*ast.BinaryExpr, bool) {
n, ok := node.(*ast.BinaryExpr)
if !ok {
return nil, false
}

_, xBinary := n.X.(*ast.BinaryExpr)
_, xParen := n.X.(*ast.ParenExpr)
_, yBinary := n.Y.(*ast.BinaryExpr)
_, yParen := n.Y.(*ast.ParenExpr)
if (!xBinary && !xParen) || (!yBinary && !yParen) {
return nil, false
}

return n, true
}

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

return 2
}

// 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 *MutatorRemoveTerm) Mutate(node ast.Node, changed chan bool) {
n, ok := m.check(node)
if !ok {
changed <- false

return
}

var r *ast.Ident

switch n.Op {
case token.LAND:
r = ast.NewIdent("true")
case token.LOR:
r = ast.NewIdent("false")
}

x := n.X
y := n.Y

n.X = r

changed <- true
<-changed

n.X = x

changed <- true
<-changed

n.Y = r

changed <- true
<-changed

n.Y = y

changed <- true
<-changed
}

// String implements the String method of the Stringer interface
func (m MutatorRemoveTerm) String() string {
return "expression/remove"
}
22 changes: 22 additions & 0 deletions mutator/expression/remove_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package expression

import (
"testing"

. "github.com/stretchr/testify/assert"

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

func TestMutateElse(t *testing.T) {
m := NewMutatorRemoveTerm()
NotNil(t, m)

test.Mutator(
t,
"../../testdata/expression/remove.go",
"../../testdata/expression/remove.go",
m,
6,
)
}
23 changes: 23 additions & 0 deletions testdata/expression/remove.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// +build example-main

package main

import (
"fmt"
)

func main() {
i := 1

for i != 4 {
if i >= 1 && i <= 1 {
fmt.Println(i)
} else if (i >= 2 && i <= 2) || i == 2 {
fmt.Println(i * 2)
} else {

}

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

package main

import (
"fmt"
)

func main() {
i := 1

for i != 4 {
if true && i <= 1 {
fmt.Println(i)
} else if (i >= 2 && i <= 2) || i == 2 {
fmt.Println(i * 2)
} else {

}

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

package main

import (
"fmt"
)

func main() {
i := 1

for i != 4 {
if i >= 1 && true {
fmt.Println(i)
} else if (i >= 2 && i <= 2) || i == 2 {
fmt.Println(i * 2)
} else {

}

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

package main

import (
"fmt"
)

func main() {
i := 1

for i != 4 {
if i >= 1 && i <= 1 {
fmt.Println(i)
} else if false || i == 2 {
fmt.Println(i * 2)
} else {

}

i++
}
}
23 changes: 23 additions & 0 deletions testdata/expression/remove.go.3.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// +build example-main

package main

import (
"fmt"
)

func main() {
i := 1

for i != 4 {
if i >= 1 && i <= 1 {
fmt.Println(i)
} else if (i >= 2 && i <= 2) || false {
fmt.Println(i * 2)
} else {

}

i++
}
}
23 changes: 23 additions & 0 deletions testdata/expression/remove.go.4.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// +build example-main

package main

import (
"fmt"
)

func main() {
i := 1

for i != 4 {
if i >= 1 && i <= 1 {
fmt.Println(i)
} else if (true && i <= 2) || i == 2 {
fmt.Println(i * 2)
} else {

}

i++
}
}
23 changes: 23 additions & 0 deletions testdata/expression/remove.go.5.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// +build example-main

package main

import (
"fmt"
)

func main() {
i := 1

for i != 4 {
if i >= 1 && i <= 1 {
fmt.Println(i)
} else if (i >= 2 && true) || i == 2 {
fmt.Println(i * 2)
} else {

}

i++
}
}

0 comments on commit 854b834

Please sign in to comment.