mirror of https://github.com/stretchr/testify.git
Implement delta comparison for map values
parent
88a414d072
commit
249123e03a
|
@ -175,6 +175,11 @@ func InDeltaf(t TestingT, expected interface{}, actual interface{}, delta float6
|
|||
return InDelta(t, expected, actual, delta, append([]interface{}{msg}, args...)...)
|
||||
}
|
||||
|
||||
// InDeltaMapValuesf is the same as InDelta, but it compares all values between two maps. Both maps must have exactly the same keys.
|
||||
func InDeltaMapValuesf(t TestingT, expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) bool {
|
||||
return InDeltaMapValues(t, expected, actual, delta, append([]interface{}{msg}, args...)...)
|
||||
}
|
||||
|
||||
// InDeltaSlicef is the same as InDelta, except it compares two slices.
|
||||
func InDeltaSlicef(t TestingT, expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) bool {
|
||||
return InDeltaSlice(t, expected, actual, delta, append([]interface{}{msg}, args...)...)
|
||||
|
|
|
@ -330,6 +330,16 @@ func (a *Assertions) InDelta(expected interface{}, actual interface{}, delta flo
|
|||
return InDelta(a.t, expected, actual, delta, msgAndArgs...)
|
||||
}
|
||||
|
||||
// InDeltaMapValues is the same as InDelta, but it compares all values between two maps. Both maps must have exactly the same keys.
|
||||
func (a *Assertions) InDeltaMapValues(expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) bool {
|
||||
return InDeltaMapValues(a.t, expected, actual, delta, msgAndArgs...)
|
||||
}
|
||||
|
||||
// InDeltaMapValuesf is the same as InDelta, but it compares all values between two maps. Both maps must have exactly the same keys.
|
||||
func (a *Assertions) InDeltaMapValuesf(expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) bool {
|
||||
return InDeltaMapValuesf(a.t, expected, actual, delta, msg, args...)
|
||||
}
|
||||
|
||||
// InDeltaSlice is the same as InDelta, except it compares two slices.
|
||||
func (a *Assertions) InDeltaSlice(expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) bool {
|
||||
return InDeltaSlice(a.t, expected, actual, delta, msgAndArgs...)
|
||||
|
|
|
@ -912,6 +912,47 @@ func InDeltaSlice(t TestingT, expected, actual interface{}, delta float64, msgAn
|
|||
return true
|
||||
}
|
||||
|
||||
// InDeltaMapValues is the same as InDelta, but it compares all values between two maps. Both maps must have exactly the same keys.
|
||||
func InDeltaMapValues(t TestingT, expected, actual interface{}, delta float64, msgAndArgs ...interface{}) bool {
|
||||
if expected == nil || actual == nil ||
|
||||
reflect.TypeOf(actual).Kind() != reflect.Map ||
|
||||
reflect.TypeOf(expected).Kind() != reflect.Map {
|
||||
return Fail(t, "Arguments must be maps", msgAndArgs...)
|
||||
}
|
||||
|
||||
expectedMap := reflect.ValueOf(expected)
|
||||
actualMap := reflect.ValueOf(actual)
|
||||
|
||||
if expectedMap.Len() != actualMap.Len() {
|
||||
return Fail(t, "Arguments must have the same numbe of keys", msgAndArgs...)
|
||||
}
|
||||
|
||||
for _, k := range expectedMap.MapKeys() {
|
||||
ev := expectedMap.MapIndex(k)
|
||||
av := actualMap.MapIndex(k)
|
||||
|
||||
if !ev.IsValid() {
|
||||
return Fail(t, fmt.Sprintf("missing key %q in expected map", k), msgAndArgs...)
|
||||
}
|
||||
|
||||
if !av.IsValid() {
|
||||
return Fail(t, fmt.Sprintf("missing key %q in actual map", k), msgAndArgs...)
|
||||
}
|
||||
|
||||
if !InDelta(
|
||||
t,
|
||||
ev.Interface(),
|
||||
av.Interface(),
|
||||
delta,
|
||||
msgAndArgs...,
|
||||
) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func calcRelativeError(expected, actual interface{}) (float64, error) {
|
||||
af, aok := toFloat(expected)
|
||||
if !aok {
|
||||
|
|
|
@ -1045,6 +1045,82 @@ func TestInDeltaSlice(t *testing.T) {
|
|||
False(t, InDeltaSlice(mockT, "", nil, 1), "Expected non numeral slices to fail")
|
||||
}
|
||||
|
||||
func TestInDeltaMapValues(t *testing.T) {
|
||||
mockT := new(testing.T)
|
||||
|
||||
for _, tc := range []struct {
|
||||
title string
|
||||
expect interface{}
|
||||
actual interface{}
|
||||
f func(TestingT, bool, ...interface{}) bool
|
||||
delta float64
|
||||
}{
|
||||
{
|
||||
title: "Within delta",
|
||||
expect: map[string]float64{
|
||||
"foo": 1.0,
|
||||
"bar": 2.0,
|
||||
},
|
||||
actual: map[string]float64{
|
||||
"foo": 1.01,
|
||||
"bar": 1.99,
|
||||
},
|
||||
delta: 0.1,
|
||||
f: True,
|
||||
},
|
||||
{
|
||||
title: "Within delta",
|
||||
expect: map[int]float64{
|
||||
1: 1.0,
|
||||
2: 2.0,
|
||||
},
|
||||
actual: map[int]float64{
|
||||
1: 1.0,
|
||||
2: 1.99,
|
||||
},
|
||||
delta: 0.1,
|
||||
f: True,
|
||||
},
|
||||
{
|
||||
title: "Different number of keys",
|
||||
expect: map[int]float64{
|
||||
1: 1.0,
|
||||
2: 2.0,
|
||||
},
|
||||
actual: map[int]float64{
|
||||
1: 1.0,
|
||||
},
|
||||
delta: 0.1,
|
||||
f: False,
|
||||
},
|
||||
{
|
||||
title: "Within delta with zero value",
|
||||
expect: map[string]float64{
|
||||
"zero": 0.0,
|
||||
},
|
||||
actual: map[string]float64{
|
||||
"zero": 0.0,
|
||||
},
|
||||
delta: 0.1,
|
||||
f: True,
|
||||
},
|
||||
{
|
||||
title: "With missing key with zero value",
|
||||
expect: map[string]float64{
|
||||
"zero": 0.0,
|
||||
"foo": 0.0,
|
||||
},
|
||||
actual: map[string]float64{
|
||||
"zero": 0.0,
|
||||
"bar": 0.0,
|
||||
},
|
||||
f: False,
|
||||
},
|
||||
} {
|
||||
tc.f(t, InDeltaMapValues(mockT, tc.expect, tc.actual, tc.delta), tc.title+"\n"+diff(tc.expect, tc.actual))
|
||||
}
|
||||
}
|
||||
|
||||
func TestInEpsilon(t *testing.T) {
|
||||
mockT := new(testing.T)
|
||||
|
||||
|
|
|
@ -401,6 +401,20 @@ func InDelta(t TestingT, expected interface{}, actual interface{}, delta float64
|
|||
}
|
||||
}
|
||||
|
||||
// InDeltaMapValues is the same as InDelta, but it compares all values between two maps. Both maps must have exactly the same keys.
|
||||
func InDeltaMapValues(t TestingT, expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) {
|
||||
if !assert.InDeltaMapValues(t, expected, actual, delta, msgAndArgs...) {
|
||||
t.FailNow()
|
||||
}
|
||||
}
|
||||
|
||||
// InDeltaMapValuesf is the same as InDelta, but it compares all values between two maps. Both maps must have exactly the same keys.
|
||||
func InDeltaMapValuesf(t TestingT, expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) {
|
||||
if !assert.InDeltaMapValuesf(t, expected, actual, delta, msg, args...) {
|
||||
t.FailNow()
|
||||
}
|
||||
}
|
||||
|
||||
// InDeltaSlice is the same as InDelta, except it compares two slices.
|
||||
func InDeltaSlice(t TestingT, expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) {
|
||||
if !assert.InDeltaSlice(t, expected, actual, delta, msgAndArgs...) {
|
||||
|
|
|
@ -331,6 +331,16 @@ func (a *Assertions) InDelta(expected interface{}, actual interface{}, delta flo
|
|||
InDelta(a.t, expected, actual, delta, msgAndArgs...)
|
||||
}
|
||||
|
||||
// InDeltaMapValues is the same as InDelta, but it compares all values between two maps. Both maps must have exactly the same keys.
|
||||
func (a *Assertions) InDeltaMapValues(expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) {
|
||||
InDeltaMapValues(a.t, expected, actual, delta, msgAndArgs...)
|
||||
}
|
||||
|
||||
// InDeltaMapValuesf is the same as InDelta, but it compares all values between two maps. Both maps must have exactly the same keys.
|
||||
func (a *Assertions) InDeltaMapValuesf(expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) {
|
||||
InDeltaMapValuesf(a.t, expected, actual, delta, msg, args...)
|
||||
}
|
||||
|
||||
// InDeltaSlice is the same as InDelta, except it compares two slices.
|
||||
func (a *Assertions) InDeltaSlice(expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) {
|
||||
InDeltaSlice(a.t, expected, actual, delta, msgAndArgs...)
|
||||
|
|
Loading…
Reference in New Issue