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 15package load 16 17import ( 18 "bytes" 19 "io/ioutil" 20 "os" 21 "path/filepath" 22 "testing" 23 24 "cuelang.org/go/cue/ast" 25 "cuelang.org/go/cue/cuecontext" 26 "cuelang.org/go/cue/token" 27 "cuelang.org/go/internal/diff" 28) 29 30var testTagVars = map[string]TagVar{ 31 "now": stringVar("2006-01-02T15:04:05.999999999Z"), 32 "os": stringVar("m1"), 33 "cwd": stringVar("home"), 34 "username": stringVar("cueser"), 35 "hostname": stringVar("cuebe"), 36 "rand": {Func: func() (ast.Expr, error) { 37 return ast.NewLit(token.INT, "112950970371208119678246559335704039641"), nil 38 }}, 39} 40 41func stringVar(s string) TagVar { 42 return TagVar{Func: func() (ast.Expr, error) { return ast.NewString(s), nil }} 43} 44 45func TestTags(t *testing.T) { 46 dir, _ := ioutil.TempDir("", "") 47 defer os.RemoveAll(dir) 48 49 testCases := []struct { 50 in string 51 out string 52 err string 53 }{{ 54 in: ` 55 rand: int @tag(foo,var=rand) 56 time: string @tag(bar,var=now) 57 host: string @tag(bar,var=hostname) 58 user: string @tag(bar,var=username) 59 cwd: string @tag(bar,var=cwd) 60 `, 61 62 out: `{ 63 rand: 112950970371208119678246559335704039641 64 time: "2006-01-02T15:04:05.999999999Z" 65 host: "cuebe" 66 user: "cueser" 67 cwd: "home" 68 }`, 69 }, { 70 in: ` 71 time: int @tag(bar,var=now) 72 `, 73 err: `time: conflicting values int and "2006-01-02T15:04:05.999999999Z" (mismatched types int and string)`, 74 }, { 75 // Auto inject only on marked places 76 // TODO: Is this the right thing to do? 77 in: ` 78 u1: string @tag(bar,var=username) 79 u2: string @tag(bar) 80 `, 81 out: `{ 82 u1: "cueser" 83 u2: string // not filled 84 }`, 85 }, { 86 in: ` 87 u1: string @tag(bar,var=user) 88 `, 89 err: `tag variable 'user' not found`, 90 }} 91 92 for _, tc := range testCases { 93 t.Run("", func(t *testing.T) { 94 cfg := &Config{ 95 Dir: dir, 96 Overlay: map[string]Source{ 97 filepath.Join(dir, "foo.cue"): FromString(tc.in), 98 }, 99 TagVars: testTagVars, 100 } 101 b := Instances([]string{"foo.cue"}, cfg)[0] 102 103 c := cuecontext.New() 104 got := c.BuildInstance(b) 105 switch err := got.Err(); { 106 case (err == nil) != (tc.err == ""): 107 t.Fatalf("error: got %v; want %v", err, tc.err) 108 109 case err != nil: 110 got := err.Error() 111 if got != tc.err { 112 t.Fatalf("error: got %v; want %v", got, tc.err) 113 } 114 115 default: 116 want := c.CompileString(tc.out) 117 if !got.Equals(want) { 118 _, es := diff.Diff(got, want) 119 b := &bytes.Buffer{} 120 diff.Print(b, es) 121 t.Error(b) 122 } 123 } 124 }) 125 } 126} 127