test all keyvalue and fix bugs
This commit is contained in:
@@ -23,21 +23,30 @@ func (kv KVSlice) Less(i, j int) bool { return kv[i].Key < kv[j].Key }
|
||||
func (kv KVSlice) Swap(i, j int) { kv[i], kv[j] = kv[j], kv[i] }
|
||||
|
||||
// EnvKV turns a struct with `env` keys (used with go-simpler/env) into a standard formatted
|
||||
// environment variable key/value pair list, one per line. Note you must dereference a pointer
|
||||
// type to use this. This allows the composition of the config in this file with an extended
|
||||
// form with a customized variant of realy to produce correct environment variables both read
|
||||
// and write.
|
||||
// environment variable key/value pair list, one per line. If a pointer to a struct is passed,
|
||||
// it will be automatically dereferenced. This allows the composition of the config in this file
|
||||
// with an extended form with a customized variant of realy to produce correct environment
|
||||
// variables both read and write.
|
||||
func EnvKV(cfg any) (m KVSlice) {
|
||||
t := reflect.TypeOf(cfg)
|
||||
// Handle pointer types by dereferencing them
|
||||
v := reflect.ValueOf(cfg)
|
||||
if v.Kind() == reflect.Ptr {
|
||||
if v.IsNil() {
|
||||
return // Return empty slice for nil pointers
|
||||
}
|
||||
return EnvKV(v.Elem().Interface())
|
||||
}
|
||||
|
||||
t := v.Type()
|
||||
for i := 0; i < t.NumField(); i++ {
|
||||
k := t.Field(i).Tag.Get("env")
|
||||
v := reflect.ValueOf(cfg).Field(i).Interface()
|
||||
fieldValue := v.Field(i).Interface()
|
||||
var val string
|
||||
switch u := v.(type) {
|
||||
switch u := fieldValue.(type) {
|
||||
case string:
|
||||
val = u
|
||||
case int, int64, int32, uint64, uint32, bool, time.Duration:
|
||||
val = fmt.Sprint(v)
|
||||
val = fmt.Sprint(fieldValue)
|
||||
case []string:
|
||||
if len(u) > 0 {
|
||||
val = strings.Join(u, ",")
|
||||
@@ -52,7 +61,8 @@ func EnvKV(cfg any) (m KVSlice) {
|
||||
return
|
||||
}
|
||||
|
||||
// PrintEnv renders the key/values of a config.C to a provided io.Writer.
|
||||
// PrintEnv renders the key/values of a config struct to a provided io.Writer.
|
||||
// If a pointer to a struct is passed, it will be automatically dereferenced.
|
||||
func PrintEnv(cfg any, printer io.Writer) {
|
||||
_, _ = fmt.Fprintln(printer, "#!/usr/bin/env bash")
|
||||
kvs := EnvKV(cfg)
|
||||
|
||||
@@ -90,10 +90,58 @@ func TestEnvKV(t *testing.T) {
|
||||
if !found {
|
||||
t.Errorf("Expected to find ADDITIONAL_FIELD with value 'additional' in embedded struct")
|
||||
}
|
||||
|
||||
// Test case 3: Pointer to a struct
|
||||
pointerStruct := &TestStruct{
|
||||
StringField: "pointer-string",
|
||||
IntField: 123,
|
||||
BoolField: false,
|
||||
DurationField: 10 * time.Second,
|
||||
StringSlice: []string{"four", "five", "six"},
|
||||
}
|
||||
|
||||
pointerKVs := EnvKV(pointerStruct)
|
||||
|
||||
// Expected key-value pairs for pointer struct
|
||||
expectedPointer := KVSlice{
|
||||
{Key: "STRING_FIELD", Value: "pointer-string"},
|
||||
{Key: "INT_FIELD", Value: "123"},
|
||||
{Key: "BOOL_FIELD", Value: "false"},
|
||||
{Key: "DURATION_FIELD", Value: "10s"},
|
||||
{Key: "STRING_SLICE", Value: "four,five,six"},
|
||||
{Key: "EMPTY_SLICE", Value: ""},
|
||||
}
|
||||
|
||||
// Check if the number of key-value pairs is correct
|
||||
if len(pointerKVs) != len(expectedPointer) {
|
||||
t.Errorf("Expected %d key-value pairs for pointer struct, got %d", len(expectedPointer), len(pointerKVs))
|
||||
}
|
||||
|
||||
// Create a map for easier comparison
|
||||
pointerKVMap := make(map[string]string)
|
||||
for _, kv := range pointerKVs {
|
||||
pointerKVMap[kv.Key] = kv.Value
|
||||
}
|
||||
|
||||
// Check if all expected key-value pairs are present
|
||||
for _, kv := range expectedPointer {
|
||||
if val, ok := pointerKVMap[kv.Key]; !ok || val != kv.Value {
|
||||
t.Errorf("Expected key %s with value %s for pointer struct, got %s", kv.Key, kv.Value, val)
|
||||
}
|
||||
}
|
||||
|
||||
// Test case 4: Nil pointer
|
||||
var nilPointer *TestStruct = nil
|
||||
nilKVs := EnvKV(nilPointer)
|
||||
|
||||
// Nil pointer should return empty slice
|
||||
if len(nilKVs) != 0 {
|
||||
t.Errorf("Expected empty slice for nil pointer, got %d items", len(nilKVs))
|
||||
}
|
||||
}
|
||||
|
||||
func TestPrintEnv(t *testing.T) {
|
||||
// Create a test struct
|
||||
// Test case 1: Regular struct
|
||||
testStruct := TestStruct{
|
||||
StringField: "test-string",
|
||||
IntField: 42,
|
||||
@@ -123,6 +171,56 @@ func TestPrintEnv(t *testing.T) {
|
||||
if output != expected {
|
||||
t.Errorf("PrintEnv output does not match expected.\nExpected:\n%s\nGot:\n%s", expected, output)
|
||||
}
|
||||
|
||||
// Test case 2: Pointer to struct
|
||||
pointerStruct := &TestStruct{
|
||||
StringField: "pointer-string",
|
||||
IntField: 123,
|
||||
BoolField: false,
|
||||
DurationField: 10 * time.Second,
|
||||
StringSlice: []string{"four", "five", "six"},
|
||||
}
|
||||
|
||||
// Create a new buffer for the pointer test
|
||||
var pointerBuf bytes.Buffer
|
||||
|
||||
// Call PrintEnv with a pointer
|
||||
PrintEnv(pointerStruct, &pointerBuf)
|
||||
|
||||
// Get the output as a string
|
||||
pointerOutput := pointerBuf.String()
|
||||
|
||||
// Expected output for pointer struct
|
||||
expectedPointer := "#!/usr/bin/env bash\n" +
|
||||
"export BOOL_FIELD=false\n" +
|
||||
"export DURATION_FIELD=10s\n" +
|
||||
"export EMPTY_SLICE=\n" +
|
||||
"export INT_FIELD=123\n" +
|
||||
"export STRING_FIELD=pointer-string\n" +
|
||||
"export STRING_SLICE=four,five,six\n"
|
||||
|
||||
if pointerOutput != expectedPointer {
|
||||
t.Errorf("PrintEnv output for pointer struct does not match expected.\nExpected:\n%s\nGot:\n%s",
|
||||
expectedPointer, pointerOutput)
|
||||
}
|
||||
|
||||
// Test case 3: Nil pointer
|
||||
var nilPointer *TestStruct = nil
|
||||
var nilBuf bytes.Buffer
|
||||
|
||||
// Call PrintEnv with a nil pointer
|
||||
PrintEnv(nilPointer, &nilBuf)
|
||||
|
||||
// Get the output as a string
|
||||
nilOutput := nilBuf.String()
|
||||
|
||||
// Expected output for nil pointer (just the shebang line)
|
||||
expectedNil := "#!/usr/bin/env bash\n"
|
||||
|
||||
if nilOutput != expectedNil {
|
||||
t.Errorf("PrintEnv output for nil pointer does not match expected.\nExpected:\n%s\nGot:\n%s",
|
||||
expectedNil, nilOutput)
|
||||
}
|
||||
}
|
||||
|
||||
func TestKVSliceSorting(t *testing.T) {
|
||||
|
||||
Reference in New Issue
Block a user