this repo has no description
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

cue/testdata: convert txtar tests to inline @test format

Convert 11 txtar test files from golden-file
format (out/evalalpha, out/eval sections) to
inline @test(...) annotations. Also add rule
to CLAUDE.md for handling structure sharing
(~(field)) with shareID directives.

Files converted:
- basicrewrite/002_arithmetic.txtar
- basicrewrite/014_disjunctions.txtar
- eval/issue500.txtar
- fulleval/000_detect_conflicting_value.txtar
- fulleval/024_Issue_#23.txtar
- fulleval/027_len_of_incomplete_types.txtar
- fulleval/029_Issue_#94.txtar
- fulleval/031_comparison_against_bottom.txtar
- fulleval/041.txtar
- fulleval/042_cross-dependent_comprehension.txtar
- fulleval/046_non-structural_direct_cycles.txtar

Signed-off-by: Marcel van Lohuizen <mpvl@gmail.com>
Change-Id: I7f2f21543b3247fff5021f451b626c48d239b81d
Reviewed-on: https://cue.gerrithub.io/c/cue-lang/cue/+/1234947
Reviewed-by: Daniel Martí <mvdan@mvdan.cc>
TryBot-Result: CUEcueckoo <cueckoo@cuelang.org>
Unity-Result: CUE porcuepine <cue.porcuepine@gmail.com>

