this repo has no description
1package buildattr
2
3import (
4 "testing"
5
6 "cuelang.org/go/cue/errors"
7 "cuelang.org/go/cue/format"
8 "cuelang.org/go/cue/parser"
9
10 "github.com/go-quicktest/qt"
11)
12
13var shouldBuildFileTests = []struct {
14 testName string
15 syntax string
16 tags map[string]bool
17 wantOK bool
18 wantAttr string
19 wantError string
20 wantTagCalls map[string]bool
21}{{
22 testName: "EmptyFile",
23 syntax: "",
24 wantOK: true,
25}, {
26 testName: "PackageWithIf",
27 syntax: `
28@if(foo)
29
30package something
31`,
32 wantOK: false,
33 wantTagCalls: map[string]bool{"foo": true},
34 wantAttr: "@if(foo)",
35}, {
36 testName: "PackageWithComments",
37 syntax: `
38
39// Some comment
40
41@if(foo)
42
43// Other comment
44
45package something
46`,
47 wantOK: false,
48 wantTagCalls: map[string]bool{"foo": true},
49 wantAttr: "@if(foo)",
50}, {
51 testName: "PackageWithIfSuccess",
52 syntax: `
53@if(foo)
54
55package something
56`,
57 tags: map[string]bool{"foo": true},
58 wantOK: true,
59 wantTagCalls: map[string]bool{"foo": true},
60 wantAttr: "@if(foo)",
61}, {
62 testName: "PackageWithIfAfterPackageClause",
63 syntax: `
64package something
65
66@if(foo)
67`,
68 wantOK: true,
69}, {
70 testName: "InvalidExpr",
71 syntax: `
72@if(foo + bar)
73
74package something
75`,
76 wantOK: false,
77 wantAttr: "@if(foo + bar)",
78 wantError: `invalid operator \+ in build attribute
79`,
80}, {
81 testName: "MultipleIfAttributes",
82 syntax: `
83
84@if(foo)
85@if(bar)
86
87package something
88`,
89 wantOK: false,
90 wantAttr: "@if(foo)",
91 wantError: `previous declaration here:
92 testfile.cue:3:1
93multiple @if attributes:
94 testfile.cue:4:1
95`,
96}, {
97 testName: "MultipleIfAttributesWithOneAfterPackage",
98 syntax: `
99
100@if(foo)
101
102package something
103
104@if(bar)
105`,
106 wantOK: false,
107 wantAttr: "@if(foo)",
108 wantTagCalls: map[string]bool{"foo": true},
109}, {
110 testName: "And#0",
111 syntax: `
112@if(foo && bar)
113
114package something
115`,
116 wantOK: false,
117 wantAttr: "@if(foo && bar)",
118 wantTagCalls: map[string]bool{
119 "foo": true,
120 "bar": true,
121 },
122}, {
123 testName: "And#1",
124 syntax: `
125@if(foo && bar)
126
127package something
128`,
129 tags: map[string]bool{"foo": true},
130 wantOK: false,
131 wantAttr: "@if(foo && bar)",
132 wantTagCalls: map[string]bool{
133 "foo": true,
134 "bar": true,
135 },
136}, {
137 testName: "And#2",
138 syntax: `
139@if(foo && bar)
140
141package something
142`,
143 tags: map[string]bool{"bar": true},
144 wantOK: false,
145 wantAttr: "@if(foo && bar)",
146 wantTagCalls: map[string]bool{
147 "foo": true,
148 "bar": true,
149 },
150}, {
151 testName: "And#3",
152 syntax: `
153@if(foo && bar)
154
155package something
156`,
157 tags: map[string]bool{"foo": true, "bar": true},
158 wantOK: true,
159 wantAttr: "@if(foo && bar)",
160 wantTagCalls: map[string]bool{
161 "foo": true,
162 "bar": true,
163 },
164}, {
165 testName: "Or#0",
166 syntax: `
167@if(foo || bar)
168
169package something
170`,
171 wantOK: false,
172 wantAttr: "@if(foo || bar)",
173 wantTagCalls: map[string]bool{
174 "foo": true,
175 "bar": true,
176 },
177}, {
178 testName: "Or#1",
179 syntax: `
180@if(foo || bar)
181
182package something
183`,
184 tags: map[string]bool{"foo": true},
185 wantOK: true,
186 wantAttr: "@if(foo || bar)",
187 wantTagCalls: map[string]bool{
188 "foo": true,
189 "bar": true,
190 },
191}, {
192 testName: "Or#2",
193 syntax: `
194@if(foo || bar)
195
196package something
197`,
198 tags: map[string]bool{"bar": true},
199 wantOK: true,
200 wantAttr: "@if(foo || bar)",
201 wantTagCalls: map[string]bool{
202 "foo": true,
203 "bar": true,
204 },
205}, {
206 testName: "Or#3",
207 syntax: `
208@if(foo || bar)
209
210package something
211`,
212 tags: map[string]bool{"foo": true, "bar": true},
213 wantOK: true,
214 wantAttr: "@if(foo || bar)",
215 wantTagCalls: map[string]bool{
216 "foo": true,
217 "bar": true,
218 },
219}, {
220 testName: "Not#0",
221 syntax: `
222@if(!foo)
223
224package something
225`,
226 wantOK: true,
227 wantAttr: "@if(!foo)",
228 wantTagCalls: map[string]bool{
229 "foo": true,
230 },
231}, {
232 testName: "Not#1",
233 syntax: `
234@if(!foo)
235
236package something
237`,
238 tags: map[string]bool{"foo": true},
239 wantOK: false,
240 wantAttr: "@if(!foo)",
241 wantTagCalls: map[string]bool{
242 "foo": true,
243 },
244}, {
245 testName: "ComplexExpr",
246 syntax: `
247@if(foo || (!bar && baz))
248
249package something
250`,
251 tags: map[string]bool{
252 "baz": true,
253 },
254 wantOK: true,
255 wantTagCalls: map[string]bool{
256 "foo": true,
257 "bar": true,
258 "baz": true,
259 },
260 wantAttr: "@if(foo || (!bar && baz))",
261}, {
262 testName: "IgnoreOnly",
263 syntax: `
264@ignore()
265
266package something
267`,
268 wantOK: false,
269 wantAttr: "@ignore()",
270}, {
271 testName: "IgnoreWithBuildAttrs",
272 syntax: `
273@ignore()
274@if(blah)
275
276package something
277`,
278 wantOK: false,
279 wantAttr: "@ignore()",
280}, {
281 // It's arguable whether multiple @if attributes
282 // should be an error when there's an @ignore
283 // attribute, but it's easily worked around by
284 // putting the @ignore attribute first, which should
285 // be fairly intuitive.
286 testName: "IgnoreWithMultipleEarlierIfs",
287 syntax: `
288@if(foo)
289@if(bar)
290@ignore()
291
292package something
293`,
294 wantOK: false,
295 wantError: `previous declaration here:
296 testfile.cue:2:1
297multiple @if attributes:
298 testfile.cue:3:1
299`,
300 wantAttr: "@if(foo)",
301}, {
302 testName: "IgnoreWithMultipleLaterIfs",
303 syntax: `
304@ignore()
305@if(foo)
306@if(bar)
307
308package something
309`,
310 wantOK: false,
311 wantAttr: "@ignore()",
312}, {
313 testName: "IgnoreWithoutPackageClause",
314 syntax: `
315@ignore()
316a: 5
317`,
318 wantOK: false,
319 wantAttr: "@ignore()",
320}, {
321 testName: "IfAfterDeclaration",
322 syntax: `
323a: 1
324@if(foo)
325`,
326 wantOK: true,
327}}
328
329func TestShouldBuildFile(t *testing.T) {
330 for _, test := range shouldBuildFileTests {
331 t.Run(test.testName, func(t *testing.T) {
332 f, err := parser.ParseFile("testfile.cue", test.syntax)
333 qt.Assert(t, qt.IsNil(err))
334 tagsUsed := make(map[string]bool)
335 ok, attr, err := ShouldBuildFile(f, func(tag string) bool {
336 tagsUsed[tag] = true
337 return test.tags[tag]
338 })
339 qt.Check(t, qt.Equals(ok, test.wantOK))
340 if test.wantAttr == "" {
341 qt.Assert(t, qt.IsNil(attr))
342 } else {
343 qt.Assert(t, qt.Not(qt.IsNil(attr)))
344 attrStr, err := format.Node(attr)
345 qt.Assert(t, qt.IsNil(err))
346 qt.Assert(t, qt.Equals(string(attrStr), test.wantAttr))
347 }
348 if test.wantError != "" {
349 qt.Assert(t, qt.Not(qt.IsNil(err)))
350 qt.Assert(t, qt.Matches(errors.Details(err, nil), test.wantError))
351 qt.Assert(t, qt.Equals(ok, false))
352 return
353 }
354 qt.Assert(t, qt.IsNil(err))
355 if len(tagsUsed) == 0 {
356 tagsUsed = nil
357 }
358 qt.Check(t, qt.DeepEquals(tagsUsed, test.wantTagCalls))
359 })
360 }
361}