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  }