+293 -637
+11
CLAUDE.md
··· 162 162 as a field attribute after a closing `}` — e.g., `} @test(eq, ...)` is 163 163 wrong; move it inside the struct as a trailing decl attribute instead. 164 164 165 + 13. **Structure sharing (`~(field)`)**: When the `out/evalalpha` section shows a 166 + field as a shared reference (e.g., `y: ~(x)`), add `@test(shareID:v3=name)` to 167 + both the referencing field (`y`) and the referenced field (`x`), using the same 168 + name to assert they share the same underlying vertex. Use the `:v3` version suffix 169 + when the sharing is v3-specific (i.e., v2 expanded the field into an independent 170 + struct). Example: 171 + ``` 172 + x: a & {b: 1} @test(eq, {a: 1, b: 1}) @test(shareID:v3=xy) 173 + y: x @test(eq, {a: 1, b: 1}) @test(shareID:v3=xy) 174 + ``` 175 + 165 176 ### Contribution Model 166 177 - Single commit per PR/CL model 167 178 - Uses `git codereview` workflow for managing changes
+58 -128
cue/testdata/basicrewrite/002_arithmetic.txtar
··· 1 - #name: arithmetic 2 - #evalPartial 3 - #todo:inline: medium — evalPartial; incomplete values may need @test(kind=...) or @test(final) 4 1 -- in.cue -- 5 - i1: 1 & int 6 - i2: 2 & int 2 + i1: 1 & int @test(eq, 1) 3 + i2: 2 & int @test(eq, 2) 7 4 8 - sum: -1 + +2 // 1 9 - div1: 2.0 / 3 * 6 // 4 10 - div2: 2 / 3 * 6 // 4 11 - div3: 1.00 / 1.00 12 - divZero: 1.0 / 0 13 - div00: 0 / 0 14 - b: 1 != 4 15 - add: div1 + 1.0 5 + sum: -1 + +2 @test(eq, 1) 6 + div1: 2.0 / 3 * 6 @test(eq, 4.0) @test(kind=float) 7 + div2: 2 / 3 * 6 @test(eq, 4.0) @test(kind=float, 8 + hint="we may consider this to be int in the future") 9 + div3: 1.00 / 1.00 @test(eq, 1.0) @test(kind=float) 10 + divZero: 1.0 / 0 @test(err, code=eval, contains="division by zero", pos=[0:10]) 11 + div00: 0 / 0 @test(err, code=eval, contains="division undefined", pos=[0:10]) 12 + b: 1 != 4 @test(eq, true) 13 + add: div1 + 1.0 @test(eq, 5.0) 14 + 15 + idiv00: div(0, 0) @test(err, code=eval, contains="division by zero", pos=[0:9]) 16 + imod00: mod(0, 0) @test(err, code=eval, contains="division by zero", pos=[0:9]) 17 + iquo00: quo(0, 0) @test(err, code=eval, contains="division by zero", pos=[0:9]) 18 + irem00: rem(0, 0) @test(err, code=eval, contains="division by zero", pos=[0:9]) 16 19 17 - idiv00: div(0, 0) 18 - imod00: mod(0, 0) 19 - iquo00: quo(0, 0) 20 - irem00: rem(0, 0) 20 + v1: 1.0T / 2.0 @test(eq, 5.0E+11) 21 + v2: 2.0 == 2 @test(eq, true) 22 + v3: 2.0 / 3.0 @test(eq, 0.6666666666666666666666666666666667) 23 + v5: div(i1, i2) @test(eq, 0) 21 24 22 - v1: 1.0T / 2.0 23 - v2: 2.0 == 2 24 - v3: 2.0 / 3.0 25 - v5: div(i1, i2) 25 + e0: 2 + "a" @test(err, code=eval, contains="invalid operands", pos=[0:5, 0:9]) 26 + e5: div(1.0, 2) @test(err, code=eval, contains="cannot use", pos=[0:9]) 27 + e6: rem(2, 2.0) @test(err, code=eval, contains="cannot use", pos=[0:12]) 28 + e7: quo(2, 2.0) @test(err, code=eval, contains="cannot use", pos=[0:12]) 29 + e8: mod(1.0, 1) @test(err, code=eval, contains="cannot use", pos=[0:9]) 30 + -- out/errors.txt -- 31 + [eval] divZero: failed arithmetic: division by zero: 32 + ./in.cue:8:10 33 + [eval] div00: failed arithmetic: division undefined: 34 + ./in.cue:9:10 35 + [eval] idiv00: error in call to div: division by zero: 36 + ./in.cue:13:9 37 + [eval] imod00: error in call to mod: division by zero: 38 + ./in.cue:14:9 39 + [eval] iquo00: error in call to quo: division by zero: 40 + ./in.cue:15:9 41 + [eval] irem00: error in call to rem: division by zero: 42 + ./in.cue:16:9 43 + [eval] e0: invalid operands 2 and "a" to '+' (type int and string): 44 + ./in.cue:23:5 45 + ./in.cue:23:9 46 + [eval] e5: cannot use 1.0 (type float) as int in argument 1 to div: 47 + ./in.cue:29:9 48 + [eval] e6: cannot use 2.0 (type float) as int in argument 2 to rem: 49 + ./in.cue:30:12 50 + [eval] e7: cannot use 2.0 (type float) as int in argument 2 to quo: 51 + ./in.cue:31:12 52 + [eval] e8: cannot use 1.0 (type float) as int in argument 1 to mod: 53 + ./in.cue:32:9 54 + -- out/eval/stats -- 55 + Leaks: 0 56 + Freed: 24 57 + Reused: 22 58 + Allocs: 2 59 + Retain: 0 26 60 27 - e0: 2 + "a" 28 - // these are now all alloweed 29 - // e1: 2.0 / i1 30 - // e2: i1 / 2.0 31 - // e3: 3.0 % i2 32 - // e4: i1 % 2.0 33 - e5: div(1.0, 2) 34 - e6: rem(2, 2.0) 35 - e7: quo(2, 2.0) 36 - e8: mod(1.0, 1) 61 + Unifications: 24 62 + Conjuncts: 26 63 + Disjuncts: 24 37 64 -- out/compile -- 38 65 --- in.cue 39 66 { ··· 61 88 e7: quo(2, 2.0) 62 89 e8: mod(1.0, 1) 63 90 } 64 - -- out/eval/stats -- 65 - Leaks: 0 66 - Freed: 24 67 - Reused: 22 68 - Allocs: 2 69 - Retain: 0 70 - 71 - Unifications: 24 72 - Conjuncts: 26 73 - Disjuncts: 24 74 - -- out/evalalpha -- 75 - Errors: 76 - divZero: failed arithmetic: division by zero: 77 - ./in.cue:8:10 78 - div00: failed arithmetic: division undefined: 79 - ./in.cue:9:10 80 - idiv00: error in call to div: division by zero: 81 - ./in.cue:13:9 82 - imod00: error in call to mod: division by zero: 83 - ./in.cue:14:9 84 - iquo00: error in call to quo: division by zero: 85 - ./in.cue:15:9 86 - irem00: error in call to rem: division by zero: 87 - ./in.cue:16:9 88 - e0: invalid operands 2 and "a" to '+' (type int and string): 89 - ./in.cue:23:5 90 - ./in.cue:23:9 91 - e5: cannot use 1.0 (type float) as int in argument 1 to div: 92 - ./in.cue:29:9 93 - e6: cannot use 2.0 (type float) as int in argument 2 to rem: 94 - ./in.cue:30:12 95 - e7: cannot use 2.0 (type float) as int in argument 2 to quo: 96 - ./in.cue:31:12 97 - e8: cannot use 1.0 (type float) as int in argument 1 to mod: 98 - ./in.cue:32:9 99 - 100 - Result: 101 - (_|_){ 102 - // [eval] 103 - i1: (int){ 1 } 104 - i2: (int){ 2 } 105 - sum: (int){ 1 } 106 - div1: (float){ 4.000000000000000000000000000000000 } 107 - div2: (float){ 4.000000000000000000000000000000000 } 108 - div3: (float){ 1.0 } 109 - divZero: (_|_){ 110 - // [eval] divZero: failed arithmetic: division by zero: 111 - // ./in.cue:8:10 112 - } 113 - div00: (_|_){ 114 - // [eval] div00: failed arithmetic: division undefined: 115 - // ./in.cue:9:10 116 - } 117 - b: (bool){ true } 118 - add: (float){ 5.000000000000000000000000000000000 } 119 - idiv00: (_|_){ 120 - // [eval] idiv00: error in call to div: division by zero: 121 - // ./in.cue:13:9 122 - } 123 - imod00: (_|_){ 124 - // [eval] imod00: error in call to mod: division by zero: 125 - // ./in.cue:14:9 126 - } 127 - iquo00: (_|_){ 128 - // [eval] iquo00: error in call to quo: division by zero: 129 - // ./in.cue:15:9 130 - } 131 - irem00: (_|_){ 132 - // [eval] irem00: error in call to rem: division by zero: 133 - // ./in.cue:16:9 134 - } 135 - v1: (float){ 5.0E+11 } 136 - v2: (bool){ true } 137 - v3: (float){ 0.6666666666666666666666666666666667 } 138 - v5: (int){ 0 } 139 - e0: (_|_){ 140 - // [eval] e0: invalid operands 2 and "a" to '+' (type int and string): 141 - // ./in.cue:23:5 142 - // ./in.cue:23:9 143 - } 144 - e5: (_|_){ 145 - // [eval] e5: cannot use 1.0 (type float) as int in argument 1 to div: 146 - // ./in.cue:29:9 147 - } 148 - e6: (_|_){ 149 - // [eval] e6: cannot use 2.0 (type float) as int in argument 2 to rem: 150 - // ./in.cue:30:12 151 - } 152 - e7: (_|_){ 153 - // [eval] e7: cannot use 2.0 (type float) as int in argument 2 to quo: 154 - // ./in.cue:31:12 155 - } 156 - e8: (_|_){ 157 - // [eval] e8: cannot use 1.0 (type float) as int in argument 1 to mod: 158 - // ./in.cue:32:9 159 - } 160 - }
+26 -50
cue/testdata/basicrewrite/014_disjunctions.txtar
··· 1 - #name: disjunctions 2 - #evalPartial 3 - #todo:inline: medium — disjunctions; use @test(final) for default selection 4 1 -- in.cue -- 5 - o1: 1 | 2 | 3 6 - o2: (1 | 2 | 3) & 1 7 - o3: 2 & (1 | *2 | 3) 8 - o4: (1 | *2 | 3) & (1 | 2 | *3) 9 - o5: (1 | *2 | 3) & (3 | *2 | 1) 10 - o6: (1 | 2 | 3) & (3 | 1 | 2) 11 - o7: (1 | 2 | 3) & (2 | 3) 12 - o8: (1 | 2 | 3) & (3 | 2) 13 - o9: (2 | 3) & (1 | 2 | 3) 14 - o10: (3 | 2) & (1 | *2 | 3) 2 + o1: 1 | 2 | 3 @test(eq, 1 | 2 | 3) 3 + o2: (1 | 2 | 3) & 1 @test(eq, 1) 4 + o3: 2 & (1 | *2 | 3) @test(eq, 2) 5 + o4: (1 | *2 | 3) & (1 | 2 | *3) @test(eq, 1 | 2 | 3) 6 + o5: (1 | *2 | 3) & (3 | *2 | 1) @test(eq, *2 | 1 | 3) 7 + o6: (1 | 2 | 3) & (3 | 1 | 2) @test(eq, 1 | 2 | 3) 8 + o7: (1 | 2 | 3) & (2 | 3) @test(eq, 2 | 3) 9 + o8: (1 | 2 | 3) & (3 | 2) @test(eq, 2 | 3) 10 + o9: (2 | 3) & (1 | 2 | 3) @test(eq, 2 | 3) 11 + o10: (3 | 2) & (1 | *2 | 3) @test(eq, *2 | 3) 15 12 16 - m1: (1 | (*2 | 3)) & (>=2 & <=3) 17 - m2: (1 | (*2 | 3)) & (2 | 3) 18 - m3: (*1 | *(*2 | 3)) & (2 | 3) 19 - m4: (2 | 3) & (*2 | 3) 20 - m5: (*2 | 3) & (2 | 3) 13 + m1: (1 | (*2 | 3)) & (>=2 & <=3) @test(eq, *2 | 3) 14 + m2: (1 | (*2 | 3)) & (2 | 3) @test(eq, *2 | 3) 15 + m3: (*1 | *(*2 | 3)) & (2 | 3) @test(eq, *2 | 3) 16 + m4: (2 | 3) & (*2 | 3) @test(eq, *2 | 3) 17 + m5: (*2 | 3) & (2 | 3) @test(eq, *2 | 3) 21 18 22 - // (*2 | 3) & (2 | 3) 23 - // (2 | 3) & (*2 | 3) 24 19 // 2&(*2 | 3) | 3&(*2 | 3) 25 20 // (*1 | (*2 | 3)) & (2 | 3) 26 21 // *1& (2 | 3) | (*2 | 3)&(2 | 3) ··· 33 28 // *2 | 3 34 29 35 30 // All errors are treated the same as per the unification model. 36 - i1: [1, 2][3] | "c" 31 + i1: [1, 2][3] | "c" @test(eq, "c") 32 + -- out/eval/stats -- 33 + Leaks: 1 34 + Freed: 134 35 + Reused: 126 36 + Allocs: 9 37 + Retain: 1 38 + 39 + Unifications: 18 40 + Conjuncts: 150 41 + Disjuncts: 135 37 42 -- out/compile -- 38 43 --- in.cue 39 44 { ··· 57 62 2, 58 63 ][3]|"c") 59 64 } 60 - -- out/eval/stats -- 61 - Leaks: 1 62 - Freed: 134 63 - Reused: 126 64 - Allocs: 9 65 - Retain: 1 66 - 67 - Unifications: 18 68 - Conjuncts: 150 69 - Disjuncts: 135 70 - -- out/evalalpha -- 71 - (struct){ 72 - o1: (int){ |((int){ 1 }, (int){ 2 }, (int){ 3 }) } 73 - o2: (int){ 1 } 74 - o3: (int){ 2 } 75 - o4: (int){ |((int){ 1 }, (int){ 2 }, (int){ 3 }) } 76 - o5: (int){ |(*(int){ 2 }, (int){ 1 }, (int){ 3 }) } 77 - o6: (int){ |((int){ 1 }, (int){ 2 }, (int){ 3 }) } 78 - o7: (int){ |((int){ 2 }, (int){ 3 }) } 79 - o8: (int){ |((int){ 2 }, (int){ 3 }) } 80 - o9: (int){ |((int){ 2 }, (int){ 3 }) } 81 - o10: (int){ |(*(int){ 2 }, (int){ 3 }) } 82 - m1: (int){ |(*(int){ 2 }, (int){ 3 }) } 83 - m2: (int){ |(*(int){ 2 }, (int){ 3 }) } 84 - m3: (int){ |(*(int){ 2 }, (int){ 3 }) } 85 - m4: (int){ |(*(int){ 2 }, (int){ 3 }) } 86 - m5: (int){ |(*(int){ 2 }, (int){ 3 }) } 87 - i1: (string){ "c" } 88 - }
+18 -32
cue/testdata/fulleval/000_detect_conflicting_value.txtar
··· 1 - #name: detect conflicting value 2 - #evalFull 3 - #todo:inline: medium — disjunctions; use @test(final) for default selection 1 + # Tests that a float value conflicting with a disjunction of an int value and int type 2 + # reports an empty disjunction error. Issue: regression test for early evaluator behavior. 4 3 -- in.cue -- 5 4 a: 8000.9 6 - a: 7080 | int 7 - -- out/compile -- 8 - --- in.cue 9 - { 10 - a: 8000.9 11 - a: (7080|int) 12 - } 5 + a: 7080 | int @test(err, code=eval, 6 + suberr=(code=eval, contains="conflicting values", args=[8000.9, 7080], pos=[in.cue:1:4, in.cue:2:4]), 7 + suberr=(code=eval, contains="conflicting values", args=[8000.9, int], pos=[in.cue:1:4, in.cue:2:11])) 8 + -- out/errors.txt -- 9 + [eval] a: 2 errors in empty disjunction: 10 + a: conflicting values 8000.9 and 7080 (mismatched types float and int): 11 + ./in.cue:1:4 12 + ./in.cue:2:4 13 + a: conflicting values 8000.9 and int (mismatched types float and int): 14 + ./in.cue:1:4 15 + ./in.cue:2:11 13 16 -- out/eval/stats -- 14 17 Leaks: 0 15 18 Freed: 4 ··· 20 23 Unifications: 2 21 24 Conjuncts: 5 22 25 Disjuncts: 4 23 - -- out/evalalpha -- 24 - Errors: 25 - a: 2 errors in empty disjunction: 26 - a: conflicting values 8000.9 and 7080 (mismatched types float and int): 27 - ./in.cue:1:4 28 - ./in.cue:2:4 29 - a: conflicting values 8000.9 and int (mismatched types float and int): 30 - ./in.cue:1:4 31 - ./in.cue:2:11 32 - 33 - Result: 34 - (_|_){ 35 - // [eval] 36 - a: (_|_){ 37 - // [eval] a: 2 errors in empty disjunction: 38 - // a: conflicting values 8000.9 and 7080 (mismatched types float and int): 39 - // ./in.cue:1:4 40 - // ./in.cue:2:4 41 - // a: conflicting values 8000.9 and int (mismatched types float and int): 42 - // ./in.cue:1:4 43 - // ./in.cue:2:11 44 - } 26 + -- out/compile -- 27 + --- in.cue 28 + { 29 + a: 8000.9 30 + a: (7080|int) 45 31 }
+26 -48
cue/testdata/fulleval/024_Issue_#23.txtar
··· 1 - #name: Issue #23 2 - #evalFull 3 - #todo:inline: medium — disjunctions; use @test(final) for default selection 1 + # Tests that unifying a struct with a disjunction where neither branch matches reports 2 + # an empty disjunction error. Issue #23. 4 3 -- in.cue -- 5 - x: {a: 1} | {a: 2} 6 - y: x & {a: 3} 4 + x: {a: 1} | {a: 2} 5 + y: x & {a: 3} @test(err, code=eval, 6 + suberr=(code=eval, contains="conflicting values", args=[1, 3], pos=[in.cue:1:8, in.cue:2:4, in.cue:2:12]), 7 + suberr=(code=eval, contains="conflicting values", args=[2, 3], pos=[in.cue:1:17, in.cue:2:4, in.cue:2:12])) 8 + -- out/errors.txt -- 9 + [eval] y: 2 errors in empty disjunction: 10 + y.a: conflicting values 1 and 3: 11 + ./in.cue:1:8 12 + ./in.cue:2:4 13 + ./in.cue:2:12 14 + y.a: conflicting values 2 and 3: 15 + ./in.cue:1:17 16 + ./in.cue:2:4 17 + ./in.cue:2:12 18 + -- out/eval/stats -- 19 + Leaks: 0 20 + Freed: 11 21 + Reused: 6 22 + Allocs: 5 23 + Retain: 0 24 + 25 + Unifications: 7 26 + Conjuncts: 15 27 + Disjuncts: 11 7 28 -- out/compile -- 8 29 --- in.cue 9 30 { ··· 16 37 a: 3 17 38 }) 18 39 } 19 - -- out/eval/stats -- 20 - Leaks: 0 21 - Freed: 11 22 - Reused: 6 23 - Allocs: 5 24 - Retain: 0 25 - 26 - Unifications: 7 27 - Conjuncts: 15 28 - Disjuncts: 11 29 - -- out/evalalpha -- 30 - Errors: 31 - y: 2 errors in empty disjunction: 32 - y.a: conflicting values 1 and 3: 33 - ./in.cue:1:12 34 - ./in.cue:2:4 35 - ./in.cue:2:12 36 - y.a: conflicting values 2 and 3: 37 - ./in.cue:1:21 38 - ./in.cue:2:4 39 - ./in.cue:2:12 40 - 41 - Result: 42 - (_|_){ 43 - // [eval] 44 - x: (struct){ |((struct){ 45 - a: (int){ 1 } 46 - }, (struct){ 47 - a: (int){ 2 } 48 - }) } 49 - y: (_|_){ 50 - // [eval] y: 2 errors in empty disjunction: 51 - // y.a: conflicting values 1 and 3: 52 - // ./in.cue:1:12 53 - // ./in.cue:2:4 54 - // ./in.cue:2:12 55 - // y.a: conflicting values 2 and 3: 56 - // ./in.cue:1:21 57 - // ./in.cue:2:4 58 - // ./in.cue:2:12 59 - a: (int){ 3 } 60 - } 61 - }
+20 -71
cue/testdata/fulleval/027_len_of_incomplete_types.txtar
··· 1 - #name: len of incomplete types 2 - #evalFull 3 - #todo:inline: medium — disjunctions; use @test(final) for default selection 4 1 -- in.cue -- 5 2 args: *[] | [...string] 6 - v1: len(args) 7 - v2: len([]) 8 - v3: len({}) 9 - v4: len({a: 3}) 10 - v5: len({a: 3} | {a: 4}) 11 - v6: len('sf' | 'dd') 12 - v7: len([2] | *[1, 2]) 13 - v8: len([2] | [1, 2]) 14 - v9: len("😂") 15 - v10: len("") 16 - -- out/evalalpha/stats -- 3 + v1: len(args) @test(eq, 0) 4 + v2: len([]) @test(eq, 0) 5 + v3: len({}) @test(eq, 0) 6 + v4: len({a: 3}) @test(eq, 1) 7 + v5: len({a: 3} | {a: 4}) @test(err, code=incomplete, contains="unresolved disjunction", pos=[in.cue:6:5]) 8 + v6: len('sf' | 'dd') @test(err, code=incomplete, contains="unresolved disjunction", pos=[in.cue:7:5]) 9 + v7: len([2] | *[1, 2]) @test(eq, 2) 10 + v8: len([2] | [1, 2]) @test(err, code=incomplete, contains="unresolved disjunction", pos=[in.cue:9:5]) 11 + v9: len("😂") @test(eq, 4, 12 + hint="len of strings should be deprecated and this should be an error in the future") 13 + v10: len("") @test(eq, 0, 14 + hint="len of strings should be deprecated and this should be an error in the future") 15 + -- out/errors.txt -- 16 + [incomplete] v5: unresolved disjunction {a:3} | {a:4} (type struct): 17 + ./in.cue:6:5 18 + [incomplete] v6: unresolved disjunction 'sf' | 'dd' (type bytes): 19 + ./in.cue:7:5 20 + [incomplete] v8: unresolved disjunction [2] | [1,2] (type list): 21 + ./in.cue:9:5 22 + -- out/eval/stats -- 17 23 Leaks: 0 18 24 Freed: 38 19 25 Reused: 20 ··· 23 29 Unifications: 27 24 30 Conjuncts: 37 25 31 Disjuncts: 10 26 - -- diff/-out/evalalpha/stats<==>+out/eval/stats -- 27 - diff old new 28 - --- old 29 - +++ new 30 - @@ -1,9 +1,9 @@ 31 - -Leaks: 3 32 - -Freed: 90 33 - -Reused: 84 34 - -Allocs: 9 35 - -Retain: 3 36 - +Leaks: 0 37 - +Freed: 38 38 - +Reused: 20 39 - +Allocs: 18 40 - +Retain: 0 41 - 42 - -Unifications: 59 43 - -Conjuncts: 105 44 - -Disjuncts: 93 45 - +Unifications: 27 46 - +Conjuncts: 37 47 - +Disjuncts: 10 48 - -- out/eval/stats -- 49 - Leaks: 3 50 - Freed: 90 51 - Reused: 84 52 - Allocs: 9 53 - Retain: 3 54 - 55 - Unifications: 59 56 - Conjuncts: 105 57 - Disjuncts: 93 58 - -- out/evalalpha -- 59 - (struct){ 60 - args: (list){ |(*(#list){ 61 - }, (list){ 62 - }) } 63 - v1: (int){ 0 } 64 - v2: (int){ 0 } 65 - v3: (int){ 0 } 66 - v4: (int){ 1 } 67 - v5: (_|_){ 68 - // [incomplete] v5: unresolved disjunction {a:3} | {a:4} (type struct): 69 - // ./in.cue:6:7 70 - } 71 - v6: (_|_){ 72 - // [incomplete] v6: unresolved disjunction 'sf' | 'dd' (type bytes): 73 - // ./in.cue:7:7 74 - } 75 - v7: (int){ 2 } 76 - v8: (_|_){ 77 - // [incomplete] v8: unresolved disjunction [2] | [1,2] (type list): 78 - // ./in.cue:9:7 79 - } 80 - v9: (int){ 4 } 81 - v10: (int){ 0 } 82 - } 83 32 -- out/compile -- 84 33 --- in.cue 85 34 {
+37 -67
cue/testdata/fulleval/029_Issue_#94.txtar
··· 1 - #name: Issue #94 2 - #evalFull 3 - #todo:inline: medium — comprehension; may need @test(final) for incomplete fields 1 + # Tests field visibility and comprehension iteration: comprehensions only iterate 2 + # regular (non-optional, non-hidden, non-definition) fields; select and index access 3 + # have different rules for optional, hidden, and definition fields. Issue #94. 4 4 -- in.cue -- 5 5 foo: { 6 6 opt?: 1 ··· 8 8 #def: 3 9 9 regular: 4 10 10 _hidden: 5 11 + @test(eq, {opt?: 1, txt: 2, #def: 3, regular: 4, _hidden: 5}) 11 12 } 12 13 comp: {for k, v in foo {"\(k)": v}} 13 14 select: { 14 - opt: foo.opt 15 - "txt": foo.txt 16 - #def: foo.#def 17 - regular: foo.regular 18 - _hidden: foo._hidden 15 + opt: foo.opt @test(err, code=incomplete, contains="cannot reference optional field", pos=[0:15]) 16 + "txt": foo.txt @test(eq, 2) 17 + #def: foo.#def @test(eq, 3) 18 + regular: foo.regular @test(eq, 4) 19 + _hidden: foo._hidden @test(eq, 5) 19 20 } 20 21 index: { 21 - opt: foo["opt"] 22 - "txt": foo["txt"] 23 - #def: foo["#def"] 24 - regular: foo["regular"] 25 - _hidden: foo["_hidden"] 22 + opt: foo["opt"] @test(err, code=incomplete, contains="cannot reference optional field", pos=[0:15]) 23 + "txt": foo["txt"] @test(eq, 2) 24 + #def: foo["#def"] @test(err, code=incomplete, contains="undefined field", pos=[0:15]) 25 + regular: foo["regular"] @test(eq, 4) 26 + _hidden: foo["_hidden"] @test(err, code=incomplete, contains="undefined field", pos=[0:15]) 26 27 } 28 + -- out/errors.txt -- 29 + [incomplete] select.opt: cannot reference optional field: opt: 30 + ./in.cue:10:15 31 + [incomplete] index.opt: cannot reference optional field: opt: 32 + ./in.cue:17:15 33 + [incomplete] index.#def: undefined field: "#def": 34 + ./in.cue:19:15 35 + [incomplete] index._hidden: undefined field: "_hidden": 36 + ./in.cue:21:15 37 + -- out/eval/stats -- 38 + Leaks: 0 39 + Freed: 22 40 + Reused: 19 41 + Allocs: 3 42 + Retain: 0 43 + 44 + Unifications: 22 45 + Conjuncts: 32 46 + Disjuncts: 22 47 + 48 + MisalignedConjunct: 1 49 + 50 + NumCloseIDs: 1 27 51 -- out/compile -- 28 52 --- in.cue 29 53 { ··· 54 78 _hidden: 〈1;foo〉["_hidden"] 55 79 } 56 80 } 57 - -- out/eval/stats -- 58 - Leaks: 0 59 - Freed: 22 60 - Reused: 19 61 - Allocs: 3 62 - Retain: 0 63 - 64 - Unifications: 22 65 - Conjuncts: 32 66 - Disjuncts: 22 67 - 68 - MisalignedConjunct: 1 69 - 70 - NumCloseIDs: 1 71 - -- out/evalalpha -- 72 - (struct){ 73 - foo: (struct){ 74 - opt?: (int){ 1 } 75 - txt: (int){ 2 } 76 - #def: (int){ 3 } 77 - regular: (int){ 4 } 78 - _hidden: (int){ 5 } 79 - } 80 - comp: (struct){ 81 - txt: (int){ 2 } 82 - regular: (int){ 4 } 83 - } 84 - select: (struct){ 85 - opt: (_|_){ 86 - // [incomplete] select.opt: cannot reference optional field: opt: 87 - // ./in.cue:10:15 88 - } 89 - txt: (int){ 2 } 90 - #def: (int){ 3 } 91 - regular: (int){ 4 } 92 - _hidden: (int){ 5 } 93 - } 94 - index: (struct){ 95 - opt: (_|_){ 96 - // [incomplete] index.opt: cannot reference optional field: opt: 97 - // ./in.cue:17:15 98 - } 99 - txt: (int){ 2 } 100 - #def: (_|_){ 101 - // [incomplete] index.#def: undefined field: "#def": 102 - // ./in.cue:19:15 103 - } 104 - regular: (int){ 4 } 105 - _hidden: (_|_){ 106 - // [incomplete] index._hidden: undefined field: "_hidden": 107 - // ./in.cue:21:15 108 - } 109 - } 110 - }
+33 -55
cue/testdata/fulleval/031_comparison_against_bottom.txtar
··· 1 - #name: comparison against bottom 2 - #evalFull 3 - #todo:inline: medium — multiple error cases; annotate with @test(err) per field 4 1 -- in.cue -- 5 - a: _|_ == _|_ 6 - b: err == 1 & 2 // not a literal error, so not allowed 7 - c: err == _|_ // allowed 8 - d: err != _|_ // allowed 9 - e: err != 1 & 3 2 + a: _|_ == _|_ @test(eq, true) 3 + b: err == 1 & 2 @test(err, code=eval, contains="conflicting values", args=[2, 1], pos=[in.cue:12:6, in.cue:12:10]) // not a literal error, so not allowed 4 + c: err == _|_ @test(eq, true) // allowed 5 + d: err != _|_ @test(eq, false) // allowed 6 + e: err != 1 & 3 @test(err, code=eval, contains="conflicting values", args=[2, 1], pos=[in.cue:12:6, in.cue:12:10]) 10 7 // z: err == err // TODO: should infer to be true? 11 - f: ({a: 1} & {a: 2}) == _|_ 12 - g: ({a: 1} & {b: 2}) == _|_ 13 - h: _|_ == ({a: 1} & {a: 2}) 14 - i: _|_ == ({a: 1} & {b: 2}) 8 + f: ({a: 1} & {a: 2}) == _|_ @test(eq, true) 9 + g: ({a: 1} & {b: 2}) == _|_ @test(eq, false) 10 + h: _|_ == ({a: 1} & {a: 2}) @test(eq, true) 11 + i: _|_ == ({a: 1} & {b: 2}) @test(eq, false) 15 12 16 - err: 1 & 2 13 + err: 1 & 2 @test(err, code=eval, contains="conflicting values 2 and 1", pos=[in.cue:12:6, in.cue:12:10]) 14 + -- out/errors.txt -- 15 + [eval] err: conflicting values 2 and 1: 16 + ./in.cue:12:6 17 + ./in.cue:12:10 18 + [eval] err: conflicting values 2 and 1: 19 + ./in.cue:12:6 20 + ./in.cue:12:10 21 + [eval] err: conflicting values 2 and 1: 22 + ./in.cue:12:6 23 + ./in.cue:12:10 24 + -- out/todo.txt -- 25 + Our aim is to disallow comparisons against errors and replace them with more 26 + precise functions. 27 + -- out/eval/stats -- 28 + Leaks: 0 29 + Freed: 21 30 + Reused: 16 31 + Allocs: 5 32 + Retain: 4 33 + 34 + Unifications: 21 35 + Conjuncts: 28 36 + Disjuncts: 21 17 37 -- out/compile -- 18 38 --- in.cue 19 39 { ··· 44 64 })) 45 65 err: (1 & 2) 46 66 } 47 - -- out/eval/stats -- 48 - Leaks: 0 49 - Freed: 21 50 - Reused: 16 51 - Allocs: 5 52 - Retain: 4 53 - 54 - Unifications: 21 55 - Conjuncts: 28 56 - Disjuncts: 21 57 - -- out/evalalpha -- 58 - Errors: 59 - err: conflicting values 2 and 1: 60 - ./in.cue:12:6 61 - ./in.cue:12:10 62 - 63 - Result: 64 - (_|_){ 65 - // [eval] 66 - a: (bool){ true } 67 - b: (_|_){ 68 - // [eval] err: conflicting values 2 and 1: 69 - // ./in.cue:12:6 70 - // ./in.cue:12:10 71 - } 72 - c: (bool){ true } 73 - d: (bool){ false } 74 - e: (_|_){ 75 - // [eval] err: conflicting values 2 and 1: 76 - // ./in.cue:12:6 77 - // ./in.cue:12:10 78 - } 79 - f: (bool){ true } 80 - g: (bool){ false } 81 - h: (bool){ true } 82 - i: (bool){ false } 83 - err: (_|_){ 84 - // [eval] err: conflicting values 2 and 1: 85 - // ./in.cue:12:6 86 - // ./in.cue:12:10 87 - } 88 - }
+16 -26
cue/testdata/fulleval/041.txtar
··· 1 - #evalFull 2 - #todo:inline: medium — comprehension; may need @test(final) for incomplete fields 3 1 -- in.cue -- 4 2 t: { 5 3 #ok: *true | bool 6 4 if #ok { 7 5 x: int 8 6 } 9 - } 10 - s: t & { 11 - #ok: false 12 - } 13 - -- out/compile -- 14 - --- in.cue 15 - { 16 - t: { 17 - #ok: (*true|bool) 18 - if 〈0;#ok〉 { 19 - x: int 20 - } 21 - } 22 - s: (〈0;t〉 & { 23 - #ok: false 24 - }) 7 + @test(eq, { 8 + #ok: *true | bool 9 + x: int 10 + }) 25 11 } 12 + s: t & {#ok: false} @test(eq, {#ok: false}) 26 13 -- out/eval/stats -- 27 14 Leaks: 0 28 15 Freed: 11 ··· 37 24 MisalignedConjunct: 1 38 25 39 26 NumCloseIDs: 2 40 - -- out/evalalpha -- 41 - (struct){ 42 - t: (struct){ 43 - #ok: (bool){ |(*(bool){ true }, (bool){ bool }) } 44 - x: (int){ int } 27 + -- out/compile -- 28 + --- in.cue 29 + { 30 + t: { 31 + #ok: (*true|bool) 32 + if 〈0;#ok〉 { 33 + x: int 34 + } 45 35 } 46 - s: (struct){ 47 - #ok: (bool){ false } 48 - } 36 + s: (〈0;t〉 & { 37 + #ok: false 38 + }) 49 39 }
+21 -68
cue/testdata/fulleval/042_cross-dependent_comprehension.txtar
··· 1 - #name: cross-dependent comprehension 2 - #evalFull 3 - #todo:inline: medium — comprehension; may need @test(final) for incomplete fields 1 + # Tests that comprehension conditions referencing fields resolve correctly when the 2 + # condition is cross-dependent. x unifies #a with b:true and c:4, resolving the 3 + # comprehension. y is an alias of x with the same value. 4 4 -- in.cue -- 5 5 #a: { 6 6 if b { 7 7 c: 4 8 8 } 9 9 b: bool 10 + @test(err, code=incomplete, args=[bool], pos=[in.cue:5:5]) 10 11 } 11 - x: (#a & {b: true}) & {c: 4} 12 - y: x 12 + x: (#a & {b: true}) & {c: 4} @test(eq, {b: true, c: 4}) @test(shareID=xy) 13 + y: x @test(eq, {b: true, c: 4}) @test(shareID=xy) 14 + -- out/errors.txt -- 15 + [incomplete] #a: incomplete bool: bool: 16 + ./in.cue:5:5 17 + -- out/eval/stats -- 18 + Leaks: 0 19 + Freed: 10 20 + Reused: 6 21 + Allocs: 4 22 + Retain: 4 23 + 24 + Unifications: 10 25 + Conjuncts: 18 26 + Disjuncts: 12 27 + 28 + NumCloseIDs: 3 13 29 -- out/compile -- 14 30 --- in.cue 15 31 { ··· 26 42 }) 27 43 y: 〈0;x〉 28 44 } 29 - -- out/eval/stats -- 30 - Leaks: 0 31 - Freed: 10 32 - Reused: 6 33 - Allocs: 4 34 - Retain: 4 35 - 36 - Unifications: 10 37 - Conjuncts: 18 38 - Disjuncts: 12 39 - 40 - NumCloseIDs: 3 41 - -- out/evalalpha -- 42 - (struct){ 43 - #a: (_|_){ 44 - // [incomplete] #a: incomplete bool: bool: 45 - // ./in.cue:5:5 46 - b: (bool){ bool } 47 - } 48 - x: (#struct){ 49 - b: (bool){ true } 50 - c: (int){ 4 } 51 - } 52 - y: ~(x) 53 - } 54 - -- diff/-out/evalalpha<==>+out/eval -- 55 - diff old new 56 - --- old 57 - +++ new 58 - @@ -5,11 +5,8 @@ 59 - b: (bool){ bool } 60 - } 61 - x: (#struct){ 62 - - c: (int){ 4 } 63 - - b: (bool){ true } 64 - - } 65 - - y: (#struct){ 66 - - c: (int){ 4 } 67 - - b: (bool){ true } 68 - - } 69 - + b: (bool){ true } 70 - + c: (int){ 4 } 71 - + } 72 - + y: ~(x) 73 - } 74 - -- diff/todo/p3 -- 75 - Reordering 76 - -- out/eval -- 77 - (struct){ 78 - #a: (_|_){ 79 - // [incomplete] #a: incomplete bool: bool: 80 - // ./in.cue:5:5 81 - b: (bool){ bool } 82 - } 83 - x: (#struct){ 84 - c: (int){ 4 } 85 - b: (bool){ true } 86 - } 87 - y: (#struct){ 88 - c: (int){ 4 } 89 - b: (bool){ true } 90 - } 91 - }
+27 -92
cue/testdata/fulleval/046_non-structural_direct_cycles.txtar
··· 1 - #name: non-structural direct cycles 2 - #evalFull 3 - #todo:inline: hard — cycle semantics require @test(err, code=cycle) and careful scoping 1 + # Tests non-structural direct cycles where a struct is unified with one of its own 2 + # fields. c1 resolves successfully (bar.baz is merged), c2 conflicts because bar:1 3 + # (int) cannot unify with the struct c2.bar. 4 4 -- in.cue -- 5 - c1: {bar: baz: 2} & c1.bar 6 - c2: {bar: 1} & c2.bar 7 - -- out/compile -- 8 - --- in.cue 9 - { 10 - c1: ({ 11 - bar: { 12 - baz: 2 13 - } 14 - } & 〈0;c1〉.bar) 15 - c2: ({ 16 - bar: 1 17 - } & 〈0;c2〉.bar) 18 - } 5 + c1: {bar: baz: 2} & c1.bar @test(eq, {bar: {baz: 2}, baz: 2}) 6 + c2: {bar: 1} & c2.bar @test(err, code=eval, 7 + contains="conflicting values", 8 + args=[{bar:1}, 1, struct, int], 9 + pos=[in.cue:2:5, in.cue:2:11, in.cue:2:16]) 10 + -- out/errors.txt -- 11 + [eval] c2: conflicting values {bar:1} and 1 (mismatched types struct and int): 12 + ./in.cue:2:5 13 + ./in.cue:2:11 14 + ./in.cue:2:16 15 + -- out/todo.txt -- 16 + v3 error message for c2 says "conflicting values {bar:1} and 1 (mismatched types struct and int)" 17 + while v2 says "conflicting values 1 and {bar:1} (mismatched types int and struct)" (operand order swapped). 18 + v3 also reports an extra position (in.cue:2:21) not present in v2. 19 19 -- out/eval/stats -- 20 20 Leaks: 0 21 21 Freed: 7 ··· 26 26 Unifications: 7 27 27 Conjuncts: 10 28 28 Disjuncts: 8 29 - -- out/evalalpha -- 30 - Errors: 31 - c2: conflicting values {bar:1} and 1 (mismatched types struct and int): 32 - ./in.cue:2:5 33 - ./in.cue:2:16 34 - ./in.cue:2:21 35 - 36 - Result: 37 - (_|_){ 38 - // [eval] 39 - c1: (struct){ 40 - bar: (struct){ 41 - baz: (int){ 2 } 29 + -- out/compile -- 30 + --- in.cue 31 + { 32 + c1: ({ 33 + bar: { 34 + baz: 2 42 35 } 43 - baz: (int){ 2 } 44 - } 45 - c2: (_|_){ 46 - // [eval] c2: conflicting values {bar:1} and 1 (mismatched types struct and int): 47 - // ./in.cue:2:5 48 - // ./in.cue:2:16 49 - // ./in.cue:2:21 50 - bar: (_|_){// 1 51 - } 52 - } 53 - } 54 - -- diff/-out/evalalpha<==>+out/eval -- 55 - diff old new 56 - --- old 57 - +++ new 58 - @@ -1,7 +1,8 @@ 59 - Errors: 60 - -c2: conflicting values 1 and {bar:1} (mismatched types int and struct): 61 - +c2: conflicting values {bar:1} and 1 (mismatched types struct and int): 62 - ./in.cue:2:5 63 - ./in.cue:2:16 64 - + ./in.cue:2:21 65 - 66 - Result: 67 - (_|_){ 68 - @@ -13,9 +14,11 @@ 69 - baz: (int){ 2 } 70 - } 71 - c2: (_|_){ 72 - - // [eval] c2: conflicting values 1 and {bar:1} (mismatched types int and struct): 73 - + // [eval] c2: conflicting values {bar:1} and 1 (mismatched types struct and int): 74 - // ./in.cue:2:5 75 - // ./in.cue:2:16 76 - - bar: (int){ 1 } 77 - + // ./in.cue:2:21 78 - + bar: (_|_){// 1 79 - + } 80 - } 81 - } 82 - -- diff/todo/p3 -- 83 - Additional error message. Seems okay. 84 - -- out/eval -- 85 - Errors: 86 - c2: conflicting values 1 and {bar:1} (mismatched types int and struct): 87 - ./in.cue:2:5 88 - ./in.cue:2:16 89 - 90 - Result: 91 - (_|_){ 92 - // [eval] 93 - c1: (struct){ 94 - bar: (struct){ 95 - baz: (int){ 2 } 96 - } 97 - baz: (int){ 2 } 98 - } 99 - c2: (_|_){ 100 - // [eval] c2: conflicting values 1 and {bar:1} (mismatched types int and struct): 101 - // ./in.cue:2:5 102 - // ./in.cue:2:16 103 - bar: (int){ 1 } 104 - } 36 + } & 〈0;c1〉.bar) 37 + c2: ({ 38 + bar: 1 39 + } & 〈0;c2〉.bar) 105 40 }