Skip to content

Commit

Permalink
feat: Support map types in flag, tag and env loaders
Browse files Browse the repository at this point in the history
Adds support for loading configuration into map[string]string and
map[string]int (and related) types.
The string encoding used is the same as the one used in pflag: elements
are delimited by comma's (like for slices) and key values are split by
equals sign (=). For example:
key1=val1,key2=val2

While updating the string parser, I have updated the error messages that
are returned. They now leverage error wrapping and include more
information about the field and value that contained the error.
  • Loading branch information
wdullaer committed Jan 21, 2025
1 parent 71ec8bd commit 6674c17
Show file tree
Hide file tree
Showing 4 changed files with 357 additions and 33 deletions.
27 changes: 23 additions & 4 deletions env_test.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
package multiconfig

import (
"os"
"strings"
"testing"

"github.com/fatih/structs"
"github.com/stretchr/testify/require"
)

func TestENV(t *testing.T) {
Expand Down Expand Up @@ -128,9 +128,7 @@ func setEnvVars(t *testing.T, structName, prefix string) {

for key, val := range env {
env := prefix + "_" + key
if err := os.Setenv(env, val); err != nil {
t.Fatal(err)
}
t.Setenv(env, val)
}
}

Expand All @@ -152,3 +150,24 @@ func TestENVgetPrefix(t *testing.T) {
t.Errorf("Prefix is wrong: %s, want: %s", p, prefix)
}
}

func TestMapEnvSupport(t *testing.T) {
m := &EnvironmentLoader{CamelCase: true}

env := map[string]string{
"_MAP_STRING_INT": "key1=1234,key2=456",
"_MAP_STRING_STRING": "key1=val1,key2=val2",
}
for key, val := range env {
t.Setenv(key, val)
}

var e struct {
MapStringInt map[string]int
MapStringString map[string]string
}

require.NoError(t, m.Load(&e))
require.EqualValues(t, map[string]int{"key1": 1234, "key2": 456}, e.MapStringInt)
require.EqualValues(t, map[string]string{"key1": "val1", "key2": "val2"}, e.MapStringString)
}
19 changes: 19 additions & 0 deletions flag_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,7 @@ func TestFlagValueSupport(t *testing.T) {
t.Fatalf("got %q, want %q", e.Public, m.Args[3])
}
}

func TestCustomUsageTag(t *testing.T) {
const usageMsg = "foobar help"
strt := struct {
Expand All @@ -239,6 +240,24 @@ func TestCustomUsageTag(t *testing.T) {
}
}

func TestMapFlagSupport(t *testing.T) {
m := &FlagLoader{CamelCase: true}

m.Args = []string{
"-map-string-int", "key1=1234,key2=456",
"-map-string-string", "key1=val1,key2=val2",
}

var e struct {
MapStringInt map[string]int
MapStringString map[string]string
}

require.NoError(t, m.Load(&e))
require.EqualValues(t, map[string]int{"key1": 1234, "key2": 456}, e.MapStringInt)
require.EqualValues(t, map[string]string{"key1": "val1", "key2": "val2"}, e.MapStringString)
}

// getFlags returns a slice of arguments that can be passed to flag.Parse()
func getFlags(t *testing.T, structName, prefix string) []string {
t.Helper()
Expand Down
Loading

0 comments on commit 6674c17

Please sign in to comment.