github.com/solo-io/cue@v0.4.7/pkg/tool/os/env_test.go (about) 1 // Copyright 2019 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 os 16 17 import ( 18 "os" 19 "testing" 20 21 "github.com/google/go-cmp/cmp" 22 "github.com/google/go-cmp/cmp/cmpopts" 23 24 "github.com/solo-io/cue/cue" 25 "github.com/solo-io/cue/cue/ast" 26 "github.com/solo-io/cue/cue/errors" 27 "github.com/solo-io/cue/cue/parser" 28 "github.com/solo-io/cue/cue/token" 29 "github.com/solo-io/cue/internal/task" 30 "github.com/solo-io/cue/internal/value" 31 ) 32 33 func TestGetenv(t *testing.T) { 34 35 for _, p := range [][2]string{ 36 {"CUEOSTESTMOOD", "yippie"}, 37 {"CUEOSTESTTRUE", "True"}, 38 {"CUEOSTESTFALSE", "0"}, 39 {"CUEOSTESTBI", "1"}, 40 {"CUEOSTESTNUM", "34K"}, 41 {"CUEOSTESTNUMD", "not a num"}, 42 {"CUEOSTESTMULTI", "10"}, 43 } { 44 os.Setenv(p[0], p[1]) 45 } 46 47 config := `{ 48 CUEOSTESTMOOD: string 49 CUEOSTESTTRUE: bool 50 CUEOSTESTFALSE: bool | string 51 CUEOSTESTBI: *bool | int, 52 CUEOSTESTNUM: int 53 CUEOSTESTNUMD: *int | *bool | string 54 CUEOSTESTMULTI: *<10 | string 55 CUEOSTESTNULL: int | null 56 }` 57 58 want := map[string]interface{}{ 59 "CUEOSTESTMOOD": ast.NewString("yippie"), 60 "CUEOSTESTTRUE": ast.NewBool(true), 61 "CUEOSTESTFALSE": &ast.BinaryExpr{ 62 Op: token.OR, 63 X: ast.NewBool(false), 64 Y: ast.NewString("0"), 65 }, 66 "CUEOSTESTBI": &ast.BinaryExpr{ 67 Op: token.OR, 68 X: ast.NewLit(token.INT, "1"), 69 Y: ast.NewBool(true), 70 }, 71 "CUEOSTESTNUM": &ast.BasicLit{Kind: token.INT, Value: "34K"}, 72 "CUEOSTESTNUMD": ast.NewString("not a num"), 73 "CUEOSTESTMULTI": &ast.BinaryExpr{ 74 Op: token.OR, 75 X: ast.NewLit(token.INT, "10"), 76 Y: ast.NewString("10"), 77 }, 78 "CUEOSTESTNULL": nil, 79 } 80 81 for _, tc := range []struct { 82 pkg string 83 runner task.Runner 84 }{ 85 {"tool/os.Getenv", &getenvCmd{}}, 86 {"tool/os.Environ", &environCmd{}}, 87 } { 88 v := parse(t, tc.pkg, config) 89 got, err := tc.runner.Run(&task.Context{Obj: v}) 90 if err != nil { 91 t.Fatal(err) 92 } 93 94 var opts = []cmp.Option{ 95 cmpopts.IgnoreFields(ast.BinaryExpr{}, "OpPos"), 96 cmpopts.IgnoreFields(ast.BasicLit{}, "ValuePos"), 97 cmpopts.IgnoreUnexported(ast.BasicLit{}, ast.BinaryExpr{}), 98 // For ignoring addinonal entries from os.Environ: 99 cmpopts.IgnoreMapEntries(func(s string, x interface{}) bool { 100 _, ok := want[s] 101 return !ok 102 }), 103 } 104 105 if !cmp.Equal(got, want, opts...) { 106 t.Error(cmp.Diff(got, want, opts...)) 107 } 108 109 // Errors: 110 for _, etc := range []struct{ config, err string }{{ 111 config: `{ CUEOSTESTNULL: [...string] }`, 112 err: "expected unsupported type error", 113 }, { 114 config: `{ CUEOSTESTNUMD: int }`, 115 err: "expected invalid number error", 116 }, { 117 config: `{ CUEOSTESTNUMD: null }`, 118 err: "expected invalid type", 119 }} { 120 t.Run(etc.err, func(t *testing.T) { 121 v = parse(t, tc.pkg, etc.config) 122 if _, err = tc.runner.Run(&task.Context{Obj: v}); err == nil { 123 t.Error(etc.err) 124 } 125 }) 126 } 127 } 128 } 129 130 func parse(t *testing.T, kind, expr string) cue.Value { 131 t.Helper() 132 133 x, err := parser.ParseExpr("test", expr) 134 if err != nil { 135 errors.Print(os.Stderr, err, nil) 136 t.Fatal(err) 137 } 138 var r cue.Runtime 139 i, err := r.CompileExpr(x) 140 if err != nil { 141 t.Fatal(err) 142 } 143 return value.UnifyBuiltin(i.Value(), kind) 144 }