Support text Un/Marshaller for map keys (#863)
This commit is contained in:
+127
-1
@@ -16,6 +16,27 @@ import (
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
type unmarshalTextKey struct {
|
||||
A string
|
||||
B string
|
||||
}
|
||||
|
||||
func (k *unmarshalTextKey) UnmarshalText(text []byte) error {
|
||||
parts := strings.Split(string(text), "-")
|
||||
if len(parts) != 2 {
|
||||
return fmt.Errorf("invalid text key: %s", text)
|
||||
}
|
||||
k.A = parts[0]
|
||||
k.B = parts[1]
|
||||
return nil
|
||||
}
|
||||
|
||||
type unmarshalBadTextKey struct{}
|
||||
|
||||
func (k *unmarshalBadTextKey) UnmarshalText(text []byte) error {
|
||||
return fmt.Errorf("error")
|
||||
}
|
||||
|
||||
func ExampleDecoder_DisallowUnknownFields() {
|
||||
type S struct {
|
||||
Key1 string
|
||||
@@ -315,6 +336,7 @@ func TestUnmarshal(t *testing.T) {
|
||||
target interface{}
|
||||
expected interface{}
|
||||
err bool
|
||||
assert func(t *testing.T, test test)
|
||||
}
|
||||
examples := []struct {
|
||||
skip bool
|
||||
@@ -350,6 +372,96 @@ func TestUnmarshal(t *testing.T) {
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "kv text key",
|
||||
input: `a-1 = "foo"`,
|
||||
gen: func() test {
|
||||
type doc = map[unmarshalTextKey]string
|
||||
|
||||
return test{
|
||||
target: &doc{},
|
||||
expected: &doc{{A: "a", B: "1"}: "foo"},
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "table text key",
|
||||
input: `["a-1"]
|
||||
foo = "bar"`,
|
||||
gen: func() test {
|
||||
type doc = map[unmarshalTextKey]map[string]string
|
||||
|
||||
return test{
|
||||
target: &doc{},
|
||||
expected: &doc{{A: "a", B: "1"}: map[string]string{"foo": "bar"}},
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "kv ptr text key",
|
||||
input: `a-1 = "foo"`,
|
||||
gen: func() test {
|
||||
type doc = map[*unmarshalTextKey]string
|
||||
|
||||
return test{
|
||||
target: &doc{},
|
||||
expected: &doc{{A: "a", B: "1"}: "foo"},
|
||||
assert: func(t *testing.T, test test) {
|
||||
// Despite the documentation:
|
||||
// Pointer variable equality is determined based on the equality of the
|
||||
// referenced values (as opposed to the memory addresses).
|
||||
// assert.Equal does not work properly with maps with pointer keys
|
||||
// https://github.com/stretchr/testify/issues/1143
|
||||
expected := make(map[unmarshalTextKey]string)
|
||||
for k, v := range *(test.expected.(*doc)) {
|
||||
expected[*k] = v
|
||||
}
|
||||
got := make(map[unmarshalTextKey]string)
|
||||
for k, v := range *(test.target.(*doc)) {
|
||||
got[*k] = v
|
||||
}
|
||||
assert.Equal(t, expected, got)
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "kv bad text key",
|
||||
input: `a-1 = "foo"`,
|
||||
gen: func() test {
|
||||
type doc = map[unmarshalBadTextKey]string
|
||||
|
||||
return test{
|
||||
target: &doc{},
|
||||
err: true,
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "kv bad ptr text key",
|
||||
input: `a-1 = "foo"`,
|
||||
gen: func() test {
|
||||
type doc = map[*unmarshalBadTextKey]string
|
||||
|
||||
return test{
|
||||
target: &doc{},
|
||||
err: true,
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "table bad text key",
|
||||
input: `["a-1"]
|
||||
foo = "bar"`,
|
||||
gen: func() test {
|
||||
type doc = map[unmarshalBadTextKey]map[string]string
|
||||
|
||||
return test{
|
||||
target: &doc{},
|
||||
err: true,
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "time.time with negative zone",
|
||||
input: `a = 1979-05-27T00:32:00-07:00 `, // space intentional
|
||||
@@ -1521,6 +1633,16 @@ B = "data"`,
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "empty map into map with invalid key type",
|
||||
input: ``,
|
||||
gen: func() test {
|
||||
return test{
|
||||
target: &map[int]string{},
|
||||
expected: &map[int]string{},
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "into map with convertible key type",
|
||||
input: `A = "hello"`,
|
||||
@@ -1777,7 +1899,11 @@ B = "data"`,
|
||||
require.Error(t, err)
|
||||
} else {
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, test.expected, test.target)
|
||||
if test.assert != nil {
|
||||
test.assert(t, test)
|
||||
} else {
|
||||
assert.Equal(t, test.expected, test.target)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user