1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
|
package internal_test
import (
"encoding/json"
"strings"
"testing"
"github.com/peterbourgon/ff/v3/internal"
)
func TestTraverseMap(t *testing.T) {
t.Parallel()
tests := []struct {
Name string
M map[string]any
Delim string
Want map[string]struct{}
}{
{
Name: "single values",
M: map[string]any{
"s": "foo",
"i": 123,
"i64": int64(123),
"u": uint64(123),
"f": 1.23,
"jn": json.Number("123"),
"b": true,
"nil": nil,
},
Delim: ".",
Want: map[string]struct{}{
"s=foo": {},
"i=123": {},
"i64=123": {},
"u=123": {},
"f=1.23": {},
"jn=123": {},
"b=true": {},
"nil=": {},
},
},
{
Name: "slices",
M: map[string]any{
"is": []any{1, 2, 3},
"ss": []any{"a", "b", "c"},
"bs": []any{true, false},
"as": []any{"a", 1, true},
},
Want: map[string]struct{}{
"is=1": {},
"is=2": {},
"is=3": {},
"ss=a": {},
"ss=b": {},
"ss=c": {},
"bs=true": {},
"bs=false": {},
"as=a": {},
"as=1": {},
"as=true": {},
},
},
{
Name: "nested maps",
M: map[string]any{
"m": map[string]any{
"s": "foo",
"m2": map[string]any{
"i": 123,
},
},
},
Delim: ".",
Want: map[string]struct{}{
"m.s=foo": {},
"m.m2.i=123": {},
},
},
{
Name: "nested maps with '-' delimiter",
M: map[string]any{
"m": map[string]any{
"s": "foo",
"m2": map[string]any{
"i": 123,
},
},
},
Delim: "-",
Want: map[string]struct{}{
"m-s=foo": {},
"m-m2-i=123": {},
},
},
{
Name: "nested map[any]any",
M: map[string]any{
"m": map[any]any{
"m2": map[string]any{
"i": 999,
},
},
},
Delim: ".",
Want: map[string]struct{}{
"m.m2.i=999": {},
},
},
}
for _, test := range tests {
t.Run(test.Name, func(t *testing.T) {
observe := func(name, value string) error {
key := name + "=" + value
if _, ok := test.Want[key]; !ok {
t.Errorf("set(%s, %s): unexpected call to set", name, value)
}
delete(test.Want, key)
return nil
}
if err := internal.TraverseMap(test.M, test.Delim, observe); err != nil {
t.Fatal(err)
}
for key := range test.Want {
name, value, _ := strings.Cut(key, "=")
t.Errorf("set(%s, %s): expected but did not occur", name, value)
}
})
}
}
|