From de4d9f94ac235bfe9d809733c19059841ba6b090 Mon Sep 17 00:00:00 2001 From: Sasha Smundak Date: Tue, 3 Mar 2020 17:36:00 -0800 Subject: [PATCH] Fix bug in buildPropertyMap in previous commit. Property value should be evaluated before proeprty map is populated with it. Added the test for this case. --- proptools/unpack.go | 50 ++++++++++++++++++++-------------------- proptools/unpack_test.go | 16 ++++++++++--- 2 files changed, 38 insertions(+), 28 deletions(-) diff --git a/proptools/unpack.go b/proptools/unpack.go index 8dc9ca8..4a0858c 100644 --- a/proptools/unpack.go +++ b/proptools/unpack.go @@ -136,32 +136,32 @@ func (ctx *unpackContext) buildPropertyMap(prefix string, properties []*parser.P } ctx.propertyMap[name] = &packedProperty{property, false} - if structProperty, ok := property.Value.(*parser.Map); ok { - ctx.buildPropertyMap(name, structProperty.Properties) - } - - // If it is a list, unroll it unless its elements are of primitive type - // (no further mapping will be needed in that case, so we avoid cluttering - // the map). - listExpr, ok := property.Value.Eval().(*parser.List) - if !ok || len(listExpr.Values) == 0 { - continue - } - if t := listExpr.Values[0].Eval().Type(); t == parser.StringType || t == parser.Int64Type || t == parser.BoolType { - continue - } - - itemProperties := make([]*parser.Property, len(listExpr.Values), len(listExpr.Values)) - for i, expr := range listExpr.Values { - itemProperties[i] = &parser.Property{ - Name: property.Name + "[" + strconv.Itoa(i) + "]", - NamePos: property.NamePos, - ColonPos: property.ColonPos, - Value: expr, + switch propValue := property.Value.Eval().(type) { + case *parser.Map: + ctx.buildPropertyMap(name, propValue.Properties) + case *parser.List: + // If it is a list, unroll it unless its elements are of primitive type + // (no further mapping will be needed in that case, so we avoid cluttering + // the map). + if len(propValue.Values) == 0 { + continue + } + if t := propValue.Values[0].Type(); t == parser.StringType || t == parser.Int64Type || t == parser.BoolType { + continue + } + + itemProperties := make([]*parser.Property, len(propValue.Values), len(propValue.Values)) + for i, expr := range propValue.Values { + itemProperties[i] = &parser.Property{ + Name: property.Name + "[" + strconv.Itoa(i) + "]", + NamePos: property.NamePos, + ColonPos: property.ColonPos, + Value: expr, + } + } + if !ctx.buildPropertyMap(prefix, itemProperties) { + return false } - } - if !ctx.buildPropertyMap(prefix, itemProperties) { - return false } } diff --git a/proptools/unpack_test.go b/proptools/unpack_test.go index 54ec01a..6a4d7b4 100644 --- a/proptools/unpack_test.go +++ b/proptools/unpack_test.go @@ -496,21 +496,31 @@ var validUnpackTestCases = []struct { list = ["abc"] string = "def" list_with_variable = [string] + struct_value = { name: "foo" } m { s: string, list: list, list2: list_with_variable, + structattr: struct_value, } `, output: []interface{}{ &struct { - S string - List []string - List2 []string + S string + List []string + List2 []string + Structattr struct { + Name string + } }{ S: "def", List: []string{"abc"}, List2: []string{"def"}, + Structattr: struct { + Name string + }{ + Name: "foo", + }, }, }, },