Skip to content

Commit 7ab4951

Browse files
committed
fix(json parser): use Exportable interface when schema or property is not specified
1 parent ff98f63 commit 7ab4951

3 files changed

Lines changed: 67 additions & 6 deletions

File tree

schema/json/parser/parser.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,14 +43,14 @@ func (p *Parser) Parse(data interface{}) (interface{}, error) {
4343
}
4444

4545
func (p *Parser) parse(data interface{}, s *schema.Schema) (interface{}, error) {
46-
if s == nil {
47-
return data, nil
48-
}
49-
5046
if e, ok := data.(Exportable); ok {
5147
data = e.Export()
5248
}
5349

50+
if s == nil {
51+
return data, nil
52+
}
53+
5454
if s.Boolean != nil {
5555
if *s.Boolean {
5656
return data, nil

schema/json/parser/parser_object.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ import (
99
"regexp"
1010
"regexp/syntax"
1111
"sort"
12-
"strings"
1312
"strconv"
13+
"strings"
1414
)
1515

1616
func (p *Parser) parseObject(data interface{}, s *schema.Schema, evaluated map[string]bool) (*sortedmap.LinkedHashMap[string, interface{}], error) {
@@ -253,7 +253,11 @@ func (p *Parser) parseMap(v reflect.Value, s *schema.Schema, evaluated map[strin
253253
name := fmt.Sprintf("%v", k.Interface())
254254
if _, found := obj.Get(name); !found {
255255
o := v.MapIndex(k)
256-
obj.Set(name, o.Interface())
256+
val := o.Interface()
257+
if e, ok := val.(Exportable); ok {
258+
val = e.Export()
259+
}
260+
obj.Set(name, val)
257261
}
258262
}
259263
}

schema/json/parser/parser_test.go

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,3 +276,60 @@ func TestParser_Null(t *testing.T) {
276276
})
277277
}
278278
}
279+
280+
type exportable struct {
281+
export func() any
282+
}
283+
284+
func (e *exportable) Export() any {
285+
return e.export()
286+
}
287+
288+
func TestParser_Exportable(t *testing.T) {
289+
testcases := []struct {
290+
name string
291+
data interface{}
292+
schema *schema.Schema
293+
test func(t *testing.T, v interface{}, err error)
294+
}{
295+
{
296+
name: "schema integer",
297+
data: &exportable{export: func() any { return 123 }},
298+
schema: schematest.New("integer"),
299+
test: func(t *testing.T, v interface{}, err error) {
300+
require.NoError(t, err)
301+
require.Equal(t, int64(123), v)
302+
},
303+
},
304+
{
305+
name: "no schema",
306+
data: &exportable{export: func() any { return 123 }},
307+
schema: nil,
308+
test: func(t *testing.T, v interface{}, err error) {
309+
require.NoError(t, err)
310+
require.Equal(t, 123, v)
311+
},
312+
},
313+
{
314+
name: "exportable as additional property",
315+
data: map[string]interface{}{"foo": &exportable{export: func() any { return 123 }}},
316+
schema: schematest.New("object"),
317+
test: func(t *testing.T, v interface{}, err error) {
318+
require.NoError(t, err)
319+
require.Equal(t, map[string]any{"foo": 123}, v)
320+
},
321+
},
322+
}
323+
324+
t.Parallel()
325+
for _, tc := range testcases {
326+
tc := tc
327+
t.Run(tc.name, func(t *testing.T) {
328+
t.Parallel()
329+
330+
p := &parser.Parser{Schema: tc.schema}
331+
v, err := p.Parse(tc.data)
332+
tc.test(t, v, err)
333+
})
334+
}
335+
}

0 commit comments

Comments
 (0)