1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package adt_test
16
17 import (
18 "testing"
19
20 "cuelang.org/go/cue/parser"
21 "cuelang.org/go/internal/core/adt"
22 "cuelang.org/go/internal/core/compile"
23 "cuelang.org/go/internal/core/eval"
24 "cuelang.org/go/internal/core/runtime"
25 )
26
27
28
29
30 func TestClosedness(t *testing.T) {
31 r := runtime.New()
32 ctx := eval.NewContext(r, nil)
33
34 mkStruct := func(info adt.CloseInfo, s string) *adt.StructInfo {
35 x, err := parser.ParseExpr("", s)
36 if err != nil {
37 t.Fatal(err)
38 }
39 expr, err := compile.Expr(nil, r, "", x)
40 if err != nil {
41 t.Fatal(err)
42 }
43 st := expr.Elem().(*adt.StructLit)
44 st.Init()
45
46 return &adt.StructInfo{
47 StructLit: st,
48 CloseInfo: info,
49 }
50 }
51
52 mkRef := func(s string) adt.Expr {
53 f := adt.MakeIdentLabel(r, s, "")
54 return &adt.FieldReference{Label: f}
55 }
56
57 type test struct {
58 f string
59 found bool
60 }
61
62 testCases := []struct {
63 desc string
64 n func() *adt.Vertex
65 tests []test
66 required bool
67 }{{
68 desc: "simple embedding",
69
70
71
72
73
74
75
76
77
78
79 n: func() *adt.Vertex {
80 var (
81 root adt.CloseInfo
82 embed = root.SpawnEmbed(mkRef("dummy"))
83 def = embed.SpawnRef(nil, false, mkRef("def"))
84 )
85 return &adt.Vertex{
86 Structs: []*adt.StructInfo{
87 mkStruct(root, "{a: 1, c: 1}"),
88 mkStruct(def, "{c: 1, d: 1}"),
89 },
90 }
91 },
92 tests: []test{
93 {"a", true},
94 {"c", true},
95 {"d", true},
96 {"e", false},
97 },
98 required: false,
99 }, {
100 desc: "closing embedding",
101
102
103
104
105
106
107
108
109
110
111 n: func() *adt.Vertex {
112 var (
113 root adt.CloseInfo
114 embed = root.SpawnEmbed(mkRef("dummy"))
115 def = embed.SpawnRef(nil, true, mkRef("#def"))
116 )
117 return &adt.Vertex{
118 Structs: []*adt.StructInfo{
119 mkStruct(root, "{a: 1, c: 1}"),
120 mkStruct(def, "{c: 1, d: 1}"),
121 },
122 }
123 },
124 tests: []test{
125 {"a", true},
126 {"c", true},
127 {"d", true},
128 {"e", false},
129 },
130 required: true,
131 }, {
132 desc: "narrow down definitions in subfields",
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152 n: func() *adt.Vertex {
153 var (
154 root adt.CloseInfo
155 foo = root.SpawnRef(nil, true, mkRef("#foo"))
156 bar = foo.SpawnRef(nil, true, mkRef("#bar"))
157 baz = foo.SpawnRef(nil, true, mkRef("#baz"))
158 )
159 return &adt.Vertex{
160 Structs: []*adt.StructInfo{
161 mkStruct(root, "{a: 1, b:1}"),
162 mkStruct(foo, "{d: 1, e: 1}"),
163 mkStruct(bar, "{d: 1, e: 1}"),
164 mkStruct(baz, "{d: 1, f: 1}"),
165 },
166 }
167 },
168 tests: []test{
169 {"a", false},
170 {"b", false},
171 {"d", true},
172 {"e", false},
173 {"f", false},
174 },
175 required: true,
176 }, {
177 desc: "chained references",
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192 n: func() *adt.Vertex {
193 var (
194 root adt.CloseInfo
195 foo = root.SpawnRef(nil, false, mkRef("foo"))
196 bar = foo.SpawnRef(nil, false, mkRef("bar"))
197 baz = bar.SpawnEmbed(mkRef("#baz"))
198 def = baz.SpawnRef(nil, true, mkRef("#baz"))
199 )
200 return &adt.Vertex{
201 Structs: []*adt.StructInfo{
202 mkStruct(bar, "{e: 1}"),
203 mkStruct(def, "{c: 1, d: 1}"),
204 mkStruct(root, "{a: 1, c: 1}"),
205 },
206 }
207 },
208 tests: []test{
209 {"a", false},
210 {"c", true},
211 {"d", true},
212 {"e", true},
213 {"f", false},
214 },
215 required: true,
216 }, {
217 desc: "conjunction embedding",
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237 n: func() *adt.Vertex {
238 var (
239 root adt.CloseInfo
240 foo = root.SpawnRef(nil, false, mkRef("foo"))
241 embed = foo.SpawnEmbed(mkRef("dummy"))
242 bar = embed.SpawnRef(nil, true, mkRef("#bar"))
243 baz = embed.SpawnRef(nil, true, mkRef("#baz"))
244 )
245 return &adt.Vertex{
246 Structs: []*adt.StructInfo{
247 mkStruct(root, "{a: 1, c: 1}"),
248 mkStruct(foo, "{f: 1}"),
249 mkStruct(bar, "{c: 1, d: 1}"),
250 mkStruct(baz, "{d: 1}"),
251 mkStruct(baz, "{e: 1}"),
252 },
253 }
254 },
255 tests: []test{
256 {"a", false},
257 {"c", false},
258 {"d", true},
259 {"e", false},
260 {"f", true},
261 {"g", false},
262 },
263 required: true,
264 }, {
265 desc: "local closing",
266
267
268
269
270
271
272
273
274
275
276
277
278
279 n: func() *adt.Vertex {
280 var (
281 root adt.CloseInfo
282
283 spawned = root.SpawnRef(nil, false, mkRef("dummy"))
284 embed = spawned.SpawnEmbed(mkRef("dummy"))
285 def = embed.SpawnRef(nil, true, mkRef("#def"))
286 )
287 return &adt.Vertex{
288 Structs: []*adt.StructInfo{
289 mkStruct(spawned, "{a: 1, b: 1}"),
290 mkStruct(root, "{c: 1, d: 1}"),
291 mkStruct(def, "{c: 1, e: 1}"),
292 },
293 }
294 },
295 tests: []test{
296 {"d", false},
297 {"a", true},
298 {"c", true},
299 {"e", true},
300 {"f", false},
301 },
302 required: true,
303 }, {
304 desc: "local closing of def",
305
306
307
308
309
310
311
312
313
314
315
316
317
318 n: func() *adt.Vertex {
319 var (
320 root adt.CloseInfo
321 test = root.SpawnRef(nil, true, mkRef("#test"))
322
323 spawned = test.SpawnRef(nil, false, mkRef("dummy"))
324 embed = spawned.SpawnEmbed(mkRef("dummy"))
325 def = embed.SpawnRef(nil, true, mkRef("#def"))
326 )
327 return &adt.Vertex{
328 Structs: []*adt.StructInfo{
329 mkStruct(spawned, "{a: 1, b: 1}"),
330 mkStruct(test, "{c: 1, d: 1}"),
331 mkStruct(def, "{c: 1, e: 1}"),
332 },
333 }
334 },
335 tests: []test{
336 {"a", true},
337 {"d", false},
338 {"c", true},
339 {"e", true},
340 {"f", false},
341 },
342 required: true,
343 }, {
344 desc: "branching",
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362 n: func() *adt.Vertex {
363 var (
364 root adt.CloseInfo
365 foo = root.SpawnRef(nil, true, mkRef("#foo"))
366 bar1 = foo.SpawnRef(nil, true, mkRef("#bar1"))
367 bar2 = foo.SpawnRef(nil, true, mkRef("#bar2"))
368 baz1 = bar1.SpawnRef(nil, true, mkRef("#baz1"))
369 baz2 = bar1.SpawnRef(nil, true, mkRef("#baz2"))
370 baz3 = bar2.SpawnRef(nil, true, mkRef("#baz3"))
371 spw3 = bar2.SpawnRef(nil, false, mkRef("spw3"))
372 emb2 = spw3.SpawnEmbed(mkRef("emb"))
373 baz4 = emb2.SpawnRef(nil, true, mkRef("#baz4"))
374 )
375 return &adt.Vertex{
376 Structs: []*adt.StructInfo{
377 mkStruct(root, "{}"),
378 mkStruct(foo, "{}"),
379 mkStruct(bar1, "{}"),
380 mkStruct(bar2, "{}"),
381 mkStruct(baz1, "{e: 1, f: 1, g: 1}"),
382 mkStruct(baz2, "{e: 1, f: 1, g: 1}"),
383 mkStruct(baz3, "{e: 1, g: 1}"),
384 mkStruct(baz4, "{e: 1, f: 1}"),
385 },
386 }
387 },
388 tests: []test{
389 {"a", false},
390 {"e", true},
391 {"f", false},
392 {"g", false},
393 },
394 required: true,
395 }}
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413 for _, tc := range testCases {
414 t.Run(tc.desc, func(t *testing.T) {
415 n := tc.n()
416 for _, sub := range tc.tests {
417 t.Run(sub.f, func(t *testing.T) {
418 f := adt.MakeIdentLabel(r, sub.f, "")
419
420 ok, required := adt.Accept(ctx, n, f)
421 if ok != sub.found || required != tc.required {
422 t.Errorf("got (%v, %v); want (%v, %v)",
423 ok, required, sub.found, tc.required)
424 }
425 })
426 }
427 })
428 }
429 }
430
View as plain text