Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Parses value assignments literals directly as string. #138

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 32 additions & 13 deletions tosca/value_assignment.go
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,21 @@ func (p ValueAssignment) String() string {

// UnmarshalYAML unmarshals a yaml into a ValueAssignment
func (p *ValueAssignment) UnmarshalYAML(unmarshal func(interface{}) error) error {
return p.unmarshalYAMLJSON(unmarshal)
if err := p.unmarshalYAMLJSON(unmarshal); err == nil {
return nil
}

// Not a List nor a TOSCA function, nor a map or complex type, let's try literal
// For YAML parsing literals are always considered as string
var s string
if err := unmarshal(&s); err != nil {
return err
}

p.Value = s
p.Type = ValueAssignmentLiteral
return nil

}

// UnmarshalJSON unmarshals json into a ValueAssignment
Expand All @@ -174,7 +188,20 @@ func (p *ValueAssignment) UnmarshalJSON(b []byte) error {
jsonUnmarshal := func(itf interface{}) error {
return json.Unmarshal(b, itf)
}
return p.unmarshalYAMLJSON(jsonUnmarshal)
if err := p.unmarshalYAMLJSON(jsonUnmarshal); err == nil {
return nil
}

// Not a List nor a TOSCA function, nor a map or complex type, let's try literal
// For JSON it could be any type
var s interface{}
if err := jsonUnmarshal(&s); err != nil {
return err
}

p.Value = s
p.Type = ValueAssignmentLiteral
return nil
}

// unmarshalYAMLJSON unmarshals yaml or json into a ValueAssignment
Expand Down Expand Up @@ -210,20 +237,12 @@ func (p *ValueAssignment) unmarshalYAMLJSON(unmarshal func(interface{}) error) e

// JSON map unmarshaling expects a map[string]interface{}
var strMap map[string]interface{}
if err := unmarshal(&strMap); err == nil {
p.Value = strMap
p.Type = ValueAssignmentMap
return nil
}

// Not a List nor a TOSCA function, nor a map or complex type, let's try literal
var s interface{}
if err := unmarshal(&s); err != nil {
if err := unmarshal(&strMap); err != nil {
return err
}

p.Value = s
p.Type = ValueAssignmentLiteral
p.Value = strMap
p.Type = ValueAssignmentMap
return nil
}

Expand Down
38 changes: 25 additions & 13 deletions tosca/value_assignment_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -213,22 +213,24 @@ func TestValueAssignment_UnmarshalYAML(t *testing.T) {
yaml string
}
tests := []struct {
name string
args args
wantErr bool
wantType ValueAssignmentType
name string
args args
wantErr bool
wantType ValueAssignmentType
wantValue string
}{
{"StringLiteral", args{"1"}, false, ValueAssignmentLiteral},
{"FunctionSimple", args{"{ get_property: [SELF, port] }"}, false, ValueAssignmentFunction},
{"FunctionNested", args{`{concat: [get_attribute: [SELF, ip_address], ":", get_property: [SELF, port]]}`}, false, ValueAssignmentFunction},
{"FunctionNestedErr", args{`{ concat: [get_attribute: [SELF, ip_address], ":", get_property: [SELF, port] }`}, true, ValueAssignmentFunction},
{"ListShort", args{`["1", "two"]`}, false, ValueAssignmentList},
{"VersionLiteral", args{`1.10`}, false, ValueAssignmentLiteral, "1.10"},
{"StringLiteral", args{"1"}, false, ValueAssignmentLiteral, "1"},
{"FunctionSimple", args{"{ get_property: [SELF, port] }"}, false, ValueAssignmentFunction, "get_property: [SELF, port]"},
{"FunctionNested", args{`{concat: [get_attribute: [SELF, ip_address], ":", get_property: [SELF, port]]}`}, false, ValueAssignmentFunction, `concat: [get_attribute: [SELF, ip_address], ":", get_property: [SELF, port]]`},
{"FunctionNestedErr", args{`{ concat: [get_attribute: [SELF, ip_address], ":", get_property: [SELF, port] }`}, true, ValueAssignmentFunction, `concat: [get_attribute: [SELF, ip_address], ":", get_property: [SELF, port]"`},
{"ListShort", args{`["1", "two"]`}, false, ValueAssignmentList, `["1", "two"]`},
{"ListExpend", args{`- "1"
- "two"
`}, false, ValueAssignmentList},
{"MapShort", args{`{"1": "one", 2: "two"}`}, false, ValueAssignmentMap},
`}, false, ValueAssignmentList, `["1", "two"]`},
{"MapShort", args{`{"1": "one", 2: "two"}`}, false, ValueAssignmentMap, `{"1": "one", 2: "two"}`},
{"MapExpend", args{`"1": "one"
2: "two"`}, false, ValueAssignmentMap},
2: "two"`}, false, ValueAssignmentMap, `{"1": "one", 2: "two"}`},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
Expand All @@ -241,6 +243,15 @@ func TestValueAssignment_UnmarshalYAML(t *testing.T) {
}
if err == nil {
require.Equal(t, tt.wantType, p.Type)
if tt.wantType != ValueAssignmentMap {
// Maps can't be tested reliably as we can't ensure keys order
assert.Equal(t, tt.wantValue, p.String())
} else {
var m map[interface{}]interface{}
err := yaml.Unmarshal([]byte(tt.wantValue), &m)
require.NoError(t, err)
assert.Equal(t, m, p.Value)
}
}
})
}
Expand Down Expand Up @@ -365,6 +376,7 @@ func TestValueAssignment_UnmarshalJSON(t *testing.T) {
wantType ValueAssignmentType
wantValue interface{}
}{
{"IntLiteral", `1.10`, ValueAssignmentLiteral, 1.10},
{"StringLiteral", `"abc"`, ValueAssignmentLiteral, "abc"},
{"List", `["1", "two"]`, ValueAssignmentList, []interface{}{"1", "two"}},
{"Map", `{"one":"val1","two":"val2"}`, ValueAssignmentMap,
Expand All @@ -382,7 +394,7 @@ func TestValueAssignment_UnmarshalJSON(t *testing.T) {
assert.Equal(t, tt.wantType.String(), v.Type.String(),
"Unexpected type error unmarshalling %s", tt.jsonVal)
assert.Equal(t, tt.wantValue, v.Value,
"Unexpected value error unmarshalling %s", tt.jsonVal)
"Unexpected value error unmarshalling %s (%t)", tt.jsonVal, v.Value)
}
})
}
Expand Down