blob: fb0e1899da814eb58844acec0af6a5b472796ee5 [file] [log] [blame]
Colin Cross9d34f352019-11-22 16:03:51 -08001// Copyright 2020 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
15package soongconfig
16
17import (
18 "reflect"
19 "testing"
Liz Kammerfe8853d2020-12-16 09:34:33 -080020
21 "github.com/google/blueprint/proptools"
Colin Cross9d34f352019-11-22 16:03:51 -080022)
23
24func Test_CanonicalizeToProperty(t *testing.T) {
25 tests := []struct {
26 name string
27 arg string
28 want string
29 }{
30 {
31 name: "lowercase",
32 arg: "board",
33 want: "board",
34 },
35 {
36 name: "uppercase",
37 arg: "BOARD",
38 want: "BOARD",
39 },
40 {
41 name: "numbers",
42 arg: "BOARD123",
43 want: "BOARD123",
44 },
45 {
46 name: "underscore",
47 arg: "TARGET_BOARD",
48 want: "TARGET_BOARD",
49 },
50 {
51 name: "dash",
52 arg: "TARGET-BOARD",
53 want: "TARGET_BOARD",
54 },
55 {
56 name: "unicode",
57 arg: "boardĪ»",
58 want: "board_",
59 },
60 }
61 for _, tt := range tests {
62 t.Run(tt.name, func(t *testing.T) {
63 if got := CanonicalizeToProperty(tt.arg); got != tt.want {
64 t.Errorf("canonicalizeToProperty() = %v, want %v", got, tt.want)
65 }
66 })
67 }
68}
69
70func Test_typeForPropertyFromPropertyStruct(t *testing.T) {
71 tests := []struct {
72 name string
73 ps interface{}
74 property string
75 want string
76 }{
77 {
78 name: "string",
79 ps: struct {
80 A string
81 }{},
82 property: "a",
83 want: "string",
84 },
85 {
86 name: "list",
87 ps: struct {
88 A []string
89 }{},
90 property: "a",
91 want: "[]string",
92 },
93 {
94 name: "missing",
95 ps: struct {
96 A []string
97 }{},
98 property: "b",
99 want: "",
100 },
101 {
102 name: "nested",
103 ps: struct {
104 A struct {
105 B string
106 }
107 }{},
108 property: "a.b",
109 want: "string",
110 },
111 {
112 name: "missing nested",
113 ps: struct {
114 A struct {
115 B string
116 }
117 }{},
118 property: "a.c",
119 want: "",
120 },
121 {
122 name: "not a struct",
123 ps: struct {
124 A string
125 }{},
126 property: "a.b",
127 want: "",
128 },
129 {
130 name: "nested pointer",
131 ps: struct {
132 A *struct {
133 B string
134 }
135 }{},
136 property: "a.b",
137 want: "string",
138 },
139 {
140 name: "nested interface",
141 ps: struct {
142 A interface{}
143 }{
144 A: struct {
145 B string
146 }{},
147 },
148 property: "a.b",
149 want: "string",
150 },
151 {
152 name: "nested interface pointer",
153 ps: struct {
154 A interface{}
155 }{
156 A: &struct {
157 B string
158 }{},
159 },
160 property: "a.b",
161 want: "string",
162 },
163 {
164 name: "nested interface nil pointer",
165 ps: struct {
166 A interface{}
167 }{
168 A: (*struct {
169 B string
170 })(nil),
171 },
172 property: "a.b",
173 want: "string",
174 },
175 }
176 for _, tt := range tests {
177 t.Run(tt.name, func(t *testing.T) {
178 typ := typeForPropertyFromPropertyStruct(tt.ps, tt.property)
179 got := ""
180 if typ != nil {
181 got = typ.String()
182 }
183 if got != tt.want {
184 t.Errorf("typeForPropertyFromPropertyStruct() = %v, want %v", got, tt.want)
185 }
186 })
187 }
188}
189
190func Test_createAffectablePropertiesType(t *testing.T) {
Colin Cross9d34f352019-11-22 16:03:51 -0800191 tests := []struct {
192 name string
193 affectableProperties []string
194 factoryProps interface{}
195 want string
196 }{
197 {
198 name: "string",
199 affectableProperties: []string{"cflags"},
200 factoryProps: struct {
201 Cflags string
202 }{},
203 want: "*struct { Cflags string }",
204 },
205 {
206 name: "list",
207 affectableProperties: []string{"cflags"},
208 factoryProps: struct {
209 Cflags []string
210 }{},
211 want: "*struct { Cflags []string }",
212 },
213 {
214 name: "string pointer",
215 affectableProperties: []string{"cflags"},
216 factoryProps: struct {
217 Cflags *string
218 }{},
219 want: "*struct { Cflags *string }",
220 },
221 {
222 name: "subset",
223 affectableProperties: []string{"cflags"},
224 factoryProps: struct {
225 Cflags string
226 Ldflags string
227 }{},
228 want: "*struct { Cflags string }",
229 },
230 {
231 name: "none",
232 affectableProperties: []string{"cflags"},
233 factoryProps: struct {
234 Ldflags string
235 }{},
236 want: "",
237 },
238 }
239 for _, tt := range tests {
240 t.Run(tt.name, func(t *testing.T) {
241 typ := createAffectablePropertiesType(tt.affectableProperties, []interface{}{tt.factoryProps})
242 got := ""
243 if typ != nil {
244 got = typ.String()
245 }
246 if !reflect.DeepEqual(got, tt.want) {
247 t.Errorf("createAffectablePropertiesType() = %v, want %v", got, tt.want)
248 }
249 })
250 }
251}
Liz Kammerfe8853d2020-12-16 09:34:33 -0800252
253type properties struct {
254 A *string
255 B bool
256}
257type soongConfigVariables struct {
258 Bool_var properties
259 Other_bool_var properties
260}
261
262type soongConfigProps struct {
263 Soong_config_variables soongConfigVariables
264}
265
266func Test_PropertiesToApply(t *testing.T) {
267
268 mt := &ModuleType{
269 BaseModuleType: "foo",
270 ConfigNamespace: "bar",
271 Variables: []soongConfigVariable{
272 newBoolVariable("bool_var"),
273 newBoolVariable("other_bool_var"),
274 },
275 affectableProperties: []string{
276 "a",
277 "b",
278 },
279 }
280 props := soongConfigProps{
281 Soong_config_variables: soongConfigVariables{
282 Bool_var: properties{
283 A: proptools.StringPtr("a"),
284 B: true,
285 },
286 Other_bool_var: properties{
287 A: proptools.StringPtr("other"),
288 B: false,
289 },
290 },
291 }
292
293 testCases := []struct {
294 config SoongConfig
295 wantProps []interface{}
296 }{
297 {
298 config: Config(map[string]string{}),
299 },
300 {
301 config: Config(map[string]string{"bool_var": "y"}),
302 wantProps: []interface{}{props.Soong_config_variables.Bool_var},
303 },
304 {
305 config: Config(map[string]string{"other_bool_var": "y"}),
306 wantProps: []interface{}{props.Soong_config_variables.Other_bool_var},
307 },
308 }
309
310 for _, tc := range testCases {
311 gotProps, err := PropertiesToApply(mt, reflect.ValueOf(&props), tc.config)
312 if err != nil {
313 t.Errorf("Unexpected error in PropertiesToApply: %s", err)
314 }
315
316 if !reflect.DeepEqual(gotProps, tc.wantProps) {
317 t.Errorf("Expected %s, got %s", tc.wantProps, gotProps)
318 }
319 }
320}