203 lines
6.3 KiB
Go
203 lines
6.3 KiB
Go
|
package assertions
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
"time"
|
||
|
)
|
||
|
|
||
|
// ShouldHappenBefore receives exactly 2 time.Time arguments and asserts that the first happens before the second.
|
||
|
func ShouldHappenBefore(actual interface{}, expected ...interface{}) string {
|
||
|
if fail := need(1, expected); fail != success {
|
||
|
return fail
|
||
|
}
|
||
|
actualTime, firstOk := actual.(time.Time)
|
||
|
expectedTime, secondOk := expected[0].(time.Time)
|
||
|
|
||
|
if !firstOk || !secondOk {
|
||
|
return shouldUseTimes
|
||
|
}
|
||
|
|
||
|
if !actualTime.Before(expectedTime) {
|
||
|
return fmt.Sprintf(shouldHaveHappenedBefore, actualTime, expectedTime, actualTime.Sub(expectedTime))
|
||
|
}
|
||
|
|
||
|
return success
|
||
|
}
|
||
|
|
||
|
// ShouldHappenOnOrBefore receives exactly 2 time.Time arguments and asserts that the first happens on or before the second.
|
||
|
func ShouldHappenOnOrBefore(actual interface{}, expected ...interface{}) string {
|
||
|
if fail := need(1, expected); fail != success {
|
||
|
return fail
|
||
|
}
|
||
|
actualTime, firstOk := actual.(time.Time)
|
||
|
expectedTime, secondOk := expected[0].(time.Time)
|
||
|
|
||
|
if !firstOk || !secondOk {
|
||
|
return shouldUseTimes
|
||
|
}
|
||
|
|
||
|
if actualTime.Equal(expectedTime) {
|
||
|
return success
|
||
|
}
|
||
|
return ShouldHappenBefore(actualTime, expectedTime)
|
||
|
}
|
||
|
|
||
|
// ShouldHappenAfter receives exactly 2 time.Time arguments and asserts that the first happens after the second.
|
||
|
func ShouldHappenAfter(actual interface{}, expected ...interface{}) string {
|
||
|
if fail := need(1, expected); fail != success {
|
||
|
return fail
|
||
|
}
|
||
|
actualTime, firstOk := actual.(time.Time)
|
||
|
expectedTime, secondOk := expected[0].(time.Time)
|
||
|
|
||
|
if !firstOk || !secondOk {
|
||
|
return shouldUseTimes
|
||
|
}
|
||
|
if !actualTime.After(expectedTime) {
|
||
|
return fmt.Sprintf(shouldHaveHappenedAfter, actualTime, expectedTime, expectedTime.Sub(actualTime))
|
||
|
}
|
||
|
return success
|
||
|
}
|
||
|
|
||
|
// ShouldHappenOnOrAfter receives exactly 2 time.Time arguments and asserts that the first happens on or after the second.
|
||
|
func ShouldHappenOnOrAfter(actual interface{}, expected ...interface{}) string {
|
||
|
if fail := need(1, expected); fail != success {
|
||
|
return fail
|
||
|
}
|
||
|
actualTime, firstOk := actual.(time.Time)
|
||
|
expectedTime, secondOk := expected[0].(time.Time)
|
||
|
|
||
|
if !firstOk || !secondOk {
|
||
|
return shouldUseTimes
|
||
|
}
|
||
|
if actualTime.Equal(expectedTime) {
|
||
|
return success
|
||
|
}
|
||
|
return ShouldHappenAfter(actualTime, expectedTime)
|
||
|
}
|
||
|
|
||
|
// ShouldHappenBetween receives exactly 3 time.Time arguments and asserts that the first happens between (not on) the second and third.
|
||
|
func ShouldHappenBetween(actual interface{}, expected ...interface{}) string {
|
||
|
if fail := need(2, expected); fail != success {
|
||
|
return fail
|
||
|
}
|
||
|
actualTime, firstOk := actual.(time.Time)
|
||
|
min, secondOk := expected[0].(time.Time)
|
||
|
max, thirdOk := expected[1].(time.Time)
|
||
|
|
||
|
if !firstOk || !secondOk || !thirdOk {
|
||
|
return shouldUseTimes
|
||
|
}
|
||
|
|
||
|
if !actualTime.After(min) {
|
||
|
return fmt.Sprintf(shouldHaveHappenedBetween, actualTime, min, max, min.Sub(actualTime))
|
||
|
}
|
||
|
if !actualTime.Before(max) {
|
||
|
return fmt.Sprintf(shouldHaveHappenedBetween, actualTime, min, max, actualTime.Sub(max))
|
||
|
}
|
||
|
return success
|
||
|
}
|
||
|
|
||
|
// ShouldHappenOnOrBetween receives exactly 3 time.Time arguments and asserts that the first happens between or on the second and third.
|
||
|
func ShouldHappenOnOrBetween(actual interface{}, expected ...interface{}) string {
|
||
|
if fail := need(2, expected); fail != success {
|
||
|
return fail
|
||
|
}
|
||
|
actualTime, firstOk := actual.(time.Time)
|
||
|
min, secondOk := expected[0].(time.Time)
|
||
|
max, thirdOk := expected[1].(time.Time)
|
||
|
|
||
|
if !firstOk || !secondOk || !thirdOk {
|
||
|
return shouldUseTimes
|
||
|
}
|
||
|
if actualTime.Equal(min) || actualTime.Equal(max) {
|
||
|
return success
|
||
|
}
|
||
|
return ShouldHappenBetween(actualTime, min, max)
|
||
|
}
|
||
|
|
||
|
// ShouldNotHappenOnOrBetween receives exactly 3 time.Time arguments and asserts that the first
|
||
|
// does NOT happen between or on the second or third.
|
||
|
func ShouldNotHappenOnOrBetween(actual interface{}, expected ...interface{}) string {
|
||
|
if fail := need(2, expected); fail != success {
|
||
|
return fail
|
||
|
}
|
||
|
actualTime, firstOk := actual.(time.Time)
|
||
|
min, secondOk := expected[0].(time.Time)
|
||
|
max, thirdOk := expected[1].(time.Time)
|
||
|
|
||
|
if !firstOk || !secondOk || !thirdOk {
|
||
|
return shouldUseTimes
|
||
|
}
|
||
|
if actualTime.Equal(min) || actualTime.Equal(max) {
|
||
|
return fmt.Sprintf(shouldNotHaveHappenedOnOrBetween, actualTime, min, max)
|
||
|
}
|
||
|
if actualTime.After(min) && actualTime.Before(max) {
|
||
|
return fmt.Sprintf(shouldNotHaveHappenedOnOrBetween, actualTime, min, max)
|
||
|
}
|
||
|
return success
|
||
|
}
|
||
|
|
||
|
// ShouldHappenWithin receives a time.Time, a time.Duration, and a time.Time (3 arguments)
|
||
|
// and asserts that the first time.Time happens within or on the duration specified relative to
|
||
|
// the other time.Time.
|
||
|
func ShouldHappenWithin(actual interface{}, expected ...interface{}) string {
|
||
|
if fail := need(2, expected); fail != success {
|
||
|
return fail
|
||
|
}
|
||
|
actualTime, firstOk := actual.(time.Time)
|
||
|
tolerance, secondOk := expected[0].(time.Duration)
|
||
|
threshold, thirdOk := expected[1].(time.Time)
|
||
|
|
||
|
if !firstOk || !secondOk || !thirdOk {
|
||
|
return shouldUseDurationAndTime
|
||
|
}
|
||
|
|
||
|
min := threshold.Add(-tolerance)
|
||
|
max := threshold.Add(tolerance)
|
||
|
return ShouldHappenOnOrBetween(actualTime, min, max)
|
||
|
}
|
||
|
|
||
|
// ShouldNotHappenWithin receives a time.Time, a time.Duration, and a time.Time (3 arguments)
|
||
|
// and asserts that the first time.Time does NOT happen within or on the duration specified relative to
|
||
|
// the other time.Time.
|
||
|
func ShouldNotHappenWithin(actual interface{}, expected ...interface{}) string {
|
||
|
if fail := need(2, expected); fail != success {
|
||
|
return fail
|
||
|
}
|
||
|
actualTime, firstOk := actual.(time.Time)
|
||
|
tolerance, secondOk := expected[0].(time.Duration)
|
||
|
threshold, thirdOk := expected[1].(time.Time)
|
||
|
|
||
|
if !firstOk || !secondOk || !thirdOk {
|
||
|
return shouldUseDurationAndTime
|
||
|
}
|
||
|
|
||
|
min := threshold.Add(-tolerance)
|
||
|
max := threshold.Add(tolerance)
|
||
|
return ShouldNotHappenOnOrBetween(actualTime, min, max)
|
||
|
}
|
||
|
|
||
|
// ShouldBeChronological receives a []time.Time slice and asserts that the are
|
||
|
// in chronological order starting with the first time.Time as the earliest.
|
||
|
func ShouldBeChronological(actual interface{}, expected ...interface{}) string {
|
||
|
if fail := need(0, expected); fail != success {
|
||
|
return fail
|
||
|
}
|
||
|
|
||
|
times, ok := actual.([]time.Time)
|
||
|
if !ok {
|
||
|
return shouldUseTimeSlice
|
||
|
}
|
||
|
|
||
|
var previous time.Time
|
||
|
for i, current := range times {
|
||
|
if i > 0 && current.Before(previous) {
|
||
|
return fmt.Sprintf(shouldHaveBeenChronological,
|
||
|
i, i-1, previous.String(), i, current.String())
|
||
|
}
|
||
|
previous = current
|
||
|
}
|
||
|
return ""
|
||
|
}
|