blob: 75bc3d1a16b7e1290c58579e69569c572419de77 [file] [log] [blame]
Shinichiro Hamajib69bf8a2015-06-10 14:52:06 +09001// Copyright 2015 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
Fumitoshi Ukai744bb2b2015-06-25 00:10:52 +090015package kati
Fumitoshi Ukaib36f3872015-04-10 15:06:38 +090016
17import (
18 "reflect"
19 "testing"
20)
21
22func TestParseExpr(t *testing.T) {
23 for _, tc := range []struct {
24 in string
25 val Value
26 isErr bool
27 }{
28 {
29 in: "foo",
30 val: literal("foo"),
31 },
32 {
33 in: "(foo)",
34 val: literal("(foo)"),
35 },
36 {
37 in: "{foo}",
38 val: literal("{foo}"),
39 },
40 {
41 in: "$$",
42 val: literal("$"),
43 },
44 {
45 in: "foo$$bar",
46 val: literal("foo$bar"),
47 },
48 {
49 in: "$foo",
Fumitoshi Ukai55c8fa92015-06-25 15:56:10 +090050 val: expr{&varref{varname: literal("f")}, literal("oo")},
Fumitoshi Ukaib36f3872015-04-10 15:06:38 +090051 },
52 {
53 in: "$(foo)",
Fumitoshi Ukaib8acae92015-06-18 15:36:57 +090054 val: &varref{varname: literal("foo")},
Fumitoshi Ukaib36f3872015-04-10 15:06:38 +090055 },
56 {
57 in: "$(foo:.c=.o)",
58 val: varsubst{
59 varname: literal("foo"),
60 pat: literal(".c"),
61 subst: literal(".o"),
62 },
63 },
64 {
65 in: "$(subst $(space),$(,),$(foo))/bar",
Fumitoshi Ukai55c8fa92015-06-25 15:56:10 +090066 val: expr{
Fumitoshi Ukaib36f3872015-04-10 15:06:38 +090067 &funcSubst{
68 fclosure: fclosure{
69 args: []Value{
Fumitoshi Ukaib2670d92015-04-16 10:28:27 +090070 literal("(subst"),
Fumitoshi Ukaib8acae92015-06-18 15:36:57 +090071 &varref{
Fumitoshi Ukaib36f3872015-04-10 15:06:38 +090072 varname: literal("space"),
73 },
Fumitoshi Ukaib8acae92015-06-18 15:36:57 +090074 &varref{
Fumitoshi Ukaib36f3872015-04-10 15:06:38 +090075 varname: literal(","),
76 },
Fumitoshi Ukaib8acae92015-06-18 15:36:57 +090077 &varref{
Fumitoshi Ukaib36f3872015-04-10 15:06:38 +090078 varname: literal("foo"),
79 },
80 },
81 },
82 },
83 literal("/bar"),
84 },
85 },
86 {
87 in: "$(subst $(space),$,,$(foo))",
88 val: &funcSubst{
89 fclosure: fclosure{
90 args: []Value{
Fumitoshi Ukaib2670d92015-04-16 10:28:27 +090091 literal("(subst"),
Fumitoshi Ukaib8acae92015-06-18 15:36:57 +090092 &varref{
Fumitoshi Ukaib36f3872015-04-10 15:06:38 +090093 varname: literal("space"),
94 },
Fumitoshi Ukaib8acae92015-06-18 15:36:57 +090095 &varref{
Fumitoshi Ukaib36f3872015-04-10 15:06:38 +090096 varname: literal(""),
97 },
Fumitoshi Ukai55c8fa92015-06-25 15:56:10 +090098 expr{
Fumitoshi Ukaib36f3872015-04-10 15:06:38 +090099 literal(","),
Fumitoshi Ukaib8acae92015-06-18 15:36:57 +0900100 &varref{
Fumitoshi Ukaib36f3872015-04-10 15:06:38 +0900101 varname: literal("foo"),
102 },
103 },
104 },
105 },
106 },
107 },
108 {
109 in: `$(shell echo '()')`,
110 val: &funcShell{
111 fclosure: fclosure{
112 args: []Value{
Fumitoshi Ukaib2670d92015-04-16 10:28:27 +0900113 literal("(shell"),
Fumitoshi Ukaib36f3872015-04-10 15:06:38 +0900114 literal("echo '()'"),
115 },
116 },
117 },
118 },
119 {
Fumitoshi Ukaiebf945c2015-04-10 17:30:04 +0900120 in: `${shell echo '()'}`,
Fumitoshi Ukaib36f3872015-04-10 15:06:38 +0900121 val: &funcShell{
122 fclosure: fclosure{
123 args: []Value{
Fumitoshi Ukaib2670d92015-04-16 10:28:27 +0900124 literal("{shell"),
Fumitoshi Ukaib36f3872015-04-10 15:06:38 +0900125 literal("echo '()'"),
126 },
127 },
128 },
129 },
130 {
131 in: `$(shell echo ')')`,
Fumitoshi Ukai55c8fa92015-06-25 15:56:10 +0900132 val: expr{
Fumitoshi Ukaib36f3872015-04-10 15:06:38 +0900133 &funcShell{
134 fclosure: fclosure{
135 args: []Value{
Fumitoshi Ukaib2670d92015-04-16 10:28:27 +0900136 literal("(shell"),
Fumitoshi Ukaib36f3872015-04-10 15:06:38 +0900137 literal("echo '"),
138 },
139 },
140 },
141 literal("')"),
142 },
143 },
144 {
145 in: `${shell echo ')'}`,
146 val: &funcShell{
147 fclosure: fclosure{
148 args: []Value{
Fumitoshi Ukaib2670d92015-04-16 10:28:27 +0900149 literal("{shell"),
Fumitoshi Ukaib36f3872015-04-10 15:06:38 +0900150 literal("echo ')'"),
151 },
152 },
153 },
154 },
155 {
156 in: `${shell echo '}'}`,
Fumitoshi Ukai55c8fa92015-06-25 15:56:10 +0900157 val: expr{
Fumitoshi Ukaib36f3872015-04-10 15:06:38 +0900158 &funcShell{
159 fclosure: fclosure{
160 args: []Value{
Fumitoshi Ukaib2670d92015-04-16 10:28:27 +0900161 literal("{shell"),
Fumitoshi Ukaib36f3872015-04-10 15:06:38 +0900162 literal("echo '"),
163 },
164 },
165 },
166 literal("'}"),
167 },
168 },
169 {
170 in: `$(shell make --version | ruby -n0e 'puts $$_[/Make (\d)/,1]')`,
171 val: &funcShell{
172 fclosure: fclosure{
173 args: []Value{
Fumitoshi Ukaib2670d92015-04-16 10:28:27 +0900174 literal("(shell"),
Fumitoshi Ukaib36f3872015-04-10 15:06:38 +0900175 literal(`make --version | ruby -n0e 'puts $_[/Make (\d)/,1]'`),
176 },
Fumitoshi Ukaib36f3872015-04-10 15:06:38 +0900177 },
178 },
179 },
Fumitoshi Ukaiee5c6fc2015-04-16 13:13:10 +0900180 {
181 in: `$(and ${TRUE}, $(X) )`,
182 val: &funcAnd{
183 fclosure: fclosure{
184 args: []Value{
185 literal("(and"),
Fumitoshi Ukaib8acae92015-06-18 15:36:57 +0900186 &varref{
Fumitoshi Ukaiee5c6fc2015-04-16 13:13:10 +0900187 varname: literal("TRUE"),
188 },
Fumitoshi Ukaib8acae92015-06-18 15:36:57 +0900189 &varref{
Fumitoshi Ukaiee5c6fc2015-04-16 13:13:10 +0900190 varname: literal("X"),
191 },
192 },
193 },
194 },
195 },
196 {
197 in: `$(call func, \
198 foo)`,
199 val: &funcCall{
200 fclosure: fclosure{
201 args: []Value{
202 literal("(call"),
203 literal("func"),
204 literal(" foo"),
205 },
206 },
207 },
208 },
209 {
210 in: `$(call func, \)`,
211 val: &funcCall{
212 fclosure: fclosure{
213 args: []Value{
214 literal("(call"),
215 literal("func"),
216 literal(` \`),
217 },
218 },
219 },
220 },
Fumitoshi Ukaida7f2552015-04-16 13:33:37 +0900221 {
222 in: `$(eval ## comment)`,
223 val: &funcNop{
224 expr: `$(eval ## comment)`,
225 },
226 },
Fumitoshi Ukai150c8612015-04-16 15:35:44 +0900227 {
228 in: `$(eval foo = bar)`,
229 val: &funcEvalAssign{
230 lhs: "foo",
231 op: "=",
232 rhs: literal("bar"),
233 },
234 },
235 {
236 in: `$(eval foo :=)`,
237 val: &funcEvalAssign{
238 lhs: "foo",
239 op: ":=",
240 rhs: literal(""),
241 },
242 },
Fumitoshi Ukaid8cec172015-04-28 00:08:09 +0900243 {
244 in: `$(eval foo := $(bar))`,
245 val: &funcEvalAssign{
246 lhs: "foo",
247 op: ":=",
Fumitoshi Ukaib8acae92015-06-18 15:36:57 +0900248 rhs: &varref{
Fumitoshi Ukaid8cec172015-04-28 00:08:09 +0900249 literal("bar"),
250 },
251 },
252 },
253 {
254 in: `$(eval foo := $$(bar))`,
255 val: &funcEvalAssign{
256 lhs: "foo",
257 op: ":=",
258 rhs: literal("$(bar)"),
259 },
260 },
261 {
262 in: `$(strip $1)`,
263 val: &funcStrip{
264 fclosure: fclosure{
265 args: []Value{
266 literal("(strip"),
267 paramref(1),
Fumitoshi Ukaif0a2ba72015-04-19 00:02:32 +0900268 },
269 },
270 },
Fumitoshi Ukaid8cec172015-04-28 00:08:09 +0900271 },
272 {
273 in: `$(strip $(1))`,
274 val: &funcStrip{
275 fclosure: fclosure{
276 args: []Value{
277 literal("(strip"),
278 paramref(1),
Fumitoshi Ukaif0a2ba72015-04-19 00:02:32 +0900279 },
280 },
281 },
Fumitoshi Ukaid8cec172015-04-28 00:08:09 +0900282 },
Fumitoshi Ukaib36f3872015-04-10 15:06:38 +0900283 } {
Fumitoshi Ukai7c9aa9f2015-06-12 23:51:38 +0900284 val, _, err := parseExpr([]byte(tc.in), nil, true)
Fumitoshi Ukaib36f3872015-04-10 15:06:38 +0900285 if tc.isErr {
286 if err == nil {
287 t.Errorf(`parseExpr(%q)=_, _, nil; want error`, tc.in)
288 }
289 continue
290 }
291 if err != nil {
292 t.Errorf(`parseExpr(%q)=_, _, %v; want nil error`, tc.in, err)
293 continue
294 }
295 if got, want := val, tc.val; !reflect.DeepEqual(got, want) {
296 t.Errorf("parseExpr(%[1]q)=%[2]q %#[2]v, _, _;\n want %[3]q %#[3]v, _, _", tc.in, got, want)
297 }
298 }
299}