time.go 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. package assertions
  2. import (
  3. "fmt"
  4. "time"
  5. )
  6. // ShouldHappenBefore receives exactly 2 time.Time arguments and asserts that the first happens before the second.
  7. func ShouldHappenBefore(actual interface{}, expected ...interface{}) string {
  8. if fail := need(1, expected); fail != success {
  9. return fail
  10. }
  11. actualTime, firstOk := actual.(time.Time)
  12. expectedTime, secondOk := expected[0].(time.Time)
  13. if !firstOk || !secondOk {
  14. return shouldUseTimes
  15. }
  16. if !actualTime.Before(expectedTime) {
  17. return fmt.Sprintf(shouldHaveHappenedBefore, actualTime, expectedTime, actualTime.Sub(expectedTime))
  18. }
  19. return success
  20. }
  21. // ShouldHappenOnOrBefore receives exactly 2 time.Time arguments and asserts that the first happens on or before the second.
  22. func ShouldHappenOnOrBefore(actual interface{}, expected ...interface{}) string {
  23. if fail := need(1, expected); fail != success {
  24. return fail
  25. }
  26. actualTime, firstOk := actual.(time.Time)
  27. expectedTime, secondOk := expected[0].(time.Time)
  28. if !firstOk || !secondOk {
  29. return shouldUseTimes
  30. }
  31. if actualTime.Equal(expectedTime) {
  32. return success
  33. }
  34. return ShouldHappenBefore(actualTime, expectedTime)
  35. }
  36. // ShouldHappenAfter receives exactly 2 time.Time arguments and asserts that the first happens after the second.
  37. func ShouldHappenAfter(actual interface{}, expected ...interface{}) string {
  38. if fail := need(1, expected); fail != success {
  39. return fail
  40. }
  41. actualTime, firstOk := actual.(time.Time)
  42. expectedTime, secondOk := expected[0].(time.Time)
  43. if !firstOk || !secondOk {
  44. return shouldUseTimes
  45. }
  46. if !actualTime.After(expectedTime) {
  47. return fmt.Sprintf(shouldHaveHappenedAfter, actualTime, expectedTime, expectedTime.Sub(actualTime))
  48. }
  49. return success
  50. }
  51. // ShouldHappenOnOrAfter receives exactly 2 time.Time arguments and asserts that the first happens on or after the second.
  52. func ShouldHappenOnOrAfter(actual interface{}, expected ...interface{}) string {
  53. if fail := need(1, expected); fail != success {
  54. return fail
  55. }
  56. actualTime, firstOk := actual.(time.Time)
  57. expectedTime, secondOk := expected[0].(time.Time)
  58. if !firstOk || !secondOk {
  59. return shouldUseTimes
  60. }
  61. if actualTime.Equal(expectedTime) {
  62. return success
  63. }
  64. return ShouldHappenAfter(actualTime, expectedTime)
  65. }
  66. // ShouldHappenBetween receives exactly 3 time.Time arguments and asserts that the first happens between (not on) the second and third.
  67. func ShouldHappenBetween(actual interface{}, expected ...interface{}) string {
  68. if fail := need(2, expected); fail != success {
  69. return fail
  70. }
  71. actualTime, firstOk := actual.(time.Time)
  72. min, secondOk := expected[0].(time.Time)
  73. max, thirdOk := expected[1].(time.Time)
  74. if !firstOk || !secondOk || !thirdOk {
  75. return shouldUseTimes
  76. }
  77. if !actualTime.After(min) {
  78. return fmt.Sprintf(shouldHaveHappenedBetween, actualTime, min, max, min.Sub(actualTime))
  79. }
  80. if !actualTime.Before(max) {
  81. return fmt.Sprintf(shouldHaveHappenedBetween, actualTime, min, max, actualTime.Sub(max))
  82. }
  83. return success
  84. }
  85. // ShouldHappenOnOrBetween receives exactly 3 time.Time arguments and asserts that the first happens between or on the second and third.
  86. func ShouldHappenOnOrBetween(actual interface{}, expected ...interface{}) string {
  87. if fail := need(2, expected); fail != success {
  88. return fail
  89. }
  90. actualTime, firstOk := actual.(time.Time)
  91. min, secondOk := expected[0].(time.Time)
  92. max, thirdOk := expected[1].(time.Time)
  93. if !firstOk || !secondOk || !thirdOk {
  94. return shouldUseTimes
  95. }
  96. if actualTime.Equal(min) || actualTime.Equal(max) {
  97. return success
  98. }
  99. return ShouldHappenBetween(actualTime, min, max)
  100. }
  101. // ShouldNotHappenOnOrBetween receives exactly 3 time.Time arguments and asserts that the first
  102. // does NOT happen between or on the second or third.
  103. func ShouldNotHappenOnOrBetween(actual interface{}, expected ...interface{}) string {
  104. if fail := need(2, expected); fail != success {
  105. return fail
  106. }
  107. actualTime, firstOk := actual.(time.Time)
  108. min, secondOk := expected[0].(time.Time)
  109. max, thirdOk := expected[1].(time.Time)
  110. if !firstOk || !secondOk || !thirdOk {
  111. return shouldUseTimes
  112. }
  113. if actualTime.Equal(min) || actualTime.Equal(max) {
  114. return fmt.Sprintf(shouldNotHaveHappenedOnOrBetween, actualTime, min, max)
  115. }
  116. if actualTime.After(min) && actualTime.Before(max) {
  117. return fmt.Sprintf(shouldNotHaveHappenedOnOrBetween, actualTime, min, max)
  118. }
  119. return success
  120. }
  121. // ShouldHappenWithin receives a time.Time, a time.Duration, and a time.Time (3 arguments)
  122. // and asserts that the first time.Time happens within or on the duration specified relative to
  123. // the other time.Time.
  124. func ShouldHappenWithin(actual interface{}, expected ...interface{}) string {
  125. if fail := need(2, expected); fail != success {
  126. return fail
  127. }
  128. actualTime, firstOk := actual.(time.Time)
  129. tolerance, secondOk := expected[0].(time.Duration)
  130. threshold, thirdOk := expected[1].(time.Time)
  131. if !firstOk || !secondOk || !thirdOk {
  132. return shouldUseDurationAndTime
  133. }
  134. min := threshold.Add(-tolerance)
  135. max := threshold.Add(tolerance)
  136. return ShouldHappenOnOrBetween(actualTime, min, max)
  137. }
  138. // ShouldNotHappenWithin receives a time.Time, a time.Duration, and a time.Time (3 arguments)
  139. // and asserts that the first time.Time does NOT happen within or on the duration specified relative to
  140. // the other time.Time.
  141. func ShouldNotHappenWithin(actual interface{}, expected ...interface{}) string {
  142. if fail := need(2, expected); fail != success {
  143. return fail
  144. }
  145. actualTime, firstOk := actual.(time.Time)
  146. tolerance, secondOk := expected[0].(time.Duration)
  147. threshold, thirdOk := expected[1].(time.Time)
  148. if !firstOk || !secondOk || !thirdOk {
  149. return shouldUseDurationAndTime
  150. }
  151. min := threshold.Add(-tolerance)
  152. max := threshold.Add(tolerance)
  153. return ShouldNotHappenOnOrBetween(actualTime, min, max)
  154. }
  155. // ShouldBeChronological receives a []time.Time slice and asserts that they are
  156. // in chronological order starting with the first time.Time as the earliest.
  157. func ShouldBeChronological(actual interface{}, expected ...interface{}) string {
  158. if fail := need(0, expected); fail != success {
  159. return fail
  160. }
  161. times, ok := actual.([]time.Time)
  162. if !ok {
  163. return shouldUseTimeSlice
  164. }
  165. var previous time.Time
  166. for i, current := range times {
  167. if i > 0 && current.Before(previous) {
  168. return fmt.Sprintf(shouldHaveBeenChronological,
  169. i, i-1, previous.String(), i, current.String())
  170. }
  171. previous = current
  172. }
  173. return ""
  174. }
  175. // ShouldNotBeChronological receives a []time.Time slice and asserts that they are
  176. // NOT in chronological order.
  177. func ShouldNotBeChronological(actual interface{}, expected ...interface{}) string {
  178. if fail := need(0, expected); fail != success {
  179. return fail
  180. }
  181. if _, ok := actual.([]time.Time); !ok {
  182. return shouldUseTimeSlice
  183. }
  184. result := ShouldBeChronological(actual, expected...)
  185. if result != "" {
  186. return ""
  187. }
  188. return shouldNotHaveBeenchronological
  189. }