Last active
May 1, 2021 13:02
-
-
Save rciorba/79e17881b1739afe2ff504b7edbcfc73 to your computer and use it in GitHub Desktop.
foo
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module github.com/rciorba/gopterbugreport | |
go 1.16 | |
require github.com/leanovate/gopter v0.2.9 // indirect |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c= | |
github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package gopterbugreport | |
import ( | |
"fmt" | |
"reflect" | |
"testing" | |
"github.com/leanovate/gopter" | |
"github.com/leanovate/gopter/commands" | |
"github.com/leanovate/gopter/gen" | |
) | |
// The Tests | |
// simplified SUT, if true we should fail the next PostCondition | |
type SUT = bool | |
// simplified state is gonna be just the length of the original state | |
type baState = int | |
// the setCommand type. | |
type setCommand struct { | |
Index int | |
Value bool | |
} | |
func (cmd setCommand) Run(sut commands.SystemUnderTest) commands.Result { | |
// fmt.Printf("Run got CMD: %v \n", cmd) | |
if cmd.Index == 12 { | |
// Intentional "bug" in our SUT, from now on fail the postcondition | |
return true | |
} | |
return sut | |
} | |
func (cmd setCommand) NextState(state commands.State) commands.State { | |
fmt.Printf("NextState got CMD: %v \n", cmd) | |
st := state.(baState) | |
if cmd.Index < 0 || cmd.Index >= st { | |
panic(fmt.Sprintf("Index out of range [0, %v]: %v", st-1, cmd.Index)) | |
} | |
return st | |
} | |
func (setCommand) PreCondition(state commands.State) bool { | |
return true | |
} | |
func (setCommand) PostCondition(state commands.State, result commands.Result) *gopter.PropResult { | |
sut := result.(SUT) | |
if sut { | |
fmt.Printf("We've encountered the fake bug, so we'll fail the PostCondition\n") | |
return &gopter.PropResult{Status: gopter.PropFalse} | |
} | |
return &gopter.PropResult{Status: gopter.PropTrue} | |
} | |
func (cmd setCommand) String() string { | |
return fmt.Sprintf("Set(%v, %v)", cmd.Index, cmd.Value) | |
} | |
// We will use this in combination with gen.OneConstOf, to work arround the issue with IntRange | |
// generating values outside the declared range. | |
func makeIntSequence(start, end int) []interface{} { | |
seq := make([]interface{}, end+1-start) | |
for i := start; i <= end; i++ { | |
seq[i-start] = i | |
} | |
return seq | |
} | |
func makeGenSetCommand(state baState) gopter.Gen { | |
genCommand := gen.Struct( | |
reflect.TypeOf(setCommand{}), | |
map[string]gopter.Gen{ | |
// Despite the declared range we will see out of bounds indexes. | |
"Index": gen.IntRange(6, state-1), | |
// Using OneConstOf avoids the index-out-of-range issue. | |
// "Index": gen.OneConstOf(makeIntSequence(0, state-1)...), | |
"Value": gen.Bool(), | |
}, | |
) | |
return genCommand | |
} | |
var bitarrayCommands = &commands.ProtoCommands{ | |
NewSystemUnderTestFunc: func(initialState commands.State) commands.SystemUnderTest { | |
return false | |
}, | |
InitialStateGen: gen.Const(16), | |
GenCommandFunc: func(state commands.State) gopter.Gen { | |
st := state.(baState) | |
return makeGenSetCommand(st) | |
}, | |
} | |
func TestIntRangeShrinking(t *testing.T) { | |
var params *gopter.TestParameters | |
params = gopter.DefaultTestParameters() | |
params.Rng.Seed(1) // Just for this example to generate reproducible results | |
params.Workers = 1 | |
properties := gopter.NewProperties(params) | |
properties.Property("always equivalent", commands.Prop(bitarrayCommands)) | |
properties.TestingRun(t) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment