Skip to content

Commit

Permalink
Fix handling of empty prop name in json tag (#123)
Browse files Browse the repository at this point in the history
  • Loading branch information
vearutop authored Jan 20, 2025
1 parent b59113f commit 8a67fbf
Show file tree
Hide file tree
Showing 2 changed files with 109 additions and 4 deletions.
4 changes: 2 additions & 2 deletions reflect.go
Original file line number Diff line number Diff line change
Expand Up @@ -1032,8 +1032,9 @@ func (r *Reflector) walkProperties(v reflect.Value, parent *Schema, rc *ReflectC
}

deepIndirect := refl.DeepIndirect(field.Type)
propName := strings.Split(tag, ",")[0]

if tag == "" && field.Anonymous &&
if propName == "" && field.Anonymous &&
(field.Type.Kind() == reflect.Struct || deepIndirect.Kind() == reflect.Struct) {
forceReference := (field.Type.Implements(typeOfEmbedReferencer) && field.Tag.Get("refer") == "") ||
field.Tag.Get("refer") == "true"
Expand Down Expand Up @@ -1089,7 +1090,6 @@ func (r *Reflector) walkProperties(v reflect.Value, parent *Schema, rc *ReflectC
continue
}

propName := strings.Split(tag, ",")[0]
omitEmpty := strings.Contains(tag, ",omitempty")
required := false

Expand Down
109 changes: 107 additions & 2 deletions reflect_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1654,7 +1654,15 @@ func TestReflector_Reflect_deeplyEmbedded(t *testing.T) {
Baz float64 `json:"baz" title:"Bazzz."`
}

s, err := r.Reflect(My{})
val := My{}
val.DeeplyEmbedded = &DeeplyEmbedded{}
val.Foo = "abcde"
val.Bar = 123
val.Baz = 4.56

assertjson.EqMarshal(t, `{"foo":"abcde","bar":123,"baz":4.56}`, val)

s, err := r.Reflect(val)
require.NoError(t, err)

assertjson.EqMarshal(t, `{
Expand All @@ -1667,6 +1675,96 @@ func TestReflector_Reflect_deeplyEmbedded(t *testing.T) {
}`, s)
}

func TestReflector_Reflect_deeplyEmbedded_emptyJSONTags(t *testing.T) {
r := jsonschema.Reflector{}

type Embed struct {
Foo string `json:",omitempty" minLength:"5"` // Empty name in tag results in Go field name.
Bar int `json:"bar" minimum:"3"`
}

type DeeplyEmbedded struct {
Embed `json:""`
}

type My struct {
*DeeplyEmbedded `json:",inline"` // `inline` does not have any specific handling by encoding/json.

Baz float64 `json:"baz" title:"Bazzz."`
}

val := My{}
val.DeeplyEmbedded = &DeeplyEmbedded{}
val.Foo = "abcde"
val.Bar = 123
val.Baz = 4.56

assertjson.EqMarshal(t, `{"Foo":"abcde","bar":123,"baz":4.56}`, val)

s, err := r.Reflect(val)
require.NoError(t, err)

assertjson.EqMarshal(t, `{
"properties":{
"bar":{"minimum":3,"type":"integer"},
"baz":{"title":"Bazzz.","type":"number"},
"Foo":{"minLength":5,"type":"string"}
},
"type":"object"
}`, s)
}

func TestReflector_Reflect_deeplyEmbedded_validJSONTags(t *testing.T) {
r := jsonschema.Reflector{}

type Embed struct {
Foo string `json:"foo" minLength:"5"`
Bar int `json:"bar" minimum:"3"`
}

type DeeplyEmbedded struct {
Embed `json:"emb"`
}

type My struct {
*DeeplyEmbedded `json:"deep,inline"` // `inline` does not have any specific handling by encoding/json.

Baz float64 `json:"baz" title:"Bazzz."`
}

val := My{}
val.DeeplyEmbedded = &DeeplyEmbedded{}
val.Foo = "abcde"
val.Bar = 123
val.Baz = 4.56

assertjson.EqMarshal(t, `{"deep":{"emb":{"foo":"abcde","bar":123}},"baz":4.56}`, val)

s, err := r.Reflect(val)
require.NoError(t, err)

assertjson.EqMarshal(t, `{
"definitions":{
"JsonschemaGoTestDeeplyEmbedded":{
"properties":{"emb":{"$ref":"#/definitions/JsonschemaGoTestEmbed"}},
"type":"object"
},
"JsonschemaGoTestEmbed":{
"properties":{
"bar":{"minimum":3,"type":"integer"},
"foo":{"minLength":5,"type":"string"}
},
"type":"object"
}
},
"properties":{
"baz":{"title":"Bazzz.","type":"number"},
"deep":{"$ref":"#/definitions/JsonschemaGoTestDeeplyEmbedded"}
},
"type":"object"
}`, s)
}

func TestReflector_Reflect_deeplyEmbeddedUnexported(t *testing.T) {
r := jsonschema.Reflector{}

Expand All @@ -1685,7 +1783,14 @@ func TestReflector_Reflect_deeplyEmbeddedUnexported(t *testing.T) {
Baz float64 `json:"baz" title:"Bazzz."`
}

s, err := r.Reflect(My{})
val := My{}
val.Foo = "abcde"
val.Bar = 123
val.Baz = 4.56

assertjson.EqMarshal(t, `{"foo":"abcde","bar":123,"baz":4.56}`, val)

s, err := r.Reflect(val)
require.NoError(t, err)

assertjson.EqMarshal(t, `{
Expand Down

0 comments on commit 8a67fbf

Please sign in to comment.