2017-09-11 23:00:31 +00:00
|
|
|
package gohcl
|
2017-05-21 15:47:05 +00:00
|
|
|
|
|
|
|
import (
|
2017-05-21 19:44:07 +00:00
|
|
|
"encoding/json"
|
2017-05-21 15:47:05 +00:00
|
|
|
"fmt"
|
|
|
|
"reflect"
|
|
|
|
"testing"
|
|
|
|
|
2017-05-21 19:44:07 +00:00
|
|
|
"github.com/davecgh/go-spew/spew"
|
2019-09-09 23:08:19 +00:00
|
|
|
"github.com/hashicorp/hcl/v2"
|
|
|
|
hclJSON "github.com/hashicorp/hcl/v2/json"
|
2017-09-11 22:38:42 +00:00
|
|
|
"github.com/zclconf/go-cty/cty"
|
2017-05-21 15:47:05 +00:00
|
|
|
)
|
|
|
|
|
2017-05-21 19:44:07 +00:00
|
|
|
func TestDecodeBody(t *testing.T) {
|
|
|
|
deepEquals := func(other interface{}) func(v interface{}) bool {
|
|
|
|
return func(v interface{}) bool {
|
|
|
|
return reflect.DeepEqual(v, other)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-09-20 23:23:23 +00:00
|
|
|
type withNameExpression struct {
|
|
|
|
Name hcl.Expression `hcl:"name"`
|
|
|
|
}
|
|
|
|
|
gohcl: retain nested blocks while decoding
Currently, if nonzero struct is passed to the DecodeBody function,
decoding process will keep already initialized top-level fields values or
overwrite them, if they are specified in HCL. This behaviour is useful,
as it allows to have some default values for top-level fields.
However, if the field is a type block or slice (multiple blocks), then the
entire block is overwritten, which erases the existing values. Because of
that, setting default values in nested structs is not possible.
With this commit, decode functions will check if the value is
nil and only then set them to empty struct, which allows for appending
to existing structs.
In case of a slice, either new empty element will be added, or existing
element will be used for setting new value (so values will be merged).
Also, to keep the same behavior as json.Unmarshal, if retained list
have more elements than new list, additional elements will be removed
and existing elements will be merged. This allows to have default values
also for positional elements.
Behavior added by this patch is the same as in json.Unmarshal and
yaml.Unmarshal, which both retain nested structs during unmarshaling
process, so I believe this is an expected behavior from user
perspective.
2019-10-10 16:15:24 +00:00
|
|
|
type withTwoAttributes struct {
|
|
|
|
A string `hcl:"a,optional"`
|
|
|
|
B string `hcl:"b,optional"`
|
|
|
|
}
|
|
|
|
|
|
|
|
type withNestedBlock struct {
|
|
|
|
Plain string `hcl:"plain,optional"`
|
|
|
|
Nested *withTwoAttributes `hcl:"nested,block"`
|
|
|
|
}
|
|
|
|
|
|
|
|
type withListofNestedBlocks struct {
|
|
|
|
Nested []*withTwoAttributes `hcl:"nested,block"`
|
|
|
|
}
|
|
|
|
|
2017-05-21 19:44:07 +00:00
|
|
|
tests := []struct {
|
|
|
|
Body map[string]interface{}
|
gohcl: retain nested blocks while decoding
Currently, if nonzero struct is passed to the DecodeBody function,
decoding process will keep already initialized top-level fields values or
overwrite them, if they are specified in HCL. This behaviour is useful,
as it allows to have some default values for top-level fields.
However, if the field is a type block or slice (multiple blocks), then the
entire block is overwritten, which erases the existing values. Because of
that, setting default values in nested structs is not possible.
With this commit, decode functions will check if the value is
nil and only then set them to empty struct, which allows for appending
to existing structs.
In case of a slice, either new empty element will be added, or existing
element will be used for setting new value (so values will be merged).
Also, to keep the same behavior as json.Unmarshal, if retained list
have more elements than new list, additional elements will be removed
and existing elements will be merged. This allows to have default values
also for positional elements.
Behavior added by this patch is the same as in json.Unmarshal and
yaml.Unmarshal, which both retain nested structs during unmarshaling
process, so I believe this is an expected behavior from user
perspective.
2019-10-10 16:15:24 +00:00
|
|
|
Target func() interface{}
|
2017-05-21 19:44:07 +00:00
|
|
|
Check func(v interface{}) bool
|
|
|
|
DiagCount int
|
|
|
|
}{
|
|
|
|
{
|
|
|
|
map[string]interface{}{},
|
gohcl: retain nested blocks while decoding
Currently, if nonzero struct is passed to the DecodeBody function,
decoding process will keep already initialized top-level fields values or
overwrite them, if they are specified in HCL. This behaviour is useful,
as it allows to have some default values for top-level fields.
However, if the field is a type block or slice (multiple blocks), then the
entire block is overwritten, which erases the existing values. Because of
that, setting default values in nested structs is not possible.
With this commit, decode functions will check if the value is
nil and only then set them to empty struct, which allows for appending
to existing structs.
In case of a slice, either new empty element will be added, or existing
element will be used for setting new value (so values will be merged).
Also, to keep the same behavior as json.Unmarshal, if retained list
have more elements than new list, additional elements will be removed
and existing elements will be merged. This allows to have default values
also for positional elements.
Behavior added by this patch is the same as in json.Unmarshal and
yaml.Unmarshal, which both retain nested structs during unmarshaling
process, so I believe this is an expected behavior from user
perspective.
2019-10-10 16:15:24 +00:00
|
|
|
makeInstantiateType(struct{}{}),
|
2017-05-21 19:44:07 +00:00
|
|
|
deepEquals(struct{}{}),
|
|
|
|
0,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
map[string]interface{}{},
|
gohcl: retain nested blocks while decoding
Currently, if nonzero struct is passed to the DecodeBody function,
decoding process will keep already initialized top-level fields values or
overwrite them, if they are specified in HCL. This behaviour is useful,
as it allows to have some default values for top-level fields.
However, if the field is a type block or slice (multiple blocks), then the
entire block is overwritten, which erases the existing values. Because of
that, setting default values in nested structs is not possible.
With this commit, decode functions will check if the value is
nil and only then set them to empty struct, which allows for appending
to existing structs.
In case of a slice, either new empty element will be added, or existing
element will be used for setting new value (so values will be merged).
Also, to keep the same behavior as json.Unmarshal, if retained list
have more elements than new list, additional elements will be removed
and existing elements will be merged. This allows to have default values
also for positional elements.
Behavior added by this patch is the same as in json.Unmarshal and
yaml.Unmarshal, which both retain nested structs during unmarshaling
process, so I believe this is an expected behavior from user
perspective.
2019-10-10 16:15:24 +00:00
|
|
|
makeInstantiateType(struct {
|
2017-09-12 00:29:56 +00:00
|
|
|
Name string `hcl:"name"`
|
gohcl: retain nested blocks while decoding
Currently, if nonzero struct is passed to the DecodeBody function,
decoding process will keep already initialized top-level fields values or
overwrite them, if they are specified in HCL. This behaviour is useful,
as it allows to have some default values for top-level fields.
However, if the field is a type block or slice (multiple blocks), then the
entire block is overwritten, which erases the existing values. Because of
that, setting default values in nested structs is not possible.
With this commit, decode functions will check if the value is
nil and only then set them to empty struct, which allows for appending
to existing structs.
In case of a slice, either new empty element will be added, or existing
element will be used for setting new value (so values will be merged).
Also, to keep the same behavior as json.Unmarshal, if retained list
have more elements than new list, additional elements will be removed
and existing elements will be merged. This allows to have default values
also for positional elements.
Behavior added by this patch is the same as in json.Unmarshal and
yaml.Unmarshal, which both retain nested structs during unmarshaling
process, so I believe this is an expected behavior from user
perspective.
2019-10-10 16:15:24 +00:00
|
|
|
}{}),
|
2017-05-21 19:44:07 +00:00
|
|
|
deepEquals(struct {
|
2017-09-12 00:29:56 +00:00
|
|
|
Name string `hcl:"name"`
|
2017-05-21 19:44:07 +00:00
|
|
|
}{}),
|
|
|
|
1, // name is required
|
|
|
|
},
|
|
|
|
{
|
|
|
|
map[string]interface{}{},
|
gohcl: retain nested blocks while decoding
Currently, if nonzero struct is passed to the DecodeBody function,
decoding process will keep already initialized top-level fields values or
overwrite them, if they are specified in HCL. This behaviour is useful,
as it allows to have some default values for top-level fields.
However, if the field is a type block or slice (multiple blocks), then the
entire block is overwritten, which erases the existing values. Because of
that, setting default values in nested structs is not possible.
With this commit, decode functions will check if the value is
nil and only then set them to empty struct, which allows for appending
to existing structs.
In case of a slice, either new empty element will be added, or existing
element will be used for setting new value (so values will be merged).
Also, to keep the same behavior as json.Unmarshal, if retained list
have more elements than new list, additional elements will be removed
and existing elements will be merged. This allows to have default values
also for positional elements.
Behavior added by this patch is the same as in json.Unmarshal and
yaml.Unmarshal, which both retain nested structs during unmarshaling
process, so I believe this is an expected behavior from user
perspective.
2019-10-10 16:15:24 +00:00
|
|
|
makeInstantiateType(struct {
|
2017-09-12 00:29:56 +00:00
|
|
|
Name *string `hcl:"name"`
|
gohcl: retain nested blocks while decoding
Currently, if nonzero struct is passed to the DecodeBody function,
decoding process will keep already initialized top-level fields values or
overwrite them, if they are specified in HCL. This behaviour is useful,
as it allows to have some default values for top-level fields.
However, if the field is a type block or slice (multiple blocks), then the
entire block is overwritten, which erases the existing values. Because of
that, setting default values in nested structs is not possible.
With this commit, decode functions will check if the value is
nil and only then set them to empty struct, which allows for appending
to existing structs.
In case of a slice, either new empty element will be added, or existing
element will be used for setting new value (so values will be merged).
Also, to keep the same behavior as json.Unmarshal, if retained list
have more elements than new list, additional elements will be removed
and existing elements will be merged. This allows to have default values
also for positional elements.
Behavior added by this patch is the same as in json.Unmarshal and
yaml.Unmarshal, which both retain nested structs during unmarshaling
process, so I believe this is an expected behavior from user
perspective.
2019-10-10 16:15:24 +00:00
|
|
|
}{}),
|
2017-05-21 19:44:07 +00:00
|
|
|
deepEquals(struct {
|
2017-09-12 00:29:56 +00:00
|
|
|
Name *string `hcl:"name"`
|
2017-05-21 19:44:07 +00:00
|
|
|
}{}),
|
|
|
|
0,
|
2018-02-17 18:36:04 +00:00
|
|
|
}, // name nil
|
|
|
|
{
|
|
|
|
map[string]interface{}{},
|
gohcl: retain nested blocks while decoding
Currently, if nonzero struct is passed to the DecodeBody function,
decoding process will keep already initialized top-level fields values or
overwrite them, if they are specified in HCL. This behaviour is useful,
as it allows to have some default values for top-level fields.
However, if the field is a type block or slice (multiple blocks), then the
entire block is overwritten, which erases the existing values. Because of
that, setting default values in nested structs is not possible.
With this commit, decode functions will check if the value is
nil and only then set them to empty struct, which allows for appending
to existing structs.
In case of a slice, either new empty element will be added, or existing
element will be used for setting new value (so values will be merged).
Also, to keep the same behavior as json.Unmarshal, if retained list
have more elements than new list, additional elements will be removed
and existing elements will be merged. This allows to have default values
also for positional elements.
Behavior added by this patch is the same as in json.Unmarshal and
yaml.Unmarshal, which both retain nested structs during unmarshaling
process, so I believe this is an expected behavior from user
perspective.
2019-10-10 16:15:24 +00:00
|
|
|
makeInstantiateType(struct {
|
2018-02-17 18:36:04 +00:00
|
|
|
Name string `hcl:"name,optional"`
|
gohcl: retain nested blocks while decoding
Currently, if nonzero struct is passed to the DecodeBody function,
decoding process will keep already initialized top-level fields values or
overwrite them, if they are specified in HCL. This behaviour is useful,
as it allows to have some default values for top-level fields.
However, if the field is a type block or slice (multiple blocks), then the
entire block is overwritten, which erases the existing values. Because of
that, setting default values in nested structs is not possible.
With this commit, decode functions will check if the value is
nil and only then set them to empty struct, which allows for appending
to existing structs.
In case of a slice, either new empty element will be added, or existing
element will be used for setting new value (so values will be merged).
Also, to keep the same behavior as json.Unmarshal, if retained list
have more elements than new list, additional elements will be removed
and existing elements will be merged. This allows to have default values
also for positional elements.
Behavior added by this patch is the same as in json.Unmarshal and
yaml.Unmarshal, which both retain nested structs during unmarshaling
process, so I believe this is an expected behavior from user
perspective.
2019-10-10 16:15:24 +00:00
|
|
|
}{}),
|
2018-02-17 18:36:04 +00:00
|
|
|
deepEquals(struct {
|
|
|
|
Name string `hcl:"name,optional"`
|
|
|
|
}{}),
|
|
|
|
0,
|
|
|
|
}, // name optional
|
2017-09-20 23:23:23 +00:00
|
|
|
{
|
|
|
|
map[string]interface{}{},
|
gohcl: retain nested blocks while decoding
Currently, if nonzero struct is passed to the DecodeBody function,
decoding process will keep already initialized top-level fields values or
overwrite them, if they are specified in HCL. This behaviour is useful,
as it allows to have some default values for top-level fields.
However, if the field is a type block or slice (multiple blocks), then the
entire block is overwritten, which erases the existing values. Because of
that, setting default values in nested structs is not possible.
With this commit, decode functions will check if the value is
nil and only then set them to empty struct, which allows for appending
to existing structs.
In case of a slice, either new empty element will be added, or existing
element will be used for setting new value (so values will be merged).
Also, to keep the same behavior as json.Unmarshal, if retained list
have more elements than new list, additional elements will be removed
and existing elements will be merged. This allows to have default values
also for positional elements.
Behavior added by this patch is the same as in json.Unmarshal and
yaml.Unmarshal, which both retain nested structs during unmarshaling
process, so I believe this is an expected behavior from user
perspective.
2019-10-10 16:15:24 +00:00
|
|
|
makeInstantiateType(withNameExpression{}),
|
2017-09-20 23:23:23 +00:00
|
|
|
func(v interface{}) bool {
|
|
|
|
if v == nil {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
wne, valid := v.(withNameExpression)
|
|
|
|
if !valid {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
if wne.Name == nil {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
nameVal, _ := wne.Name.Value(nil)
|
|
|
|
if !nameVal.IsNull() {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
return true
|
|
|
|
},
|
|
|
|
0,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
map[string]interface{}{
|
|
|
|
"name": "Ermintrude",
|
|
|
|
},
|
gohcl: retain nested blocks while decoding
Currently, if nonzero struct is passed to the DecodeBody function,
decoding process will keep already initialized top-level fields values or
overwrite them, if they are specified in HCL. This behaviour is useful,
as it allows to have some default values for top-level fields.
However, if the field is a type block or slice (multiple blocks), then the
entire block is overwritten, which erases the existing values. Because of
that, setting default values in nested structs is not possible.
With this commit, decode functions will check if the value is
nil and only then set them to empty struct, which allows for appending
to existing structs.
In case of a slice, either new empty element will be added, or existing
element will be used for setting new value (so values will be merged).
Also, to keep the same behavior as json.Unmarshal, if retained list
have more elements than new list, additional elements will be removed
and existing elements will be merged. This allows to have default values
also for positional elements.
Behavior added by this patch is the same as in json.Unmarshal and
yaml.Unmarshal, which both retain nested structs during unmarshaling
process, so I believe this is an expected behavior from user
perspective.
2019-10-10 16:15:24 +00:00
|
|
|
makeInstantiateType(withNameExpression{}),
|
2017-09-20 23:23:23 +00:00
|
|
|
func(v interface{}) bool {
|
|
|
|
if v == nil {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
wne, valid := v.(withNameExpression)
|
|
|
|
if !valid {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
if wne.Name == nil {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
nameVal, _ := wne.Name.Value(nil)
|
|
|
|
if !nameVal.Equals(cty.StringVal("Ermintrude")).True() {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
return true
|
|
|
|
},
|
|
|
|
0,
|
|
|
|
},
|
2017-05-21 19:44:07 +00:00
|
|
|
{
|
|
|
|
map[string]interface{}{
|
|
|
|
"name": "Ermintrude",
|
|
|
|
},
|
gohcl: retain nested blocks while decoding
Currently, if nonzero struct is passed to the DecodeBody function,
decoding process will keep already initialized top-level fields values or
overwrite them, if they are specified in HCL. This behaviour is useful,
as it allows to have some default values for top-level fields.
However, if the field is a type block or slice (multiple blocks), then the
entire block is overwritten, which erases the existing values. Because of
that, setting default values in nested structs is not possible.
With this commit, decode functions will check if the value is
nil and only then set them to empty struct, which allows for appending
to existing structs.
In case of a slice, either new empty element will be added, or existing
element will be used for setting new value (so values will be merged).
Also, to keep the same behavior as json.Unmarshal, if retained list
have more elements than new list, additional elements will be removed
and existing elements will be merged. This allows to have default values
also for positional elements.
Behavior added by this patch is the same as in json.Unmarshal and
yaml.Unmarshal, which both retain nested structs during unmarshaling
process, so I believe this is an expected behavior from user
perspective.
2019-10-10 16:15:24 +00:00
|
|
|
makeInstantiateType(struct {
|
2017-09-12 00:29:56 +00:00
|
|
|
Name string `hcl:"name"`
|
gohcl: retain nested blocks while decoding
Currently, if nonzero struct is passed to the DecodeBody function,
decoding process will keep already initialized top-level fields values or
overwrite them, if they are specified in HCL. This behaviour is useful,
as it allows to have some default values for top-level fields.
However, if the field is a type block or slice (multiple blocks), then the
entire block is overwritten, which erases the existing values. Because of
that, setting default values in nested structs is not possible.
With this commit, decode functions will check if the value is
nil and only then set them to empty struct, which allows for appending
to existing structs.
In case of a slice, either new empty element will be added, or existing
element will be used for setting new value (so values will be merged).
Also, to keep the same behavior as json.Unmarshal, if retained list
have more elements than new list, additional elements will be removed
and existing elements will be merged. This allows to have default values
also for positional elements.
Behavior added by this patch is the same as in json.Unmarshal and
yaml.Unmarshal, which both retain nested structs during unmarshaling
process, so I believe this is an expected behavior from user
perspective.
2019-10-10 16:15:24 +00:00
|
|
|
}{}),
|
2017-05-21 19:44:07 +00:00
|
|
|
deepEquals(struct {
|
2017-09-12 00:29:56 +00:00
|
|
|
Name string `hcl:"name"`
|
2017-05-21 19:44:07 +00:00
|
|
|
}{"Ermintrude"}),
|
|
|
|
0,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
map[string]interface{}{
|
|
|
|
"name": "Ermintrude",
|
|
|
|
"age": 23,
|
|
|
|
},
|
gohcl: retain nested blocks while decoding
Currently, if nonzero struct is passed to the DecodeBody function,
decoding process will keep already initialized top-level fields values or
overwrite them, if they are specified in HCL. This behaviour is useful,
as it allows to have some default values for top-level fields.
However, if the field is a type block or slice (multiple blocks), then the
entire block is overwritten, which erases the existing values. Because of
that, setting default values in nested structs is not possible.
With this commit, decode functions will check if the value is
nil and only then set them to empty struct, which allows for appending
to existing structs.
In case of a slice, either new empty element will be added, or existing
element will be used for setting new value (so values will be merged).
Also, to keep the same behavior as json.Unmarshal, if retained list
have more elements than new list, additional elements will be removed
and existing elements will be merged. This allows to have default values
also for positional elements.
Behavior added by this patch is the same as in json.Unmarshal and
yaml.Unmarshal, which both retain nested structs during unmarshaling
process, so I believe this is an expected behavior from user
perspective.
2019-10-10 16:15:24 +00:00
|
|
|
makeInstantiateType(struct {
|
2017-09-12 00:29:56 +00:00
|
|
|
Name string `hcl:"name"`
|
gohcl: retain nested blocks while decoding
Currently, if nonzero struct is passed to the DecodeBody function,
decoding process will keep already initialized top-level fields values or
overwrite them, if they are specified in HCL. This behaviour is useful,
as it allows to have some default values for top-level fields.
However, if the field is a type block or slice (multiple blocks), then the
entire block is overwritten, which erases the existing values. Because of
that, setting default values in nested structs is not possible.
With this commit, decode functions will check if the value is
nil and only then set them to empty struct, which allows for appending
to existing structs.
In case of a slice, either new empty element will be added, or existing
element will be used for setting new value (so values will be merged).
Also, to keep the same behavior as json.Unmarshal, if retained list
have more elements than new list, additional elements will be removed
and existing elements will be merged. This allows to have default values
also for positional elements.
Behavior added by this patch is the same as in json.Unmarshal and
yaml.Unmarshal, which both retain nested structs during unmarshaling
process, so I believe this is an expected behavior from user
perspective.
2019-10-10 16:15:24 +00:00
|
|
|
}{}),
|
2017-05-21 19:44:07 +00:00
|
|
|
deepEquals(struct {
|
2017-09-12 00:29:56 +00:00
|
|
|
Name string `hcl:"name"`
|
2017-05-21 19:44:07 +00:00
|
|
|
}{"Ermintrude"}),
|
|
|
|
1, // Extraneous "age" property
|
|
|
|
},
|
|
|
|
{
|
|
|
|
map[string]interface{}{
|
|
|
|
"name": "Ermintrude",
|
|
|
|
"age": 50,
|
|
|
|
},
|
gohcl: retain nested blocks while decoding
Currently, if nonzero struct is passed to the DecodeBody function,
decoding process will keep already initialized top-level fields values or
overwrite them, if they are specified in HCL. This behaviour is useful,
as it allows to have some default values for top-level fields.
However, if the field is a type block or slice (multiple blocks), then the
entire block is overwritten, which erases the existing values. Because of
that, setting default values in nested structs is not possible.
With this commit, decode functions will check if the value is
nil and only then set them to empty struct, which allows for appending
to existing structs.
In case of a slice, either new empty element will be added, or existing
element will be used for setting new value (so values will be merged).
Also, to keep the same behavior as json.Unmarshal, if retained list
have more elements than new list, additional elements will be removed
and existing elements will be merged. This allows to have default values
also for positional elements.
Behavior added by this patch is the same as in json.Unmarshal and
yaml.Unmarshal, which both retain nested structs during unmarshaling
process, so I believe this is an expected behavior from user
perspective.
2019-10-10 16:15:24 +00:00
|
|
|
makeInstantiateType(struct {
|
2017-09-12 00:29:56 +00:00
|
|
|
Name string `hcl:"name"`
|
|
|
|
Attrs hcl.Attributes `hcl:",remain"`
|
gohcl: retain nested blocks while decoding
Currently, if nonzero struct is passed to the DecodeBody function,
decoding process will keep already initialized top-level fields values or
overwrite them, if they are specified in HCL. This behaviour is useful,
as it allows to have some default values for top-level fields.
However, if the field is a type block or slice (multiple blocks), then the
entire block is overwritten, which erases the existing values. Because of
that, setting default values in nested structs is not possible.
With this commit, decode functions will check if the value is
nil and only then set them to empty struct, which allows for appending
to existing structs.
In case of a slice, either new empty element will be added, or existing
element will be used for setting new value (so values will be merged).
Also, to keep the same behavior as json.Unmarshal, if retained list
have more elements than new list, additional elements will be removed
and existing elements will be merged. This allows to have default values
also for positional elements.
Behavior added by this patch is the same as in json.Unmarshal and
yaml.Unmarshal, which both retain nested structs during unmarshaling
process, so I believe this is an expected behavior from user
perspective.
2019-10-10 16:15:24 +00:00
|
|
|
}{}),
|
2017-05-21 19:44:07 +00:00
|
|
|
func(gotI interface{}) bool {
|
|
|
|
got := gotI.(struct {
|
2017-09-12 00:29:56 +00:00
|
|
|
Name string `hcl:"name"`
|
|
|
|
Attrs hcl.Attributes `hcl:",remain"`
|
2017-05-21 19:44:07 +00:00
|
|
|
})
|
|
|
|
return got.Name == "Ermintrude" && len(got.Attrs) == 1 && got.Attrs["age"] != nil
|
|
|
|
},
|
|
|
|
0,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
map[string]interface{}{
|
|
|
|
"name": "Ermintrude",
|
|
|
|
"age": 50,
|
|
|
|
},
|
gohcl: retain nested blocks while decoding
Currently, if nonzero struct is passed to the DecodeBody function,
decoding process will keep already initialized top-level fields values or
overwrite them, if they are specified in HCL. This behaviour is useful,
as it allows to have some default values for top-level fields.
However, if the field is a type block or slice (multiple blocks), then the
entire block is overwritten, which erases the existing values. Because of
that, setting default values in nested structs is not possible.
With this commit, decode functions will check if the value is
nil and only then set them to empty struct, which allows for appending
to existing structs.
In case of a slice, either new empty element will be added, or existing
element will be used for setting new value (so values will be merged).
Also, to keep the same behavior as json.Unmarshal, if retained list
have more elements than new list, additional elements will be removed
and existing elements will be merged. This allows to have default values
also for positional elements.
Behavior added by this patch is the same as in json.Unmarshal and
yaml.Unmarshal, which both retain nested structs during unmarshaling
process, so I believe this is an expected behavior from user
perspective.
2019-10-10 16:15:24 +00:00
|
|
|
makeInstantiateType(struct {
|
2017-09-12 00:29:56 +00:00
|
|
|
Name string `hcl:"name"`
|
|
|
|
Remain hcl.Body `hcl:",remain"`
|
gohcl: retain nested blocks while decoding
Currently, if nonzero struct is passed to the DecodeBody function,
decoding process will keep already initialized top-level fields values or
overwrite them, if they are specified in HCL. This behaviour is useful,
as it allows to have some default values for top-level fields.
However, if the field is a type block or slice (multiple blocks), then the
entire block is overwritten, which erases the existing values. Because of
that, setting default values in nested structs is not possible.
With this commit, decode functions will check if the value is
nil and only then set them to empty struct, which allows for appending
to existing structs.
In case of a slice, either new empty element will be added, or existing
element will be used for setting new value (so values will be merged).
Also, to keep the same behavior as json.Unmarshal, if retained list
have more elements than new list, additional elements will be removed
and existing elements will be merged. This allows to have default values
also for positional elements.
Behavior added by this patch is the same as in json.Unmarshal and
yaml.Unmarshal, which both retain nested structs during unmarshaling
process, so I believe this is an expected behavior from user
perspective.
2019-10-10 16:15:24 +00:00
|
|
|
}{}),
|
2017-05-21 19:44:07 +00:00
|
|
|
func(gotI interface{}) bool {
|
|
|
|
got := gotI.(struct {
|
2017-09-12 00:29:56 +00:00
|
|
|
Name string `hcl:"name"`
|
|
|
|
Remain hcl.Body `hcl:",remain"`
|
2017-05-21 19:44:07 +00:00
|
|
|
})
|
|
|
|
|
|
|
|
attrs, _ := got.Remain.JustAttributes()
|
|
|
|
|
|
|
|
return got.Name == "Ermintrude" && len(attrs) == 1 && attrs["age"] != nil
|
|
|
|
},
|
|
|
|
0,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
map[string]interface{}{
|
2018-02-27 15:53:20 +00:00
|
|
|
"name": "Ermintrude",
|
|
|
|
"living": true,
|
2017-05-21 19:44:07 +00:00
|
|
|
},
|
gohcl: retain nested blocks while decoding
Currently, if nonzero struct is passed to the DecodeBody function,
decoding process will keep already initialized top-level fields values or
overwrite them, if they are specified in HCL. This behaviour is useful,
as it allows to have some default values for top-level fields.
However, if the field is a type block or slice (multiple blocks), then the
entire block is overwritten, which erases the existing values. Because of
that, setting default values in nested structs is not possible.
With this commit, decode functions will check if the value is
nil and only then set them to empty struct, which allows for appending
to existing structs.
In case of a slice, either new empty element will be added, or existing
element will be used for setting new value (so values will be merged).
Also, to keep the same behavior as json.Unmarshal, if retained list
have more elements than new list, additional elements will be removed
and existing elements will be merged. This allows to have default values
also for positional elements.
Behavior added by this patch is the same as in json.Unmarshal and
yaml.Unmarshal, which both retain nested structs during unmarshaling
process, so I believe this is an expected behavior from user
perspective.
2019-10-10 16:15:24 +00:00
|
|
|
makeInstantiateType(struct {
|
2017-09-12 00:29:56 +00:00
|
|
|
Name string `hcl:"name"`
|
|
|
|
Remain map[string]cty.Value `hcl:",remain"`
|
gohcl: retain nested blocks while decoding
Currently, if nonzero struct is passed to the DecodeBody function,
decoding process will keep already initialized top-level fields values or
overwrite them, if they are specified in HCL. This behaviour is useful,
as it allows to have some default values for top-level fields.
However, if the field is a type block or slice (multiple blocks), then the
entire block is overwritten, which erases the existing values. Because of
that, setting default values in nested structs is not possible.
With this commit, decode functions will check if the value is
nil and only then set them to empty struct, which allows for appending
to existing structs.
In case of a slice, either new empty element will be added, or existing
element will be used for setting new value (so values will be merged).
Also, to keep the same behavior as json.Unmarshal, if retained list
have more elements than new list, additional elements will be removed
and existing elements will be merged. This allows to have default values
also for positional elements.
Behavior added by this patch is the same as in json.Unmarshal and
yaml.Unmarshal, which both retain nested structs during unmarshaling
process, so I believe this is an expected behavior from user
perspective.
2019-10-10 16:15:24 +00:00
|
|
|
}{}),
|
2017-05-21 19:44:07 +00:00
|
|
|
deepEquals(struct {
|
2017-09-12 00:29:56 +00:00
|
|
|
Name string `hcl:"name"`
|
|
|
|
Remain map[string]cty.Value `hcl:",remain"`
|
2017-05-21 19:44:07 +00:00
|
|
|
}{
|
|
|
|
Name: "Ermintrude",
|
|
|
|
Remain: map[string]cty.Value{
|
2018-02-27 15:53:20 +00:00
|
|
|
"living": cty.True,
|
2017-05-21 19:44:07 +00:00
|
|
|
},
|
|
|
|
}),
|
|
|
|
0,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
map[string]interface{}{
|
|
|
|
"noodle": map[string]interface{}{},
|
|
|
|
},
|
gohcl: retain nested blocks while decoding
Currently, if nonzero struct is passed to the DecodeBody function,
decoding process will keep already initialized top-level fields values or
overwrite them, if they are specified in HCL. This behaviour is useful,
as it allows to have some default values for top-level fields.
However, if the field is a type block or slice (multiple blocks), then the
entire block is overwritten, which erases the existing values. Because of
that, setting default values in nested structs is not possible.
With this commit, decode functions will check if the value is
nil and only then set them to empty struct, which allows for appending
to existing structs.
In case of a slice, either new empty element will be added, or existing
element will be used for setting new value (so values will be merged).
Also, to keep the same behavior as json.Unmarshal, if retained list
have more elements than new list, additional elements will be removed
and existing elements will be merged. This allows to have default values
also for positional elements.
Behavior added by this patch is the same as in json.Unmarshal and
yaml.Unmarshal, which both retain nested structs during unmarshaling
process, so I believe this is an expected behavior from user
perspective.
2019-10-10 16:15:24 +00:00
|
|
|
makeInstantiateType(struct {
|
2017-09-12 00:29:56 +00:00
|
|
|
Noodle struct{} `hcl:"noodle,block"`
|
gohcl: retain nested blocks while decoding
Currently, if nonzero struct is passed to the DecodeBody function,
decoding process will keep already initialized top-level fields values or
overwrite them, if they are specified in HCL. This behaviour is useful,
as it allows to have some default values for top-level fields.
However, if the field is a type block or slice (multiple blocks), then the
entire block is overwritten, which erases the existing values. Because of
that, setting default values in nested structs is not possible.
With this commit, decode functions will check if the value is
nil and only then set them to empty struct, which allows for appending
to existing structs.
In case of a slice, either new empty element will be added, or existing
element will be used for setting new value (so values will be merged).
Also, to keep the same behavior as json.Unmarshal, if retained list
have more elements than new list, additional elements will be removed
and existing elements will be merged. This allows to have default values
also for positional elements.
Behavior added by this patch is the same as in json.Unmarshal and
yaml.Unmarshal, which both retain nested structs during unmarshaling
process, so I believe this is an expected behavior from user
perspective.
2019-10-10 16:15:24 +00:00
|
|
|
}{}),
|
2017-05-21 19:44:07 +00:00
|
|
|
func(gotI interface{}) bool {
|
|
|
|
// Generating no diagnostics is good enough for this one.
|
|
|
|
return true
|
|
|
|
},
|
|
|
|
0,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
map[string]interface{}{
|
|
|
|
"noodle": []map[string]interface{}{{}},
|
|
|
|
},
|
gohcl: retain nested blocks while decoding
Currently, if nonzero struct is passed to the DecodeBody function,
decoding process will keep already initialized top-level fields values or
overwrite them, if they are specified in HCL. This behaviour is useful,
as it allows to have some default values for top-level fields.
However, if the field is a type block or slice (multiple blocks), then the
entire block is overwritten, which erases the existing values. Because of
that, setting default values in nested structs is not possible.
With this commit, decode functions will check if the value is
nil and only then set them to empty struct, which allows for appending
to existing structs.
In case of a slice, either new empty element will be added, or existing
element will be used for setting new value (so values will be merged).
Also, to keep the same behavior as json.Unmarshal, if retained list
have more elements than new list, additional elements will be removed
and existing elements will be merged. This allows to have default values
also for positional elements.
Behavior added by this patch is the same as in json.Unmarshal and
yaml.Unmarshal, which both retain nested structs during unmarshaling
process, so I believe this is an expected behavior from user
perspective.
2019-10-10 16:15:24 +00:00
|
|
|
makeInstantiateType(struct {
|
2017-09-12 00:29:56 +00:00
|
|
|
Noodle struct{} `hcl:"noodle,block"`
|
gohcl: retain nested blocks while decoding
Currently, if nonzero struct is passed to the DecodeBody function,
decoding process will keep already initialized top-level fields values or
overwrite them, if they are specified in HCL. This behaviour is useful,
as it allows to have some default values for top-level fields.
However, if the field is a type block or slice (multiple blocks), then the
entire block is overwritten, which erases the existing values. Because of
that, setting default values in nested structs is not possible.
With this commit, decode functions will check if the value is
nil and only then set them to empty struct, which allows for appending
to existing structs.
In case of a slice, either new empty element will be added, or existing
element will be used for setting new value (so values will be merged).
Also, to keep the same behavior as json.Unmarshal, if retained list
have more elements than new list, additional elements will be removed
and existing elements will be merged. This allows to have default values
also for positional elements.
Behavior added by this patch is the same as in json.Unmarshal and
yaml.Unmarshal, which both retain nested structs during unmarshaling
process, so I believe this is an expected behavior from user
perspective.
2019-10-10 16:15:24 +00:00
|
|
|
}{}),
|
2017-05-21 19:44:07 +00:00
|
|
|
func(gotI interface{}) bool {
|
|
|
|
// Generating no diagnostics is good enough for this one.
|
|
|
|
return true
|
|
|
|
},
|
|
|
|
0,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
map[string]interface{}{
|
|
|
|
"noodle": []map[string]interface{}{{}, {}},
|
|
|
|
},
|
gohcl: retain nested blocks while decoding
Currently, if nonzero struct is passed to the DecodeBody function,
decoding process will keep already initialized top-level fields values or
overwrite them, if they are specified in HCL. This behaviour is useful,
as it allows to have some default values for top-level fields.
However, if the field is a type block or slice (multiple blocks), then the
entire block is overwritten, which erases the existing values. Because of
that, setting default values in nested structs is not possible.
With this commit, decode functions will check if the value is
nil and only then set them to empty struct, which allows for appending
to existing structs.
In case of a slice, either new empty element will be added, or existing
element will be used for setting new value (so values will be merged).
Also, to keep the same behavior as json.Unmarshal, if retained list
have more elements than new list, additional elements will be removed
and existing elements will be merged. This allows to have default values
also for positional elements.
Behavior added by this patch is the same as in json.Unmarshal and
yaml.Unmarshal, which both retain nested structs during unmarshaling
process, so I believe this is an expected behavior from user
perspective.
2019-10-10 16:15:24 +00:00
|
|
|
makeInstantiateType(struct {
|
2017-09-12 00:29:56 +00:00
|
|
|
Noodle struct{} `hcl:"noodle,block"`
|
gohcl: retain nested blocks while decoding
Currently, if nonzero struct is passed to the DecodeBody function,
decoding process will keep already initialized top-level fields values or
overwrite them, if they are specified in HCL. This behaviour is useful,
as it allows to have some default values for top-level fields.
However, if the field is a type block or slice (multiple blocks), then the
entire block is overwritten, which erases the existing values. Because of
that, setting default values in nested structs is not possible.
With this commit, decode functions will check if the value is
nil and only then set them to empty struct, which allows for appending
to existing structs.
In case of a slice, either new empty element will be added, or existing
element will be used for setting new value (so values will be merged).
Also, to keep the same behavior as json.Unmarshal, if retained list
have more elements than new list, additional elements will be removed
and existing elements will be merged. This allows to have default values
also for positional elements.
Behavior added by this patch is the same as in json.Unmarshal and
yaml.Unmarshal, which both retain nested structs during unmarshaling
process, so I believe this is an expected behavior from user
perspective.
2019-10-10 16:15:24 +00:00
|
|
|
}{}),
|
2017-05-21 19:44:07 +00:00
|
|
|
func(gotI interface{}) bool {
|
|
|
|
// Generating one diagnostic is good enough for this one.
|
|
|
|
return true
|
|
|
|
},
|
|
|
|
1,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
map[string]interface{}{},
|
gohcl: retain nested blocks while decoding
Currently, if nonzero struct is passed to the DecodeBody function,
decoding process will keep already initialized top-level fields values or
overwrite them, if they are specified in HCL. This behaviour is useful,
as it allows to have some default values for top-level fields.
However, if the field is a type block or slice (multiple blocks), then the
entire block is overwritten, which erases the existing values. Because of
that, setting default values in nested structs is not possible.
With this commit, decode functions will check if the value is
nil and only then set them to empty struct, which allows for appending
to existing structs.
In case of a slice, either new empty element will be added, or existing
element will be used for setting new value (so values will be merged).
Also, to keep the same behavior as json.Unmarshal, if retained list
have more elements than new list, additional elements will be removed
and existing elements will be merged. This allows to have default values
also for positional elements.
Behavior added by this patch is the same as in json.Unmarshal and
yaml.Unmarshal, which both retain nested structs during unmarshaling
process, so I believe this is an expected behavior from user
perspective.
2019-10-10 16:15:24 +00:00
|
|
|
makeInstantiateType(struct {
|
2017-09-12 00:29:56 +00:00
|
|
|
Noodle struct{} `hcl:"noodle,block"`
|
gohcl: retain nested blocks while decoding
Currently, if nonzero struct is passed to the DecodeBody function,
decoding process will keep already initialized top-level fields values or
overwrite them, if they are specified in HCL. This behaviour is useful,
as it allows to have some default values for top-level fields.
However, if the field is a type block or slice (multiple blocks), then the
entire block is overwritten, which erases the existing values. Because of
that, setting default values in nested structs is not possible.
With this commit, decode functions will check if the value is
nil and only then set them to empty struct, which allows for appending
to existing structs.
In case of a slice, either new empty element will be added, or existing
element will be used for setting new value (so values will be merged).
Also, to keep the same behavior as json.Unmarshal, if retained list
have more elements than new list, additional elements will be removed
and existing elements will be merged. This allows to have default values
also for positional elements.
Behavior added by this patch is the same as in json.Unmarshal and
yaml.Unmarshal, which both retain nested structs during unmarshaling
process, so I believe this is an expected behavior from user
perspective.
2019-10-10 16:15:24 +00:00
|
|
|
}{}),
|
2017-05-21 19:44:07 +00:00
|
|
|
func(gotI interface{}) bool {
|
|
|
|
// Generating one diagnostic is good enough for this one.
|
|
|
|
return true
|
|
|
|
},
|
|
|
|
1,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
map[string]interface{}{
|
|
|
|
"noodle": []map[string]interface{}{},
|
|
|
|
},
|
gohcl: retain nested blocks while decoding
Currently, if nonzero struct is passed to the DecodeBody function,
decoding process will keep already initialized top-level fields values or
overwrite them, if they are specified in HCL. This behaviour is useful,
as it allows to have some default values for top-level fields.
However, if the field is a type block or slice (multiple blocks), then the
entire block is overwritten, which erases the existing values. Because of
that, setting default values in nested structs is not possible.
With this commit, decode functions will check if the value is
nil and only then set them to empty struct, which allows for appending
to existing structs.
In case of a slice, either new empty element will be added, or existing
element will be used for setting new value (so values will be merged).
Also, to keep the same behavior as json.Unmarshal, if retained list
have more elements than new list, additional elements will be removed
and existing elements will be merged. This allows to have default values
also for positional elements.
Behavior added by this patch is the same as in json.Unmarshal and
yaml.Unmarshal, which both retain nested structs during unmarshaling
process, so I believe this is an expected behavior from user
perspective.
2019-10-10 16:15:24 +00:00
|
|
|
makeInstantiateType(struct {
|
2017-09-12 00:29:56 +00:00
|
|
|
Noodle struct{} `hcl:"noodle,block"`
|
gohcl: retain nested blocks while decoding
Currently, if nonzero struct is passed to the DecodeBody function,
decoding process will keep already initialized top-level fields values or
overwrite them, if they are specified in HCL. This behaviour is useful,
as it allows to have some default values for top-level fields.
However, if the field is a type block or slice (multiple blocks), then the
entire block is overwritten, which erases the existing values. Because of
that, setting default values in nested structs is not possible.
With this commit, decode functions will check if the value is
nil and only then set them to empty struct, which allows for appending
to existing structs.
In case of a slice, either new empty element will be added, or existing
element will be used for setting new value (so values will be merged).
Also, to keep the same behavior as json.Unmarshal, if retained list
have more elements than new list, additional elements will be removed
and existing elements will be merged. This allows to have default values
also for positional elements.
Behavior added by this patch is the same as in json.Unmarshal and
yaml.Unmarshal, which both retain nested structs during unmarshaling
process, so I believe this is an expected behavior from user
perspective.
2019-10-10 16:15:24 +00:00
|
|
|
}{}),
|
2017-05-21 19:44:07 +00:00
|
|
|
func(gotI interface{}) bool {
|
|
|
|
// Generating one diagnostic is good enough for this one.
|
|
|
|
return true
|
|
|
|
},
|
|
|
|
1,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
map[string]interface{}{
|
|
|
|
"noodle": map[string]interface{}{},
|
|
|
|
},
|
gohcl: retain nested blocks while decoding
Currently, if nonzero struct is passed to the DecodeBody function,
decoding process will keep already initialized top-level fields values or
overwrite them, if they are specified in HCL. This behaviour is useful,
as it allows to have some default values for top-level fields.
However, if the field is a type block or slice (multiple blocks), then the
entire block is overwritten, which erases the existing values. Because of
that, setting default values in nested structs is not possible.
With this commit, decode functions will check if the value is
nil and only then set them to empty struct, which allows for appending
to existing structs.
In case of a slice, either new empty element will be added, or existing
element will be used for setting new value (so values will be merged).
Also, to keep the same behavior as json.Unmarshal, if retained list
have more elements than new list, additional elements will be removed
and existing elements will be merged. This allows to have default values
also for positional elements.
Behavior added by this patch is the same as in json.Unmarshal and
yaml.Unmarshal, which both retain nested structs during unmarshaling
process, so I believe this is an expected behavior from user
perspective.
2019-10-10 16:15:24 +00:00
|
|
|
makeInstantiateType(struct {
|
2017-09-12 00:29:56 +00:00
|
|
|
Noodle *struct{} `hcl:"noodle,block"`
|
gohcl: retain nested blocks while decoding
Currently, if nonzero struct is passed to the DecodeBody function,
decoding process will keep already initialized top-level fields values or
overwrite them, if they are specified in HCL. This behaviour is useful,
as it allows to have some default values for top-level fields.
However, if the field is a type block or slice (multiple blocks), then the
entire block is overwritten, which erases the existing values. Because of
that, setting default values in nested structs is not possible.
With this commit, decode functions will check if the value is
nil and only then set them to empty struct, which allows for appending
to existing structs.
In case of a slice, either new empty element will be added, or existing
element will be used for setting new value (so values will be merged).
Also, to keep the same behavior as json.Unmarshal, if retained list
have more elements than new list, additional elements will be removed
and existing elements will be merged. This allows to have default values
also for positional elements.
Behavior added by this patch is the same as in json.Unmarshal and
yaml.Unmarshal, which both retain nested structs during unmarshaling
process, so I believe this is an expected behavior from user
perspective.
2019-10-10 16:15:24 +00:00
|
|
|
}{}),
|
2017-05-21 19:44:07 +00:00
|
|
|
func(gotI interface{}) bool {
|
|
|
|
return gotI.(struct {
|
2017-09-12 00:29:56 +00:00
|
|
|
Noodle *struct{} `hcl:"noodle,block"`
|
2017-05-21 19:44:07 +00:00
|
|
|
}).Noodle != nil
|
|
|
|
},
|
|
|
|
0,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
map[string]interface{}{
|
|
|
|
"noodle": []map[string]interface{}{{}},
|
|
|
|
},
|
gohcl: retain nested blocks while decoding
Currently, if nonzero struct is passed to the DecodeBody function,
decoding process will keep already initialized top-level fields values or
overwrite them, if they are specified in HCL. This behaviour is useful,
as it allows to have some default values for top-level fields.
However, if the field is a type block or slice (multiple blocks), then the
entire block is overwritten, which erases the existing values. Because of
that, setting default values in nested structs is not possible.
With this commit, decode functions will check if the value is
nil and only then set them to empty struct, which allows for appending
to existing structs.
In case of a slice, either new empty element will be added, or existing
element will be used for setting new value (so values will be merged).
Also, to keep the same behavior as json.Unmarshal, if retained list
have more elements than new list, additional elements will be removed
and existing elements will be merged. This allows to have default values
also for positional elements.
Behavior added by this patch is the same as in json.Unmarshal and
yaml.Unmarshal, which both retain nested structs during unmarshaling
process, so I believe this is an expected behavior from user
perspective.
2019-10-10 16:15:24 +00:00
|
|
|
makeInstantiateType(struct {
|
2017-09-12 00:29:56 +00:00
|
|
|
Noodle *struct{} `hcl:"noodle,block"`
|
gohcl: retain nested blocks while decoding
Currently, if nonzero struct is passed to the DecodeBody function,
decoding process will keep already initialized top-level fields values or
overwrite them, if they are specified in HCL. This behaviour is useful,
as it allows to have some default values for top-level fields.
However, if the field is a type block or slice (multiple blocks), then the
entire block is overwritten, which erases the existing values. Because of
that, setting default values in nested structs is not possible.
With this commit, decode functions will check if the value is
nil and only then set them to empty struct, which allows for appending
to existing structs.
In case of a slice, either new empty element will be added, or existing
element will be used for setting new value (so values will be merged).
Also, to keep the same behavior as json.Unmarshal, if retained list
have more elements than new list, additional elements will be removed
and existing elements will be merged. This allows to have default values
also for positional elements.
Behavior added by this patch is the same as in json.Unmarshal and
yaml.Unmarshal, which both retain nested structs during unmarshaling
process, so I believe this is an expected behavior from user
perspective.
2019-10-10 16:15:24 +00:00
|
|
|
}{}),
|
2017-05-21 19:44:07 +00:00
|
|
|
func(gotI interface{}) bool {
|
|
|
|
return gotI.(struct {
|
2017-09-12 00:29:56 +00:00
|
|
|
Noodle *struct{} `hcl:"noodle,block"`
|
2017-05-21 19:44:07 +00:00
|
|
|
}).Noodle != nil
|
|
|
|
},
|
|
|
|
0,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
map[string]interface{}{
|
|
|
|
"noodle": []map[string]interface{}{},
|
|
|
|
},
|
gohcl: retain nested blocks while decoding
Currently, if nonzero struct is passed to the DecodeBody function,
decoding process will keep already initialized top-level fields values or
overwrite them, if they are specified in HCL. This behaviour is useful,
as it allows to have some default values for top-level fields.
However, if the field is a type block or slice (multiple blocks), then the
entire block is overwritten, which erases the existing values. Because of
that, setting default values in nested structs is not possible.
With this commit, decode functions will check if the value is
nil and only then set them to empty struct, which allows for appending
to existing structs.
In case of a slice, either new empty element will be added, or existing
element will be used for setting new value (so values will be merged).
Also, to keep the same behavior as json.Unmarshal, if retained list
have more elements than new list, additional elements will be removed
and existing elements will be merged. This allows to have default values
also for positional elements.
Behavior added by this patch is the same as in json.Unmarshal and
yaml.Unmarshal, which both retain nested structs during unmarshaling
process, so I believe this is an expected behavior from user
perspective.
2019-10-10 16:15:24 +00:00
|
|
|
makeInstantiateType(struct {
|
2017-09-12 00:29:56 +00:00
|
|
|
Noodle *struct{} `hcl:"noodle,block"`
|
gohcl: retain nested blocks while decoding
Currently, if nonzero struct is passed to the DecodeBody function,
decoding process will keep already initialized top-level fields values or
overwrite them, if they are specified in HCL. This behaviour is useful,
as it allows to have some default values for top-level fields.
However, if the field is a type block or slice (multiple blocks), then the
entire block is overwritten, which erases the existing values. Because of
that, setting default values in nested structs is not possible.
With this commit, decode functions will check if the value is
nil and only then set them to empty struct, which allows for appending
to existing structs.
In case of a slice, either new empty element will be added, or existing
element will be used for setting new value (so values will be merged).
Also, to keep the same behavior as json.Unmarshal, if retained list
have more elements than new list, additional elements will be removed
and existing elements will be merged. This allows to have default values
also for positional elements.
Behavior added by this patch is the same as in json.Unmarshal and
yaml.Unmarshal, which both retain nested structs during unmarshaling
process, so I believe this is an expected behavior from user
perspective.
2019-10-10 16:15:24 +00:00
|
|
|
}{}),
|
2017-05-21 19:44:07 +00:00
|
|
|
func(gotI interface{}) bool {
|
|
|
|
return gotI.(struct {
|
2017-09-12 00:29:56 +00:00
|
|
|
Noodle *struct{} `hcl:"noodle,block"`
|
2017-05-21 19:44:07 +00:00
|
|
|
}).Noodle == nil
|
|
|
|
},
|
|
|
|
0,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
map[string]interface{}{
|
|
|
|
"noodle": []map[string]interface{}{{}, {}},
|
|
|
|
},
|
gohcl: retain nested blocks while decoding
Currently, if nonzero struct is passed to the DecodeBody function,
decoding process will keep already initialized top-level fields values or
overwrite them, if they are specified in HCL. This behaviour is useful,
as it allows to have some default values for top-level fields.
However, if the field is a type block or slice (multiple blocks), then the
entire block is overwritten, which erases the existing values. Because of
that, setting default values in nested structs is not possible.
With this commit, decode functions will check if the value is
nil and only then set them to empty struct, which allows for appending
to existing structs.
In case of a slice, either new empty element will be added, or existing
element will be used for setting new value (so values will be merged).
Also, to keep the same behavior as json.Unmarshal, if retained list
have more elements than new list, additional elements will be removed
and existing elements will be merged. This allows to have default values
also for positional elements.
Behavior added by this patch is the same as in json.Unmarshal and
yaml.Unmarshal, which both retain nested structs during unmarshaling
process, so I believe this is an expected behavior from user
perspective.
2019-10-10 16:15:24 +00:00
|
|
|
makeInstantiateType(struct {
|
2017-09-12 00:29:56 +00:00
|
|
|
Noodle *struct{} `hcl:"noodle,block"`
|
gohcl: retain nested blocks while decoding
Currently, if nonzero struct is passed to the DecodeBody function,
decoding process will keep already initialized top-level fields values or
overwrite them, if they are specified in HCL. This behaviour is useful,
as it allows to have some default values for top-level fields.
However, if the field is a type block or slice (multiple blocks), then the
entire block is overwritten, which erases the existing values. Because of
that, setting default values in nested structs is not possible.
With this commit, decode functions will check if the value is
nil and only then set them to empty struct, which allows for appending
to existing structs.
In case of a slice, either new empty element will be added, or existing
element will be used for setting new value (so values will be merged).
Also, to keep the same behavior as json.Unmarshal, if retained list
have more elements than new list, additional elements will be removed
and existing elements will be merged. This allows to have default values
also for positional elements.
Behavior added by this patch is the same as in json.Unmarshal and
yaml.Unmarshal, which both retain nested structs during unmarshaling
process, so I believe this is an expected behavior from user
perspective.
2019-10-10 16:15:24 +00:00
|
|
|
}{}),
|
2017-05-21 19:44:07 +00:00
|
|
|
func(gotI interface{}) bool {
|
|
|
|
// Generating one diagnostic is good enough for this one.
|
|
|
|
return true
|
|
|
|
},
|
|
|
|
1,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
map[string]interface{}{
|
|
|
|
"noodle": []map[string]interface{}{},
|
|
|
|
},
|
gohcl: retain nested blocks while decoding
Currently, if nonzero struct is passed to the DecodeBody function,
decoding process will keep already initialized top-level fields values or
overwrite them, if they are specified in HCL. This behaviour is useful,
as it allows to have some default values for top-level fields.
However, if the field is a type block or slice (multiple blocks), then the
entire block is overwritten, which erases the existing values. Because of
that, setting default values in nested structs is not possible.
With this commit, decode functions will check if the value is
nil and only then set them to empty struct, which allows for appending
to existing structs.
In case of a slice, either new empty element will be added, or existing
element will be used for setting new value (so values will be merged).
Also, to keep the same behavior as json.Unmarshal, if retained list
have more elements than new list, additional elements will be removed
and existing elements will be merged. This allows to have default values
also for positional elements.
Behavior added by this patch is the same as in json.Unmarshal and
yaml.Unmarshal, which both retain nested structs during unmarshaling
process, so I believe this is an expected behavior from user
perspective.
2019-10-10 16:15:24 +00:00
|
|
|
makeInstantiateType(struct {
|
2017-09-12 00:29:56 +00:00
|
|
|
Noodle []struct{} `hcl:"noodle,block"`
|
gohcl: retain nested blocks while decoding
Currently, if nonzero struct is passed to the DecodeBody function,
decoding process will keep already initialized top-level fields values or
overwrite them, if they are specified in HCL. This behaviour is useful,
as it allows to have some default values for top-level fields.
However, if the field is a type block or slice (multiple blocks), then the
entire block is overwritten, which erases the existing values. Because of
that, setting default values in nested structs is not possible.
With this commit, decode functions will check if the value is
nil and only then set them to empty struct, which allows for appending
to existing structs.
In case of a slice, either new empty element will be added, or existing
element will be used for setting new value (so values will be merged).
Also, to keep the same behavior as json.Unmarshal, if retained list
have more elements than new list, additional elements will be removed
and existing elements will be merged. This allows to have default values
also for positional elements.
Behavior added by this patch is the same as in json.Unmarshal and
yaml.Unmarshal, which both retain nested structs during unmarshaling
process, so I believe this is an expected behavior from user
perspective.
2019-10-10 16:15:24 +00:00
|
|
|
}{}),
|
2017-05-21 19:44:07 +00:00
|
|
|
func(gotI interface{}) bool {
|
|
|
|
noodle := gotI.(struct {
|
2017-09-12 00:29:56 +00:00
|
|
|
Noodle []struct{} `hcl:"noodle,block"`
|
2017-05-21 19:44:07 +00:00
|
|
|
}).Noodle
|
|
|
|
return len(noodle) == 0
|
|
|
|
},
|
|
|
|
0,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
map[string]interface{}{
|
|
|
|
"noodle": []map[string]interface{}{{}},
|
|
|
|
},
|
gohcl: retain nested blocks while decoding
Currently, if nonzero struct is passed to the DecodeBody function,
decoding process will keep already initialized top-level fields values or
overwrite them, if they are specified in HCL. This behaviour is useful,
as it allows to have some default values for top-level fields.
However, if the field is a type block or slice (multiple blocks), then the
entire block is overwritten, which erases the existing values. Because of
that, setting default values in nested structs is not possible.
With this commit, decode functions will check if the value is
nil and only then set them to empty struct, which allows for appending
to existing structs.
In case of a slice, either new empty element will be added, or existing
element will be used for setting new value (so values will be merged).
Also, to keep the same behavior as json.Unmarshal, if retained list
have more elements than new list, additional elements will be removed
and existing elements will be merged. This allows to have default values
also for positional elements.
Behavior added by this patch is the same as in json.Unmarshal and
yaml.Unmarshal, which both retain nested structs during unmarshaling
process, so I believe this is an expected behavior from user
perspective.
2019-10-10 16:15:24 +00:00
|
|
|
makeInstantiateType(struct {
|
2017-09-12 00:29:56 +00:00
|
|
|
Noodle []struct{} `hcl:"noodle,block"`
|
gohcl: retain nested blocks while decoding
Currently, if nonzero struct is passed to the DecodeBody function,
decoding process will keep already initialized top-level fields values or
overwrite them, if they are specified in HCL. This behaviour is useful,
as it allows to have some default values for top-level fields.
However, if the field is a type block or slice (multiple blocks), then the
entire block is overwritten, which erases the existing values. Because of
that, setting default values in nested structs is not possible.
With this commit, decode functions will check if the value is
nil and only then set them to empty struct, which allows for appending
to existing structs.
In case of a slice, either new empty element will be added, or existing
element will be used for setting new value (so values will be merged).
Also, to keep the same behavior as json.Unmarshal, if retained list
have more elements than new list, additional elements will be removed
and existing elements will be merged. This allows to have default values
also for positional elements.
Behavior added by this patch is the same as in json.Unmarshal and
yaml.Unmarshal, which both retain nested structs during unmarshaling
process, so I believe this is an expected behavior from user
perspective.
2019-10-10 16:15:24 +00:00
|
|
|
}{}),
|
2017-05-21 19:44:07 +00:00
|
|
|
func(gotI interface{}) bool {
|
|
|
|
noodle := gotI.(struct {
|
2017-09-12 00:29:56 +00:00
|
|
|
Noodle []struct{} `hcl:"noodle,block"`
|
2017-05-21 19:44:07 +00:00
|
|
|
}).Noodle
|
|
|
|
return len(noodle) == 1
|
|
|
|
},
|
|
|
|
0,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
map[string]interface{}{
|
|
|
|
"noodle": []map[string]interface{}{{}, {}},
|
|
|
|
},
|
gohcl: retain nested blocks while decoding
Currently, if nonzero struct is passed to the DecodeBody function,
decoding process will keep already initialized top-level fields values or
overwrite them, if they are specified in HCL. This behaviour is useful,
as it allows to have some default values for top-level fields.
However, if the field is a type block or slice (multiple blocks), then the
entire block is overwritten, which erases the existing values. Because of
that, setting default values in nested structs is not possible.
With this commit, decode functions will check if the value is
nil and only then set them to empty struct, which allows for appending
to existing structs.
In case of a slice, either new empty element will be added, or existing
element will be used for setting new value (so values will be merged).
Also, to keep the same behavior as json.Unmarshal, if retained list
have more elements than new list, additional elements will be removed
and existing elements will be merged. This allows to have default values
also for positional elements.
Behavior added by this patch is the same as in json.Unmarshal and
yaml.Unmarshal, which both retain nested structs during unmarshaling
process, so I believe this is an expected behavior from user
perspective.
2019-10-10 16:15:24 +00:00
|
|
|
makeInstantiateType(struct {
|
2017-09-12 00:29:56 +00:00
|
|
|
Noodle []struct{} `hcl:"noodle,block"`
|
gohcl: retain nested blocks while decoding
Currently, if nonzero struct is passed to the DecodeBody function,
decoding process will keep already initialized top-level fields values or
overwrite them, if they are specified in HCL. This behaviour is useful,
as it allows to have some default values for top-level fields.
However, if the field is a type block or slice (multiple blocks), then the
entire block is overwritten, which erases the existing values. Because of
that, setting default values in nested structs is not possible.
With this commit, decode functions will check if the value is
nil and only then set them to empty struct, which allows for appending
to existing structs.
In case of a slice, either new empty element will be added, or existing
element will be used for setting new value (so values will be merged).
Also, to keep the same behavior as json.Unmarshal, if retained list
have more elements than new list, additional elements will be removed
and existing elements will be merged. This allows to have default values
also for positional elements.
Behavior added by this patch is the same as in json.Unmarshal and
yaml.Unmarshal, which both retain nested structs during unmarshaling
process, so I believe this is an expected behavior from user
perspective.
2019-10-10 16:15:24 +00:00
|
|
|
}{}),
|
2017-05-21 19:44:07 +00:00
|
|
|
func(gotI interface{}) bool {
|
|
|
|
noodle := gotI.(struct {
|
2017-09-12 00:29:56 +00:00
|
|
|
Noodle []struct{} `hcl:"noodle,block"`
|
2017-05-21 19:44:07 +00:00
|
|
|
}).Noodle
|
|
|
|
return len(noodle) == 2
|
|
|
|
},
|
|
|
|
0,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
map[string]interface{}{
|
|
|
|
"noodle": map[string]interface{}{},
|
|
|
|
},
|
gohcl: retain nested blocks while decoding
Currently, if nonzero struct is passed to the DecodeBody function,
decoding process will keep already initialized top-level fields values or
overwrite them, if they are specified in HCL. This behaviour is useful,
as it allows to have some default values for top-level fields.
However, if the field is a type block or slice (multiple blocks), then the
entire block is overwritten, which erases the existing values. Because of
that, setting default values in nested structs is not possible.
With this commit, decode functions will check if the value is
nil and only then set them to empty struct, which allows for appending
to existing structs.
In case of a slice, either new empty element will be added, or existing
element will be used for setting new value (so values will be merged).
Also, to keep the same behavior as json.Unmarshal, if retained list
have more elements than new list, additional elements will be removed
and existing elements will be merged. This allows to have default values
also for positional elements.
Behavior added by this patch is the same as in json.Unmarshal and
yaml.Unmarshal, which both retain nested structs during unmarshaling
process, so I believe this is an expected behavior from user
perspective.
2019-10-10 16:15:24 +00:00
|
|
|
makeInstantiateType(struct {
|
2017-05-21 19:44:07 +00:00
|
|
|
Noodle struct {
|
2017-09-12 00:29:56 +00:00
|
|
|
Name string `hcl:"name,label"`
|
|
|
|
} `hcl:"noodle,block"`
|
gohcl: retain nested blocks while decoding
Currently, if nonzero struct is passed to the DecodeBody function,
decoding process will keep already initialized top-level fields values or
overwrite them, if they are specified in HCL. This behaviour is useful,
as it allows to have some default values for top-level fields.
However, if the field is a type block or slice (multiple blocks), then the
entire block is overwritten, which erases the existing values. Because of
that, setting default values in nested structs is not possible.
With this commit, decode functions will check if the value is
nil and only then set them to empty struct, which allows for appending
to existing structs.
In case of a slice, either new empty element will be added, or existing
element will be used for setting new value (so values will be merged).
Also, to keep the same behavior as json.Unmarshal, if retained list
have more elements than new list, additional elements will be removed
and existing elements will be merged. This allows to have default values
also for positional elements.
Behavior added by this patch is the same as in json.Unmarshal and
yaml.Unmarshal, which both retain nested structs during unmarshaling
process, so I believe this is an expected behavior from user
perspective.
2019-10-10 16:15:24 +00:00
|
|
|
}{}),
|
2017-05-21 19:44:07 +00:00
|
|
|
func(gotI interface{}) bool {
|
|
|
|
// Generating two diagnostics is good enough for this one.
|
|
|
|
// (one for the missing noodle block and the other for
|
|
|
|
// the JSON serialization detecting the missing level of
|
|
|
|
// heirarchy for the label.)
|
|
|
|
return true
|
|
|
|
},
|
|
|
|
2,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
map[string]interface{}{
|
|
|
|
"noodle": map[string]interface{}{
|
|
|
|
"foo_foo": map[string]interface{}{},
|
|
|
|
},
|
|
|
|
},
|
gohcl: retain nested blocks while decoding
Currently, if nonzero struct is passed to the DecodeBody function,
decoding process will keep already initialized top-level fields values or
overwrite them, if they are specified in HCL. This behaviour is useful,
as it allows to have some default values for top-level fields.
However, if the field is a type block or slice (multiple blocks), then the
entire block is overwritten, which erases the existing values. Because of
that, setting default values in nested structs is not possible.
With this commit, decode functions will check if the value is
nil and only then set them to empty struct, which allows for appending
to existing structs.
In case of a slice, either new empty element will be added, or existing
element will be used for setting new value (so values will be merged).
Also, to keep the same behavior as json.Unmarshal, if retained list
have more elements than new list, additional elements will be removed
and existing elements will be merged. This allows to have default values
also for positional elements.
Behavior added by this patch is the same as in json.Unmarshal and
yaml.Unmarshal, which both retain nested structs during unmarshaling
process, so I believe this is an expected behavior from user
perspective.
2019-10-10 16:15:24 +00:00
|
|
|
makeInstantiateType(struct {
|
2017-05-21 19:44:07 +00:00
|
|
|
Noodle struct {
|
2017-09-12 00:29:56 +00:00
|
|
|
Name string `hcl:"name,label"`
|
|
|
|
} `hcl:"noodle,block"`
|
gohcl: retain nested blocks while decoding
Currently, if nonzero struct is passed to the DecodeBody function,
decoding process will keep already initialized top-level fields values or
overwrite them, if they are specified in HCL. This behaviour is useful,
as it allows to have some default values for top-level fields.
However, if the field is a type block or slice (multiple blocks), then the
entire block is overwritten, which erases the existing values. Because of
that, setting default values in nested structs is not possible.
With this commit, decode functions will check if the value is
nil and only then set them to empty struct, which allows for appending
to existing structs.
In case of a slice, either new empty element will be added, or existing
element will be used for setting new value (so values will be merged).
Also, to keep the same behavior as json.Unmarshal, if retained list
have more elements than new list, additional elements will be removed
and existing elements will be merged. This allows to have default values
also for positional elements.
Behavior added by this patch is the same as in json.Unmarshal and
yaml.Unmarshal, which both retain nested structs during unmarshaling
process, so I believe this is an expected behavior from user
perspective.
2019-10-10 16:15:24 +00:00
|
|
|
}{}),
|
2017-05-21 19:44:07 +00:00
|
|
|
func(gotI interface{}) bool {
|
|
|
|
noodle := gotI.(struct {
|
|
|
|
Noodle struct {
|
2017-09-12 00:29:56 +00:00
|
|
|
Name string `hcl:"name,label"`
|
|
|
|
} `hcl:"noodle,block"`
|
2017-05-21 19:44:07 +00:00
|
|
|
}).Noodle
|
|
|
|
return noodle.Name == "foo_foo"
|
|
|
|
},
|
|
|
|
0,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
map[string]interface{}{
|
|
|
|
"noodle": map[string]interface{}{
|
|
|
|
"foo_foo": map[string]interface{}{},
|
|
|
|
"bar_baz": map[string]interface{}{},
|
|
|
|
},
|
|
|
|
},
|
gohcl: retain nested blocks while decoding
Currently, if nonzero struct is passed to the DecodeBody function,
decoding process will keep already initialized top-level fields values or
overwrite them, if they are specified in HCL. This behaviour is useful,
as it allows to have some default values for top-level fields.
However, if the field is a type block or slice (multiple blocks), then the
entire block is overwritten, which erases the existing values. Because of
that, setting default values in nested structs is not possible.
With this commit, decode functions will check if the value is
nil and only then set them to empty struct, which allows for appending
to existing structs.
In case of a slice, either new empty element will be added, or existing
element will be used for setting new value (so values will be merged).
Also, to keep the same behavior as json.Unmarshal, if retained list
have more elements than new list, additional elements will be removed
and existing elements will be merged. This allows to have default values
also for positional elements.
Behavior added by this patch is the same as in json.Unmarshal and
yaml.Unmarshal, which both retain nested structs during unmarshaling
process, so I believe this is an expected behavior from user
perspective.
2019-10-10 16:15:24 +00:00
|
|
|
makeInstantiateType(struct {
|
2017-05-21 19:44:07 +00:00
|
|
|
Noodle struct {
|
2017-09-12 00:29:56 +00:00
|
|
|
Name string `hcl:"name,label"`
|
|
|
|
} `hcl:"noodle,block"`
|
gohcl: retain nested blocks while decoding
Currently, if nonzero struct is passed to the DecodeBody function,
decoding process will keep already initialized top-level fields values or
overwrite them, if they are specified in HCL. This behaviour is useful,
as it allows to have some default values for top-level fields.
However, if the field is a type block or slice (multiple blocks), then the
entire block is overwritten, which erases the existing values. Because of
that, setting default values in nested structs is not possible.
With this commit, decode functions will check if the value is
nil and only then set them to empty struct, which allows for appending
to existing structs.
In case of a slice, either new empty element will be added, or existing
element will be used for setting new value (so values will be merged).
Also, to keep the same behavior as json.Unmarshal, if retained list
have more elements than new list, additional elements will be removed
and existing elements will be merged. This allows to have default values
also for positional elements.
Behavior added by this patch is the same as in json.Unmarshal and
yaml.Unmarshal, which both retain nested structs during unmarshaling
process, so I believe this is an expected behavior from user
perspective.
2019-10-10 16:15:24 +00:00
|
|
|
}{}),
|
2017-05-21 19:44:07 +00:00
|
|
|
func(gotI interface{}) bool {
|
|
|
|
// One diagnostic is enough for this one.
|
|
|
|
return true
|
|
|
|
},
|
|
|
|
1,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
map[string]interface{}{
|
|
|
|
"noodle": map[string]interface{}{
|
|
|
|
"foo_foo": map[string]interface{}{},
|
|
|
|
"bar_baz": map[string]interface{}{},
|
|
|
|
},
|
|
|
|
},
|
gohcl: retain nested blocks while decoding
Currently, if nonzero struct is passed to the DecodeBody function,
decoding process will keep already initialized top-level fields values or
overwrite them, if they are specified in HCL. This behaviour is useful,
as it allows to have some default values for top-level fields.
However, if the field is a type block or slice (multiple blocks), then the
entire block is overwritten, which erases the existing values. Because of
that, setting default values in nested structs is not possible.
With this commit, decode functions will check if the value is
nil and only then set them to empty struct, which allows for appending
to existing structs.
In case of a slice, either new empty element will be added, or existing
element will be used for setting new value (so values will be merged).
Also, to keep the same behavior as json.Unmarshal, if retained list
have more elements than new list, additional elements will be removed
and existing elements will be merged. This allows to have default values
also for positional elements.
Behavior added by this patch is the same as in json.Unmarshal and
yaml.Unmarshal, which both retain nested structs during unmarshaling
process, so I believe this is an expected behavior from user
perspective.
2019-10-10 16:15:24 +00:00
|
|
|
makeInstantiateType(struct {
|
2017-05-21 19:44:07 +00:00
|
|
|
Noodles []struct {
|
2017-09-12 00:29:56 +00:00
|
|
|
Name string `hcl:"name,label"`
|
|
|
|
} `hcl:"noodle,block"`
|
gohcl: retain nested blocks while decoding
Currently, if nonzero struct is passed to the DecodeBody function,
decoding process will keep already initialized top-level fields values or
overwrite them, if they are specified in HCL. This behaviour is useful,
as it allows to have some default values for top-level fields.
However, if the field is a type block or slice (multiple blocks), then the
entire block is overwritten, which erases the existing values. Because of
that, setting default values in nested structs is not possible.
With this commit, decode functions will check if the value is
nil and only then set them to empty struct, which allows for appending
to existing structs.
In case of a slice, either new empty element will be added, or existing
element will be used for setting new value (so values will be merged).
Also, to keep the same behavior as json.Unmarshal, if retained list
have more elements than new list, additional elements will be removed
and existing elements will be merged. This allows to have default values
also for positional elements.
Behavior added by this patch is the same as in json.Unmarshal and
yaml.Unmarshal, which both retain nested structs during unmarshaling
process, so I believe this is an expected behavior from user
perspective.
2019-10-10 16:15:24 +00:00
|
|
|
}{}),
|
2017-05-21 19:44:07 +00:00
|
|
|
func(gotI interface{}) bool {
|
|
|
|
noodles := gotI.(struct {
|
|
|
|
Noodles []struct {
|
2017-09-12 00:29:56 +00:00
|
|
|
Name string `hcl:"name,label"`
|
|
|
|
} `hcl:"noodle,block"`
|
2017-05-21 19:44:07 +00:00
|
|
|
}).Noodles
|
|
|
|
return len(noodles) == 2 && (noodles[0].Name == "foo_foo" || noodles[0].Name == "bar_baz") && (noodles[1].Name == "foo_foo" || noodles[1].Name == "bar_baz") && noodles[0].Name != noodles[1].Name
|
|
|
|
},
|
|
|
|
0,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
map[string]interface{}{
|
|
|
|
"noodle": map[string]interface{}{
|
|
|
|
"foo_foo": map[string]interface{}{
|
|
|
|
"type": "rice",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
gohcl: retain nested blocks while decoding
Currently, if nonzero struct is passed to the DecodeBody function,
decoding process will keep already initialized top-level fields values or
overwrite them, if they are specified in HCL. This behaviour is useful,
as it allows to have some default values for top-level fields.
However, if the field is a type block or slice (multiple blocks), then the
entire block is overwritten, which erases the existing values. Because of
that, setting default values in nested structs is not possible.
With this commit, decode functions will check if the value is
nil and only then set them to empty struct, which allows for appending
to existing structs.
In case of a slice, either new empty element will be added, or existing
element will be used for setting new value (so values will be merged).
Also, to keep the same behavior as json.Unmarshal, if retained list
have more elements than new list, additional elements will be removed
and existing elements will be merged. This allows to have default values
also for positional elements.
Behavior added by this patch is the same as in json.Unmarshal and
yaml.Unmarshal, which both retain nested structs during unmarshaling
process, so I believe this is an expected behavior from user
perspective.
2019-10-10 16:15:24 +00:00
|
|
|
makeInstantiateType(struct {
|
2017-05-21 19:44:07 +00:00
|
|
|
Noodle struct {
|
2017-09-12 00:29:56 +00:00
|
|
|
Name string `hcl:"name,label"`
|
|
|
|
Type string `hcl:"type"`
|
|
|
|
} `hcl:"noodle,block"`
|
gohcl: retain nested blocks while decoding
Currently, if nonzero struct is passed to the DecodeBody function,
decoding process will keep already initialized top-level fields values or
overwrite them, if they are specified in HCL. This behaviour is useful,
as it allows to have some default values for top-level fields.
However, if the field is a type block or slice (multiple blocks), then the
entire block is overwritten, which erases the existing values. Because of
that, setting default values in nested structs is not possible.
With this commit, decode functions will check if the value is
nil and only then set them to empty struct, which allows for appending
to existing structs.
In case of a slice, either new empty element will be added, or existing
element will be used for setting new value (so values will be merged).
Also, to keep the same behavior as json.Unmarshal, if retained list
have more elements than new list, additional elements will be removed
and existing elements will be merged. This allows to have default values
also for positional elements.
Behavior added by this patch is the same as in json.Unmarshal and
yaml.Unmarshal, which both retain nested structs during unmarshaling
process, so I believe this is an expected behavior from user
perspective.
2019-10-10 16:15:24 +00:00
|
|
|
}{}),
|
2017-05-21 19:44:07 +00:00
|
|
|
func(gotI interface{}) bool {
|
|
|
|
noodle := gotI.(struct {
|
|
|
|
Noodle struct {
|
2017-09-12 00:29:56 +00:00
|
|
|
Name string `hcl:"name,label"`
|
|
|
|
Type string `hcl:"type"`
|
|
|
|
} `hcl:"noodle,block"`
|
2017-05-21 19:44:07 +00:00
|
|
|
}).Noodle
|
|
|
|
return noodle.Name == "foo_foo" && noodle.Type == "rice"
|
|
|
|
},
|
|
|
|
0,
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
map[string]interface{}{
|
|
|
|
"name": "Ermintrude",
|
|
|
|
"age": 34,
|
|
|
|
},
|
gohcl: retain nested blocks while decoding
Currently, if nonzero struct is passed to the DecodeBody function,
decoding process will keep already initialized top-level fields values or
overwrite them, if they are specified in HCL. This behaviour is useful,
as it allows to have some default values for top-level fields.
However, if the field is a type block or slice (multiple blocks), then the
entire block is overwritten, which erases the existing values. Because of
that, setting default values in nested structs is not possible.
With this commit, decode functions will check if the value is
nil and only then set them to empty struct, which allows for appending
to existing structs.
In case of a slice, either new empty element will be added, or existing
element will be used for setting new value (so values will be merged).
Also, to keep the same behavior as json.Unmarshal, if retained list
have more elements than new list, additional elements will be removed
and existing elements will be merged. This allows to have default values
also for positional elements.
Behavior added by this patch is the same as in json.Unmarshal and
yaml.Unmarshal, which both retain nested structs during unmarshaling
process, so I believe this is an expected behavior from user
perspective.
2019-10-10 16:15:24 +00:00
|
|
|
makeInstantiateType(map[string]string(nil)),
|
2017-05-21 19:44:07 +00:00
|
|
|
deepEquals(map[string]string{
|
|
|
|
"name": "Ermintrude",
|
|
|
|
"age": "34",
|
|
|
|
}),
|
|
|
|
0,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
map[string]interface{}{
|
|
|
|
"name": "Ermintrude",
|
|
|
|
"age": 89,
|
|
|
|
},
|
gohcl: retain nested blocks while decoding
Currently, if nonzero struct is passed to the DecodeBody function,
decoding process will keep already initialized top-level fields values or
overwrite them, if they are specified in HCL. This behaviour is useful,
as it allows to have some default values for top-level fields.
However, if the field is a type block or slice (multiple blocks), then the
entire block is overwritten, which erases the existing values. Because of
that, setting default values in nested structs is not possible.
With this commit, decode functions will check if the value is
nil and only then set them to empty struct, which allows for appending
to existing structs.
In case of a slice, either new empty element will be added, or existing
element will be used for setting new value (so values will be merged).
Also, to keep the same behavior as json.Unmarshal, if retained list
have more elements than new list, additional elements will be removed
and existing elements will be merged. This allows to have default values
also for positional elements.
Behavior added by this patch is the same as in json.Unmarshal and
yaml.Unmarshal, which both retain nested structs during unmarshaling
process, so I believe this is an expected behavior from user
perspective.
2019-10-10 16:15:24 +00:00
|
|
|
makeInstantiateType(map[string]*hcl.Attribute(nil)),
|
2017-05-21 19:44:07 +00:00
|
|
|
func(gotI interface{}) bool {
|
2017-09-11 23:40:37 +00:00
|
|
|
got := gotI.(map[string]*hcl.Attribute)
|
2017-05-21 19:44:07 +00:00
|
|
|
return len(got) == 2 && got["name"] != nil && got["age"] != nil
|
|
|
|
},
|
|
|
|
0,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
map[string]interface{}{
|
|
|
|
"name": "Ermintrude",
|
|
|
|
"age": 13,
|
|
|
|
},
|
gohcl: retain nested blocks while decoding
Currently, if nonzero struct is passed to the DecodeBody function,
decoding process will keep already initialized top-level fields values or
overwrite them, if they are specified in HCL. This behaviour is useful,
as it allows to have some default values for top-level fields.
However, if the field is a type block or slice (multiple blocks), then the
entire block is overwritten, which erases the existing values. Because of
that, setting default values in nested structs is not possible.
With this commit, decode functions will check if the value is
nil and only then set them to empty struct, which allows for appending
to existing structs.
In case of a slice, either new empty element will be added, or existing
element will be used for setting new value (so values will be merged).
Also, to keep the same behavior as json.Unmarshal, if retained list
have more elements than new list, additional elements will be removed
and existing elements will be merged. This allows to have default values
also for positional elements.
Behavior added by this patch is the same as in json.Unmarshal and
yaml.Unmarshal, which both retain nested structs during unmarshaling
process, so I believe this is an expected behavior from user
perspective.
2019-10-10 16:15:24 +00:00
|
|
|
makeInstantiateType(map[string]hcl.Expression(nil)),
|
2017-05-21 19:44:07 +00:00
|
|
|
func(gotI interface{}) bool {
|
2017-09-11 23:40:37 +00:00
|
|
|
got := gotI.(map[string]hcl.Expression)
|
2017-05-21 19:44:07 +00:00
|
|
|
return len(got) == 2 && got["name"] != nil && got["age"] != nil
|
|
|
|
},
|
|
|
|
0,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
map[string]interface{}{
|
2018-02-27 15:53:20 +00:00
|
|
|
"name": "Ermintrude",
|
|
|
|
"living": true,
|
2017-05-21 19:44:07 +00:00
|
|
|
},
|
gohcl: retain nested blocks while decoding
Currently, if nonzero struct is passed to the DecodeBody function,
decoding process will keep already initialized top-level fields values or
overwrite them, if they are specified in HCL. This behaviour is useful,
as it allows to have some default values for top-level fields.
However, if the field is a type block or slice (multiple blocks), then the
entire block is overwritten, which erases the existing values. Because of
that, setting default values in nested structs is not possible.
With this commit, decode functions will check if the value is
nil and only then set them to empty struct, which allows for appending
to existing structs.
In case of a slice, either new empty element will be added, or existing
element will be used for setting new value (so values will be merged).
Also, to keep the same behavior as json.Unmarshal, if retained list
have more elements than new list, additional elements will be removed
and existing elements will be merged. This allows to have default values
also for positional elements.
Behavior added by this patch is the same as in json.Unmarshal and
yaml.Unmarshal, which both retain nested structs during unmarshaling
process, so I believe this is an expected behavior from user
perspective.
2019-10-10 16:15:24 +00:00
|
|
|
makeInstantiateType(map[string]cty.Value(nil)),
|
2017-05-21 19:44:07 +00:00
|
|
|
deepEquals(map[string]cty.Value{
|
2018-02-27 15:53:20 +00:00
|
|
|
"name": cty.StringVal("Ermintrude"),
|
|
|
|
"living": cty.True,
|
2017-05-21 19:44:07 +00:00
|
|
|
}),
|
|
|
|
0,
|
|
|
|
},
|
gohcl: retain nested blocks while decoding
Currently, if nonzero struct is passed to the DecodeBody function,
decoding process will keep already initialized top-level fields values or
overwrite them, if they are specified in HCL. This behaviour is useful,
as it allows to have some default values for top-level fields.
However, if the field is a type block or slice (multiple blocks), then the
entire block is overwritten, which erases the existing values. Because of
that, setting default values in nested structs is not possible.
With this commit, decode functions will check if the value is
nil and only then set them to empty struct, which allows for appending
to existing structs.
In case of a slice, either new empty element will be added, or existing
element will be used for setting new value (so values will be merged).
Also, to keep the same behavior as json.Unmarshal, if retained list
have more elements than new list, additional elements will be removed
and existing elements will be merged. This allows to have default values
also for positional elements.
Behavior added by this patch is the same as in json.Unmarshal and
yaml.Unmarshal, which both retain nested structs during unmarshaling
process, so I believe this is an expected behavior from user
perspective.
2019-10-10 16:15:24 +00:00
|
|
|
{
|
|
|
|
// Retain "nested" block while decoding
|
|
|
|
map[string]interface{}{
|
|
|
|
"plain": "foo",
|
|
|
|
},
|
|
|
|
func() interface{} {
|
|
|
|
return &withNestedBlock{
|
|
|
|
Plain: "bar",
|
|
|
|
Nested: &withTwoAttributes{
|
|
|
|
A: "bar",
|
|
|
|
},
|
|
|
|
}
|
|
|
|
},
|
|
|
|
func(gotI interface{}) bool {
|
|
|
|
foo := gotI.(withNestedBlock)
|
|
|
|
return foo.Plain == "foo" && foo.Nested != nil && foo.Nested.A == "bar"
|
|
|
|
},
|
|
|
|
0,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
// Retain values in "nested" block while decoding
|
|
|
|
map[string]interface{}{
|
|
|
|
"nested": map[string]interface{}{
|
|
|
|
"a": "foo",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
func() interface{} {
|
|
|
|
return &withNestedBlock{
|
|
|
|
Nested: &withTwoAttributes{
|
|
|
|
B: "bar",
|
|
|
|
},
|
|
|
|
}
|
|
|
|
},
|
|
|
|
func(gotI interface{}) bool {
|
|
|
|
foo := gotI.(withNestedBlock)
|
|
|
|
return foo.Nested.A == "foo" && foo.Nested.B == "bar"
|
|
|
|
},
|
|
|
|
0,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
// Retain values in "nested" block list while decoding
|
|
|
|
map[string]interface{}{
|
|
|
|
"nested": []map[string]interface{}{
|
|
|
|
{
|
|
|
|
"a": "foo",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
func() interface{} {
|
|
|
|
return &withListofNestedBlocks{
|
|
|
|
Nested: []*withTwoAttributes{
|
|
|
|
&withTwoAttributes{
|
|
|
|
B: "bar",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
},
|
|
|
|
func(gotI interface{}) bool {
|
|
|
|
n := gotI.(withListofNestedBlocks)
|
|
|
|
return n.Nested[0].A == "foo" && n.Nested[0].B == "bar"
|
|
|
|
},
|
|
|
|
0,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
// Remove additional elements from the list while decoding nested blocks
|
|
|
|
map[string]interface{}{
|
|
|
|
"nested": []map[string]interface{}{
|
|
|
|
{
|
|
|
|
"a": "foo",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
func() interface{} {
|
|
|
|
return &withListofNestedBlocks{
|
|
|
|
Nested: []*withTwoAttributes{
|
|
|
|
&withTwoAttributes{
|
|
|
|
B: "bar",
|
|
|
|
},
|
|
|
|
&withTwoAttributes{
|
|
|
|
B: "bar",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
},
|
|
|
|
func(gotI interface{}) bool {
|
|
|
|
n := gotI.(withListofNestedBlocks)
|
|
|
|
return len(n.Nested) == 1
|
|
|
|
},
|
|
|
|
0,
|
|
|
|
},
|
2017-05-21 19:44:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
for i, test := range tests {
|
|
|
|
// For convenience here we're going to use the JSON parser
|
|
|
|
// to process the given body.
|
|
|
|
buf, err := json.Marshal(test.Body)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("error JSON-encoding body for test %d: %s", i, err)
|
|
|
|
}
|
|
|
|
|
|
|
|
t.Run(string(buf), func(t *testing.T) {
|
2018-01-27 18:36:15 +00:00
|
|
|
file, diags := hclJSON.Parse(buf, "test.json")
|
2017-05-21 19:44:07 +00:00
|
|
|
if len(diags) != 0 {
|
|
|
|
t.Fatalf("diagnostics while parsing: %s", diags.Error())
|
|
|
|
}
|
|
|
|
|
gohcl: retain nested blocks while decoding
Currently, if nonzero struct is passed to the DecodeBody function,
decoding process will keep already initialized top-level fields values or
overwrite them, if they are specified in HCL. This behaviour is useful,
as it allows to have some default values for top-level fields.
However, if the field is a type block or slice (multiple blocks), then the
entire block is overwritten, which erases the existing values. Because of
that, setting default values in nested structs is not possible.
With this commit, decode functions will check if the value is
nil and only then set them to empty struct, which allows for appending
to existing structs.
In case of a slice, either new empty element will be added, or existing
element will be used for setting new value (so values will be merged).
Also, to keep the same behavior as json.Unmarshal, if retained list
have more elements than new list, additional elements will be removed
and existing elements will be merged. This allows to have default values
also for positional elements.
Behavior added by this patch is the same as in json.Unmarshal and
yaml.Unmarshal, which both retain nested structs during unmarshaling
process, so I believe this is an expected behavior from user
perspective.
2019-10-10 16:15:24 +00:00
|
|
|
targetVal := reflect.ValueOf(test.Target())
|
2017-05-21 19:44:07 +00:00
|
|
|
|
|
|
|
diags = DecodeBody(file.Body, nil, targetVal.Interface())
|
|
|
|
if len(diags) != test.DiagCount {
|
|
|
|
t.Errorf("wrong number of diagnostics %d; want %d", len(diags), test.DiagCount)
|
|
|
|
for _, diag := range diags {
|
|
|
|
t.Logf(" - %s", diag.Error())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
got := targetVal.Elem().Interface()
|
|
|
|
if !test.Check(got) {
|
|
|
|
t.Errorf("wrong result\ngot: %s", spew.Sdump(got))
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2017-05-21 15:47:05 +00:00
|
|
|
func TestDecodeExpression(t *testing.T) {
|
|
|
|
tests := []struct {
|
|
|
|
Value cty.Value
|
|
|
|
Target interface{}
|
|
|
|
Want interface{}
|
|
|
|
DiagCount int
|
|
|
|
}{
|
|
|
|
{
|
|
|
|
cty.StringVal("hello"),
|
|
|
|
"",
|
|
|
|
"hello",
|
|
|
|
0,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
cty.StringVal("hello"),
|
|
|
|
cty.NilVal,
|
|
|
|
cty.StringVal("hello"),
|
|
|
|
0,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
cty.NumberIntVal(2),
|
|
|
|
"",
|
|
|
|
"2",
|
|
|
|
0,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
cty.StringVal("true"),
|
|
|
|
false,
|
|
|
|
true,
|
|
|
|
0,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
cty.NullVal(cty.String),
|
|
|
|
"",
|
|
|
|
"",
|
|
|
|
1, // null value is not allowed
|
|
|
|
},
|
|
|
|
{
|
|
|
|
cty.UnknownVal(cty.String),
|
|
|
|
"",
|
|
|
|
"",
|
|
|
|
1, // value must be known
|
|
|
|
},
|
|
|
|
{
|
|
|
|
cty.ListVal([]cty.Value{cty.True}),
|
|
|
|
false,
|
|
|
|
false,
|
|
|
|
1, // bool required
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
for i, test := range tests {
|
|
|
|
t.Run(fmt.Sprintf("%02d", i), func(t *testing.T) {
|
|
|
|
expr := &fixedExpression{test.Value}
|
|
|
|
|
|
|
|
targetVal := reflect.New(reflect.TypeOf(test.Target))
|
|
|
|
|
|
|
|
diags := DecodeExpression(expr, nil, targetVal.Interface())
|
|
|
|
if len(diags) != test.DiagCount {
|
|
|
|
t.Errorf("wrong number of diagnostics %d; want %d", len(diags), test.DiagCount)
|
|
|
|
for _, diag := range diags {
|
|
|
|
t.Logf(" - %s", diag.Error())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
got := targetVal.Elem().Interface()
|
|
|
|
if !reflect.DeepEqual(got, test.Want) {
|
|
|
|
t.Errorf("wrong result\ngot: %#v\nwant: %#v", got, test.Want)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
type fixedExpression struct {
|
|
|
|
val cty.Value
|
|
|
|
}
|
|
|
|
|
2017-09-11 23:40:37 +00:00
|
|
|
func (e *fixedExpression) Value(ctx *hcl.EvalContext) (cty.Value, hcl.Diagnostics) {
|
2017-05-21 15:47:05 +00:00
|
|
|
return e.val, nil
|
|
|
|
}
|
|
|
|
|
2017-09-11 23:40:37 +00:00
|
|
|
func (e *fixedExpression) Range() (r hcl.Range) {
|
2017-05-21 15:47:05 +00:00
|
|
|
return
|
|
|
|
}
|
2017-09-11 23:40:37 +00:00
|
|
|
func (e *fixedExpression) StartRange() (r hcl.Range) {
|
2017-05-21 15:47:05 +00:00
|
|
|
return
|
|
|
|
}
|
2017-05-23 01:54:23 +00:00
|
|
|
|
2017-09-11 23:40:37 +00:00
|
|
|
func (e *fixedExpression) Variables() []hcl.Traversal {
|
2017-05-23 01:54:23 +00:00
|
|
|
return nil
|
|
|
|
}
|
gohcl: retain nested blocks while decoding
Currently, if nonzero struct is passed to the DecodeBody function,
decoding process will keep already initialized top-level fields values or
overwrite them, if they are specified in HCL. This behaviour is useful,
as it allows to have some default values for top-level fields.
However, if the field is a type block or slice (multiple blocks), then the
entire block is overwritten, which erases the existing values. Because of
that, setting default values in nested structs is not possible.
With this commit, decode functions will check if the value is
nil and only then set them to empty struct, which allows for appending
to existing structs.
In case of a slice, either new empty element will be added, or existing
element will be used for setting new value (so values will be merged).
Also, to keep the same behavior as json.Unmarshal, if retained list
have more elements than new list, additional elements will be removed
and existing elements will be merged. This allows to have default values
also for positional elements.
Behavior added by this patch is the same as in json.Unmarshal and
yaml.Unmarshal, which both retain nested structs during unmarshaling
process, so I believe this is an expected behavior from user
perspective.
2019-10-10 16:15:24 +00:00
|
|
|
|
|
|
|
func makeInstantiateType(target interface{}) func() interface{} {
|
|
|
|
return func() interface{} {
|
|
|
|
return reflect.New(reflect.TypeOf(target)).Interface()
|
|
|
|
}
|
|
|
|
}
|