diff --git a/models/models_methods.go b/models/models_methods.go index 66fbf198..8ba9b582 100644 --- a/models/models_methods.go +++ b/models/models_methods.go @@ -223,7 +223,11 @@ func (env *EnvironmentItemModel) Normalize() error { return nil } -// Normalize ... +// Normalize - if successful this makes the model JSON serializable. +// Without this, if the object was created with e.g. a YAML parser, +// the type of `opts` might be map[interface]interface, which is not JSON serializable. +// After this call it's ensured that the type of objects is map[string]interface, +// which is JSON serializable. func (envsSerializeObj *EnvsSerializeModel) Normalize() error { for _, envObj := range envsSerializeObj.Envs { if err := envObj.Normalize(); err != nil { diff --git a/models/models_methods_test.go b/models/models_methods_test.go index f6e1d4cb..3889dff1 100644 --- a/models/models_methods_test.go +++ b/models/models_methods_test.go @@ -3,6 +3,10 @@ package models import ( "testing" + yaml "gopkg.in/yaml.v2" + + "encoding/json" + "github.com/bitrise-io/go-utils/pointers" "github.com/stretchr/testify/require" ) @@ -359,3 +363,33 @@ func TestValidate(t *testing.T) { } require.NoError(t, env.Validate()) } + +func Test_EnvsSerializeModel_Normalize(t *testing.T) { + yamlContent := `envs: +- KEY_ONE: first value +- KEY_TWO: second value, with options + opts: + is_expand: true +` + var objFromYAML EnvsSerializeModel + require.NoError(t, yaml.Unmarshal([]byte(yamlContent), &objFromYAML)) + + // the objFromYAML object in this state can't be serialized to JSON directly, + // as the YAML parser parses the `opts` into map[interface]interface, + // which is not supported by JSON + { + _, err := json.Marshal(objFromYAML) + require.EqualError(t, err, `json: unsupported type: map[interface {}]interface {}`) + } + + // now, if we call Normalize on this object, that will convert the map[interface]interface + // into map[string]interface, which is JSON serializable + require.NoError(t, objFromYAML.Normalize()) + + // let's try the serialization again - this time it will work! + { + jsonContBytes, err := json.Marshal(objFromYAML) + require.NoError(t, err) + require.Equal(t, `{"envs":[{"KEY_ONE":"first value","opts":{}},{"KEY_TWO":"second value, with options","opts":{"is_expand":true}}]}`, string(jsonContBytes)) + } +}