1// Copyright 2017 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 parser
16
17import (
18	"strings"
19	"testing"
20)
21
22var splitNTestCases = []struct {
23	in       *MakeString
24	expected []*MakeString
25	sep      string
26	n        int
27}{
28	{
29		// "a b c$(var1)d e f$(var2) h i j"
30		in:  genMakeString("a b c", "var1", "d e f", "var2", " h i j"),
31		sep: " ",
32		n:   -1,
33		expected: []*MakeString{
34			genMakeString("a"),
35			genMakeString("b"),
36			genMakeString("c", "var1", "d"),
37			genMakeString("e"),
38			genMakeString("f", "var2", ""),
39			genMakeString("h"),
40			genMakeString("i"),
41			genMakeString("j"),
42		},
43	},
44	{
45		// "a b c$(var1)d e f$(var2) h i j"
46		in:  genMakeString("a b c", "var1", "d e f", "var2", " h i j"),
47		sep: " ",
48		n:   3,
49		expected: []*MakeString{
50			genMakeString("a"),
51			genMakeString("b"),
52			genMakeString("c", "var1", "d e f", "var2", " h i j"),
53		},
54	},
55	{
56		// "$(var1) $(var2)"
57		in:  genMakeString("", "var1", " ", "var2", ""),
58		sep: " ",
59		n:   -1,
60		expected: []*MakeString{
61			genMakeString("", "var1", ""),
62			genMakeString("", "var2", ""),
63		},
64	},
65	{
66		// "a,,b,c,"
67		in:  genMakeString("a,,b,c,"),
68		sep: ",",
69		n:   -1,
70		expected: []*MakeString{
71			genMakeString("a"),
72			genMakeString(""),
73			genMakeString("b"),
74			genMakeString("c"),
75			genMakeString(""),
76		},
77	},
78}
79
80func TestMakeStringSplitN(t *testing.T) {
81	for _, test := range splitNTestCases {
82		got := test.in.SplitN(test.sep, test.n)
83		gotString := dumpArray(got)
84		expectedString := dumpArray(test.expected)
85		if gotString != expectedString {
86			t.Errorf("expected:\n%s\ngot:\n%s", expectedString, gotString)
87		}
88	}
89}
90
91var valueTestCases = []struct {
92	in       *MakeString
93	expected string
94}{
95	{
96		in:       genMakeString("a b"),
97		expected: "a b",
98	},
99	{
100		in:       genMakeString("a\\ \\\tb\\\\"),
101		expected: "a \tb\\",
102	},
103	{
104		in:       genMakeString("a\\b\\"),
105		expected: "a\\b\\",
106	},
107}
108
109func TestMakeStringValue(t *testing.T) {
110	for _, test := range valueTestCases {
111		got := test.in.Value(nil)
112		if got != test.expected {
113			t.Errorf("\nwith: %q\nwant: %q\n got: %q", test.in.Dump(), test.expected, got)
114		}
115	}
116}
117
118var splitWordsTestCases = []struct {
119	in       *MakeString
120	expected []*MakeString
121}{
122	{
123		in:       genMakeString(""),
124		expected: []*MakeString{},
125	},
126	{
127		in: genMakeString(` a b\ c d`),
128		expected: []*MakeString{
129			genMakeString("a"),
130			genMakeString(`b\ c`),
131			genMakeString("d"),
132		},
133	},
134	{
135		in: SimpleMakeString("  a\tb"+`\`+"\t"+`\ c d  `, NoPos),
136		expected: []*MakeString{
137			genMakeString("a"),
138			genMakeString("b" + `\` + "\t" + `\ c`),
139			genMakeString("d"),
140		},
141	},
142	{
143		in: genMakeString(`a\\ b\\\ c d`),
144		expected: []*MakeString{
145			genMakeString(`a\\`),
146			genMakeString(`b\\\ c`),
147			genMakeString("d"),
148		},
149	},
150	{
151		in: genMakeString(`\\ a`),
152		expected: []*MakeString{
153			genMakeString(`\\`),
154			genMakeString("a"),
155		},
156	},
157	{
158		// "  "
159		in: &MakeString{
160			Strings:   []string{" \t \t"},
161			Variables: nil,
162		},
163		expected: []*MakeString{},
164	},
165	{
166		// " a $(X)b c "
167		in: genMakeString(" a ", "X", "b c "),
168		expected: []*MakeString{
169			genMakeString("a"),
170			genMakeString("", "X", "b"),
171			genMakeString("c"),
172		},
173	},
174	{
175		// " a b$(X)c d"
176		in: genMakeString(" a b", "X", "c d"),
177		expected: []*MakeString{
178			genMakeString("a"),
179			genMakeString("b", "X", "c"),
180			genMakeString("d"),
181		},
182	},
183	{
184		// "$(X) $(Y)"
185		in: genMakeString("", "X", " ", "Y", ""),
186		expected: []*MakeString{
187			genMakeString("", "X", ""),
188			genMakeString("", "Y", ""),
189		},
190	},
191	{
192		// " a$(X) b"
193		in: genMakeString(" a", "X", " b"),
194		expected: []*MakeString{
195			genMakeString("a", "X", ""),
196			genMakeString("b"),
197		},
198	},
199	{
200		// "a$(X) b$(Y) "
201		in: genMakeString("a", "X", " b", "Y", " "),
202		expected: []*MakeString{
203			genMakeString("a", "X", ""),
204			genMakeString("b", "Y", ""),
205		},
206	},
207}
208
209func TestMakeStringWords(t *testing.T) {
210	for _, test := range splitWordsTestCases {
211		got := test.in.Words()
212		gotString := dumpArray(got)
213		expectedString := dumpArray(test.expected)
214		if gotString != expectedString {
215			t.Errorf("with:\n%q\nexpected:\n%s\ngot:\n%s", test.in.Dump(), expectedString, gotString)
216		}
217	}
218}
219
220func dumpArray(a []*MakeString) string {
221	ret := make([]string, len(a))
222
223	for i, s := range a {
224		ret[i] = s.Dump()
225	}
226
227	return strings.Join(ret, "|||")
228}
229
230// generates MakeString from alternating string chunks and variable names,
231// e.g., genMakeString("a", "X", "b") returns MakeString for "a$(X)b"
232func genMakeString(items ...string) *MakeString {
233	n := len(items) / 2
234	if len(items) != (2*n + 1) {
235		panic("genMakeString expects odd number of arguments")
236	}
237
238	ms := &MakeString{Strings: make([]string, n+1), Variables: make([]Variable, n)}
239	ms.Strings[0] = items[0]
240	for i := 1; i <= n; i++ {
241		ms.Variables[i-1] = Variable{Name: SimpleMakeString(items[2*i-1], NoPos)}
242		ms.Strings[i] = items[2*i]
243	}
244	return ms
245}
246