This fixes a bug in the flattener so that objects are flattened as one list object

This commit is contained in:
Sander van Harmelen 2015-11-19 17:37:23 +01:00
parent 2deb1d1db2
commit 2f117c801c
2 changed files with 67 additions and 26 deletions

View File

@ -1,8 +1,6 @@
package parser
import (
"github.com/hashicorp/hcl/hcl/ast"
)
import "github.com/hashicorp/hcl/hcl/ast"
// flattenObjects takes an AST node, walks it, and flattens
func flattenObjects(node ast.Node) {
@ -60,25 +58,14 @@ func flattenListType(
// Great! We have a match go through all the items and flatten
for _, elem := range ot.List {
// This won't fail since we verified it earlier
ot := elem.(*ast.ObjectType)
// Go over all the subitems and merge them in
for _, subitem := range ot.List.Items {
// Copy the new key
keys := make([]*ast.ObjectKey, len(item.Keys)+len(subitem.Keys))
copy(keys, item.Keys)
copy(keys[len(item.Keys):], subitem.Keys)
// Add it to the frontier so that we can recurse
frontier = append(frontier, &ast.ObjectItem{
Keys: keys,
Assign: item.Assign,
Val: subitem.Val,
LeadComment: item.LeadComment,
LineComment: item.LineComment,
})
}
// Add it to the frontier so that we can recurse
frontier = append(frontier, &ast.ObjectItem{
Keys: item.Keys,
Assign: item.Assign,
Val: elem,
LeadComment: item.LeadComment,
LineComment: item.LineComment,
})
}
return items, frontier

View File

@ -178,6 +178,60 @@ func TestObjectType(t *testing.T) {
}
}
func TestFlattenObjects(t *testing.T) {
var literals = []struct {
src string
nodeType []ast.Node
}{
{
`{
"foo": [
{
"foo": "svh",
"bar": "fatih"
}
]
}`,
[]ast.Node{
&ast.ObjectType{},
&ast.LiteralType{},
&ast.LiteralType{},
&ast.ListType{},
},
},
}
for _, l := range literals {
t.Logf("Testing:\n%s\n", l.src)
f, err := Parse([]byte(l.src))
if err != nil {
t.Error(err)
}
// the first object is always an ObjectList so just assert that one
// so we can use it as such
obj, ok := f.Node.(*ast.ObjectList)
if !ok {
t.Errorf("node should be *ast.ObjectList, got: %T", f.Node)
}
// check if the types are correct
var i int
for _, item := range obj.Items {
equals(t, reflect.TypeOf(l.nodeType[i]), reflect.TypeOf(item.Val))
i++
if obj, ok := item.Val.(*ast.ObjectType); ok {
for _, item := range obj.List.Items {
equals(t, reflect.TypeOf(l.nodeType[i]), reflect.TypeOf(item.Val))
i++
}
}
}
}
}
func TestObjectKey(t *testing.T) {
keys := []struct {
exp []token.Type
@ -225,6 +279,10 @@ func TestParse(t *testing.T) {
Name string
Err bool
}{
{
"array.json",
false,
},
{
"basic.json",
false,
@ -233,10 +291,6 @@ func TestParse(t *testing.T) {
"object.json",
false,
},
{
"array.json",
false,
},
{
"types.json",
false,