func/cmd/config_test.go

182 lines
3.8 KiB
Go

package cmd_test
import (
"bytes"
"encoding/json"
"fmt"
"io"
"sort"
"testing"
"github.com/ory/viper"
fnCmd "knative.dev/func/cmd"
fn "knative.dev/func/pkg/functions"
)
func TestListEnvs(t *testing.T) {
mock := newMockLoaderSaver()
foo := "foo"
bar := "bar"
envs := []fn.Env{{Name: &foo, Value: &bar}}
mock.load = func(path string) (fn.Function, error) {
if path != "<path>" {
t.Fatalf("bad path, got %q but expected <path>", path)
}
return fn.Function{Run: fn.RunSpec{Envs: envs}}, nil
}
cmd := fnCmd.NewConfigCmd(mock, fnCmd.NewClient)
cmd.SetArgs([]string{"envs", "-o=json", "--path=<path>"})
var buff bytes.Buffer
cmd.SetOut(&buff)
cmd.SetErr(&buff)
err := cmd.Execute()
if err != nil {
t.Fatal(err)
}
var data []fn.Env
err = json.Unmarshal(buff.Bytes(), &data)
if err != nil {
t.Fatal(err)
}
if !envsEqual(envs, data) {
t.Errorf("env mismatch, expedted %v but got %v", envs, data)
}
}
func TestListEnvAdd(t *testing.T) {
// strings as vars so we can take address of them
foo := "foo"
bar := "bar"
answer := "answer"
fortyTwo := "42"
configMapExpression := "{{ configMap:myMap }}"
mock := newMockLoaderSaver()
mock.load = func(path string) (fn.Function, error) {
return fn.Function{Run: fn.RunSpec{Envs: []fn.Env{{Name: &foo, Value: &bar}}}}, nil
}
var expectedEnvs []fn.Env
mock.save = func(f fn.Function) error {
if !envsEqual(expectedEnvs, f.Run.Envs) {
return fmt.Errorf("unexpected envs: got %v but %v was expected", f.Run.Envs, expectedEnvs)
}
return nil
}
expectedEnvs = []fn.Env{{Name: &foo, Value: &bar}, {Name: &answer, Value: &fortyTwo}}
cmd := fnCmd.NewConfigCmd(mock, fnCmd.NewClient)
cmd.SetArgs([]string{"envs", "add", "--name=answer", "--value=42"})
cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
err := cmd.Execute()
if err != nil {
t.Error(err)
}
viper.Reset()
expectedEnvs = []fn.Env{{Name: &foo, Value: &bar}, {Name: nil, Value: &configMapExpression}}
cmd = fnCmd.NewConfigCmd(mock, fnCmd.NewClient)
cmd.SetArgs([]string{"envs", "add", "--value={{ configMap:myMap }}"})
cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
err = cmd.Execute()
if err != nil {
t.Error(err)
}
viper.Reset()
cmd = fnCmd.NewConfigCmd(mock, fnCmd.NewClient)
cmd.SetArgs([]string{"envs", "add", "--name=1", "--value=abc"})
cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
err = cmd.Execute()
if err == nil {
t.Error("expected variable name error but got nil")
}
}
func envsEqual(a, b []fn.Env) bool {
if len(a) != len(b) {
return false
}
strPtrEq := func(x, y *string) bool {
switch {
case x == nil && y == nil:
return true
case x != nil && y != nil:
return *x == *y
default:
return false
}
}
strPtrLess := func(x, y *string) bool {
switch {
case x == nil && y == nil:
return false
case x != nil && y != nil:
return *x < *y
case x == nil:
return true
default:
return false
}
}
lessForSlice := func(s []fn.Env) func(i, j int) bool {
return func(i, j int) bool {
x := s[i]
y := s[j]
if strPtrLess(x.Name, y.Name) {
return true
}
return strPtrLess(x.Value, y.Value)
}
}
sort.Slice(a, lessForSlice(a))
sort.Slice(b, lessForSlice(b))
for i := range a {
x := a[i]
y := b[i]
if !strPtrEq(x.Name, y.Name) || !strPtrEq(x.Value, y.Value) {
return false
}
}
return true
}
func newMockLoaderSaver() *mockLoaderSaver {
return &mockLoaderSaver{
load: func(path string) (fn.Function, error) {
return fn.Function{}, nil
},
save: func(f fn.Function) error {
return nil
},
}
}
type mockLoaderSaver struct {
load func(path string) (fn.Function, error)
save func(f fn.Function) error
}
func (m mockLoaderSaver) Load(path string) (fn.Function, error) {
return m.load(path)
}
func (m mockLoaderSaver) Save(f fn.Function) error {
return m.save(f)
}