1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package adt_test
16
17 import (
18 "flag"
19 "fmt"
20 "path/filepath"
21 "sort"
22 "strings"
23 "testing"
24
25 "golang.org/x/tools/txtar"
26
27 "cuelang.org/go/cue"
28 "cuelang.org/go/cue/ast"
29 "cuelang.org/go/cue/cuecontext"
30 "cuelang.org/go/cue/errors"
31 "cuelang.org/go/cue/token"
32 "cuelang.org/go/internal"
33 "cuelang.org/go/internal/core/adt"
34 "cuelang.org/go/internal/core/debug"
35 "cuelang.org/go/internal/core/eval"
36 "cuelang.org/go/internal/core/runtime"
37 "cuelang.org/go/internal/core/validate"
38 "cuelang.org/go/internal/cuetxtar"
39 _ "cuelang.org/go/pkg"
40 )
41
42 var (
43 todo = flag.Bool("todo", false, "run tests marked with #todo-compile")
44 )
45
46
47 func TestEval(t *testing.T) {
48 test := cuetxtar.TxTarTest{
49 Root: "../../../cue/testdata",
50 Name: "eval",
51 Skip: alwaysSkip,
52 ToDo: needFix,
53 }
54
55 if *todo {
56 test.ToDo = nil
57 }
58
59 test.Run(t, func(tc *cuetxtar.Test) {
60 runEvalTest(tc, internal.DefaultVersion)
61 })
62 }
63
64 var alwaysSkip = map[string]string{
65 "compile/erralias": "compile error",
66 }
67
68 var needFix = map[string]string{
69 "DIR/NAME": "reason",
70 }
71
72 func TestEvalAlpha(t *testing.T) {
73 adt.DebugDeps = true
74
75 var todoAlpha = map[string]string{
76
77
78
79
80
81 "builtins/list/sort": "list package",
82 "benchmarks/sort": "list package",
83 "fulleval/032_or_builtin_should_not_fail_on_non-concrete_empty_list": "unimplemented",
84 "resolve/048_builtins": "unimplemented",
85 "fulleval/049_alias_reuse_in_nested_scope": "list",
86 }
87
88 test := cuetxtar.TxTarTest{
89 Root: "../../../cue/testdata",
90 Name: "evalalpha",
91 Fallback: "eval",
92 Skip: alwaysSkip,
93 ToDo: todoAlpha,
94 }
95
96 if *todo {
97 test.ToDo = nil
98 }
99
100 var ran, skipped, errorCount int
101
102 test.Run(t, func(t *cuetxtar.Test) {
103 if reason := skipFiles(t.Instance().Files...); reason != "" {
104 skipped++
105 t.Skip(reason)
106 }
107 ran++
108
109 errorCount += runEvalTest(t, internal.DevVersion)
110 })
111
112 t.Logf("todo: %d, ran: %d, skipped: %d, nodeErrors: %d",
113 len(todoAlpha), ran, skipped, errorCount)
114 }
115
116
117
118 func skipFiles(a ...*ast.File) (reason string) {
119
120 fn := func(n ast.Node) bool {
121 switch x := n.(type) {
122 case *ast.BinaryExpr:
123 if x.Op == token.OR {
124 reason = "disjunctions"
125 }
126 }
127 return true
128 }
129 for _, f := range a {
130 ast.Walk(f, fn, nil)
131 }
132 return reason
133 }
134
135 func runEvalTest(t *cuetxtar.Test, version internal.EvaluatorVersion) (errorCount int) {
136 a := t.Instance()
137
138 r := runtime.NewVersioned(internal.DefaultVersion)
139
140 v, err := r.Build(nil, a)
141 if err != nil {
142 t.WriteErrors(err)
143 return
144 }
145
146 e := eval.New(r)
147 ctx := e.NewContext(v)
148 ctx.Version = version
149 v.Finalize(ctx)
150
151
152 if m := ctx.ErrorGraphs; len(m) > 0 {
153 errorCount += 1
154 i := 0
155 keys := make([]string, len(m))
156 for k := range m {
157 keys[i] = k
158 i++
159 }
160 t.Errorf("unexpected node errors: %d", len(ctx.ErrorGraphs))
161 sort.Strings(keys)
162 for _, s := range keys {
163 t.Errorf(" -- path: %s", s)
164 }
165 }
166
167 if version != internal.DevVersion {
168 stats := ctx.Stats()
169 w := t.Writer("stats")
170 fmt.Fprintln(w, stats)
171 }
172
173
174
175
176 if b := validate.Validate(ctx, v, &validate.Config{
177 AllErrors: true,
178 }); b != nil {
179 fmt.Fprintln(t, "Errors:")
180 t.WriteErrors(b.Err)
181 fmt.Fprintln(t, "")
182 fmt.Fprintln(t, "Result:")
183 }
184
185 if v == nil {
186 return
187 }
188
189 debug.WriteNode(t, r, v, &debug.Config{Cwd: t.Dir})
190 fmt.Fprintln(t)
191
192 return
193 }
194
195
196 func TestX(t *testing.T) {
197 var verbosity int
198 verbosity = 1
199
200 adt.DebugDeps = true
201
202 var version internal.EvaluatorVersion
203 version = internal.DevVersion
204 openGraph := true
205
206
207 in := `
208 -- cue.mod/module.cue --
209 module: "mod.test"
210
211 -- in.cue --
212 `
213
214 if strings.HasSuffix(strings.TrimSpace(in), ".cue --") {
215 t.Skip()
216 }
217
218 a := txtar.Parse([]byte(in))
219 instance := cuetxtar.Load(a, t.TempDir())[0]
220 if instance.Err != nil {
221 t.Fatal(instance.Err)
222 }
223
224 r := runtime.NewVersioned(version)
225
226 v, err := r.Build(nil, instance)
227 if err != nil {
228 t.Fatal(err)
229 }
230
231
232
233 adt.Verbosity = verbosity
234 t.Cleanup(func() { adt.Verbosity = 0 })
235
236 e := eval.New(r)
237 ctx := e.NewContext(v)
238 v.Finalize(ctx)
239 adt.Verbosity = 0
240
241 out := debug.NodeString(r, v, nil)
242 if openGraph {
243 for p, g := range ctx.ErrorGraphs {
244 path := filepath.Join(".debug/TestX", p)
245 adt.OpenNodeGraph("TestX", path, in, out, g)
246 }
247 }
248
249 if b := validate.Validate(ctx, v, &validate.Config{
250 AllErrors: true,
251 }); b != nil {
252 t.Log(errors.Details(b.Err, nil))
253 }
254
255 t.Error(out)
256
257 t.Log(ctx.Stats())
258 }
259
260 func BenchmarkUnifyAPI(b *testing.B) {
261 for i := 0; i < b.N; i++ {
262 b.StopTimer()
263 ctx := cuecontext.New()
264 v := ctx.CompileString("")
265 for j := 0; j < 500; j++ {
266 if j == 400 {
267 b.StartTimer()
268 }
269 v = v.FillPath(cue.ParsePath(fmt.Sprintf("i_%d", i)), i)
270 }
271 }
272 }
273
274 func TestIssue2293(t *testing.T) {
275 ctx := cuecontext.New()
276 c := `a: {}, a`
277 v1 := ctx.CompileString(c)
278 v2 := ctx.CompileString(c)
279
280 v1.Unify(v2)
281 }
282
View as plain text