diff --git a/pkg/extension/schema.go b/pkg/extension/schema.go index cf71a4568c8ed734bda41e344936b728a8ed8b99..1e44488e0918776fbe770f52b333bba8828317e8 100644 --- a/pkg/extension/schema.go +++ b/pkg/extension/schema.go @@ -22,7 +22,7 @@ const ( // NewActionsCollection - создает коллекцию для хранения действий расширений в пространстве func NewActionsCollection(spaceID, envID string) *collections.Collection { sch := schema.New( - "extension", field.String(validate.Required()).SetTitle("Расширение").SetTextSearch(true), + "extension", field.String().SetTitle("Расширение"), "action", field.String(validate.Required()).SetTitle("Действия").SetTextSearch(true), "target", field.Number( field.NumberFormatInt, @@ -94,15 +94,17 @@ func NewActionsCollection(spaceID, envID string) *collections.Collection { } func getEnumOpt(opts map[int32]string) []validate.EnumOpt { - keys := make([]string, 0, len(opts)) - for _, k := range opts { + keys := make([]int32, 0, len(opts)) + for k := range opts { keys = append(keys, k) } - sort.Strings(keys) + sort.Slice(keys, func(i, j int) bool { + return keys[i] < keys[j] + }) enum := make([]validate.EnumOpt, len(opts)) for i, n := range keys { - enum[i] = validate.EnumOpt{Name: n, Value: float64(i)} + enum[i] = validate.EnumOpt{Name: opts[n], Value: float64(n)} } return enum } diff --git a/pkg/extension/schema_test.go b/pkg/extension/schema_test.go index b15a210045b85ef7349cbdaad3b7365eb6c411a0..7d33a4b5ef724ad2e2a9dc98723b39f8139a46b2 100644 --- a/pkg/extension/schema_test.go +++ b/pkg/extension/schema_test.go @@ -17,10 +17,10 @@ func Test_getEnumOpt(t *testing.T) { name: "#1", opts: map[int32]string{1: "a", 2: "b", 3: "c", 1000: "w"}, want: []validate.EnumOpt{ - {Name: "a", Value: float64(0)}, - {Name: "b", Value: float64(1)}, - {Name: "c", Value: float64(2)}, - {Name: "w", Value: float64(3)}, + {Name: "a", Value: float64(1)}, + {Name: "b", Value: float64(2)}, + {Name: "c", Value: float64(3)}, + {Name: "w", Value: float64(1000)}, }, }, } diff --git a/pkg/extension/server.go b/pkg/extension/server.go index 4e3c4fc2817869a32159cece4fb90706d3bbd36a..4ddb3143008efaeaaf70b5c74042feaece95b5df 100644 --- a/pkg/extension/server.go +++ b/pkg/extension/server.go @@ -73,6 +73,12 @@ func SingleExtension(extension Extension) ServerOption { } } +func WithRouteFn(fn RouteFn) ServerOption { + return func(c *Server) { + c.extensions = fn + } +} + type Server struct { extensions RouteFn wrapErr WrapErrFn diff --git a/pkg/schema/walk/fn.go b/pkg/schema/walk/fn.go index c3eaf35c569c18ba8ead7c7ff48c08d03f2a9d90..9b1d4f22316cf37cae1af824d98f611b7dc0bcf7 100644 --- a/pkg/schema/walk/fn.go +++ b/pkg/schema/walk/fn.go @@ -1,10 +1,15 @@ package walk +import "reflect" + func GenericMerge(c *WalkContext) (err error) { return } func KeepSrc(c *WalkContext) (err error) { + if reflect.DeepEqual(c.Src, c.Dst) { + return + } c.Dst = c.Src c.Changed = true return diff --git a/pkg/schema/walk/walk_test.go b/pkg/schema/walk/walk_test.go index e20adb462735e83c92c8b04f5c159e336e49f2b0..3fd01bd577c3fe16abb1cae7b2e9785e0edc659c 100644 --- a/pkg/schema/walk/walk_test.go +++ b/pkg/schema/walk/walk_test.go @@ -46,6 +46,54 @@ func TestWalker_DataWalk(t *testing.T) { wantErr bool }{ {"generic", + &WalkConfig{ + Fields: map[string]FieldConfig{}, + }, + map[string]interface{}{ + "a": "src_a", + "b": "src_b", + "obj1": map[string]interface{}{ + "a": "src_obj1_a", + "b": "src_obj1_b", + "obj2": map[string]interface{}{ + "a": "dst_obj1_obj2_a", + }, + "obj3": map[string]interface{}{ + "e": "dst_obj1_obj3_e", + }, + }, + "inline_str_1": "src_inline_1", + "inline_str_2": "src_inline_2", + "slice": []interface{}{"src_s1", "src_s2"}, + }, + map[string]interface{}{ + "a": "dst_a", + "field_not_extists": "remove", + "obj1": map[string]interface{}{ + "a": "dst_obj1_a", + "obj2": map[string]interface{}{ + "a": "dst_obj1_obj2_a", + }, + }, + "inline_str_1": "dst_inline_1", + "inline_str_2": "dst_inline_2", + "slice": []interface{}{"dst_s1", "dst_s2", "dst_s3"}, + }, + map[string]interface{}{ + "a": "dst_a", + "obj1": map[string]interface{}{ + "a": "dst_obj1_a", + "obj2": map[string]interface{}{ + "a": "dst_obj1_obj2_a", + }, + }, + "inline_str_1": "dst_inline_1", + "inline_str_2": "dst_inline_2", + "slice": []interface{}{"dst_s1", "dst_s2", "dst_s3"}, + }, + false, false, + }, + {"keep src changed", &WalkConfig{ Fields: map[string]FieldConfig{ "obj1.a": {Fn: KeepSrc}, @@ -96,6 +144,68 @@ func TestWalker_DataWalk(t *testing.T) { "inline_str_2": "src_inline_2", "slice": []interface{}{"dst_s1", "src_s2", "dst_s3"}, }, + true, false, + }, + {"keep src not changed", + &WalkConfig{ + Fields: map[string]FieldConfig{ + "obj1.a": {Fn: KeepSrc}, + "slice.1": {Fn: KeepSrc}, + "inline_str_1": {Fn: KeepSrc}, + "inline_str_2": {Fn: KeepSrc}, + }, + }, + map[string]interface{}{ + "a": "src_a", + "b": "src_b", + "obj1": map[string]interface{}{ + "a": "src_obj1_a", + "b": "src_obj1_b", + "obj2": map[string]interface{}{ + "a": "dst_obj1_obj2_a", + }, + "obj3": map[string]interface{}{ + "e": "dst_obj1_obj3_e", + }, + }, + "inline_str_1": "src_inline_1", + "inline_str_2": "src_inline_2", + "slice": []interface{}{"src_s1", "src_s2"}, + }, + map[string]interface{}{ + "a": "src_a", + "b": "src_b", + "obj1": map[string]interface{}{ + "a": "src_obj1_a", + "b": "src_obj1_b", + "obj2": map[string]interface{}{ + "a": "dst_obj1_obj2_a", + }, + "obj3": map[string]interface{}{ + "e": "dst_obj1_obj3_e", + }, + }, + "inline_str_1": "src_inline_1", + "inline_str_2": "src_inline_2", + "slice": []interface{}{"src_s1", "src_s2"}, + }, + map[string]interface{}{ + "a": "src_a", + "b": "src_b", + "obj1": map[string]interface{}{ + "a": "src_obj1_a", + "b": "src_obj1_b", + "obj2": map[string]interface{}{ + "a": "dst_obj1_obj2_a", + }, + "obj3": map[string]interface{}{ + "e": "dst_obj1_obj3_e", + }, + }, + "inline_str_1": "src_inline_1", + "inline_str_2": "src_inline_2", + "slice": []interface{}{"src_s1", "src_s2"}, + }, false, false, }, } @@ -103,11 +213,12 @@ func TestWalker_DataWalk(t *testing.T) { t.Run(tt.name, func(t *testing.T) { m := NewWalker(s, tt.config) dst := tt.dst - res, _, err := m.DataWalk(context.Background(), dst, tt.src) - assert.Equal(t, tt.res, res) + res, chg, err := m.DataWalk(context.Background(), dst, tt.src) if tt.wantErr { require.Error(t, err) } else { + assert.Equal(t, tt.res, res) + assert.Equal(t, tt.wantChanged, chg) require.NoError(t, err) } })