xref: /aosp_15_r20/build/soong/androidmk/parser/make_strings_test.go (revision 333d2b3687b3a337dbcca9d65000bca186795e39)
1*333d2b36SAndroid Build Coastguard Worker// Copyright 2017 Google Inc. All rights reserved.
2*333d2b36SAndroid Build Coastguard Worker//
3*333d2b36SAndroid Build Coastguard Worker// Licensed under the Apache License, Version 2.0 (the "License");
4*333d2b36SAndroid Build Coastguard Worker// you may not use this file except in compliance with the License.
5*333d2b36SAndroid Build Coastguard Worker// You may obtain a copy of the License at
6*333d2b36SAndroid Build Coastguard Worker//
7*333d2b36SAndroid Build Coastguard Worker//     http://www.apache.org/licenses/LICENSE-2.0
8*333d2b36SAndroid Build Coastguard Worker//
9*333d2b36SAndroid Build Coastguard Worker// Unless required by applicable law or agreed to in writing, software
10*333d2b36SAndroid Build Coastguard Worker// distributed under the License is distributed on an "AS IS" BASIS,
11*333d2b36SAndroid Build Coastguard Worker// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*333d2b36SAndroid Build Coastguard Worker// See the License for the specific language governing permissions and
13*333d2b36SAndroid Build Coastguard Worker// limitations under the License.
14*333d2b36SAndroid Build Coastguard Worker
15*333d2b36SAndroid Build Coastguard Workerpackage parser
16*333d2b36SAndroid Build Coastguard Worker
17*333d2b36SAndroid Build Coastguard Workerimport (
18*333d2b36SAndroid Build Coastguard Worker	"strings"
19*333d2b36SAndroid Build Coastguard Worker	"testing"
20*333d2b36SAndroid Build Coastguard Worker)
21*333d2b36SAndroid Build Coastguard Worker
22*333d2b36SAndroid Build Coastguard Workervar splitNTestCases = []struct {
23*333d2b36SAndroid Build Coastguard Worker	in       *MakeString
24*333d2b36SAndroid Build Coastguard Worker	expected []*MakeString
25*333d2b36SAndroid Build Coastguard Worker	sep      string
26*333d2b36SAndroid Build Coastguard Worker	n        int
27*333d2b36SAndroid Build Coastguard Worker}{
28*333d2b36SAndroid Build Coastguard Worker	{
29*333d2b36SAndroid Build Coastguard Worker		// "a b c$(var1)d e f$(var2) h i j"
30*333d2b36SAndroid Build Coastguard Worker		in:  genMakeString("a b c", "var1", "d e f", "var2", " h i j"),
31*333d2b36SAndroid Build Coastguard Worker		sep: " ",
32*333d2b36SAndroid Build Coastguard Worker		n:   -1,
33*333d2b36SAndroid Build Coastguard Worker		expected: []*MakeString{
34*333d2b36SAndroid Build Coastguard Worker			genMakeString("a"),
35*333d2b36SAndroid Build Coastguard Worker			genMakeString("b"),
36*333d2b36SAndroid Build Coastguard Worker			genMakeString("c", "var1", "d"),
37*333d2b36SAndroid Build Coastguard Worker			genMakeString("e"),
38*333d2b36SAndroid Build Coastguard Worker			genMakeString("f", "var2", ""),
39*333d2b36SAndroid Build Coastguard Worker			genMakeString("h"),
40*333d2b36SAndroid Build Coastguard Worker			genMakeString("i"),
41*333d2b36SAndroid Build Coastguard Worker			genMakeString("j"),
42*333d2b36SAndroid Build Coastguard Worker		},
43*333d2b36SAndroid Build Coastguard Worker	},
44*333d2b36SAndroid Build Coastguard Worker	{
45*333d2b36SAndroid Build Coastguard Worker		// "a b c$(var1)d e f$(var2) h i j"
46*333d2b36SAndroid Build Coastguard Worker		in:  genMakeString("a b c", "var1", "d e f", "var2", " h i j"),
47*333d2b36SAndroid Build Coastguard Worker		sep: " ",
48*333d2b36SAndroid Build Coastguard Worker		n:   3,
49*333d2b36SAndroid Build Coastguard Worker		expected: []*MakeString{
50*333d2b36SAndroid Build Coastguard Worker			genMakeString("a"),
51*333d2b36SAndroid Build Coastguard Worker			genMakeString("b"),
52*333d2b36SAndroid Build Coastguard Worker			genMakeString("c", "var1", "d e f", "var2", " h i j"),
53*333d2b36SAndroid Build Coastguard Worker		},
54*333d2b36SAndroid Build Coastguard Worker	},
55*333d2b36SAndroid Build Coastguard Worker	{
56*333d2b36SAndroid Build Coastguard Worker		// "$(var1) $(var2)"
57*333d2b36SAndroid Build Coastguard Worker		in:  genMakeString("", "var1", " ", "var2", ""),
58*333d2b36SAndroid Build Coastguard Worker		sep: " ",
59*333d2b36SAndroid Build Coastguard Worker		n:   -1,
60*333d2b36SAndroid Build Coastguard Worker		expected: []*MakeString{
61*333d2b36SAndroid Build Coastguard Worker			genMakeString("", "var1", ""),
62*333d2b36SAndroid Build Coastguard Worker			genMakeString("", "var2", ""),
63*333d2b36SAndroid Build Coastguard Worker		},
64*333d2b36SAndroid Build Coastguard Worker	},
65*333d2b36SAndroid Build Coastguard Worker	{
66*333d2b36SAndroid Build Coastguard Worker		// "a,,b,c,"
67*333d2b36SAndroid Build Coastguard Worker		in:  genMakeString("a,,b,c,"),
68*333d2b36SAndroid Build Coastguard Worker		sep: ",",
69*333d2b36SAndroid Build Coastguard Worker		n:   -1,
70*333d2b36SAndroid Build Coastguard Worker		expected: []*MakeString{
71*333d2b36SAndroid Build Coastguard Worker			genMakeString("a"),
72*333d2b36SAndroid Build Coastguard Worker			genMakeString(""),
73*333d2b36SAndroid Build Coastguard Worker			genMakeString("b"),
74*333d2b36SAndroid Build Coastguard Worker			genMakeString("c"),
75*333d2b36SAndroid Build Coastguard Worker			genMakeString(""),
76*333d2b36SAndroid Build Coastguard Worker		},
77*333d2b36SAndroid Build Coastguard Worker	},
78*333d2b36SAndroid Build Coastguard Worker	{
79*333d2b36SAndroid Build Coastguard Worker		// "x$(var1)y bar"
80*333d2b36SAndroid Build Coastguard Worker		in:  genMakeString("x", "var1", "y bar"),
81*333d2b36SAndroid Build Coastguard Worker		sep: " ",
82*333d2b36SAndroid Build Coastguard Worker		n:   2,
83*333d2b36SAndroid Build Coastguard Worker		expected: []*MakeString{
84*333d2b36SAndroid Build Coastguard Worker			genMakeString("x", "var1", "y"),
85*333d2b36SAndroid Build Coastguard Worker			genMakeString("bar"),
86*333d2b36SAndroid Build Coastguard Worker		},
87*333d2b36SAndroid Build Coastguard Worker	},
88*333d2b36SAndroid Build Coastguard Worker}
89*333d2b36SAndroid Build Coastguard Worker
90*333d2b36SAndroid Build Coastguard Workerfunc TestMakeStringSplitN(t *testing.T) {
91*333d2b36SAndroid Build Coastguard Worker	for _, test := range splitNTestCases {
92*333d2b36SAndroid Build Coastguard Worker		got := test.in.SplitN(test.sep, test.n)
93*333d2b36SAndroid Build Coastguard Worker		gotString := dumpArray(got)
94*333d2b36SAndroid Build Coastguard Worker		expectedString := dumpArray(test.expected)
95*333d2b36SAndroid Build Coastguard Worker		if gotString != expectedString {
96*333d2b36SAndroid Build Coastguard Worker			t.Errorf("expected:\n%s\ngot:\n%s", expectedString, gotString)
97*333d2b36SAndroid Build Coastguard Worker		}
98*333d2b36SAndroid Build Coastguard Worker	}
99*333d2b36SAndroid Build Coastguard Worker}
100*333d2b36SAndroid Build Coastguard Worker
101*333d2b36SAndroid Build Coastguard Workervar valueTestCases = []struct {
102*333d2b36SAndroid Build Coastguard Worker	in       *MakeString
103*333d2b36SAndroid Build Coastguard Worker	expected string
104*333d2b36SAndroid Build Coastguard Worker}{
105*333d2b36SAndroid Build Coastguard Worker	{
106*333d2b36SAndroid Build Coastguard Worker		in:       genMakeString("a b"),
107*333d2b36SAndroid Build Coastguard Worker		expected: "a b",
108*333d2b36SAndroid Build Coastguard Worker	},
109*333d2b36SAndroid Build Coastguard Worker	{
110*333d2b36SAndroid Build Coastguard Worker		in:       genMakeString("a\\ \\\tb\\\\"),
111*333d2b36SAndroid Build Coastguard Worker		expected: "a \tb\\",
112*333d2b36SAndroid Build Coastguard Worker	},
113*333d2b36SAndroid Build Coastguard Worker	{
114*333d2b36SAndroid Build Coastguard Worker		in:       genMakeString("a\\b\\"),
115*333d2b36SAndroid Build Coastguard Worker		expected: "a\\b\\",
116*333d2b36SAndroid Build Coastguard Worker	},
117*333d2b36SAndroid Build Coastguard Worker}
118*333d2b36SAndroid Build Coastguard Worker
119*333d2b36SAndroid Build Coastguard Workerfunc TestMakeStringValue(t *testing.T) {
120*333d2b36SAndroid Build Coastguard Worker	for _, test := range valueTestCases {
121*333d2b36SAndroid Build Coastguard Worker		got := test.in.Value(nil)
122*333d2b36SAndroid Build Coastguard Worker		if got != test.expected {
123*333d2b36SAndroid Build Coastguard Worker			t.Errorf("\nwith: %q\nwant: %q\n got: %q", test.in.Dump(), test.expected, got)
124*333d2b36SAndroid Build Coastguard Worker		}
125*333d2b36SAndroid Build Coastguard Worker	}
126*333d2b36SAndroid Build Coastguard Worker}
127*333d2b36SAndroid Build Coastguard Worker
128*333d2b36SAndroid Build Coastguard Workervar splitWordsTestCases = []struct {
129*333d2b36SAndroid Build Coastguard Worker	in       *MakeString
130*333d2b36SAndroid Build Coastguard Worker	expected []*MakeString
131*333d2b36SAndroid Build Coastguard Worker}{
132*333d2b36SAndroid Build Coastguard Worker	{
133*333d2b36SAndroid Build Coastguard Worker		in:       genMakeString(""),
134*333d2b36SAndroid Build Coastguard Worker		expected: []*MakeString{},
135*333d2b36SAndroid Build Coastguard Worker	},
136*333d2b36SAndroid Build Coastguard Worker	{
137*333d2b36SAndroid Build Coastguard Worker		in: genMakeString(` a b\ c d`),
138*333d2b36SAndroid Build Coastguard Worker		expected: []*MakeString{
139*333d2b36SAndroid Build Coastguard Worker			genMakeString("a"),
140*333d2b36SAndroid Build Coastguard Worker			genMakeString(`b\ c`),
141*333d2b36SAndroid Build Coastguard Worker			genMakeString("d"),
142*333d2b36SAndroid Build Coastguard Worker		},
143*333d2b36SAndroid Build Coastguard Worker	},
144*333d2b36SAndroid Build Coastguard Worker	{
145*333d2b36SAndroid Build Coastguard Worker		in: SimpleMakeString("  a\tb"+`\`+"\t"+`\ c d  `, NoPos),
146*333d2b36SAndroid Build Coastguard Worker		expected: []*MakeString{
147*333d2b36SAndroid Build Coastguard Worker			genMakeString("a"),
148*333d2b36SAndroid Build Coastguard Worker			genMakeString("b" + `\` + "\t" + `\ c`),
149*333d2b36SAndroid Build Coastguard Worker			genMakeString("d"),
150*333d2b36SAndroid Build Coastguard Worker		},
151*333d2b36SAndroid Build Coastguard Worker	},
152*333d2b36SAndroid Build Coastguard Worker	{
153*333d2b36SAndroid Build Coastguard Worker		in: genMakeString(`a\\ b\\\ c d`),
154*333d2b36SAndroid Build Coastguard Worker		expected: []*MakeString{
155*333d2b36SAndroid Build Coastguard Worker			genMakeString(`a\\`),
156*333d2b36SAndroid Build Coastguard Worker			genMakeString(`b\\\ c`),
157*333d2b36SAndroid Build Coastguard Worker			genMakeString("d"),
158*333d2b36SAndroid Build Coastguard Worker		},
159*333d2b36SAndroid Build Coastguard Worker	},
160*333d2b36SAndroid Build Coastguard Worker	{
161*333d2b36SAndroid Build Coastguard Worker		in: genMakeString(`\\ a`),
162*333d2b36SAndroid Build Coastguard Worker		expected: []*MakeString{
163*333d2b36SAndroid Build Coastguard Worker			genMakeString(`\\`),
164*333d2b36SAndroid Build Coastguard Worker			genMakeString("a"),
165*333d2b36SAndroid Build Coastguard Worker		},
166*333d2b36SAndroid Build Coastguard Worker	},
167*333d2b36SAndroid Build Coastguard Worker	{
168*333d2b36SAndroid Build Coastguard Worker		// "  "
169*333d2b36SAndroid Build Coastguard Worker		in: &MakeString{
170*333d2b36SAndroid Build Coastguard Worker			Strings:   []string{" \t \t"},
171*333d2b36SAndroid Build Coastguard Worker			Variables: nil,
172*333d2b36SAndroid Build Coastguard Worker		},
173*333d2b36SAndroid Build Coastguard Worker		expected: []*MakeString{},
174*333d2b36SAndroid Build Coastguard Worker	},
175*333d2b36SAndroid Build Coastguard Worker	{
176*333d2b36SAndroid Build Coastguard Worker		// " a $(X)b c "
177*333d2b36SAndroid Build Coastguard Worker		in: genMakeString(" a ", "X", "b c "),
178*333d2b36SAndroid Build Coastguard Worker		expected: []*MakeString{
179*333d2b36SAndroid Build Coastguard Worker			genMakeString("a"),
180*333d2b36SAndroid Build Coastguard Worker			genMakeString("", "X", "b"),
181*333d2b36SAndroid Build Coastguard Worker			genMakeString("c"),
182*333d2b36SAndroid Build Coastguard Worker		},
183*333d2b36SAndroid Build Coastguard Worker	},
184*333d2b36SAndroid Build Coastguard Worker	{
185*333d2b36SAndroid Build Coastguard Worker		// " a b$(X)c d"
186*333d2b36SAndroid Build Coastguard Worker		in: genMakeString(" a b", "X", "c d"),
187*333d2b36SAndroid Build Coastguard Worker		expected: []*MakeString{
188*333d2b36SAndroid Build Coastguard Worker			genMakeString("a"),
189*333d2b36SAndroid Build Coastguard Worker			genMakeString("b", "X", "c"),
190*333d2b36SAndroid Build Coastguard Worker			genMakeString("d"),
191*333d2b36SAndroid Build Coastguard Worker		},
192*333d2b36SAndroid Build Coastguard Worker	},
193*333d2b36SAndroid Build Coastguard Worker	{
194*333d2b36SAndroid Build Coastguard Worker		// "$(X) $(Y)"
195*333d2b36SAndroid Build Coastguard Worker		in: genMakeString("", "X", " ", "Y", ""),
196*333d2b36SAndroid Build Coastguard Worker		expected: []*MakeString{
197*333d2b36SAndroid Build Coastguard Worker			genMakeString("", "X", ""),
198*333d2b36SAndroid Build Coastguard Worker			genMakeString("", "Y", ""),
199*333d2b36SAndroid Build Coastguard Worker		},
200*333d2b36SAndroid Build Coastguard Worker	},
201*333d2b36SAndroid Build Coastguard Worker	{
202*333d2b36SAndroid Build Coastguard Worker		// " a$(X) b"
203*333d2b36SAndroid Build Coastguard Worker		in: genMakeString(" a", "X", " b"),
204*333d2b36SAndroid Build Coastguard Worker		expected: []*MakeString{
205*333d2b36SAndroid Build Coastguard Worker			genMakeString("a", "X", ""),
206*333d2b36SAndroid Build Coastguard Worker			genMakeString("b"),
207*333d2b36SAndroid Build Coastguard Worker		},
208*333d2b36SAndroid Build Coastguard Worker	},
209*333d2b36SAndroid Build Coastguard Worker	{
210*333d2b36SAndroid Build Coastguard Worker		// "a$(X) b$(Y) "
211*333d2b36SAndroid Build Coastguard Worker		in: genMakeString("a", "X", " b", "Y", " "),
212*333d2b36SAndroid Build Coastguard Worker		expected: []*MakeString{
213*333d2b36SAndroid Build Coastguard Worker			genMakeString("a", "X", ""),
214*333d2b36SAndroid Build Coastguard Worker			genMakeString("b", "Y", ""),
215*333d2b36SAndroid Build Coastguard Worker		},
216*333d2b36SAndroid Build Coastguard Worker	},
217*333d2b36SAndroid Build Coastguard Worker}
218*333d2b36SAndroid Build Coastguard Worker
219*333d2b36SAndroid Build Coastguard Workerfunc TestMakeStringWords(t *testing.T) {
220*333d2b36SAndroid Build Coastguard Worker	for _, test := range splitWordsTestCases {
221*333d2b36SAndroid Build Coastguard Worker		got := test.in.Words()
222*333d2b36SAndroid Build Coastguard Worker		gotString := dumpArray(got)
223*333d2b36SAndroid Build Coastguard Worker		expectedString := dumpArray(test.expected)
224*333d2b36SAndroid Build Coastguard Worker		if gotString != expectedString {
225*333d2b36SAndroid Build Coastguard Worker			t.Errorf("with:\n%q\nexpected:\n%s\ngot:\n%s", test.in.Dump(), expectedString, gotString)
226*333d2b36SAndroid Build Coastguard Worker		}
227*333d2b36SAndroid Build Coastguard Worker	}
228*333d2b36SAndroid Build Coastguard Worker}
229*333d2b36SAndroid Build Coastguard Worker
230*333d2b36SAndroid Build Coastguard Workervar endsWithTestCases = []struct {
231*333d2b36SAndroid Build Coastguard Worker	in       *MakeString
232*333d2b36SAndroid Build Coastguard Worker	endsWith rune
233*333d2b36SAndroid Build Coastguard Worker	expected bool
234*333d2b36SAndroid Build Coastguard Worker}{
235*333d2b36SAndroid Build Coastguard Worker	{
236*333d2b36SAndroid Build Coastguard Worker		in:       genMakeString("foo", "X", "bar ="),
237*333d2b36SAndroid Build Coastguard Worker		endsWith: '=',
238*333d2b36SAndroid Build Coastguard Worker		expected: true,
239*333d2b36SAndroid Build Coastguard Worker	},
240*333d2b36SAndroid Build Coastguard Worker	{
241*333d2b36SAndroid Build Coastguard Worker		in:       genMakeString("foo", "X", "bar ="),
242*333d2b36SAndroid Build Coastguard Worker		endsWith: ':',
243*333d2b36SAndroid Build Coastguard Worker		expected: false,
244*333d2b36SAndroid Build Coastguard Worker	},
245*333d2b36SAndroid Build Coastguard Worker	{
246*333d2b36SAndroid Build Coastguard Worker		in:       genMakeString("foo", "X", ""),
247*333d2b36SAndroid Build Coastguard Worker		endsWith: '=',
248*333d2b36SAndroid Build Coastguard Worker		expected: false,
249*333d2b36SAndroid Build Coastguard Worker	},
250*333d2b36SAndroid Build Coastguard Worker}
251*333d2b36SAndroid Build Coastguard Worker
252*333d2b36SAndroid Build Coastguard Workerfunc TestMakeStringEndsWith(t *testing.T) {
253*333d2b36SAndroid Build Coastguard Worker	for _, test := range endsWithTestCases {
254*333d2b36SAndroid Build Coastguard Worker		if test.in.EndsWith(test.endsWith) != test.expected {
255*333d2b36SAndroid Build Coastguard Worker			t.Errorf("with:\n%q\nexpected:\n%t\ngot:\n%t", test.in.Dump(), test.expected, !test.expected)
256*333d2b36SAndroid Build Coastguard Worker		}
257*333d2b36SAndroid Build Coastguard Worker	}
258*333d2b36SAndroid Build Coastguard Worker}
259*333d2b36SAndroid Build Coastguard Worker
260*333d2b36SAndroid Build Coastguard Workerfunc dumpArray(a []*MakeString) string {
261*333d2b36SAndroid Build Coastguard Worker	ret := make([]string, len(a))
262*333d2b36SAndroid Build Coastguard Worker
263*333d2b36SAndroid Build Coastguard Worker	for i, s := range a {
264*333d2b36SAndroid Build Coastguard Worker		ret[i] = s.Dump()
265*333d2b36SAndroid Build Coastguard Worker	}
266*333d2b36SAndroid Build Coastguard Worker
267*333d2b36SAndroid Build Coastguard Worker	return strings.Join(ret, "|||")
268*333d2b36SAndroid Build Coastguard Worker}
269*333d2b36SAndroid Build Coastguard Worker
270*333d2b36SAndroid Build Coastguard Worker// generates MakeString from alternating string chunks and variable names,
271*333d2b36SAndroid Build Coastguard Worker// e.g., genMakeString("a", "X", "b") returns MakeString for "a$(X)b"
272*333d2b36SAndroid Build Coastguard Workerfunc genMakeString(items ...string) *MakeString {
273*333d2b36SAndroid Build Coastguard Worker	n := len(items) / 2
274*333d2b36SAndroid Build Coastguard Worker	if len(items) != (2*n + 1) {
275*333d2b36SAndroid Build Coastguard Worker		panic("genMakeString expects odd number of arguments")
276*333d2b36SAndroid Build Coastguard Worker	}
277*333d2b36SAndroid Build Coastguard Worker
278*333d2b36SAndroid Build Coastguard Worker	ms := &MakeString{Strings: make([]string, n+1), Variables: make([]Variable, n)}
279*333d2b36SAndroid Build Coastguard Worker	ms.Strings[0] = items[0]
280*333d2b36SAndroid Build Coastguard Worker	for i := 1; i <= n; i++ {
281*333d2b36SAndroid Build Coastguard Worker		ms.Variables[i-1] = Variable{Name: SimpleMakeString(items[2*i-1], NoPos)}
282*333d2b36SAndroid Build Coastguard Worker		ms.Strings[i] = items[2*i]
283*333d2b36SAndroid Build Coastguard Worker	}
284*333d2b36SAndroid Build Coastguard Worker	return ms
285*333d2b36SAndroid Build Coastguard Worker}
286