1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package export_test
16
17 import (
18 "testing"
19
20 "cuelang.org/go/cue"
21 "cuelang.org/go/cue/ast"
22 "cuelang.org/go/cue/cuecontext"
23 "cuelang.org/go/cue/errors"
24 "cuelang.org/go/cue/format"
25 "cuelang.org/go/cue/parser"
26 "cuelang.org/go/encoding/gocode/gocodec"
27 "cuelang.org/go/internal/astinternal"
28 "cuelang.org/go/internal/core/adt"
29 "cuelang.org/go/internal/core/compile"
30 "cuelang.org/go/internal/core/convert"
31 "cuelang.org/go/internal/core/eval"
32 "cuelang.org/go/internal/core/export"
33 "cuelang.org/go/internal/core/runtime"
34 "cuelang.org/go/internal/cuetxtar"
35 "cuelang.org/go/internal/value"
36 "golang.org/x/tools/txtar"
37 )
38
39 func TestDefinition(t *testing.T) {
40 test := cuetxtar.TxTarTest{
41 Root: "./testdata/main",
42 Name: "definition",
43 }
44
45 r := runtime.New()
46
47 test.Run(t, func(t *cuetxtar.Test) {
48 a := t.Instance()
49
50 v, errs := compile.Files(nil, r, "", a.Files...)
51 if errs != nil {
52 t.Fatal(errs)
53 }
54 v.Finalize(eval.NewContext(r, v))
55
56
57
58
59 file, errs := export.Def(r, "", v)
60 errors.Print(t, errs, nil)
61 _, _ = t.Write(formatNode(t.T, file))
62 })
63 }
64
65 func formatNode(t *testing.T, n ast.Node) []byte {
66 t.Helper()
67
68 b, err := format.Node(n)
69 if err != nil {
70 t.Fatal(err)
71 }
72 return b
73 }
74
75
76
77 func TestGenerated(t *testing.T) {
78 ctx := cuecontext.New()
79
80 testCases := []struct {
81 in func(ctx *adt.OpContext) (adt.Expr, error)
82 out string
83 p *export.Profile
84 }{{
85 in: func(ctx *adt.OpContext) (adt.Expr, error) {
86 in := &C{
87 Terminals: []*A{{Name: "Name", Description: "Desc"}},
88 }
89 return convert.GoValueToValue(ctx, in, false), nil
90 },
91 out: `Terminals: [{Name: "Name", Description: "Desc"}]`,
92 }, {
93 in: func(ctx *adt.OpContext) (adt.Expr, error) {
94 in := &C{
95 Terminals: []*A{{Name: "Name", Description: "Desc"}},
96 }
97 return convert.GoTypeToExpr(ctx, in)
98 },
99 out: `*null|{Terminals?: *null|[...*null|{Name: string, Description: string}]}`,
100 }, {
101 in: func(ctx *adt.OpContext) (adt.Expr, error) {
102 in := []*A{{Name: "Name", Description: "Desc"}}
103 return convert.GoValueToValue(ctx, in, false), nil
104 },
105 out: `[{Name: "Name", Description: "Desc"}]`,
106 }, {
107 in: func(ctx *adt.OpContext) (adt.Expr, error) {
108 in := []*A{{Name: "Name", Description: "Desc"}}
109 return convert.GoTypeToExpr(ctx, in)
110 },
111 out: `*null|[...*null|{Name: string, Description: string}]`,
112 }, {
113 in: func(ctx *adt.OpContext) (adt.Expr, error) {
114 expr, err := parser.ParseExpr("test", `{
115 x: Guide.#Terminal
116 Guide: {}
117 }`)
118 if err != nil {
119 return nil, err
120 }
121 c, err := compile.Expr(nil, ctx, "_", expr)
122 if err != nil {
123 return nil, err
124 }
125 root := &adt.Vertex{}
126 root.AddConjunct(c)
127 root.Finalize(ctx)
128
129
130 n := &adt.Vertex{}
131 n.AddConjunct(adt.MakeRootConjunct(nil, root.Arcs[0]))
132 n.AddConjunct(adt.MakeRootConjunct(nil, root.Arcs[1]))
133 n.Finalize(ctx)
134
135 return n, nil
136 },
137 out: `<[l2// x: undefined field: #Terminal] _|_>`,
138 p: export.Final,
139 }, {
140 in: func(r *adt.OpContext) (adt.Expr, error) {
141 v := ctx.CompileString(`
142 #Provider: {
143 ID: string
144 notConcrete: bool
145 a: int
146 b: a + 1
147 }`)
148
149 spec := v.LookupPath(cue.ParsePath("#Provider"))
150 spec2 := spec.FillPath(cue.ParsePath("ID"), "12345")
151 root := v.FillPath(cue.ParsePath("providers.foo"), spec2)
152 _, n := value.ToInternal(root)
153
154 return n, nil
155 },
156 out: `#Provider: {ID: string, notConcrete: bool, a: int, b: a+1}, providers: {foo: {ID: "12345", notConcrete: bool, a: int, b: a+1}}`,
157 p: export.All,
158 }, {
159
160 in: func(r *adt.OpContext) (adt.Expr, error) {
161 valA := ctx.CompileString(`
162 #One: { version: string }
163 `)
164
165 valB := ctx.CompileString(`
166 #One: _
167 ones: {[string]: #One}
168 `)
169 v := valB.Unify(valA)
170 _, n := value.ToInternal(v)
171 return n, nil
172 },
173 out: `#One: {version: string}, ones: {[string]: #One}`,
174 p: export.All,
175 }, {
176
177
178
179 in: func(r *adt.OpContext) (adt.Expr, error) {
180 v := ctx.CompileString(`
181 #A: b: c: string
182 `)
183 v = v.LookupPath(cue.ParsePath("#A.b"))
184
185 _, n := value.ToInternal(v)
186 return n, nil
187 },
188 out: `_#def, _#def: {c: string}`,
189 p: export.All,
190 }, {
191
192
193 in: func(r *adt.OpContext) (adt.Expr, error) {
194 v := ctx.CompileString(`
195 #A: { "foo", #enum: 2 }
196 `)
197 v = v.LookupPath(cue.ParsePath("#A"))
198
199 _, n := value.ToInternal(v)
200 return n, nil
201 },
202 out: `"foo", #enum: 2`,
203 p: export.All,
204 }, {
205
206 in: func(r *adt.OpContext) (adt.Expr, error) {
207 m := make(map[string]interface{})
208 v := ctx.Encode(m)
209 _, x := value.ToInternal(v)
210 return x, nil
211 },
212 out: ``,
213 }, {
214 in: func(r *adt.OpContext) (adt.Expr, error) {
215 v := &adt.Vertex{}
216 v.SetValue(r, &adt.StructMarker{})
217 return v, nil
218 },
219 out: ``,
220 }}
221 for _, tc := range testCases {
222 t.Run("", func(t *testing.T) {
223 ctx := adt.NewContext((*runtime.Runtime)(ctx), &adt.Vertex{})
224
225 v, err := tc.in(ctx)
226 if err != nil {
227 t.Fatal("failed test case: ", err)
228 }
229
230 p := tc.p
231 if p == nil {
232 p = export.Simplified
233 }
234
235 var n ast.Node
236 switch x := v.(type) {
237 case *adt.Vertex:
238 n, err = p.Def(ctx, "", x)
239 default:
240 n, err = p.Expr(ctx, "", v)
241 }
242 if err != nil {
243 t.Fatal("failed export: ", err)
244 }
245 got := astinternal.DebugStr(n)
246 if got != tc.out {
247 t.Errorf("got: %s\nwant: %s", got, tc.out)
248 }
249 })
250 }
251 }
252
253 type A struct {
254 Name string
255 Description string
256 }
257
258 type B struct {
259 Image string
260 }
261
262 type C struct {
263 Terminals []*A
264 }
265
266
267 func TestX(t *testing.T) {
268 t.Skip()
269
270 in := `
271 -- in.cue --
272 `
273
274 archive := txtar.Parse([]byte(in))
275 a := cuetxtar.Load(archive, t.TempDir())
276 if err := a[0].Err; err != nil {
277 t.Fatal(err)
278 }
279
280
281
282
283 ctx := cuecontext.New()
284 r := (*runtime.Runtime)(ctx)
285 v, errs := compile.Files(nil, r, "", a[0].Files...)
286 if errs != nil {
287 t.Fatal(errs)
288 }
289 v.Finalize(eval.NewContext(r, v))
290
291 file, errs := export.Def(r, "main", v)
292 if errs != nil {
293 t.Fatal(errs)
294 }
295
296 t.Error(string(formatNode(t, file)))
297 }
298
299 func TestFromGo(t *testing.T) {
300 type Struct struct {
301 A string
302 B string
303 }
304
305 m := make(map[string]Struct)
306 m["hello"] = Struct{
307 A: "a",
308 B: "b",
309 }
310 var r cue.Runtime
311 codec := gocodec.New(&r, nil)
312 v, err := codec.Decode(m)
313 if err != nil {
314 panic(err)
315 }
316
317 syn, _ := format.Node(v.Syntax())
318 if got := string(syn); got != `{
319 hello: {
320 A: "a"
321 B: "b"
322 }
323 }` {
324 t.Errorf("incorrect ordering: %s\n", got)
325 }
326 }
327
328 func TestFromAPI(t *testing.T) {
329 testCases := []struct {
330 expr ast.Expr
331 out string
332 }{{
333 expr: ast.NewCall(ast.NewIdent("close"), ast.NewStruct()),
334 out: `close({})`,
335 }, {
336 expr: ast.NewCall(ast.NewIdent("close"), ast.NewStruct(
337 "a", ast.NewString("foo"),
338 )),
339 out: `close({a: "foo"})`,
340 }, {
341 expr: ast.NewCall(ast.NewIdent("close"), ast.NewStruct(
342 ast.Embed(ast.NewStruct("a", ast.NewString("foo"))),
343 )),
344 out: `close({a: "foo"})`,
345 }}
346
347 for _, tc := range testCases {
348 t.Run("", func(t *testing.T) {
349 ctx := cuecontext.New()
350
351 v := ctx.BuildExpr(tc.expr)
352
353 r, x := value.ToInternal(v)
354 file, err := export.Def(r, "foo", x)
355
356 if err != nil {
357 t.Fatal(err)
358 }
359
360 got := astinternal.DebugStr(file)
361 if got != tc.out {
362 t.Errorf("got: %s\nwant: %s", got, tc.out)
363 }
364
365 })
366 }
367 }
368
View as plain text