func ShouldHappenOnOrAfter(actual interface{}, expected ...interface{}) error {
	if err := need(1, expected); err != nil {
		return err
	}
	actualTime, err := getTimeFromString(actual)
	if err != nil {
		return err
	}
	expectedTime, err := getTimeFromString(expected[0])
	if err != nil {
		return err
	}
	if actualTime.After(expectedTime) || actualTime.Equal(expectedTime) {
		return nil
	}
	return fmt.Errorf("expected '%v' to be before or on '%v'", actualTime, expectedTime)
}
ShouldHappenOnOrAfter receives exactly 2 time.Time arguments and asserts that the first happens on or after the second.
The arguments have to respect the date format RFC3339, as 2006-01-02T15:04:00+07:00

Example of testsuite file:

name: test ShouldHappenOnOrAfter
vars:
time_with_5s_before: 2006-01-02T15:04:00+07:00
time: 2006-01-02T15:04:05+07:00
testcases:
- name: test assertion
steps:
- type: exec
script: "echo {{.time}}"
assertions:
- result.systemout ShouldHappenOnOrAfter "{{.time_with_5s_before}}"
package assertions
import (
	"fmt"
	"math"
	"reflect"
	"strings"
	"time"
	"github.com/pkg/errors"
	"github.com/spf13/cast"
)
type AssertFunc func(actual interface{}, expected ...interface{}) error
var assertMap = map[string]AssertFunc{
	"ShouldEqual":                  ShouldEqual,
	"ShouldNotEqual":               ShouldNotEqual,
	"ShouldAlmostEqual":            ShouldAlmostEqual,
	"ShouldNotAlmostEqual":         ShouldNotAlmostEqual,
	"ShouldNotExist":               ShouldNotExist,
	"ShouldBeNil":                  ShouldBeNil,
	"ShouldNotBeNil":               ShouldNotBeNil,
	"ShouldBeTrue":                 ShouldBeTrue,
	"ShouldBeFalse":                ShouldBeFalse,
	"ShouldBeZeroValue":            ShouldBeZeroValue,
	"ShouldBeGreaterThan":          ShouldBeGreaterThan,
	"ShouldBeGreaterThanOrEqualTo": ShouldBeGreaterThanOrEqualTo,
	"ShouldBeLessThan":             ShouldBeLessThan,
	"ShouldBeLessThanOrEqualTo":    ShouldBeLessThanOrEqualTo,
	"ShouldBeBetween":              ShouldBeBetween,
	"ShouldNotBeBetween":           ShouldNotBeBetween,
	"ShouldBeBetweenOrEqual":       ShouldBeBetweenOrEqual,
	"ShouldNotBeBetweenOrEqual":    ShouldNotBeBetweenOrEqual,
	"ShouldContain":                ShouldContain,
	"ShouldNotContain":             ShouldNotContain,
	"ShouldContainKey":             ShouldContainKey,
	"ShouldNotContainKey":          ShouldNotContainKey,
	"ShouldBeIn":                   ShouldBeIn,
	"ShouldNotBeIn":                ShouldNotBeIn,
	"ShouldBeEmpty":                ShouldBeEmpty,
	"ShouldNotBeEmpty":             ShouldNotBeEmpty,
	"ShouldHaveLength":             ShouldHaveLength,
	"ShouldStartWith":              ShouldStartWith,
	"ShouldNotStartWith":           ShouldNotStartWith,
	"ShouldEndWith":                ShouldEndWith,
	"ShouldNotEndWith":             ShouldNotEndWith,
	"ShouldBeBlank":                ShouldBeBlank,
	"ShouldNotBeBlank":             ShouldNotBeBlank,
	"ShouldContainSubstring":       ShouldContainSubstring,
	"ShouldNotContainSubstring":    ShouldNotContainSubstring,
	"ShouldEqualTrimSpace":         ShouldEqualTrimSpace,
	"ShouldHappenBefore":           ShouldHappenBefore,
	"ShouldHappenOnOrBefore":       ShouldHappenOnOrBefore,
	"ShouldHappenAfter":            ShouldHappenAfter,
	"ShouldHappenOnOrAfter":        ShouldHappenOnOrAfter,
	"ShouldHappenBetween":          ShouldHappenBetween,
}
func Get(s string) (AssertFunc, bool) {
	f, ok := assertMap[s]
	return f, ok
}
func deepEqual(x, y interface{}) bool {
	if !reflect.DeepEqual(x, y) {
		return fmt.Sprintf("%v", x) == fmt.Sprintf("%v", y)
	}
	return true
}
func ShouldEqual(actual interface{}, expected ...interface{}) error {
	if len(expected) > 0 {
		var args string
		for i := range expected {
			actualS, err := cast.ToStringE(expected[i])
			if err != nil {
				return err
			}
			args += actualS + " "
		}
		if deepEqual(actual, strings.TrimRight(args, " ")) {
			return nil
		}
		return fmt.Errorf("expected: %v got: %v", args, actual)
	}
	if err := need(1, expected); err != nil {
		return err
	}
	if deepEqual(actual, expected[0]) {
		return nil
	}
	return fmt.Errorf("expected: %v got: %v", expected[0], actual)
}
func ShouldNotEqual(actual interface{}, expected ...interface{}) error {
	if err := ShouldEqual(actual, expected...); err == nil {
		return fmt.Errorf("not expected: %v got: %v", expected[0], actual)
	}
	return nil
}
func ShouldAlmostEqual(actual interface{}, expected ...interface{}) error {
	if err := need(2, expected); err != nil {
		return err
	}
	actualF, err := cast.ToFloat64E(actual)
	if err != nil {
		return err
	}
	expectedF, err := cast.ToFloat64E(expected[0])
	if err != nil {
		return err
	}
	deltaF, err := cast.ToFloat64E(expected[1])
	if err != nil {
		return err
	}
	actualDeltaF := math.Abs(actualF - expectedF)
	if actualDeltaF <= deltaF {
		return nil
	}
	return fmt.Errorf("expected: %v(+/- %v) got: %v (%v)", expectedF, deltaF, actualF, actualDeltaF)
}
func ShouldNotAlmostEqual(actual interface{}, expected ...interface{}) error {
	if err := need(2, expected); err != nil {
		return err
	}
	actualF, err := cast.ToFloat64E(actual)
	if err != nil {
		return err
	}
	expectedF, err := cast.ToFloat64E(expected[0])
	if err != nil {
		return err
	}
	deltaF, err := cast.ToFloat64E(expected[1])
	if err != nil {
		return err
	}
	if math.Abs(actualF-expectedF) >= deltaF {
		return nil
	}
	return fmt.Errorf("not expected: %v(+/- %v) got: %v (%v)", expected[0], expected[1], actual, math.Abs(actualF-expectedF))
}
func ShouldBeNil(actual interface{}, expected ...interface{}) error {
	if err := need(0, expected); err != nil {
		return err
	}
	if isNil(actual) {
		return nil
	}
	return fmt.Errorf("expected: Nil but is wasn't")
}
func ShouldNotExist(actual interface{}, expected ...interface{}) error {
	if ShouldBeNil(actual) != nil ||
		ShouldBeBlank(actual) != nil ||
		ShouldBeZeroValue(actual) != nil {
		return fmt.Errorf("expected not exist but it was")
	}
	return nil
}
func ShouldNotBeNil(actual interface{}, expected ...interface{}) error {
	if err := need(0, expected); err != nil {
		return err
	}
	if !isNil(actual) {
		return nil
	}
	return fmt.Errorf("expected: Not Nil but is was")
}
func ShouldBeTrue(actual interface{}, expected ...interface{}) error {
	if err := need(0, expected); err != nil {
		return err
	}
	b, err := cast.ToBoolE(actual)
	if err != nil {
		return err
	}
	if b {
		return nil
	}
	return fmt.Errorf("expected: True but is wasn't")
}
func ShouldBeFalse(actual interface{}, expected ...interface{}) error {
	if err := need(0, expected); err != nil {
		return err
	}
	b, err := cast.ToBoolE(actual)
	if err != nil {
		return err
	}
	if !b {
		return nil
	}
	return fmt.Errorf("expected: False but is wasn't")
}
func ShouldBeZeroValue(actual interface{}, expected ...interface{}) error {
	if err := need(0, expected); err != nil {
		return err
	}
	b := actual == nil || reflect.DeepEqual(actual, reflect.Zero(reflect.TypeOf(actual)).Interface())
	if b {
		return nil
	}
	return fmt.Errorf("expected: Zero Value but is wasn't")
}
func ShouldBeGreaterThan(actual interface{}, expected ...interface{}) error {
	if err := need(1, expected); err != nil {
		return err
	}
	if !areSameTypes(actual, expected[0]) {
		return newAssertionError(needSameType)
	}
	actualF, err := cast.ToFloat64E(actual)
	if err != nil {
		actualS, err := cast.ToStringE(actual)
		if err != nil {
			return err
		}
		expectedS, err := cast.ToStringE(expected[0])
		if err != nil {
			return err
		}
		if actualS > expectedS {
			return nil
		}
		return fmt.Errorf("expected: %v greater than %v but it wasn't", actual, expected[0])
	}
	expectedF, err := cast.ToFloat64E(expected[0])
	if err != nil {
		return err
	}
	if actualF > expectedF {
		return nil
	}
	return fmt.Errorf("expected: %v greater than %v but it wasn't", actual, expected[0])
}
func ShouldBeGreaterThanOrEqualTo(actual interface{}, expected ...interface{}) error {
	if err := need(1, expected); err != nil {
		return err
	}
	if !areSameTypes(actual, expected[0]) {
		return newAssertionError(needSameType)
	}
	actualF, err := cast.ToFloat64E(actual)
	if err != nil {
		actualS, err := cast.ToStringE(actual)
		if err != nil {
			return err
		}
		expectedS, err := cast.ToStringE(expected[0])
		if err != nil {
			return err
		}
		if actualS >= expectedS {
			return nil
		}
		return fmt.Errorf("expected: %v greater than or equals to %v but it wasn't", actual, expected[0])
	}
	expectedF, err := cast.ToFloat64E(expected[0])
	if err != nil {
		return err
	}
	if actualF >= expectedF {
		return nil
	}
	return fmt.Errorf("expected: %v greater than or equals to %v but it wasn't", actual, expected[0])
}
func ShouldBeLessThan(actual interface{}, expected ...interface{}) error {
	if err := need(1, expected); err != nil {
		return err
	}
	if !areSameTypes(actual, expected[0]) {
		return newAssertionError(needSameType)
	}
	actualF, err := cast.ToFloat64E(actual)
	if err != nil {
		actualS, err := cast.ToStringE(actual)
		if err != nil {
			return err
		}
		expectedS, err := cast.ToStringE(expected[0])
		if err != nil {
			return err
		}
		if actualS < expectedS {
			return nil
		}
		return fmt.Errorf("expected: %v less than %v but it wasn't", actual, expected[0])
	}
	expectedF, err := cast.ToFloat64E(expected[0])
	if err != nil {
		return err
	}
	if actualF < expectedF {
		return nil
	}
	return fmt.Errorf("expected: %v less than %v but it wasn't", actual, expected[0])
}
func ShouldBeLessThanOrEqualTo(actual interface{}, expected ...interface{}) error {
	if err := need(1, expected); err != nil {
		return err
	}
	if !areSameTypes(actual, expected[0]) {
		return newAssertionError(needSameType)
	}
	actualF, err := cast.ToFloat64E(actual)
	if err != nil {
		actualS, err := cast.ToStringE(actual)
		if err != nil {
			return err
		}
		expectedS, err := cast.ToStringE(expected[0])
		if err != nil {
			return err
		}
		if actualS <= expectedS {
			return nil
		}
		return fmt.Errorf("expected: %v less than or equals to %v but it wasn't", actual, expected[0])
	}
	expectedF, err := cast.ToFloat64E(expected[0])
	if err != nil {
		return err
	}
	if actualF <= expectedF {
		return nil
	}
	return fmt.Errorf("expected '%v' less than or equals to %v but it wasn't", actual, expected[0])
}
func ShouldBeBetween(actual interface{}, expected ...interface{}) error {
	if err := need(2, expected); err != nil {
		return err
	}
	if !areSameTypes(expected[0], expected[1]) {
		return newAssertionError(needSameType)
	}
	err1 := ShouldBeLessThan(actual, expected[1])
	err2 := ShouldBeGreaterThan(actual, expected[0])
	if err1 != nil || err2 != nil {
		return fmt.Errorf("expected '%v' between %v and %v but it wasn't", actual, expected[0], expected[1])
	}
	return nil
}
func ShouldNotBeBetween(actual interface{}, expected ...interface{}) error {
	if err := ShouldBeBetween(actual, expected...); err != nil {
		if _, ok := err.(*AssertionError); ok {
			return err
		}
		return nil
	}
	return fmt.Errorf("expected '%v' not between %v and %v but it was", actual, expected[0], expected[1])
}
func ShouldBeBetweenOrEqual(actual interface{}, expected ...interface{}) error {
	if err := need(2, expected); err != nil {
		return err
	}
	if !areSameTypes(expected[0], expected[1]) {
		return newAssertionError(needSameType)
	}
	err1 := ShouldBeLessThanOrEqualTo(actual, expected[1])
	err2 := ShouldBeGreaterThanOrEqualTo(actual, expected[0])
	if err1 != nil || err2 != nil {
		return fmt.Errorf("expected '%v' between %v and %v but it wasn't", actual, expected[0], expected[1])
	}
	return nil
}
func ShouldNotBeBetweenOrEqual(actual interface{}, expected ...interface{}) error {
	if err := ShouldBeBetweenOrEqual(actual, expected...); err != nil {
		if _, ok := err.(*AssertionError); ok {
			return err
		}
		return nil
	}
	return fmt.Errorf("expected '%v' not between or equal to %v and %v but it was", actual, expected[0], expected[1])
}
func ShouldContain(actual interface{}, expected ...interface{}) error {
	if err := need(1, expected); err != nil {
		return err
	}
	actualSlice, err := cast.ToSliceE(actual)
	if err != nil {
		return err
	}
	for i := range actualSlice {
		if ShouldEqual(actualSlice[i], expected[0]) == nil {
			return nil
		}
	}
	return fmt.Errorf("expected '%v' contain %v but it wasnt", actual, expected[0])
}
func ShouldNotContain(actual interface{}, expected ...interface{}) error {
	if err := need(1, expected); err != nil {
		return err
	}
	actualSlice, err := cast.ToSliceE(actual)
	if err != nil {
		return err
	}
	for i := range actualSlice {
		if ShouldEqual(actualSlice[i], expected[0]) == nil {
			return fmt.Errorf("expected '%v' not contain %v but it was", actual, expected[0])
		}
	}
	return nil
}
func ShouldContainKey(actual interface{}, expected ...interface{}) error {
	if err := need(1, expected); err != nil {
		return err
	}
	actualMap, err := cast.ToStringMapE(actual)
	if err != nil {
		return err
	}
	for k := range actualMap {
		if ShouldEqual(k, expected[0]) == nil {
			return nil
		}
	}
	return fmt.Errorf("expected '%v' contain key %v but it wasnt", actual, expected[0])
}
func ShouldNotContainKey(actual interface{}, expected ...interface{}) error {
	if err := need(1, expected); err != nil {
		return err
	}
	actualMap, err := cast.ToStringMapE(actual)
	if err != nil {
		return err
	}
	for k := range actualMap {
		if ShouldEqual(k, expected[0]) == nil {
			return fmt.Errorf("expected '%v' not contain key %v but it was", actual, expected[0])
		}
	}
	return nil
}
func ShouldBeIn(actual interface{}, expected ...interface{}) error {
	if err := atLeast(1, expected); err != nil {
		return err
	}
	expectedSlice, err := cast.ToSliceE(expected)
	if err != nil {
		return err
	}
	for i := range expectedSlice {
		if ShouldEqual(expectedSlice[i], actual) == nil {
			return nil
		}
	}
	return fmt.Errorf("expected '%v' in %v but it wasnt", actual, expectedSlice)
}
func ShouldNotBeIn(actual interface{}, expected ...interface{}) error {
	if err := atLeast(1, expected); err != nil {
		return err
	}
	if err := ShouldBeIn(actual, expected...); err != nil {
		return nil
	}
	return fmt.Errorf("expected '%v' not in %v but it was", actual, expected)
}
func ShouldBeEmpty(actual interface{}, expected ...interface{}) error {
	if err := need(0, expected); err != nil {
		return err
	}
	if actual == nil {
		return nil
	}
	value := reflect.ValueOf(actual)
	switch value.Kind() {
	case reflect.Slice, reflect.Chan, reflect.Map, reflect.String:
		if value.Len() == 0 {
			return nil
		}
	case reflect.Ptr:
		elem := value.Elem()
		kind := elem.Kind()
		if (kind == reflect.Slice || kind == reflect.Array) && elem.Len() == 0 {
			return nil
		}
	}
	return fmt.Errorf("expected '%v' to be empty but it wasn't", actual)
}
func ShouldNotBeEmpty(actual interface{}, expected ...interface{}) error {
	if err := need(0, expected); err != nil {
		return err
	}
	if err := ShouldBeEmpty(actual); err != nil {
		return nil
	}
	return fmt.Errorf("expected '%v' not to be empty but it wasn't", actual)
}
func ShouldHaveLength(actual interface{}, expected ...interface{}) error {
	if err := need(1, expected); err != nil {
		return err
	}
	length, err := cast.ToInt64E(expected[0])
	if err != nil {
		return err
	}
	value := reflect.ValueOf(actual)
	switch value.Kind() {
	case reflect.Slice, reflect.Chan, reflect.Map, reflect.String:
		if value.Len() == int(length) {
			return nil
		}
	case reflect.Ptr:
		elem := value.Elem()
		kind := elem.Kind()
		if (kind == reflect.Slice || kind == reflect.Array) && elem.Len() == int(length) {
			return nil
		}
	}
	return fmt.Errorf("expected '%v' have length of %d but it wasn't", actual, length)
}
func ShouldStartWith(actual interface{}, expected ...interface{}) error {
	if err := need(1, expected); err != nil {
		return err
	}
	s, err := cast.ToStringE(actual)
	if err != nil {
		return err
	}
	prefix, err := cast.ToStringE(expected[0])
	if err != nil {
		return err
	}
	if strings.HasPrefix(s, prefix) {
		return nil
	}
	return fmt.Errorf("expected '%v' have prefix %q but it wasn't", s, prefix)
}
func ShouldNotStartWith(actual interface{}, expected ...interface{}) error {
	if err := need(1, expected); err != nil {
		return err
	}
	s, err := cast.ToStringE(actual)
	if err != nil {
		return err
	}
	prefix, err := cast.ToStringE(expected[0])
	if err != nil {
		return err
	}
	if strings.HasPrefix(s, prefix) {
		return fmt.Errorf("expected '%v' not have prefix %q but it was", s, prefix)
	}
	return nil
}
func ShouldEndWith(actual interface{}, expected ...interface{}) error {
	if err := need(1, expected); err != nil {
		return err
	}
	s, err := cast.ToStringE(actual)
	if err != nil {
		return err
	}
	suffix, err := cast.ToStringE(expected[0])
	if err != nil {
		return err
	}
	if strings.HasSuffix(s, suffix) {
		return nil
	}
	return fmt.Errorf("expected '%v' have suffix %q but it wasn't", s, suffix)
}
func ShouldNotEndWith(actual interface{}, expected ...interface{}) error {
	if err := need(1, expected); err != nil {
		return err
	}
	s, err := cast.ToStringE(actual)
	if err != nil {
		return err
	}
	suffix, err := cast.ToStringE(expected[0])
	if err != nil {
		return err
	}
	if strings.HasSuffix(s, suffix) {
		return fmt.Errorf("expected '%v' not have suffix %q but it was", s, suffix)
	}
	return nil
}
func ShouldBeBlank(actual interface{}, expected ...interface{}) error {
	if err := need(0, expected); err != nil {
		return err
	}
	s, err := cast.ToStringE(actual)
	if err != nil {
		return err
	}
	if s == "" {
		return nil
	}
	return fmt.Errorf("expected '%v' to be blank but it wasn't", s)
}
func ShouldNotBeBlank(actual interface{}, expected ...interface{}) error {
	if err := need(0, expected); err != nil {
		return err
	}
	s, err := cast.ToStringE(actual)
	if err != nil {
		return err
	}
	if s == "" {
		return fmt.Errorf("expected value to not be blank but it was")
	}
	return nil
}
func ShouldContainSubstring(actual interface{}, expected ...interface{}) error {
	var arg string
	for _, e := range expected {
		arg += fmt.Sprintf("%v ", e)
	}
	s, err := cast.ToStringE(actual)
	if err != nil {
		return err
	}
	ss := strings.TrimSpace(arg)
	if strings.Contains(s, ss) {
		return nil
	}
	return fmt.Errorf("expected '%v' to contain '%v' but it wasn't", s, ss)
}
func ShouldNotContainSubstring(actual interface{}, expected ...interface{}) error {
	var arg string
	for _, e := range expected {
		arg += fmt.Sprintf("%v ", e)
	}
	s, err := cast.ToStringE(actual)
	if err != nil {
		return err
	}
	ss := strings.TrimSpace(arg)
	if strings.Contains(s, ss) {
		return fmt.Errorf("expected '%v' to not contain '%v' but it was", s, ss)
	}
	return nil
}
func ShouldEqualTrimSpace(actual interface{}, expected ...interface{}) error {
	actualS, err := cast.ToStringE(actual)
	if err != nil {
		return err
	}
	return ShouldEqual(strings.TrimSpace(actualS), expected...)
}
func ShouldHappenBefore(actual interface{}, expected ...interface{}) error {
	if err := need(1, expected); err != nil {
		return err
	}
	actualTime, err := getTimeFromString(actual)
	if err != nil {
		return err
	}
	expectedTime, err := getTimeFromString(expected[0])
	if err != nil {
		return err
	}
	if actualTime.Before(expectedTime) {
		return nil
	}
	return fmt.Errorf("expected '%v' to be before '%v'", actualTime, expectedTime)
}
func ShouldHappenOnOrBefore(actual interface{}, expected ...interface{}) error {
	if err := need(1, expected); err != nil {
		return err
	}
	actualTime, err := getTimeFromString(actual)
	if err != nil {
		return err
	}
	expectedTime, err := getTimeFromString(expected[0])
	if err != nil {
		return err
	}
	if actualTime.Before(expectedTime) || actualTime.Equal(expectedTime) {
		return nil
	}
	return fmt.Errorf("expected '%v' to be before on on '%v'", actualTime, expectedTime)
}
func ShouldHappenAfter(actual interface{}, expected ...interface{}) error {
	if err := need(1, expected); err != nil {
		return err
	}
	actualTime, err := getTimeFromString(actual)
	if err != nil {
		return err
	}
	expectedTime, err := getTimeFromString(expected[0])
	if err != nil {
		return err
	}
	if actualTime.After(expectedTime) {
		return nil
	}
	return fmt.Errorf("expected '%v' to be after '%v'", actualTime, expectedTime)
}