From f4822c580c70e3fd3d0191af484532102d4bbe0a Mon Sep 17 00:00:00 2001 From: Joschka Tillmanns Date: Fri, 15 Nov 2019 07:07:13 +0100 Subject: [PATCH] feat(custom-faker): add map support to custom fakers (#70) * add map support to custom fakers #69 * remove map from unspported keep types #69 * test if unsupported map types are supported with custom faker #69 * test if keep works on maps #69 --- faker.go | 16 +++++++++++++++- faker_test.go | 47 ++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 55 insertions(+), 8 deletions(-) diff --git a/faker.go b/faker.go index 4b47e2b..1f2428c 100644 --- a/faker.go +++ b/faker.go @@ -473,7 +473,11 @@ func getValue(a interface{}) (reflect.Value, error) { } func isZero(field reflect.Value) (bool, error) { - for _, kind := range []reflect.Kind{reflect.Struct, reflect.Slice, reflect.Array, reflect.Map} { + if field.Kind() == reflect.Map { + return field.Len() == 0, nil + } + + for _, kind := range []reflect.Kind{reflect.Struct, reflect.Slice, reflect.Array} { if kind == field.Kind() { return false, fmt.Errorf("keep not allowed on struct") } @@ -558,6 +562,16 @@ func setDataWithTag(v reflect.Value, tag string) error { } func userDefinedMap(v reflect.Value, tag string) error { + if tagFunc, ok := mapperTag[tag]; ok { + res, err := tagFunc(v) + if err != nil { + return err + } + + v.Set(reflect.ValueOf(res)) + return nil + } + len := randomSliceAndMapSize() if shouldSetNil && len == 0 { v.Set(reflect.Zero(v.Type())) diff --git a/faker_test.go b/faker_test.go index 4fef09c..6962a7d 100644 --- a/faker_test.go +++ b/faker_test.go @@ -293,6 +293,34 @@ func TestFakerData(t *testing.T) { } +func TestCustomFakerOnUnsupportedMapStringInterface(t *testing.T) { + type Sample struct { + Map map[string]interface{} `faker:"custom"` + } + + err := AddProvider("custom", func(v reflect.Value) (interface{}, error) { + return map[string]interface{}{"foo": "bar"}, nil + }) + if err != nil { + t.Error("Expected NoError, but Got Err", err) + } + + var sample = new(Sample) + err = FakeData(sample) + if err != nil { + t.Error("Expected NoError, but Got Err:", err) + } + + actual, ok := sample.Map["foo"] + if !ok { + t.Error("map key not set by custom faker") + } + + if actual != "bar" { + t.Error("map value not set by custom faker") + } +} + func TestUnsuportedMapStringInterface(t *testing.T) { type Sample struct { Map map[string]interface{} @@ -847,13 +875,16 @@ func TestItOverwritesDefaultValueIfKeepIsSet(t *testing.T) { } func TestItKeepsStructPropertyWhenTagKeepIsSet(t *testing.T) { type TestStruct struct { - FirstName string `json:"first_name,omitempty" faker:"first_name_male,keep"` - Email string `json:"email,omitempty" faker:"email,keep"` + FirstName string `json:"first_name,omitempty" faker:"first_name_male,keep"` + Email string `json:"email,omitempty" faker:"email,keep"` + Map map[string]string `json:"map,omitempty" faker:"keep"` } firstName := "Heino van der Laien" + m := map[string]string{"foo": "bar"} test := TestStruct{ FirstName: firstName, + Map: m, } err := FakeData(&test) @@ -865,6 +896,12 @@ func TestItKeepsStructPropertyWhenTagKeepIsSet(t *testing.T) { t.Fatalf("expected: %s, but got: %s", firstName, test.FirstName) } + for k, v := range m { + if test.Map[k] != v { + t.Fatalf("expected: %s, but got: %s", m, test.Map) + } + } + if test.Email == "" { t.Error("expected filled but got empty") } @@ -874,9 +911,6 @@ func TestItThrowsAnErrorWhenKeepIsUsedOnIncomparableType(t *testing.T) { type TypeStructWithStruct struct { Struct struct{} `faker:"first_name_male,keep"` } - type TypeStructWithMap struct { - Map map[string]string `faker:"first_name_male,keep"` - } type TypeStructWithSlice struct { Slice []string `faker:"first_name_male,keep"` } @@ -885,11 +919,10 @@ func TestItThrowsAnErrorWhenKeepIsUsedOnIncomparableType(t *testing.T) { } withStruct := TypeStructWithStruct{} - withMap := TypeStructWithMap{} withSlice := TypeStructWithSlice{} withArray := TypeStructWithArray{} - for _, item := range []interface{}{withArray,withStruct,withMap,withSlice} { + for _, item := range []interface{}{withArray, withStruct, withSlice} { err := FakeData(&item) if err == nil { t.Errorf("expected error, but got nil")