Skip to content

Commit

Permalink
Merge pull request #45 from au-phiware/deterministic-gen-struct
Browse files Browse the repository at this point in the history
Ensure that gen.Struct is reproducible for a given seed
  • Loading branch information
untoldwind authored Oct 20, 2018
2 parents e260458 + 63409ef commit 0bdcb15
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 1 deletion.
11 changes: 10 additions & 1 deletion gen/struct.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package gen

import (
"reflect"
"sort"

"github.com/leanovate/gopter"
)
Expand All @@ -20,7 +21,15 @@ func Struct(rt reflect.Type, gens map[string]gopter.Gen) gopter.Gen {
return func(genParams *gopter.GenParameters) *gopter.GenResult {
result := reflect.New(rt)

for name, gen := range gens {
names := make([]string, len(gens))
i := 0
for name := range gens {
names[i] = name
i++
}
sort.Strings(names)
for _, name := range names {
gen := gens[name]
field, ok := rt.FieldByName(name)
if !ok {
continue
Expand Down
48 changes: 48 additions & 0 deletions gen/struct_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,54 @@ func TestStruct(t *testing.T) {
}
}

func TestStructDeterminism(t *testing.T) {
structGen := gen.Struct(reflect.TypeOf(&testStruct{}), map[string]gopter.Gen{
"Value1": gen.Identifier(),
"Value2": gen.Int64(),
"Value3": gen.SliceOf(gen.Int8()),
})
for i := 0; i < 100; i++ {
parameters := gopter.DefaultGenParameters().CloneWithSeed(1234)
for _, expected := range []testStruct{
testStruct{
Value1: "hUeNzDbtiF4xxkidfvLaiczgpwsqfyvbbuhrjjoez4jtewulIKwzMguttazo3qwi5ufIfi6izpqT4evzrmgtmk1gQo",
Value2: -2282921689139609493,
Value3: []int8{-93, -96, -23, -58, 65, -108, 56, 63, -64, 26, -69, 62, 61, -93, -107, 52, -95},
},
testStruct{
Value1: "ubJrJEawwnoh63jv1lxd7xhtaqqrEnjawudgiixhhkw6sdmqdgxbabyoxcoE0uviwDupccvYvxcqOv0z8opjk",
Value2: -1611599231975617329,
Value3: []int8{15, -41, -106, 37, 3, 76, -65, -87, 113, -115, 76, 61, 41, 65, 11, -90, -4, 43, 110, -121, 65, 112, -128, 51, -86, 50, 30, 33, -73, -88, 94, 101, 63, -113, 45, 110, 46, 21, 115, 78, -58, 47, -110, 7, -14, -18, 2, -26, 63, -33, 77, 82, -52, -57, -105},
},
testStruct{
Value1: "axnbggD6Hgsxyxd6ZwcZ4Bn1uM7hzd0azvsuLvj3wvfvoramjcltivmditt5qhmHYfn0egagcFpuAffzaWxvalEaniojczez",
Value2: -345052727922296584,
Value3: []int8{-61, 94, 67, 9, 39, 119, 23, 1, 57, -66, 57, -94, 38, -122, 16, 82, -119, 21, -74, -66, -111, 55, -96, 8, -79, 13, -41, 124, 71, -63, 56, 16, 62, 55, -13, -35, -27, 68, -82, 22, -63, -76, 96, 60, -89, -10, -65, -102, -97, 45, 124, 117, -37, 21, 58, -87, 116, 60, -111, 27, 102, -102, -81, -123, -86, -95},
},
testStruct{
Value1: "lr",
Value2: -6442088894944465291,
Value3: []int8{-20, 38, 25, -76, -110, -98, -61, 65, -14, 52, -47, 22, -90},
},
testStruct{
Value1: "un23mggozHs4txZtydz6mIBymnxjxklkjyNzf",
Value2: -26686468742269553,
Value3: []int8{78, 91, -22, -126, -93, 35, -14, 67, -97, 13, -25, 73, -111, 26, 14, -67, 50, -23, -15, -63, -40, -103, 126, 60, -63, -83, -126, 64, 52, -50, 86, -25, -1, 108, 7, 62, 79, 89, 45, -73, 52, -7, -85, -111, -120, -21, 116, -8, -22, 34, 85, 36, 124, 12, -111, -114, -115, 91, -94, 82, -3, -46, 94, -73, 62, -117, -7, 84, -94, 13, 71, -5, 21, 32, 106, -44, 46},
},
} {
value, ok := structGen(parameters).Retrieve()

if !ok {
t.Errorf("Invalid value: %#v", value)
}
v, ok := value.(testStruct)
if !reflect.DeepEqual(expected, v) {
t.Errorf("Invalid value: %#v; expected: %#v", v, expected)
}
}
}
}

func TestStructPropageEmpty(t *testing.T) {
fail := gen.Struct(reflect.TypeOf(&testStruct{}), map[string]gopter.Gen{
"Value1": gen.Identifier().SuchThat(func(str string) bool {
Expand Down

0 comments on commit 0bdcb15

Please sign in to comment.