diff --git a/dsl/matcher.go b/dsl/matcher.go index 2790b61bb..f0e84a147 100644 --- a/dsl/matcher.go +++ b/dsl/matcher.go @@ -312,11 +312,20 @@ func match(srcType reflect.Type, params params) Matcher { return Like("string") case reflect.Bool: + if params.boolean.defined { + return Like(params.boolean.value) + } return Like(true) case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: + if params.number.integer != 0 { + return Like(params.number.integer) + } return Like(1) case reflect.Float32, reflect.Float64: + if params.number.float != 0 { + return Like(params.number.float) + } return Like(1.1) default: panic(fmt.Sprintf("match: unhandled type: %v", srcType)) @@ -327,8 +336,19 @@ func match(srcType reflect.Type, params params) Matcher { // struct fields. They are passed back into match() along with their // associated type to serve as parameters for the dsl functions. type params struct { - slice sliceParams - str stringParams + slice sliceParams + str stringParams + number numberParams + boolean boolParams +} + +type numberParams struct { + integer int + float float32 +} +type boolParams struct { + value bool + defined bool } type sliceParams struct { @@ -360,6 +380,20 @@ func pluckParams(srcType reflect.Type, pactTag string) params { } switch kind := srcType.Kind(); kind { + case reflect.Bool: + if _, err := fmt.Sscanf(pactTag, "example=%t", ¶ms.boolean.value); err != nil { + triggerInvalidPactTagPanic(pactTag, err) + } + params.boolean.defined = true + case reflect.Float32, reflect.Float64: + if _, err := fmt.Sscanf(pactTag, "example=%g", ¶ms.number.float); err != nil { + triggerInvalidPactTagPanic(pactTag, err) + } + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, + reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: + if _, err := fmt.Sscanf(pactTag, "example=%d", ¶ms.number.integer); err != nil { + triggerInvalidPactTagPanic(pactTag, err) + } case reflect.Slice: if _, err := fmt.Sscanf(pactTag, "min=%d", ¶ms.slice.min); err != nil { triggerInvalidPactTagPanic(pactTag, err) diff --git a/dsl/matcher_test.go b/dsl/matcher_test.go index 52f9d4e7b..cc67ad86c 100644 --- a/dsl/matcher_test.go +++ b/dsl/matcher_test.go @@ -563,6 +563,13 @@ func TestMatch(t *testing.T) { type wordsDTO struct { Words []string `json:"words" pact:"min=2"` } + type boolDTO struct { + Boolean bool `json:"boolean" pact:"example=true"` + } + type numberDTO struct { + Integer int `json:"integer" pact:"example=42"` + Float float32 `json:"float" pact:"example=6.66"` + } str := "str" type args struct { src interface{} @@ -622,6 +629,25 @@ func TestMatch(t *testing.T) { "words": EachLike(Like("string"), 2), }, }, + { + name: "recursive case - struct with bool", + args: args{ + src: boolDTO{}, + }, + want: StructMatcher{ + "boolean": Like(true), + }, + }, + { + name: "recursive case - struct with int and float", + args: args{ + src: numberDTO{}, + }, + want: StructMatcher{ + "integer": Like(42), + "float": Like(float32(6.66)), + }, + }, { name: "base case - string", args: args{