duration.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553
  1. package httpexpect
  2. import (
  3. "errors"
  4. "time"
  5. )
  6. // Duration provides methods to inspect attached time.Duration value.
  7. type Duration struct {
  8. noCopy noCopy
  9. chain *chain
  10. value *time.Duration
  11. }
  12. // NewDuration returns a new Duration instance.
  13. //
  14. // If reporter is nil, the function panics.
  15. //
  16. // Example:
  17. //
  18. // d := NewDuration(t, time.Second)
  19. // d.Le(time.Minute)
  20. func NewDuration(reporter Reporter, value time.Duration) *Duration {
  21. return newDuration(newChainWithDefaults("Duration()", reporter), &value)
  22. }
  23. // NewDurationC returns a new Duration instance with config.
  24. //
  25. // Requirements for config are same as for WithConfig function.
  26. //
  27. // Example:
  28. //
  29. // d := NewDurationC(config, time.Second)
  30. // d.Le(time.Minute)
  31. func NewDurationC(config Config, value time.Duration) *Duration {
  32. return newDuration(newChainWithConfig("Duration()", config.withDefaults()), &value)
  33. }
  34. func newDuration(parent *chain, val *time.Duration) *Duration {
  35. return &Duration{chain: parent.clone(), value: val}
  36. }
  37. // Raw returns underlying time.Duration value attached to Duration.
  38. // This is the value originally passed to NewDuration.
  39. //
  40. // Example:
  41. //
  42. // d := NewDuration(t, duration)
  43. // assert.Equal(t, timestamp, d.Raw())
  44. func (d *Duration) Raw() time.Duration {
  45. if d.value == nil {
  46. return 0
  47. }
  48. return *d.value
  49. }
  50. // Alias is similar to Value.Alias.
  51. func (d *Duration) Alias(name string) *Duration {
  52. opChain := d.chain.enter("Alias(%q)", name)
  53. defer opChain.leave()
  54. d.chain.setAlias(name)
  55. return d
  56. }
  57. // Deprecated: support for unset durations will be removed. The only method that
  58. // can create unset duration is Cookie.MaxAge. Instead of Cookie.MaxAge().IsSet(),
  59. // please use Cookie.HasMaxAge().
  60. func (d *Duration) IsSet() *Duration {
  61. opChain := d.chain.enter("IsSet()")
  62. defer opChain.leave()
  63. if opChain.failed() {
  64. return d
  65. }
  66. if d.value == nil {
  67. opChain.fail(AssertionFailure{
  68. Type: AssertNotNil,
  69. Actual: &AssertionValue{d.value},
  70. Errors: []error{
  71. errors.New("expected: duration is present"),
  72. },
  73. })
  74. }
  75. return d
  76. }
  77. // Deprecated: support for unset durations will be removed. The only method that
  78. // can create unset duration is Cookie.MaxAge. Instead of Cookie.MaxAge().NotSet(),
  79. // please use Cookie.NotHasMaxAge().
  80. func (d *Duration) NotSet() *Duration {
  81. opChain := d.chain.enter("NotSet()")
  82. defer opChain.leave()
  83. if opChain.failed() {
  84. return d
  85. }
  86. if !(d.value == nil) {
  87. opChain.fail(AssertionFailure{
  88. Type: AssertNotNil,
  89. Actual: &AssertionValue{d.value},
  90. Errors: []error{
  91. errors.New("expected: duration is not present"),
  92. },
  93. })
  94. }
  95. return d
  96. }
  97. // IsEqual succeeds if Duration is equal to given value.
  98. //
  99. // Example:
  100. //
  101. // d := NewDuration(t, time.Second)
  102. // d.IsEqual(time.Second)
  103. func (d *Duration) IsEqual(value time.Duration) *Duration {
  104. opChain := d.chain.enter("IsEqual()")
  105. defer opChain.leave()
  106. if opChain.failed() {
  107. return d
  108. }
  109. if d.value == nil {
  110. opChain.fail(AssertionFailure{
  111. Type: AssertNotNil,
  112. Actual: &AssertionValue{d.value},
  113. Errors: []error{
  114. errors.New("expected: duration is present"),
  115. },
  116. })
  117. return d
  118. }
  119. if !(*d.value == value) {
  120. opChain.fail(AssertionFailure{
  121. Type: AssertEqual,
  122. Actual: &AssertionValue{d.value},
  123. Expected: &AssertionValue{value},
  124. Errors: []error{
  125. errors.New("expected: durations are equal"),
  126. },
  127. })
  128. }
  129. return d
  130. }
  131. // NotEqual succeeds if Duration is not equal to given value.
  132. //
  133. // Example:
  134. //
  135. // d := NewDuration(t, time.Second)
  136. // d.NotEqual(time.Minute)
  137. func (d *Duration) NotEqual(value time.Duration) *Duration {
  138. opChain := d.chain.enter("NotEqual()")
  139. defer opChain.leave()
  140. if opChain.failed() {
  141. return d
  142. }
  143. if d.value == nil {
  144. opChain.fail(AssertionFailure{
  145. Type: AssertNotNil,
  146. Actual: &AssertionValue{d.value},
  147. Errors: []error{
  148. errors.New("expected: duration is present"),
  149. },
  150. })
  151. return d
  152. }
  153. if *d.value == value {
  154. opChain.fail(AssertionFailure{
  155. Type: AssertNotEqual,
  156. Actual: &AssertionValue{d.value},
  157. Expected: &AssertionValue{value},
  158. Errors: []error{
  159. errors.New("expected: durations are non-equal"),
  160. },
  161. })
  162. }
  163. return d
  164. }
  165. // Deprecated: use IsEqual instead.
  166. func (d *Duration) Equal(value time.Duration) *Duration {
  167. return d.IsEqual(value)
  168. }
  169. // Gt succeeds if Duration is greater than given value.
  170. //
  171. // Example:
  172. //
  173. // d := NewDuration(t, time.Minute)
  174. // d.Gt(time.Second)
  175. func (d *Duration) Gt(value time.Duration) *Duration {
  176. opChain := d.chain.enter("Gt()")
  177. defer opChain.leave()
  178. if opChain.failed() {
  179. return d
  180. }
  181. if d.value == nil {
  182. opChain.fail(AssertionFailure{
  183. Type: AssertNotNil,
  184. Actual: &AssertionValue{d.value},
  185. Errors: []error{
  186. errors.New("expected: duration is present"),
  187. },
  188. })
  189. return d
  190. }
  191. if !(*d.value > value) {
  192. opChain.fail(AssertionFailure{
  193. Type: AssertGt,
  194. Actual: &AssertionValue{d.value},
  195. Expected: &AssertionValue{value},
  196. Errors: []error{
  197. errors.New("expected: duration is larger than given value"),
  198. },
  199. })
  200. }
  201. return d
  202. }
  203. // Ge succeeds if Duration is greater than or equal to given value.
  204. //
  205. // Example:
  206. //
  207. // d := NewDuration(t, time.Minute)
  208. // d.Ge(time.Second)
  209. func (d *Duration) Ge(value time.Duration) *Duration {
  210. opChain := d.chain.enter("Ge()")
  211. defer opChain.leave()
  212. if opChain.failed() {
  213. return d
  214. }
  215. if d.value == nil {
  216. opChain.fail(AssertionFailure{
  217. Type: AssertNotNil,
  218. Actual: &AssertionValue{d.value},
  219. Errors: []error{
  220. errors.New("expected: duration is present"),
  221. },
  222. })
  223. return d
  224. }
  225. if !(*d.value >= value) {
  226. opChain.fail(AssertionFailure{
  227. Type: AssertGe,
  228. Actual: &AssertionValue{d.value},
  229. Expected: &AssertionValue{value},
  230. Errors: []error{
  231. errors.New("expected: duration is larger than or equal to given value"),
  232. },
  233. })
  234. }
  235. return d
  236. }
  237. // Lt succeeds if Duration is lesser than given value.
  238. //
  239. // Example:
  240. //
  241. // d := NewDuration(t, time.Second)
  242. // d.Lt(time.Minute)
  243. func (d *Duration) Lt(value time.Duration) *Duration {
  244. opChain := d.chain.enter("Lt()")
  245. defer opChain.leave()
  246. if opChain.failed() {
  247. return d
  248. }
  249. if d.value == nil {
  250. opChain.fail(AssertionFailure{
  251. Type: AssertNotNil,
  252. Actual: &AssertionValue{d.value},
  253. Errors: []error{
  254. errors.New("expected: duration is present"),
  255. },
  256. })
  257. return d
  258. }
  259. if !(*d.value < value) {
  260. opChain.fail(AssertionFailure{
  261. Type: AssertLt,
  262. Actual: &AssertionValue{d.value},
  263. Expected: &AssertionValue{value},
  264. Errors: []error{
  265. errors.New("expected: duration is less than given value"),
  266. },
  267. })
  268. }
  269. return d
  270. }
  271. // Le succeeds if Duration is lesser than or equal to given value.
  272. //
  273. // Example:
  274. //
  275. // d := NewDuration(t, time.Second)
  276. // d.Le(time.Minute)
  277. func (d *Duration) Le(value time.Duration) *Duration {
  278. opChain := d.chain.enter("Le()")
  279. defer opChain.leave()
  280. if opChain.failed() {
  281. return d
  282. }
  283. if d.value == nil {
  284. opChain.fail(AssertionFailure{
  285. Type: AssertNotNil,
  286. Actual: &AssertionValue{d.value},
  287. Errors: []error{
  288. errors.New("expected: duration is present"),
  289. },
  290. })
  291. return d
  292. }
  293. if !(*d.value <= value) {
  294. opChain.fail(AssertionFailure{
  295. Type: AssertLe,
  296. Actual: &AssertionValue{d.value},
  297. Expected: &AssertionValue{value},
  298. Errors: []error{
  299. errors.New("expected: duration is less than or equal to given value"),
  300. },
  301. })
  302. }
  303. return d
  304. }
  305. // InRange succeeds if Duration is within given range [min; max].
  306. //
  307. // Example:
  308. //
  309. // d := NewDuration(t, time.Minute)
  310. // d.InRange(time.Second, time.Hour)
  311. // d.InRange(time.Minute, time.Minute)
  312. func (d *Duration) InRange(min, max time.Duration) *Duration {
  313. opChain := d.chain.enter("InRange()")
  314. defer opChain.leave()
  315. if opChain.failed() {
  316. return d
  317. }
  318. if d.value == nil {
  319. opChain.fail(AssertionFailure{
  320. Type: AssertNotNil,
  321. Actual: &AssertionValue{d.value},
  322. Errors: []error{
  323. errors.New("expected: duration is present"),
  324. },
  325. })
  326. return d
  327. }
  328. if !(*d.value >= min && *d.value <= max) {
  329. opChain.fail(AssertionFailure{
  330. Type: AssertInRange,
  331. Actual: &AssertionValue{d.value},
  332. Expected: &AssertionValue{AssertionRange{min, max}},
  333. Errors: []error{
  334. errors.New("expected: duration is within given range"),
  335. },
  336. })
  337. }
  338. return d
  339. }
  340. // NotInRange succeeds if Duration is not within given range [min; max].
  341. //
  342. // Example:
  343. //
  344. // d := NewDuration(t, time.Minute*10)
  345. // d.NotInRange(time.Minute, time.Minute-time.Nanosecond)
  346. // d.NotInRange(time.Minute+time.Nanosecond, time.Minute*10)
  347. func (d *Duration) NotInRange(min, max time.Duration) *Duration {
  348. opChain := d.chain.enter("NotInRange()")
  349. defer opChain.leave()
  350. if opChain.failed() {
  351. return d
  352. }
  353. if d.value == nil {
  354. opChain.fail(AssertionFailure{
  355. Type: AssertNotNil,
  356. Actual: &AssertionValue{d.value},
  357. Errors: []error{
  358. errors.New("expected: duration is present"),
  359. },
  360. })
  361. return d
  362. }
  363. if *d.value >= min && *d.value <= max {
  364. opChain.fail(AssertionFailure{
  365. Type: AssertNotInRange,
  366. Actual: &AssertionValue{d.value},
  367. Expected: &AssertionValue{AssertionRange{min, max}},
  368. Errors: []error{
  369. errors.New("expected: duration is not within given range"),
  370. },
  371. })
  372. }
  373. return d
  374. }
  375. // InList succeeds if Duration is equal to one of the values from given
  376. // list of time.Duration.
  377. //
  378. // Example:
  379. //
  380. // d := NewDuration(t, time.Minute)
  381. // d.InList(time.Minute, time.Hour)
  382. func (d *Duration) InList(values ...time.Duration) *Duration {
  383. opChain := d.chain.enter("InList()")
  384. defer opChain.leave()
  385. if opChain.failed() {
  386. return d
  387. }
  388. if len(values) == 0 {
  389. opChain.fail(AssertionFailure{
  390. Type: AssertUsage,
  391. Errors: []error{
  392. errors.New("unexpected empty list argument"),
  393. },
  394. })
  395. return d
  396. }
  397. if d.value == nil {
  398. opChain.fail(AssertionFailure{
  399. Type: AssertNotNil,
  400. Actual: &AssertionValue{d.value},
  401. Errors: []error{
  402. errors.New("expected: duration is present"),
  403. },
  404. })
  405. return d
  406. }
  407. var isListed bool
  408. for _, v := range values {
  409. if *d.value == v {
  410. isListed = true
  411. break
  412. }
  413. }
  414. if !isListed {
  415. valueList := make([]interface{}, 0, len(values))
  416. for _, v := range values {
  417. valueList = append(valueList, v)
  418. }
  419. opChain.fail(AssertionFailure{
  420. Type: AssertBelongs,
  421. Actual: &AssertionValue{d.value},
  422. Expected: &AssertionValue{AssertionList(valueList)},
  423. Errors: []error{
  424. errors.New("expected: duration is equal to one of the values"),
  425. },
  426. })
  427. }
  428. return d
  429. }
  430. // NotInList succeeds if Duration is not equal to any of the values from
  431. // given list of time.Duration.
  432. //
  433. // Example:
  434. //
  435. // d := NewDuration(t, time.Minute)
  436. // d.NotInList(time.Second, time.Hour)
  437. func (d *Duration) NotInList(values ...time.Duration) *Duration {
  438. opChain := d.chain.enter("NotInList()")
  439. defer opChain.leave()
  440. if opChain.failed() {
  441. return d
  442. }
  443. if len(values) == 0 {
  444. opChain.fail(AssertionFailure{
  445. Type: AssertUsage,
  446. Errors: []error{
  447. errors.New("unexpected empty list argument"),
  448. },
  449. })
  450. return d
  451. }
  452. if d.value == nil {
  453. opChain.fail(AssertionFailure{
  454. Type: AssertNotNil,
  455. Actual: &AssertionValue{d.value},
  456. Errors: []error{
  457. errors.New("expected: duration is present"),
  458. },
  459. })
  460. return d
  461. }
  462. for _, v := range values {
  463. if *d.value == v {
  464. valueList := make([]interface{}, 0, len(values))
  465. for _, v := range values {
  466. valueList = append(valueList, v)
  467. }
  468. opChain.fail(AssertionFailure{
  469. Type: AssertNotBelongs,
  470. Actual: &AssertionValue{d.value},
  471. Expected: &AssertionValue{AssertionList(valueList)},
  472. Errors: []error{
  473. errors.New("expected: duration is not equal to any of the values"),
  474. },
  475. })
  476. return d
  477. }
  478. }
  479. return d
  480. }