1
2
3
4
5
6
7
8
9
10
11
12
13
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 "cuelang.org/go/cue"
25 "cuelang.org/go/cue/ast"
26 "cuelang.org/go/cue/errors"
27 "cuelang.org/go/cue/parser"
28 "cuelang.org/go/cue/token"
29 "cuelang.org/go/internal/task"
30 "cuelang.org/go/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 t.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
99 cmpopts.IgnoreMapEntries(func(s string, x interface{}) bool {
100 _, ok := want[s]
101 return !ok
102 }),
103 }
104
105 if diff := cmp.Diff(got, want, opts...); diff != "" {
106 t.Error(diff)
107 }
108
109
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 }
145
View as plain text