blob: e21d66c42d3568213150b2f89f5885db88db1a80 [file] [log] [blame]
Fumitoshi Ukaib36f3872015-04-10 15:06:38 +09001package main
2
3import (
4 "reflect"
5 "testing"
6)
7
8func TestParseExpr(t *testing.T) {
9 for _, tc := range []struct {
10 in string
11 val Value
12 isErr bool
13 }{
14 {
15 in: "foo",
16 val: literal("foo"),
17 },
18 {
19 in: "(foo)",
20 val: literal("(foo)"),
21 },
22 {
23 in: "{foo}",
24 val: literal("{foo}"),
25 },
26 {
27 in: "$$",
28 val: literal("$"),
29 },
30 {
31 in: "foo$$bar",
32 val: literal("foo$bar"),
33 },
34 {
35 in: "$foo",
36 val: Expr{varref{varname: literal("f")}, literal("oo")},
37 },
38 {
39 in: "$(foo)",
40 val: varref{varname: literal("foo")},
41 },
42 {
43 in: "$(foo:.c=.o)",
44 val: varsubst{
45 varname: literal("foo"),
46 pat: literal(".c"),
47 subst: literal(".o"),
48 },
49 },
50 {
51 in: "$(subst $(space),$(,),$(foo))/bar",
52 val: Expr{
53 &funcSubst{
54 fclosure: fclosure{
55 args: []Value{
Fumitoshi Ukaib2670d92015-04-16 10:28:27 +090056 literal("(subst"),
Fumitoshi Ukaib36f3872015-04-10 15:06:38 +090057 varref{
58 varname: literal("space"),
59 },
60 varref{
61 varname: literal(","),
62 },
63 varref{
64 varname: literal("foo"),
65 },
66 },
67 },
68 },
69 literal("/bar"),
70 },
71 },
72 {
73 in: "$(subst $(space),$,,$(foo))",
74 val: &funcSubst{
75 fclosure: fclosure{
76 args: []Value{
Fumitoshi Ukaib2670d92015-04-16 10:28:27 +090077 literal("(subst"),
Fumitoshi Ukaib36f3872015-04-10 15:06:38 +090078 varref{
79 varname: literal("space"),
80 },
81 varref{
82 varname: literal(""),
83 },
84 Expr{
85 literal(","),
86 varref{
87 varname: literal("foo"),
88 },
89 },
90 },
91 },
92 },
93 },
94 {
95 in: `$(shell echo '()')`,
96 val: &funcShell{
97 fclosure: fclosure{
98 args: []Value{
Fumitoshi Ukaib2670d92015-04-16 10:28:27 +090099 literal("(shell"),
Fumitoshi Ukaib36f3872015-04-10 15:06:38 +0900100 literal("echo '()'"),
101 },
102 },
103 },
104 },
105 {
Fumitoshi Ukaiebf945c2015-04-10 17:30:04 +0900106 in: `${shell echo '()'}`,
Fumitoshi Ukaib36f3872015-04-10 15:06:38 +0900107 val: &funcShell{
108 fclosure: fclosure{
109 args: []Value{
Fumitoshi Ukaib2670d92015-04-16 10:28:27 +0900110 literal("{shell"),
Fumitoshi Ukaib36f3872015-04-10 15:06:38 +0900111 literal("echo '()'"),
112 },
113 },
114 },
115 },
116 {
117 in: `$(shell echo ')')`,
118 val: Expr{
119 &funcShell{
120 fclosure: fclosure{
121 args: []Value{
Fumitoshi Ukaib2670d92015-04-16 10:28:27 +0900122 literal("(shell"),
Fumitoshi Ukaib36f3872015-04-10 15:06:38 +0900123 literal("echo '"),
124 },
125 },
126 },
127 literal("')"),
128 },
129 },
130 {
131 in: `${shell echo ')'}`,
132 val: &funcShell{
133 fclosure: fclosure{
134 args: []Value{
Fumitoshi Ukaib2670d92015-04-16 10:28:27 +0900135 literal("{shell"),
Fumitoshi Ukaib36f3872015-04-10 15:06:38 +0900136 literal("echo ')'"),
137 },
138 },
139 },
140 },
141 {
142 in: `${shell echo '}'}`,
143 val: Expr{
144 &funcShell{
145 fclosure: fclosure{
146 args: []Value{
Fumitoshi Ukaib2670d92015-04-16 10:28:27 +0900147 literal("{shell"),
Fumitoshi Ukaib36f3872015-04-10 15:06:38 +0900148 literal("echo '"),
149 },
150 },
151 },
152 literal("'}"),
153 },
154 },
155 {
156 in: `$(shell make --version | ruby -n0e 'puts $$_[/Make (\d)/,1]')`,
157 val: &funcShell{
158 fclosure: fclosure{
159 args: []Value{
Fumitoshi Ukaib2670d92015-04-16 10:28:27 +0900160 literal("(shell"),
Fumitoshi Ukaib36f3872015-04-10 15:06:38 +0900161 literal(`make --version | ruby -n0e 'puts $_[/Make (\d)/,1]'`),
162 },
Fumitoshi Ukaib36f3872015-04-10 15:06:38 +0900163 },
164 },
165 },
Fumitoshi Ukaiee5c6fc2015-04-16 13:13:10 +0900166 {
167 in: `$(and ${TRUE}, $(X) )`,
168 val: &funcAnd{
169 fclosure: fclosure{
170 args: []Value{
171 literal("(and"),
172 varref{
173 varname: literal("TRUE"),
174 },
175 varref{
176 varname: literal("X"),
177 },
178 },
179 },
180 },
181 },
182 {
183 in: `$(call func, \
184 foo)`,
185 val: &funcCall{
186 fclosure: fclosure{
187 args: []Value{
188 literal("(call"),
189 literal("func"),
190 literal(" foo"),
191 },
192 },
193 },
194 },
195 {
196 in: `$(call func, \)`,
197 val: &funcCall{
198 fclosure: fclosure{
199 args: []Value{
200 literal("(call"),
201 literal("func"),
202 literal(` \`),
203 },
204 },
205 },
206 },
Fumitoshi Ukaida7f2552015-04-16 13:33:37 +0900207 {
208 in: `$(eval ## comment)`,
209 val: &funcNop{
210 expr: `$(eval ## comment)`,
211 },
212 },
Fumitoshi Ukaib36f3872015-04-10 15:06:38 +0900213 } {
214 val, _, err := parseExpr([]byte(tc.in), nil)
215 if tc.isErr {
216 if err == nil {
217 t.Errorf(`parseExpr(%q)=_, _, nil; want error`, tc.in)
218 }
219 continue
220 }
221 if err != nil {
222 t.Errorf(`parseExpr(%q)=_, _, %v; want nil error`, tc.in, err)
223 continue
224 }
225 if got, want := val, tc.val; !reflect.DeepEqual(got, want) {
226 t.Errorf("parseExpr(%[1]q)=%[2]q %#[2]v, _, _;\n want %[3]q %#[3]v, _, _", tc.in, got, want)
227 }
228 }
229}