blob: 393631c1d06489875ccffcb7c5823982363b0c9a [file] [log] [blame]
Colin Cross8e0c5112015-01-23 14:15:10 -08001// Copyright 2014 Google Inc. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
Jamie Gennis1bc967e2014-05-27 16:34:41 -070015package blueprint
16
17import (
Jamie Gennis1bc967e2014-05-27 16:34:41 -070018 "bytes"
Colin Cross4adc8192015-06-22 13:38:45 -070019 "fmt"
Jamie Gennis1bc967e2014-05-27 16:34:41 -070020 "reflect"
21 "testing"
Colin Cross4adc8192015-06-22 13:38:45 -070022 "text/scanner"
23
24 "github.com/google/blueprint/parser"
25 "github.com/google/blueprint/proptools"
Jamie Gennis1bc967e2014-05-27 16:34:41 -070026)
27
28var validUnpackTestCases = []struct {
29 input string
30 output interface{}
Colin Cross4adc8192015-06-22 13:38:45 -070031 errs []error
Jamie Gennis1bc967e2014-05-27 16:34:41 -070032}{
33 {`
34 m {
35 name: "abc",
36 }
37 `,
38 struct {
39 Name string
40 }{
41 Name: "abc",
42 },
Colin Cross4adc8192015-06-22 13:38:45 -070043 nil,
Jamie Gennis1bc967e2014-05-27 16:34:41 -070044 },
45
46 {`
47 m {
48 isGood: true,
49 }
50 `,
51 struct {
52 IsGood bool
53 }{
54 IsGood: true,
55 },
Colin Cross4adc8192015-06-22 13:38:45 -070056 nil,
Jamie Gennis1bc967e2014-05-27 16:34:41 -070057 },
58
59 {`
60 m {
61 stuff: ["asdf", "jkl;", "qwert",
62 "uiop", "bnm,"]
63 }
64 `,
65 struct {
66 Stuff []string
67 }{
68 Stuff: []string{"asdf", "jkl;", "qwert", "uiop", "bnm,"},
69 },
Colin Cross4adc8192015-06-22 13:38:45 -070070 nil,
Jamie Gennis1bc967e2014-05-27 16:34:41 -070071 },
72
73 {`
74 m {
Jamie Gennis87622922014-09-30 11:38:25 -070075 nested: {
76 name: "abc",
77 }
Jamie Gennis1bc967e2014-05-27 16:34:41 -070078 }
79 `,
80 struct {
81 Nested struct {
82 Name string
83 }
84 }{
85 Nested: struct{ Name string }{
86 Name: "abc",
87 },
88 },
Colin Cross4adc8192015-06-22 13:38:45 -070089 nil,
Jamie Gennis1bc967e2014-05-27 16:34:41 -070090 },
91
92 {`
93 m {
Jamie Gennis87622922014-09-30 11:38:25 -070094 nested: {
95 name: "def",
96 }
97 }
98 `,
99 struct {
100 Nested interface{}
101 }{
102 Nested: &struct{ Name string }{
103 Name: "def",
104 },
105 },
Colin Cross4adc8192015-06-22 13:38:45 -0700106 nil,
Jamie Gennis87622922014-09-30 11:38:25 -0700107 },
108
109 {`
110 m {
111 nested: {
112 foo: "abc",
113 },
Jamie Gennis1bc967e2014-05-27 16:34:41 -0700114 bar: false,
115 baz: ["def", "ghi"],
116 }
117 `,
118 struct {
119 Nested struct {
120 Foo string
121 }
122 Bar bool
123 Baz []string
124 }{
125 Nested: struct{ Foo string }{
126 Foo: "abc",
127 },
128 Bar: false,
129 Baz: []string{"def", "ghi"},
130 },
Colin Cross4adc8192015-06-22 13:38:45 -0700131 nil,
132 },
133
134 {`
135 m {
136 nested: {
137 foo: "abc",
138 },
139 bar: false,
140 baz: ["def", "ghi"],
141 }
142 `,
143 struct {
144 Nested struct {
145 Foo string `allowNested:"true"`
146 } `blueprint:"filter(allowNested:\"true\")"`
147 Bar bool
148 Baz []string
149 }{
150 Nested: struct {
151 Foo string `allowNested:"true"`
152 }{
153 Foo: "abc",
154 },
155 Bar: false,
156 Baz: []string{"def", "ghi"},
157 },
158 nil,
159 },
160
161 {`
162 m {
163 nested: {
164 foo: "abc",
165 },
166 bar: false,
167 baz: ["def", "ghi"],
168 }
169 `,
170 struct {
171 Nested struct {
172 Foo string
173 } `blueprint:"filter(allowNested:\"true\")"`
174 Bar bool
175 Baz []string
176 }{
177 Nested: struct{ Foo string }{
178 Foo: "",
179 },
180 Bar: false,
181 Baz: []string{"def", "ghi"},
182 },
183 []error{
184 &Error{
185 Err: fmt.Errorf("filtered field nested.foo cannot be set in a Blueprint file"),
186 Pos: scanner.Position{"", 27, 4, 8},
187 },
188 },
Jamie Gennis1bc967e2014-05-27 16:34:41 -0700189 },
190}
191
192func TestUnpackProperties(t *testing.T) {
193 for _, testCase := range validUnpackTestCases {
194 r := bytes.NewBufferString(testCase.input)
Colin Crossd1facc12015-01-08 14:56:03 -0800195 file, errs := parser.Parse("", r, nil)
Jamie Gennis1bc967e2014-05-27 16:34:41 -0700196 if len(errs) != 0 {
197 t.Errorf("test case: %s", testCase.input)
198 t.Errorf("unexpected parse errors:")
199 for _, err := range errs {
200 t.Errorf(" %s", err)
201 }
202 t.FailNow()
203 }
204
Colin Crossd1facc12015-01-08 14:56:03 -0800205 module := file.Defs[0].(*parser.Module)
Jamie Gennis87622922014-09-30 11:38:25 -0700206 properties := proptools.CloneProperties(reflect.ValueOf(testCase.output))
207 proptools.ZeroProperties(properties.Elem())
208 _, errs = unpackProperties(module.Properties, properties.Interface())
Colin Cross4adc8192015-06-22 13:38:45 -0700209 if len(errs) != 0 && len(testCase.errs) == 0 {
Jamie Gennis1bc967e2014-05-27 16:34:41 -0700210 t.Errorf("test case: %s", testCase.input)
211 t.Errorf("unexpected unpack errors:")
212 for _, err := range errs {
213 t.Errorf(" %s", err)
214 }
215 t.FailNow()
Colin Cross4adc8192015-06-22 13:38:45 -0700216 } else if !reflect.DeepEqual(errs, testCase.errs) {
217 t.Errorf("test case: %s", testCase.input)
218 t.Errorf("incorrect errors:")
219 t.Errorf(" expected: %+v", testCase.errs)
220 t.Errorf(" got: %+v", errs)
Jamie Gennis1bc967e2014-05-27 16:34:41 -0700221 }
222
223 output := properties.Elem().Interface()
224 if !reflect.DeepEqual(output, testCase.output) {
225 t.Errorf("test case: %s", testCase.input)
226 t.Errorf("incorrect output:")
227 t.Errorf(" expected: %+v", testCase.output)
228 t.Errorf(" got: %+v", output)
229 }
230 }
231}