cuelang.org/go@v0.13.0/cue/query_test.go (about) 1 // Copyright 2021 CUE Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 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/cuetdtest" 24 "cuelang.org/go/internal/cuetxtar" 25 "cuelang.org/go/internal/diff" 26 "golang.org/x/tools/txtar" 27 ) 28 29 func TestLookupPath(t *testing.T) { 30 testCases := []struct { 31 in string 32 path cue.Path 33 out string `test:"update"` // :nerdSnipe: 34 err string `test:"update"` // :nerdSnipe: 35 }{{ 36 in: ` 37 #V: { 38 x: int 39 } 40 #X: { 41 [string]: int64 42 } & #V 43 v: #X 44 `, 45 path: cue.ParsePath("v.x"), 46 out: `int64`, 47 }, { 48 in: `#foo: 3`, 49 path: cue.ParsePath("#foo"), 50 out: `3`, 51 }, { 52 in: `_foo: 3`, 53 path: cue.MakePath(cue.Def("_foo")), 54 err: `field not found: #_foo`, 55 }, { 56 in: `_#foo: 3`, 57 path: cue.MakePath(cue.Def("_#foo")), 58 err: `field not found: _#foo`, 59 }, { 60 in: `"foo", #foo: 3`, 61 path: cue.ParsePath("#foo"), 62 out: `3`, 63 }, { 64 in: ` 65 a: [...int] 66 `, 67 path: cue.MakePath(cue.Str("a"), cue.AnyIndex), 68 out: `int`, 69 }, { 70 in: ` 71 [Name=string]: { a: Name } 72 `, 73 path: cue.MakePath(cue.AnyString, cue.Str("a")), 74 out: `string`, 75 }, { 76 in: ` 77 [Name=string]: { a: Name } 78 `, 79 path: cue.MakePath(cue.Str("b").Optional(), cue.Str("a")), 80 out: `"b"`, 81 }, { 82 in: ` 83 [Name=string]: { a: Name } 84 `, 85 path: cue.MakePath(cue.AnyString), 86 out: `{a: string}`, 87 }, { 88 in: ` 89 a: [Foo=string]: [Bar=string]: { b: Foo+Bar } 90 `, 91 path: cue.MakePath(cue.Str("a"), cue.Str("b"), cue.Str("c")).Optional(), 92 out: `{b: "bc"}`, 93 }, { 94 in: ` 95 a: [Foo=string]: b: [Bar=string]: { c: Foo } 96 a: foo: b: [Bar=string]: { d: Bar } 97 `, 98 path: cue.MakePath(cue.Str("a"), cue.Str("foo"), cue.Str("b"), cue.AnyString), 99 out: `{c: "foo", d: string}`, 100 }, { 101 in: ` 102 [Name=string]: { a: Name } 103 `, 104 path: cue.MakePath(cue.Str("a")), 105 err: `field not found: a`, 106 }, { 107 in: ` 108 x: { 109 [string]: int 110 } 111 y: x 112 `, 113 path: cue.MakePath(cue.Str("y"), cue.AnyString), 114 out: `int`, 115 }, { 116 in: ` 117 x: { 118 [_]: int 119 } 120 y: x 121 `, 122 path: cue.MakePath(cue.Str("y"), cue.AnyString), 123 out: `int`, 124 }, { 125 in: `t: {...}`, 126 path: cue.MakePath(cue.Str("t"), cue.AnyString), 127 out: `_`, 128 }, { 129 in: `t: [...]`, 130 path: cue.MakePath(cue.Str("t"), cue.AnyIndex), 131 out: `_`, 132 }} 133 for _, tc := range testCases { 134 cuetdtest.FullMatrix.Run(t, tc.path.String(), func(t *testing.T, m *cuetdtest.M) { 135 ctx := m.CueContext() 136 v := mustCompile(t, ctx, tc.in) 137 138 v = v.LookupPath(tc.path) 139 140 if err := v.Err(); err != nil || tc.err != "" { 141 if got := err.Error(); got != tc.err { 142 t.Errorf("error: got %v; want %v", got, tc.err) 143 } 144 } 145 146 if exists := v.Exists(); exists != (tc.err == "") { 147 t.Fatalf("exists: got %v; want: %v", exists, tc.err == "") 148 } else if !exists { 149 return 150 } 151 152 w := mustCompile(t, ctx, tc.out) 153 154 if k, d := diff.Diff(v, w); k != diff.Identity { 155 b := &bytes.Buffer{} 156 diff.Print(b, d) 157 t.Error(b) 158 } 159 }) 160 } 161 } 162 163 func TestHidden(t *testing.T) { 164 in := ` 165 -- cue.mod/module.cue -- 166 module: "mod.test" 167 language: version: "v0.9.0" 168 -- in.cue -- 169 import "mod.test/foo" 170 171 a: foo.C 172 b: _c 173 _c: 2 174 -- foo/foo.cue -- 175 package foo 176 177 C: _d 178 _d: 3 179 ` 180 181 a := txtar.Parse([]byte(in)) 182 instance := cuetxtar.Load(a, t.TempDir())[0] 183 if instance.Err != nil { 184 t.Fatal(instance.Err) 185 } 186 187 v := cuecontext.New().BuildInstance(instance) 188 189 testCases := []struct { 190 path cue.Path 191 pkg string 192 }{{ 193 path: cue.ParsePath("a"), 194 pkg: "mod.test/foo", 195 }, { 196 path: cue.ParsePath("b"), 197 pkg: "_", 198 }} 199 for _, tc := range testCases { 200 t.Run(tc.path.String(), func(t *testing.T) { 201 v := v.LookupPath(tc.path) 202 p := cue.Dereference(cue.Dereference(v)).Path().Selectors() 203 if got := p[len(p)-1].PkgPath(); got != tc.pkg { 204 t.Errorf("got %v; want %v", got, tc.pkg) 205 } 206 }) 207 } 208 }