1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package subsume
16
17 import (
18 "regexp"
19 "strconv"
20 "strings"
21 "testing"
22
23 "cuelang.org/go/cue/parser"
24 "cuelang.org/go/internal/core/adt"
25 "cuelang.org/go/internal/core/compile"
26 "cuelang.org/go/internal/core/eval"
27 "cuelang.org/go/internal/core/runtime"
28 )
29
30 func TestStructural(t *testing.T) {
31
32 t.Skip()
33
34
35
36 type subsumeTest struct {
37
38 subsumes bool
39 in string
40
41 }
42 testCases := []subsumeTest{
43
44 0: {subsumes: true, in: `a: _, b: _ `},
45 1: {subsumes: true, in: `a: _, b: null `},
46 2: {subsumes: true, in: `a: _, b: int `},
47 3: {subsumes: true, in: `a: _, b: 1 `},
48 4: {subsumes: true, in: `a: _, b: float `},
49 5: {subsumes: true, in: `a: _, b: "s" `},
50 6: {subsumes: true, in: `a: _, b: {} `},
51 7: {subsumes: true, in: `a: _, b: []`},
52 8: {subsumes: true, in: `a: _, b: _|_ `},
53
54
55 9: {subsumes: false, in: `a: null, b: _`},
56 10: {subsumes: false, in: `a: int, b: _`},
57 11: {subsumes: false, in: `a: 1, b: _`},
58 12: {subsumes: false, in: `a: float, b: _`},
59 13: {subsumes: false, in: `a: "s", b: _`},
60 14: {subsumes: false, in: `a: {}, b: _`},
61 15: {subsumes: false, in: `a: [], b: _`},
62 16: {subsumes: false, in: `a: _|_ , b: _`},
63
64
65 17: {subsumes: false, in: `a: _|_, b: null `},
66 18: {subsumes: false, in: `a: _|_, b: int `},
67 19: {subsumes: false, in: `a: _|_, b: 1 `},
68 20: {subsumes: false, in: `a: _|_, b: float `},
69 21: {subsumes: false, in: `a: _|_, b: "s" `},
70 22: {subsumes: false, in: `a: _|_, b: {} `},
71 23: {subsumes: false, in: `a: _|_, b: [] `},
72 24: {subsumes: true, in: ` a: _|_, b: _|_ `},
73
74
75 25: {subsumes: true, in: `a: null, b: _|_`},
76 26: {subsumes: true, in: `a: int, b: _|_`},
77 27: {subsumes: true, in: `a: 1, b: _|_`},
78 28: {subsumes: true, in: `a: float, b: _|_`},
79 29: {subsumes: true, in: `a: "s", b: _|_`},
80 30: {subsumes: true, in: `a: {}, b: _|_`},
81 31: {subsumes: true, in: `a: [], b: _|_`},
82 32: {subsumes: true, in: `a: true, b: _|_`},
83 33: {subsumes: true, in: `a: _|_, b: _|_`},
84
85
86 34: {subsumes: true, in: ` a: null, b: null `},
87 35: {subsumes: false, in: `a: null, b: 1 `},
88 36: {subsumes: false, in: `a: 1, b: null `},
89
90 37: {subsumes: true, in: ` a: true, b: true `},
91 38: {subsumes: false, in: `a: true, b: false `},
92
93 39: {subsumes: true, in: ` a: "a", b: "a" `},
94 40: {subsumes: false, in: `a: "a", b: "b" `},
95 41: {subsumes: true, in: ` a: string, b: "a" `},
96 42: {subsumes: false, in: `a: "a", b: string `},
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123 43: {subsumes: true, in: `a: 1, b: 1 `},
124 44: {subsumes: true, in: `a: 1.0, b: 1.0 `},
125 45: {subsumes: true, in: `a: 3.0, b: 3.0 `},
126 46: {subsumes: false, in: `a: 1.0, b: 1 `},
127 47: {subsumes: false, in: `a: 1, b: 1.0 `},
128 48: {subsumes: false, in: `a: 3, b: 3.0`},
129 49: {subsumes: true, in: `a: int, b: 1`},
130 50: {subsumes: true, in: `a: int, b: int & 1`},
131 51: {subsumes: true, in: `a: float, b: 1.0`},
132 52: {subsumes: false, in: `a: float, b: 1`},
133 53: {subsumes: false, in: `a: int, b: 1.0`},
134 54: {subsumes: true, in: `a: int, b: int`},
135 55: {subsumes: true, in: `a: number, b: int`},
136
137
138 64: {subsumes: true, in: `a: {}, b: {}`},
139 65: {subsumes: true, in: `a: {}, b: {a: 1}`},
140 66: {subsumes: true, in: `a: {a:1}, b: {a:1, b:1}`},
141 67: {subsumes: true, in: `a: {s: { a:1} }, b: { s: { a:1, b:2 }}`},
142 68: {subsumes: true, in: `a: {}, b: {}`},
143
144
145 69: {subsumes: true, in: `a: {}, b: {} & c, c: {}`},
146
147 70: {subsumes: false, in: `a: {a:1}, b: {}`},
148 71: {subsumes: false, in: `a: {a:1, b:1}, b: {a:1}`},
149 72: {subsumes: false, in: `a: {s: { a:1} }, b: { s: {}}`},
150
151 84: {subsumes: true, in: `a: 1 | 2, b: 2 | 1`},
152 85: {subsumes: true, in: `a: 1 | 2, b: 1 | 2`},
153
154 86: {subsumes: true, in: `a: number, b: 2 | 1`},
155 87: {subsumes: true, in: `a: number, b: 2 | 1`},
156 88: {subsumes: false, in: `a: int, b: 1 | 2 | 3.1`},
157
158 89: {subsumes: true, in: `a: float | number, b: 1 | 2 | 3.1`},
159
160 90: {subsumes: false, in: `a: int, b: 1 | 2 | 3.1`},
161 91: {subsumes: true, in: `a: 1 | 2, b: 1`},
162 92: {subsumes: true, in: `a: 1 | 2, b: 2`},
163 93: {subsumes: false, in: `a: 1 | 2, b: 3`},
164
165
166 94: {subsumes: false, in: `a: int + int, b: int`},
167 95: {subsumes: true, in: `a: int + int, b: int + int`},
168 96: {subsumes: true, in: `a: int + number, b: int + int`},
169 97: {subsumes: true, in: `a: number + number, b: int + int`},
170
171
172 98: {subsumes: false, in: `a: int + int, b: int * int`},
173
174
175
176 99: {subsumes: true, in: `a: !int, b: !int`},
177 100: {subsumes: true, in: `a: !number, b: !int`},
178 101: {subsumes: true, in: `a: !int, b: !number`},
179
180
181 102: {subsumes: false, in: `a: int + int, b: !number`},
182
183 103: {subsumes: false, in: `a: !bool, b: bool`},
184 104: {subsumes: true, in: `a: !bool, b: !bool`},
185
186
187 113: {subsumes: true, in: `
188 a: fn()
189 b: fn()
190 fn: _`,
191 },
192 114: {subsumes: false, in: `
193 a: fn(),
194 b: fn(1)
195 fn: _`,
196 },
197 115: {subsumes: true, in: `
198 a: fn(2)
199 b: fn(2)
200 fn: _`,
201 },
202 116: {subsumes: true, in: `
203 a: fn(number)
204 b: fn(2)
205 fn: _`,
206 },
207 117: {subsumes: false, in: `
208 a: fn(2)
209 b: fn(number)
210 fn: _`,
211 },
212
213
214
215 121: {subsumes: false, in: `a: c + d, b: int, c: int, d: int`},
216
217 122: {subsumes: true, in: `a: {}, b: c & {}, c: {}`},
218
219
220 123: {subsumes: true, in: `a: c, b: c, c: {}`},
221
222 124: {subsumes: true, in: `a: c, b: d, c: {}, d: {}`},
223 125: {subsumes: false, in: `a: c, b: d, c: {a:1}, d: {}`},
224
225 126: {subsumes: true, in: `a: c, b: d, c: {a:1}, d: c & {b:1}`},
226 127: {subsumes: false, in: `a: d, b: c, c: {a:1}, d: c & {b:1}`},
227 128: {subsumes: false, in: `a: c.c, b: c, c: { d: number}`},
228
229
230 129: {subsumes: false, in: `a: c, b: d, c: 1, d: 2`},
231
232 130: {subsumes: true, in: ` a: [1][1], b: [1][1]`},
233 131: {subsumes: true, in: ` a: [1][number], b: [1][1]`},
234 132: {subsumes: true, in: ` a: [number][1], b: [1][1]`},
235 133: {subsumes: true, in: ` a: [number][number], b: [1][1]`},
236 134: {subsumes: false, in: ` a: [1][0], b: [1][number]`},
237 135: {subsumes: false, in: ` a: [1][0], b: [number][0]`},
238 136: {subsumes: true, in: ` a: [number][number], b: [1][number]`},
239 137: {subsumes: true, in: ` a: [number][number], b: [number][1]`},
240
241 138: {subsumes: false, in: ` a: [number][number], b: number`},
242
243
244 139: {subsumes: true, in: ` a: "\(d)", b: "\(d)", d: _`},
245
246 140: {subsumes: true, in: ` a: "\(d)", b: "\(e)", d: _, e: _`},
247
248 141: {subsumes: true, in: ` a: "\(string)", b: "\("foo")"`},
249
250 142: {subsumes: true, in: ` a: "\(string)", b: "\(d)", d: "foo"`},
251 143: {subsumes: true, in: ` a: "\("foo")", b: "\("foo")"`},
252 144: {subsumes: false, in: ` a: "\("foo")", b: "\(1) \(2)"`},
253
254 145: {subsumes: false, in: ` a: "s \(d) e", b: "s a e", d: _`},
255 146: {subsumes: false, in: ` a: "s \(d)m\(d) e", b: "s a e", d: _`},
256
257
258
259
260 150: {subsumes: false, in: `a: number | *1, b: number | *2`},
261 151: {subsumes: true, in: `a: number | *2, b: number | *2`},
262 152: {subsumes: true, in: `a: int | *float, b: int | *2.0`},
263 153: {subsumes: false, in: `a: int | *2, b: int | *2.0`},
264 154: {subsumes: true, in: `a: number | *2 | *3, b: number | *2`},
265 155: {subsumes: true, in: `a: number, b: number | *2`},
266
267
268 170: {subsumes: true, in: `a: >=2, b: >=2`},
269 171: {subsumes: true, in: `a: >=1, b: >=2`},
270 172: {subsumes: true, in: `a: >0, b: >=2`},
271 173: {subsumes: true, in: `a: >1, b: >1`},
272 174: {subsumes: true, in: `a: >=1, b: >1`},
273 175: {subsumes: false, in: `a: >1, b: >=1`},
274 176: {subsumes: true, in: `a: >=1, b: >=1`},
275 177: {subsumes: true, in: `a: <1, b: <1`},
276 178: {subsumes: true, in: `a: <=1, b: <1`},
277 179: {subsumes: false, in: `a: <1, b: <=1`},
278 180: {subsumes: true, in: `a: <=1, b: <=1`},
279
280 181: {subsumes: true, in: `a: !=1, b: !=1`},
281 182: {subsumes: false, in: `a: !=1, b: !=2`},
282
283 183: {subsumes: false, in: `a: !=1, b: <=1`},
284 184: {subsumes: true, in: `a: !=1, b: <1`},
285 185: {subsumes: false, in: `a: !=1, b: >=1`},
286 186: {subsumes: true, in: `a: !=1, b: <1`},
287
288 187: {subsumes: true, in: `a: !=1, b: <=0`},
289 188: {subsumes: true, in: `a: !=1, b: >=2`},
290 189: {subsumes: true, in: `a: !=1, b: >1`},
291
292 195: {subsumes: false, in: `a: >=2, b: !=2`},
293 196: {subsumes: false, in: `a: >2, b: !=2`},
294 197: {subsumes: false, in: `a: <2, b: !=2`},
295 198: {subsumes: false, in: `a: <=2, b: !=2`},
296
297 200: {subsumes: true, in: `a: =~"foo", b: =~"foo"`},
298 201: {subsumes: false, in: `a: =~"foo", b: =~"bar"`},
299 202: {subsumes: false, in: `a: =~"foo1", b: =~"foo"`},
300
301 203: {subsumes: true, in: `a: !~"foo", b: !~"foo"`},
302 204: {subsumes: false, in: `a: !~"foo", b: !~"bar"`},
303 205: {subsumes: false, in: `a: !~"foo", b: !~"foo1"`},
304
305
306
307 210: {subsumes: false, in: `a: =~"foo", b: =~"foo1"`},
308 211: {subsumes: false, in: `a: !~"foo1", b: !~"foo"`},
309
310 220: {subsumes: true, in: `a: <5, b: 4`},
311 221: {subsumes: false, in: `a: <5, b: 5`},
312 222: {subsumes: true, in: `a: <=5, b: 5`},
313 223: {subsumes: false, in: `a: <=5.0, b: 5.00000001`},
314 224: {subsumes: true, in: `a: >5, b: 6`},
315 225: {subsumes: false, in: `a: >5, b: 5`},
316 226: {subsumes: true, in: `a: >=5, b: 5`},
317 227: {subsumes: false, in: `a: >=5, b: 4`},
318 228: {subsumes: true, in: `a: !=5, b: 6`},
319 229: {subsumes: false, in: `a: !=5, b: 5`},
320 230: {subsumes: false, in: `a: !=5.0, b: 5.0`},
321 231: {subsumes: false, in: `a: !=5.0, b: 5`},
322
323 250: {subsumes: true, in: `a: =~ #"^\d{3}$"#, b: "123"`},
324 251: {subsumes: false, in: `a: =~ #"^\d{3}$"#, b: "1234"`},
325 252: {subsumes: true, in: `a: !~ #"^\d{3}$"#, b: "1234"`},
326 253: {subsumes: false, in: `a: !~ #"^\d{3}$"#, b: "123"`},
327
328
329 300: {subsumes: true, in: `a: >0, b: >=2 & <=100`},
330 301: {subsumes: false, in: `a: >0, b: >=0 & <=100`},
331
332 310: {subsumes: true, in: `a: >=0 & <=100, b: 10`},
333 311: {subsumes: true, in: `a: >=0 & <=100, b: >=0 & <=100`},
334 312: {subsumes: false, in: `a: !=2 & !=4, b: >3`},
335 313: {subsumes: true, in: `a: !=2 & !=4, b: >5`},
336
337 314: {subsumes: false, in: `a: >=0 & <=100, b: >=0 & <=150`},
338 315: {subsumes: true, in: `a: >=0 & <=150, b: >=0 & <=100`},
339
340
341 330: {subsumes: true, in: `a: >5, b: >10 | 8`},
342 331: {subsumes: false, in: `a: >8, b: >10 | 8`},
343
344
345
346
347
348
349
350
351
352 400: {subsumes: false, in: `a: {foo: 1}, b: {}`},
353 401: {subsumes: false, in: `a: {foo?: 1}, b: {}`},
354 402: {subsumes: true, in: `a: {}, b: {foo: 1}`},
355 403: {subsumes: true, in: `a: {}, b: {foo?: 1}`},
356
357 404: {subsumes: true, in: `a: {foo: 1}, b: {foo: 1}`},
358 405: {subsumes: true, in: `a: {foo?: 1}, b: {foo: 1}`},
359 406: {subsumes: true, in: `a: {foo?: 1}, b: {foo?: 1}`},
360 407: {subsumes: false, in: `a: {foo: 1}, b: {foo?: 1}`},
361
362 408: {subsumes: false, in: `a: {foo: 1}, b: {foo: 2}`},
363 409: {subsumes: false, in: `a: {foo?: 1}, b: {foo: 2}`},
364 410: {subsumes: false, in: `a: {foo?: 1}, b: {foo?: 2}`},
365 411: {subsumes: false, in: `a: {foo: 1}, b: {foo?: 2}`},
366
367 412: {subsumes: true, in: `a: {foo: number}, b: {foo: 2}`},
368 413: {subsumes: true, in: `a: {foo?: number}, b: {foo: 2}`},
369 414: {subsumes: true, in: `a: {foo?: number}, b: {foo?: 2}`},
370 415: {subsumes: false, in: `a: {foo: number}, b: {foo?: 2}`},
371
372 416: {subsumes: false, in: `a: {foo: 1}, b: {foo: number}`},
373 417: {subsumes: false, in: `a: {foo?: 1}, b: {foo: number}`},
374 418: {subsumes: false, in: `a: {foo?: 1}, b: {foo?: number}`},
375 419: {subsumes: false, in: `a: {foo: 1}, b: {foo?: number}`},
376
377
378
379
380
381 420: {subsumes: true, in: `a: {foo?: _}, b: {}`},
382
383 430: {subsumes: false, in: `a: {[_]: 4}, b: {[_]: int}`},
384
385 431: {subsumes: false, in: `a: {[_]: int}, b: {[_]: 2}`},
386
387
388
389
390
391
392
393
394
395
396
397
398 506: {subsumes: true, in: `a: [], b: [] `},
399 507: {subsumes: true, in: `a: [1], b: [1] `},
400 508: {subsumes: false, in: `a: [1], b: [2] `},
401 509: {subsumes: false, in: `a: [1], b: [2, 3] `},
402 510: {subsumes: true, in: `a: [{b: string}], b: [{b: "foo"}] `},
403 511: {subsumes: true, in: `a: [...{b: string}], b: [{b: "foo"}] `},
404 512: {subsumes: false, in: `a: [{b: "foo"}], b: [{b: string}] `},
405 513: {subsumes: false, in: `a: [{b: string}], b: [{b: "foo"}, ...{b: "foo"}] `},
406 520: {subsumes: false, in: `a: [_, int, ...], b: [int, string, ...string] `},
407
408
409 600: {subsumes: false, in: `a: close({}), b: {a: 1}`},
410 601: {subsumes: false, in: `a: close({a: 1}), b: {a: 1}`},
411 602: {subsumes: false, in: `a: close({a: 1, b: 1}), b: {a: 1}`},
412 603: {subsumes: false, in: `a: {a: 1}, b: close({})`},
413 604: {subsumes: true, in: `a: {a: 1}, b: close({a: 1})`},
414 605: {subsumes: true, in: `a: {a: 1}, b: close({a: 1, b: 1})`},
415 606: {subsumes: true, in: `a: close({b?: 1}), b: close({b: 1})`},
416 607: {subsumes: false, in: `a: close({b: 1}), b: close({b?: 1})`},
417 608: {subsumes: true, in: `a: {}, b: close({})`},
418 609: {subsumes: true, in: `a: {}, b: close({foo?: 1})`},
419 610: {subsumes: true, in: `a: {foo?:1}, b: close({})`},
420
421
422 630: {subsumes: false, in: `a: {#a: 1}, b: {a: 1}`},
423 631: {subsumes: false, in: `a: {a: 1}, b: {#a: 1}`},
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448 }
449
450 re := regexp.MustCompile(`a: (.*).*b: ([^\n]*)`)
451 for i, tc := range testCases {
452 if tc.in == "" {
453 continue
454 }
455 m := re.FindStringSubmatch(strings.Join(strings.Split(tc.in, "\n"), ""))
456 const cutset = "\n ,"
457 key := strings.Trim(m[1], cutset) + " ⊑ " + strings.Trim(m[2], cutset)
458
459 r := runtime.New()
460
461 t.Run(strconv.Itoa(i)+"/"+key, func(t *testing.T) {
462
463 file, err := parser.ParseFile("subsume", tc.in)
464 if err != nil {
465 t.Fatal(err)
466 }
467
468 root, errs := compile.Files(nil, r, "", file)
469 if errs != nil {
470 t.Fatal(errs)
471 }
472
473 ctx := eval.NewContext(r, root)
474 root.Finalize(ctx)
475
476
477 var a, b adt.Value
478 for _, arc := range root.Arcs {
479 switch arc.Label {
480 case ctx.StringLabel("a"):
481 a = arc
482 case ctx.StringLabel("b"):
483 b = arc
484 }
485 }
486
487 err = Value(ctx, a, b)
488 got := err == nil
489
490 if got != tc.subsumes {
491 t.Errorf("got %v; want %v (%v vs %v)", got, tc.subsumes, a.Kind(), b.Kind())
492 }
493 })
494 }
495 }
496
View as plain text