1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package cue_test
16
17 import (
18 "bytes"
19 "testing"
20
21 "cuelang.org/go/cue"
22 "cuelang.org/go/cue/cuecontext"
23 "cuelang.org/go/internal/cuetxtar"
24 "cuelang.org/go/internal/diff"
25 "golang.org/x/tools/txtar"
26 )
27
28 func TestLookupPath(t *testing.T) {
29 r := &cue.Runtime{}
30
31 testCases := []struct {
32 in string
33 path cue.Path
34 out string `test:"update"`
35 err string `test:"update"`
36 }{{
37 in: `
38 #V: {
39 x: int
40 }
41 #X: {
42 [string]: int64
43 } & #V
44 v: #X
45 `,
46 path: cue.ParsePath("v.x"),
47 out: `int64`,
48 }, {
49 in: `#foo: 3`,
50 path: cue.ParsePath("#foo"),
51 out: `3`,
52 }, {
53 in: `_foo: 3`,
54 path: cue.MakePath(cue.Def("_foo")),
55 err: `field not found: #_foo`,
56 }, {
57 in: `_#foo: 3`,
58 path: cue.MakePath(cue.Def("_#foo")),
59 err: `field not found: _#foo`,
60 }, {
61 in: `"foo", #foo: 3`,
62 path: cue.ParsePath("#foo"),
63 out: `3`,
64 }, {
65 in: `
66 a: [...int]
67 `,
68 path: cue.MakePath(cue.Str("a"), cue.AnyIndex),
69 out: `int`,
70 }, {
71 in: `
72 [Name=string]: { a: Name }
73 `,
74 path: cue.MakePath(cue.AnyString, cue.Str("a")),
75 out: `string`,
76 }, {
77 in: `
78 [Name=string]: { a: Name }
79 `,
80 path: cue.MakePath(cue.Str("b").Optional(), cue.Str("a")),
81 out: `"b"`,
82 }, {
83 in: `
84 [Name=string]: { a: Name }
85 `,
86 path: cue.MakePath(cue.AnyString),
87 out: `{a: string}`,
88 }, {
89 in: `
90 a: [Foo=string]: [Bar=string]: { b: Foo+Bar }
91 `,
92 path: cue.MakePath(cue.Str("a"), cue.Str("b"), cue.Str("c")).Optional(),
93 out: `{b: "bc"}`,
94 }, {
95 in: `
96 a: [Foo=string]: b: [Bar=string]: { c: Foo }
97 a: foo: b: [Bar=string]: { d: Bar }
98 `,
99 path: cue.MakePath(cue.Str("a"), cue.Str("foo"), cue.Str("b"), cue.AnyString),
100 out: `{c: "foo", d: string}`,
101 }, {
102 in: `
103 [Name=string]: { a: Name }
104 `,
105 path: cue.MakePath(cue.Str("a")),
106 err: `field not found: a`,
107 }}
108 for _, tc := range testCases {
109 t.Run(tc.path.String(), func(t *testing.T) {
110 v := compileT(t, r, tc.in)
111
112 v = v.LookupPath(tc.path)
113
114 if err := v.Err(); err != nil || tc.err != "" {
115 if got := err.Error(); got != tc.err {
116 t.Errorf("error: got %v; want %v", got, tc.err)
117 }
118 }
119
120 if exists := v.Exists(); exists != (tc.err == "") {
121 t.Fatalf("exists: got %v; want: %v", exists, tc.err == "")
122 } else if !exists {
123 return
124 }
125
126 w := compileT(t, r, tc.out)
127
128 if k, d := diff.Diff(v, w); k != diff.Identity {
129 b := &bytes.Buffer{}
130 diff.Print(b, d)
131 t.Error(b)
132 }
133 })
134 }
135 }
136
137 func compileT(t *testing.T, r *cue.Runtime, s string) cue.Value {
138 t.Helper()
139 inst, err := r.Compile("", s)
140 if err != nil {
141 t.Fatal(err)
142 }
143 return inst.Value()
144 }
145
146 func TestHidden(t *testing.T) {
147 in := `
148 -- cue.mod/module.cue --
149 module: "mod.test"
150
151 -- in.cue --
152 import "mod.test/foo"
153
154 a: foo.C
155 b: _c
156 _c: 2
157 -- foo/foo.cue --
158 package foo
159
160 C: _d
161 _d: 3
162 `
163
164 a := txtar.Parse([]byte(in))
165 instance := cuetxtar.Load(a, t.TempDir())[0]
166 if instance.Err != nil {
167 t.Fatal(instance.Err)
168 }
169
170 v := cuecontext.New().BuildInstance(instance)
171
172 testCases := []struct {
173 path cue.Path
174 pkg string
175 }{{
176 path: cue.ParsePath("a"),
177 pkg: "mod.test/foo",
178 }, {
179 path: cue.ParsePath("b"),
180 pkg: "_",
181 }}
182 for _, tc := range testCases {
183 t.Run(tc.path.String(), func(t *testing.T) {
184 v := v.LookupPath(tc.path)
185 p := cue.Dereference(cue.Dereference(v)).Path().Selectors()
186 if got := p[len(p)-1].PkgPath(); got != tc.pkg {
187 t.Errorf("got %v; want %v", got, tc.pkg)
188 }
189 })
190 }
191 }
192
View as plain text