mirror of https://github.com/stretchr/testify.git
commit
da6c3ee82f
|
@ -475,12 +475,102 @@ func WithinDuration(t TestingT, expected, actual time.Time, delta time.Duration,
|
|||
|
||||
dt := expected.Sub(actual)
|
||||
if dt < -delta || dt > delta {
|
||||
return Fail(t, fmt.Sprintf("Max difference between %v and %v allowed is %v, but difference was %v", expected, actual, dt, delta), msgAndArgs...)
|
||||
return Fail(t, fmt.Sprintf("Max difference between %v and %v allowed is %v, but difference was %v", expected, actual, delta, dt), msgAndArgs...)
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func toFloat(x interface{}) (float64, bool) {
|
||||
var xf float64
|
||||
xok := true
|
||||
|
||||
switch xn := x.(type) {
|
||||
case uint8:
|
||||
xf = float64(xn)
|
||||
case uint16:
|
||||
xf = float64(xn)
|
||||
case uint32:
|
||||
xf = float64(xn)
|
||||
case uint64:
|
||||
xf = float64(xn)
|
||||
case int:
|
||||
xf = float64(xn)
|
||||
case int8:
|
||||
xf = float64(xn)
|
||||
case int16:
|
||||
xf = float64(xn)
|
||||
case int32:
|
||||
xf = float64(xn)
|
||||
case int64:
|
||||
xf = float64(xn)
|
||||
case float32:
|
||||
xf = float64(xn)
|
||||
case float64:
|
||||
xf = float64(xn)
|
||||
default:
|
||||
xok = false
|
||||
}
|
||||
|
||||
return xf, xok
|
||||
}
|
||||
|
||||
// InDelta asserts that the two numerals are within delta of each other.
|
||||
//
|
||||
// assert.InDelta(t, math.Pi, (22 / 7.0), 0.01)
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func InDelta(t TestingT, expected, actual interface{}, delta float64, msgAndArgs ...interface{}) bool {
|
||||
|
||||
af, aok := toFloat(expected)
|
||||
bf, bok := toFloat(actual)
|
||||
|
||||
if !aok || !bok {
|
||||
return Fail(t, fmt.Sprintf("Parameters must be numerical"), msgAndArgs...)
|
||||
}
|
||||
|
||||
dt := af - bf
|
||||
if dt < -delta || dt > delta {
|
||||
return Fail(t, fmt.Sprintf("Max difference between %v and %v allowed is %v, but difference was %v", expected, actual, delta, dt), msgAndArgs...)
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// min(|expected|, |actual|) * epsilon
|
||||
func calcEpsilonDelta(expected, actual interface{}, epsilon float64) float64 {
|
||||
af, aok := toFloat(expected)
|
||||
bf, bok := toFloat(actual)
|
||||
|
||||
if !aok || !bok {
|
||||
// invalid input
|
||||
return 0
|
||||
}
|
||||
|
||||
if af < 0 {
|
||||
af = -af
|
||||
}
|
||||
if bf < 0 {
|
||||
bf = -bf
|
||||
}
|
||||
var delta float64
|
||||
if af < bf {
|
||||
delta = af * epsilon
|
||||
} else {
|
||||
delta = bf * epsilon
|
||||
}
|
||||
return delta
|
||||
}
|
||||
|
||||
// InEpsilon asserts that expected and actual have a relative error less than epsilon
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func InEpsilon(t TestingT, expected, actual interface{}, epsilon float64, msgAndArgs ...interface{}) bool {
|
||||
delta := calcEpsilonDelta(expected, actual, epsilon)
|
||||
|
||||
return InDelta(t, expected, actual, delta, msgAndArgs...)
|
||||
}
|
||||
|
||||
/*
|
||||
Errors
|
||||
*/
|
||||
|
|
|
@ -418,3 +418,37 @@ func TestWithinDuration(t *testing.T) {
|
|||
False(t, WithinDuration(mockT, a, b, -11*time.Second), "A 10s difference is not within a 9s time difference")
|
||||
False(t, WithinDuration(mockT, b, a, -11*time.Second), "A 10s difference is not within a 9s time difference")
|
||||
}
|
||||
|
||||
func TestInDelta(t *testing.T) {
|
||||
mockT := new(testing.T)
|
||||
|
||||
True(t, InDelta(mockT, 1.001, 1, 0.01), "|1.001 - 1| <= 0.01")
|
||||
True(t, InDelta(mockT, 1, 1.001, 0.01), "|1 - 1.001| <= 0.01")
|
||||
True(t, InDelta(mockT, 1, 2, 1), "|1 - 2| <= 1")
|
||||
False(t, InDelta(mockT, 1, 2, 0.5), "Expected |1 - 2| <= 0.5 to fail")
|
||||
False(t, InDelta(mockT, 2, 1, 0.5), "Expected |2 - 1| <= 0.5 to fail")
|
||||
False(t, InDelta(mockT, "", nil, 1), "Expected non numerals to fail")
|
||||
|
||||
cases := []struct {
|
||||
a, b interface{}
|
||||
delta float64
|
||||
}{
|
||||
{uint8(2), uint8(1), 1},
|
||||
{uint16(2), uint16(1), 1},
|
||||
{uint32(2), uint32(1), 1},
|
||||
{uint64(2), uint64(1), 1},
|
||||
|
||||
{int(2), int(1), 1},
|
||||
{int8(2), int8(1), 1},
|
||||
{int16(2), int16(1), 1},
|
||||
{int32(2), int32(1), 1},
|
||||
{int64(2), int64(1), 1},
|
||||
|
||||
{float32(2), float32(1), 1},
|
||||
{float64(2), float64(1), 1},
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
True(t, InDelta(mockT, tc.a, tc.b, tc.delta), "Expected |%V - %V| <= %v", tc.a, tc.b, tc.delta)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -89,6 +89,10 @@
|
|||
//
|
||||
// assert.WithinDuration(t, timeA, timeB, deltaTime, [, message [, format-args]])
|
||||
//
|
||||
// assert.InDelta(t, numA, numB, delta, [, message [, format-args]])
|
||||
//
|
||||
// assert.InEpsilon(t, numA, numB, epsilon, [, message [, format-args]])
|
||||
//
|
||||
// assert package contains Assertions object. it has assertion methods.
|
||||
//
|
||||
// Here is an overview of the assert functions:
|
||||
|
@ -135,4 +139,8 @@
|
|||
// } [, message [, format-args]])
|
||||
//
|
||||
// assert.WithinDuration(timeA, timeB, deltaTime, [, message [, format-args]])
|
||||
//
|
||||
// assert.InDelta(numA, numB, delta, [, message [, format-args]])
|
||||
//
|
||||
// assert.InEpsilon(numA, numB, epsilon, [, message [, format-args]])
|
||||
package assert
|
||||
|
|
|
@ -168,6 +168,22 @@ func (a *Assertions) WithinDuration(expected, actual time.Time, delta time.Durat
|
|||
return WithinDuration(a.t, expected, actual, delta, msgAndArgs...)
|
||||
}
|
||||
|
||||
// InDelta asserts that the two numerals are within delta of each other.
|
||||
//
|
||||
// assert.InDelta(t, math.Pi, (22 / 7.0), 0.01)
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) InDelta(t TestingT, expected, actual interface{}, delta float64, msgAndArgs ...interface{}) bool {
|
||||
return InDelta(a.t, expected, actual, delta, msgAndArgs...)
|
||||
}
|
||||
|
||||
// InEpsilon asserts that expected and actual have a relative error less than epsilon
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) InEpsilon(t TestingT, expected, actual interface{}, epsilon float64, msgAndArgs ...interface{}) bool {
|
||||
return InEpsilon(a.t, expected, actual, epsilon, msgAndArgs...)
|
||||
}
|
||||
|
||||
// NoError asserts that a function returned no error (i.e. `nil`).
|
||||
//
|
||||
// actualObj, err := SomeFunction()
|
||||
|
|
Loading…
Reference in New Issue