Skip to content
Snippets Groups Projects
Commit 2f684ea6 authored by Alex Petraky's avatar Alex Petraky :basketball_player_tone1: Committed by Pavel Antonov
Browse files

fix(core): Исправлен обход схемы Walk для типа Array, решена ошибка отсутствия...

fix(core): Исправлен обход схемы Walk для типа Array, решена ошибка отсутствия схемы при вызове Introspect
parent 8cee81a6
No related branches found
No related tags found
No related merge requests found
......@@ -116,17 +116,17 @@ func (ArrayType) Walk(ctx context.Context, field *Field, v interface{}, fn WalkF
return nil, false, nil
}
// Выполняется обход по схеме
if opts.WalkSchema && v == nil {
params.Item.Walk(ctx, v, fn, WalkOpts(opts))
return nil, false, nil
}
arr, ok := v.([]interface{})
if !ok {
if !ok && v != nil {
return nil, false, fmt.Errorf("incorrect type: \"%s\", expected \"[]interface{}\"", reflect.ValueOf(v).Kind())
}
// Выполняется обход по схеме
if opts.WalkSchema && len(arr) == 0 {
_, _, _ = params.Item.Walk(ctx, nil, fn, WalkOpts(opts))
return nil, false, nil
}
m := make([]interface{}, 0, len(arr))
var merr *multierror.Error
......
package field
import (
"context"
"fmt"
"testing"
......@@ -23,6 +24,26 @@ func TestArrayField_Decode(t *testing.T) {
[]interface{}{1.0, 2.0},
false,
},
{
"With object inside with nil-data",
Array(
Object("a", String(),
"b", String()),
),
nil,
nil,
false,
},
{
"With object inside with data",
Array(
Object("a", String(),
"b", String()),
),
[]interface{}{map[string]interface{}{"a": "1", "b": "2"}},
[]interface{}{map[string]interface{}{"a": "1", "b": "2"}},
false,
},
{
"Incorrect type",
Array(Number("int")),
......@@ -83,3 +104,61 @@ func TestArrayField_Encode(t *testing.T) {
})
}
}
func TestArrayType_Walk(t *testing.T) {
tests := []struct {
name string
field *Field
v interface{}
fn WalkFunc
opts *WalkOptions
want interface{}
want1 bool
wantErr assert.ErrorAssertionFunc
}{
{
name: "With nil data and WalkSchema = false",
field: Array(Object("a", String(), "b", String())),
v: nil,
opts: &WalkOptions{WalkSchema: false},
want: nil,
want1: false,
wantErr: assert.NoError,
},
{
name: "With empty data and WalkSchema = false",
field: Array(Object("a", String(), "b", String())),
v: []interface{}{map[string]interface{}{}},
opts: &WalkOptions{WalkSchema: false},
fn: func(ctx context.Context, fld *Field, v interface{}) (result WalkFuncResult, err error) {
return WalkFuncResult{}, err
},
want: []interface{}{map[string]interface{}{}},
want1: false,
wantErr: assert.NoError,
},
{
name: "With data and WalkSchema = false",
field: Array(Object("a", String(), "b", String())),
v: []interface{}{map[string]interface{}{"a": "1", "b": "2"}},
opts: &WalkOptions{WalkSchema: false},
fn: func(ctx context.Context, fld *Field, v interface{}) (result WalkFuncResult, err error) {
return WalkFuncResult{}, err
},
want: []interface{}{map[string]interface{}{"a": "1", "b": "2"}},
want1: false,
wantErr: assert.NoError,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
ar := ArrayType{}
got, got1, err := ar.Walk(context.Background(), tt.field, tt.v, tt.fn, tt.opts)
if !tt.wantErr(t, err, fmt.Sprintf("Walk(%v, %v, %v, %v)", tt.field, tt.v, tt.fn, tt.opts)) {
return
}
assert.Equalf(t, tt.want, got, "Walk(%v, %v, %v, %v)", tt.field, tt.v, tt.fn, tt.opts)
assert.Equalf(t, tt.want1, got1, "Walk(%v, %v, %v, %v)", tt.field, tt.v, tt.fn, tt.opts)
})
}
}
......@@ -1343,6 +1343,60 @@ func TestSchema_Introspect(t *testing.T) {
[]string{"object_a", "field1", "field2"},
false,
},
{
// если у объекта нет данных Introspect возвращает все поля
"With not initialized object in data",
map[string]interface{}{"object": []interface{}{}},
schema.New(
"object", field.Array(
field.Object(
"a", field.String(),
"b", field.String(),
"c", field.String(),
),
).WithUI(&field.UI{Widget: "Tags"}),
),
map[string]interface{}{"object": []interface{}{}},
[]string{"object.a", "object.b", "object.c"},
[]string{},
false,
},
{
// при добавлении значения по умолчанию для поля запрос Introspect возвращает все поля
"Object initialized by modify.Default in schema",
map[string]interface{}{},
schema.New(
"object", field.Array(
field.Object(
"a", field.String(),
"b", field.String(),
"c", field.String(),
),
).AddOptions(modify.Default([]interface{}{map[string]interface{}{}})).WithUI(&field.UI{Widget: "Tags"}),
),
map[string]interface{}{},
[]string{"object.a", "object.b", "object.c"},
[]string{},
false,
},
{
// при добавлении пустого объекта перед запросом Introspect возвращаются все поля
"Object initialized in data",
map[string]interface{}{"object": []interface{}{map[string]interface{}{}}},
schema.New(
"object", field.Array(
field.Object(
"a", field.String(),
"b", field.String(),
"c", field.String(),
),
).WithUI(&field.UI{Widget: "Tags"}),
),
map[string]interface{}{"object": []interface{}{map[string]interface{}{}}},
[]string{"object.a", "object.b", "object.c"},
[]string{},
false,
},
}
ctx := context.Background()
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment