diff --git a/pkg/extension/schema_test.go b/pkg/extension/schema_test.go index 20648678a159b6703d05687530ba8e16ded4c8f2..4b4f235ae6a43bbb7e9c39a56b45c51b530d7103 100644 --- a/pkg/extension/schema_test.go +++ b/pkg/extension/schema_test.go @@ -47,6 +47,8 @@ func TestEqualSchema(t *testing.T) { require.NoError(t, err) s2 := schema.New() err = json.Unmarshal(b, s2) + s1.ClearState() + s2.ClearState() require.NoError(t, err) require.Equal(t, s1.Field, s2.Field) } diff --git a/pkg/schema/field/field.go b/pkg/schema/field/field.go index 60258788c4416dc8cd92fad0a79bc24c2aeb347e..4d2a6771bbe956f07698e52835aca53a2853bd58 100644 --- a/pkg/schema/field/field.go +++ b/pkg/schema/field/field.go @@ -106,11 +106,12 @@ func (f Field) GetState() *State { // Схемы нельзя сравнивать с активным состоянием с помощью `reflect.DeepEqual` или `assert.Equal`. // Предварительно нужно сделать `ClearState`. // После очистки состояния полей не будут рассчитываться. Для повторного включения состояния используйте `EnableState` -func (f *Field) ClearState() { +func (f *Field) ClearState() *Field { f.State = nil for _, fld := range f.ListFields() { fld.ClearState() } + return f } // EnableState включает расчет состояния поля и всех вложенных полей diff --git a/pkg/schema/field/field_json.go b/pkg/schema/field/field_json.go index dfd7f85aebafe2f6c1008db1c45b40df65c27b9d..170e3d161f87300955b06d21e8cf79e2140f9eb8 100644 --- a/pkg/schema/field/field_json.go +++ b/pkg/schema/field/field_json.go @@ -61,6 +61,8 @@ func (f *Field) UnmarshalJSON(b []byte) error { } } + j.FieldData.State = f.State + *f = Field(j.FieldData) f.Params = params _ = f.Prepare() diff --git a/pkg/schema/field/field_test.go b/pkg/schema/field/field_test.go index 26d47fa019544474007364cc22239fbf08debab6..d27d74bb473a3303c95d5fb63e927d5b314d9a42 100644 --- a/pkg/schema/field/field_test.go +++ b/pkg/schema/field/field_test.go @@ -90,3 +90,12 @@ func TestField_ListFieldsRecursive(t *testing.T) { assert.NotEmpty(t, f.State.Name) } } + +func TestField_CloneWithState(t *testing.T) { + f := Object("a", String()) + fld := f.Clone(false) + assert.Nil(t, fld.State) + f.EnableState() + fld = f.Clone(false) + assert.NotNil(t, fld.State) +} diff --git a/pkg/schema/schema.go b/pkg/schema/schema.go index 26c5638007498b149ddbf096f6be49e2adaec9bc..fdb402b412de15b3ba8aa9d2b0244ea3d22e8f09 100644 --- a/pkg/schema/schema.go +++ b/pkg/schema/schema.go @@ -48,6 +48,11 @@ func (s *Schema) Clone(reset bool) *Schema { } } +func (s *Schema) ClearState() *Schema { + s.Field.ClearState() + return s +} + func (s *Schema) Equal(sch *Schema) bool { if s == sch { return true @@ -88,7 +93,10 @@ func (s *Schema) ConvertTypes() error { if err != nil { return errors.Wrap(err, "marshal schema") } + // сохраняем состояние cхемы + state := s.Field.State *s = *New() + s.Field.State = state return errors.Wrap(s.UnmarshalJSON(b), "unmarshal schema") } diff --git a/pkg/schema/test/convert_test.go b/pkg/schema/test/convert_test.go index 9bdc79bcf5f352ebb90dae56aee45cffbace6af4..5e791570ebfc12c9efc9a4c9295ce5dacced4af5 100644 --- a/pkg/schema/test/convert_test.go +++ b/pkg/schema/test/convert_test.go @@ -23,6 +23,9 @@ func TestFromFiles(t *testing.T) { t.Run("Success", func(t *testing.T) { schemas, err := schema.FromFS(os.DirFS("assets")) + for _, s := range schemas { + s.ClearState() + } require.NoError(t, err) require.Len(t, schemas, 2, "В директории хранятся две корректные схемы") require.ElementsMatch(t, []*schema.Schema{getPagesSchema(), getPagesSchema()}, schemas, "Cхемы должны соответствовать объекту из функции") diff --git a/pkg/schema/test/object_test.go b/pkg/schema/test/object_test.go index e9c7a776bd9f282ae5fbbc5ada8a997c58e2e9dd..8bf3f82022e8501932e6474a985bcfc9f195e693 100644 --- a/pkg/schema/test/object_test.go +++ b/pkg/schema/test/object_test.go @@ -193,6 +193,9 @@ func TestSchema_JSON(t *testing.T) { err = json.Unmarshal(b, res) require.NoError(t, err) + sch.ClearState() + res.ClearState() + assert.Equal(t, sch, res) } @@ -859,6 +862,7 @@ func TestSchema_UnknownJSON(t *testing.T) { "times", field.Number("int"), "dates", field.Array(field.Time()), ) + sch.ClearState() b, err := json.Marshal(sch) require.NoError(t, err) @@ -883,6 +887,8 @@ func TestSchema_UnknownJSON(t *testing.T) { require.NoError(t, err) b, err = json.Marshal(s2) require.NoError(t, err) + s1.ClearState() + s2.ClearState() assert.Equal(t, "unknown", s2.GetType().Name(), "Схема неизвестного типа должна определяться как unknown") assert.Equal(t, s1, s2, "Схема не должна меняться при повторном маршалинге") @@ -890,6 +896,7 @@ func TestSchema_UnknownJSON(t *testing.T) { s3 := schema.New() err = json.Unmarshal(b, s3) require.NoError(t, err) + s3.ClearState() assert.Equal(t, "object", s3.GetType().Name(), "Схема должна восстановить тип object при восстановление регистрации типа") assert.Equal(t, sch, s3, "Схема должна восстановиться при восстановление регистрации типа") } diff --git a/pkg/setup/collection_test.go b/pkg/setup/collection_test.go index 43b450119a0892865486517df1d43a7e92d3dc2d..788314ca8aa15aa9e4bba63ae6c090f0e5662e69 100644 --- a/pkg/setup/collection_test.go +++ b/pkg/setup/collection_test.go @@ -35,12 +35,19 @@ func TestSetup_InstallCollections(t *testing.T) { }, }, { - name: "Install one collection success", - collections: []*collections.Collection{{ID: "1", SpaceID: "sp", Name: "space", EnvID: "env", Schema: schema.New("name", field.String())}}, + name: "Install one collection success", + collections: []*collections.Collection{{ID: "1", SpaceID: "sp", Name: "space", EnvID: "env", + Schema: schema.New("name", field.String()).ClearState()}}, collectionsCall: func(svc *mockscollections.Collections) { svc.On("Get", mock.Anything, "sp", "env", "1").Return(nil, errors.New("not found")).Once() - svc.On("Create", mock.Anything, &collections.Collection{ID: "1", SpaceID: "sp", Name: "space", EnvID: "env", Schema: schema.New("name", field.String())}).Return(&collections.Collection{ID: "1", SpaceID: "sp", Name: "space", EnvID: "env", Schema: schema.New("name", field.String())}, nil).Once() - svc.On("SetSchema", mock.Anything, "sp", "env", "1", schema.New("name", field.String())).Return(nil).Once() + svc.On("Create", mock.Anything, + &collections.Collection{ID: "1", SpaceID: "sp", Name: "space", EnvID: "env", + Schema: schema.New("name", field.String()).ClearState()}). + Return(&collections.Collection{ID: "1", SpaceID: "sp", Name: "space", EnvID: "env", + Schema: schema.New("name", field.String()).ClearState()}, nil).Once() + svc.On("SetSchema", mock.Anything, "sp", "env", "1", + schema.New("name", field.String()).ClearState()). + Return(nil).Once() }, envsCall: func(svc *envmocks.Environments) { svc.On("Migrate", mock.Anything, "sp", "env").Return(nil).Once() @@ -123,11 +130,15 @@ func TestSetup_InstallCollections(t *testing.T) { }, { name: "Fail to install collection on migrate", - collections: []*collections.Collection{{ID: "1", SpaceID: "sp", Name: "space", EnvID: "env", Schema: schema.New("name", field.String())}}, + collections: []*collections.Collection{{ID: "1", SpaceID: "sp", Name: "space", EnvID: "env", Schema: schema.New("name", field.String()).ClearState()}}, collectionsCall: func(svc *mockscollections.Collections) { svc.On("Get", mock.Anything, "sp", "env", "1").Return(nil, errors.New("not found")).Once() - svc.On("Create", mock.Anything, &collections.Collection{ID: "1", SpaceID: "sp", Name: "space", EnvID: "env", Schema: schema.New("name", field.String())}).Return(&collections.Collection{ID: "1", SpaceID: "sp", Name: "space", EnvID: "env", Schema: schema.New("name", field.String())}, nil).Once() - svc.On("SetSchema", mock.Anything, "sp", "env", "1", schema.New("name", field.String())).Return(nil).Once() + svc.On("Create", mock.Anything, &collections.Collection{ID: "1", SpaceID: "sp", Name: "space", EnvID: "env", + Schema: schema.New("name", field.String()).ClearState()}). + Return(&collections.Collection{ID: "1", SpaceID: "sp", Name: "space", EnvID: "env", + Schema: schema.New("name", field.String()).ClearState()}, nil).Once() + svc.On("SetSchema", mock.Anything, "sp", "env", "1", + schema.New("name", field.String()).ClearState()).Return(nil).Once() }, envsCall: func(svc *envmocks.Environments) { svc.On("Migrate", mock.Anything, "sp", "env").Return(errors.New("migrate error")).Once()