...
1
2
3 package matchers
4
5 import (
6 "fmt"
7 "time"
8
9 "github.com/onsi/gomega/format"
10 )
11
12 type BeTemporallyMatcher struct {
13 Comparator string
14 CompareTo time.Time
15 Threshold []time.Duration
16 }
17
18 func (matcher *BeTemporallyMatcher) FailureMessage(actual interface{}) (message string) {
19 return format.Message(actual, fmt.Sprintf("to be %s", matcher.Comparator), matcher.CompareTo)
20 }
21
22 func (matcher *BeTemporallyMatcher) NegatedFailureMessage(actual interface{}) (message string) {
23 return format.Message(actual, fmt.Sprintf("not to be %s", matcher.Comparator), matcher.CompareTo)
24 }
25
26 func (matcher *BeTemporallyMatcher) Match(actual interface{}) (bool, error) {
27
28 isTime := func(t interface{}) bool {
29 _, ok := t.(time.Time)
30 return ok
31 }
32
33 if !isTime(actual) {
34 return false, fmt.Errorf("Expected a time.Time. Got:\n%s", format.Object(actual, 1))
35 }
36
37 switch matcher.Comparator {
38 case "==", "~", ">", ">=", "<", "<=":
39 default:
40 return false, fmt.Errorf("Unknown comparator: %s", matcher.Comparator)
41 }
42
43 var threshold = time.Millisecond
44 if len(matcher.Threshold) == 1 {
45 threshold = matcher.Threshold[0]
46 }
47
48 return matcher.matchTimes(actual.(time.Time), matcher.CompareTo, threshold), nil
49 }
50
51 func (matcher *BeTemporallyMatcher) matchTimes(actual, compareTo time.Time, threshold time.Duration) (success bool) {
52 switch matcher.Comparator {
53 case "==":
54 return actual.Equal(compareTo)
55 case "~":
56 diff := actual.Sub(compareTo)
57 return -threshold <= diff && diff <= threshold
58 case ">":
59 return actual.After(compareTo)
60 case ">=":
61 return !actual.Before(compareTo)
62 case "<":
63 return actual.Before(compareTo)
64 case "<=":
65 return !actual.After(compareTo)
66 }
67 return false
68 }
69
View as plain text