timeutil_test.go 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418
  1. package timeutil
  2. import (
  3. "testing"
  4. "time"
  5. )
  6. func Test_DurationString(t *testing.T) {
  7. testCases := map[string]struct {
  8. duration time.Duration
  9. expectedDuration string
  10. }{
  11. "1a": {
  12. duration: 0,
  13. expectedDuration: "",
  14. },
  15. "1b": {
  16. duration: 24 * time.Hour,
  17. expectedDuration: "1d",
  18. },
  19. "1c": {
  20. duration: 24*time.Hour + 5*time.Minute,
  21. expectedDuration: "1445m",
  22. },
  23. "1d": {
  24. duration: 25 * time.Hour,
  25. expectedDuration: "25h",
  26. },
  27. "1e": {
  28. duration: 25 * time.Hour,
  29. expectedDuration: "25h",
  30. },
  31. "1f": {
  32. duration: 72 * time.Hour,
  33. expectedDuration: "3d",
  34. },
  35. "1g": {
  36. duration: 25 * time.Hour,
  37. expectedDuration: "25h",
  38. },
  39. "1h": {
  40. duration: 24*time.Hour + time.Second,
  41. expectedDuration: "86401s",
  42. },
  43. // Expect empty strings if durations are negative
  44. "1i": {
  45. duration: -25 * time.Hour,
  46. expectedDuration: "",
  47. },
  48. }
  49. for name, test := range testCases {
  50. t.Run(name, func(t *testing.T) {
  51. dur := DurationString(test.duration)
  52. if dur != test.expectedDuration {
  53. t.Fatalf("DurationOffsetStrings: exp (%s); act (%s)", test.expectedDuration, dur)
  54. }
  55. })
  56. }
  57. }
  58. func Test_DurationToPromOffsetString(t *testing.T) {
  59. testCases := map[string]struct {
  60. duration time.Duration
  61. expectedDuration string
  62. }{
  63. "1a": {
  64. duration: 0,
  65. expectedDuration: "",
  66. },
  67. "1b": {
  68. duration: 24 * time.Hour,
  69. expectedDuration: "offset 1d",
  70. },
  71. "1c": {
  72. duration: 24*time.Hour + 5*time.Minute,
  73. expectedDuration: "offset 1445m",
  74. },
  75. "1d": {
  76. duration: 25 * time.Hour,
  77. expectedDuration: "offset 25h",
  78. },
  79. "1e": {
  80. duration: 25 * time.Hour,
  81. expectedDuration: "offset 25h",
  82. },
  83. "1f": {
  84. duration: 72 * time.Hour,
  85. expectedDuration: "offset 3d",
  86. },
  87. "1g": {
  88. duration: 25 * time.Hour,
  89. expectedDuration: "offset 25h",
  90. },
  91. "1h": {
  92. duration: 24*time.Hour + time.Second,
  93. expectedDuration: "offset 86401s",
  94. },
  95. // Expect empty strings if durations are negative
  96. "1i": {
  97. duration: -25 * time.Hour,
  98. expectedDuration: "",
  99. },
  100. }
  101. for name, test := range testCases {
  102. t.Run(name, func(t *testing.T) {
  103. dur := DurationToPromOffsetString(test.duration)
  104. if dur != test.expectedDuration {
  105. t.Fatalf("DurationOffsetStrings: exp (%s); act (%s)", test.expectedDuration, dur)
  106. }
  107. })
  108. }
  109. }
  110. func Test_FormatStoreResolution(t *testing.T) {
  111. testCases := map[string]struct {
  112. duration time.Duration
  113. expectedDuration string
  114. }{
  115. "1a": {
  116. duration: 0,
  117. expectedDuration: "0s",
  118. },
  119. "1b": {
  120. duration: 24 * time.Hour,
  121. expectedDuration: "1d",
  122. },
  123. "1c": {
  124. duration: 24*time.Hour + 5*time.Minute,
  125. expectedDuration: "1d",
  126. },
  127. "1d": {
  128. duration: 25 * time.Hour,
  129. expectedDuration: "1d",
  130. },
  131. "1e": {
  132. duration: 25 * time.Hour,
  133. expectedDuration: "1d",
  134. },
  135. "1f": {
  136. duration: 72 * time.Hour,
  137. expectedDuration: "3d",
  138. },
  139. "1g": {
  140. duration: 25 * time.Hour,
  141. expectedDuration: "1d",
  142. },
  143. "1h": {
  144. duration: 24*time.Hour + time.Second,
  145. expectedDuration: "1d",
  146. },
  147. // Expect empty strings if durations are negative
  148. "1i": {
  149. duration: -25 * time.Hour,
  150. expectedDuration: "-25h0m0s",
  151. },
  152. }
  153. for name, test := range testCases {
  154. t.Run(name, func(t *testing.T) {
  155. dur := FormatStoreResolution(test.duration)
  156. if dur != test.expectedDuration {
  157. t.Fatalf("DurationOffsetStrings: exp (%s); act (%s)", test.expectedDuration, dur)
  158. }
  159. })
  160. }
  161. }
  162. func Test_DurationOffsetStrings(t *testing.T) {
  163. testCases := map[string]struct {
  164. duration time.Duration
  165. offset time.Duration
  166. expectedDuration string
  167. expectedOffset string
  168. }{
  169. "1a": {
  170. duration: 0,
  171. offset: 0,
  172. expectedDuration: "",
  173. expectedOffset: "",
  174. },
  175. "1b": {
  176. duration: 24 * time.Hour,
  177. offset: 0,
  178. expectedDuration: "1d",
  179. expectedOffset: "",
  180. },
  181. "1c": {
  182. duration: 24*time.Hour + 5*time.Minute,
  183. offset: 0,
  184. expectedDuration: "1445m",
  185. expectedOffset: "",
  186. },
  187. "1d": {
  188. duration: 25 * time.Hour,
  189. offset: 5 * time.Minute,
  190. expectedDuration: "25h",
  191. expectedOffset: "5m",
  192. },
  193. "1e": {
  194. duration: 25 * time.Hour,
  195. offset: 60 * time.Minute,
  196. expectedDuration: "25h",
  197. expectedOffset: "1h",
  198. },
  199. "1f": {
  200. duration: 72 * time.Hour,
  201. offset: 1440 * time.Minute,
  202. expectedDuration: "3d",
  203. expectedOffset: "1d",
  204. },
  205. "1g": {
  206. duration: 25 * time.Hour,
  207. offset: 1 * time.Second,
  208. expectedDuration: "25h",
  209. expectedOffset: "1s",
  210. },
  211. "1h": {
  212. duration: 24*time.Hour + time.Second,
  213. offset: 1 * time.Second,
  214. expectedDuration: "86401s",
  215. expectedOffset: "1s",
  216. },
  217. // Expect empty strings if durations are negative
  218. "1i": {
  219. duration: -25 * time.Hour,
  220. offset: -1 * time.Second,
  221. expectedDuration: "",
  222. expectedOffset: "",
  223. },
  224. }
  225. for name, test := range testCases {
  226. t.Run(name, func(t *testing.T) {
  227. dur, off := DurationOffsetStrings(test.duration, test.offset)
  228. if dur != test.expectedDuration || off != test.expectedOffset {
  229. t.Fatalf("DurationOffsetStrings: exp (%s %s); act (%s, %s)", test.expectedDuration, test.expectedOffset, dur, off)
  230. }
  231. })
  232. }
  233. }
  234. func Test_ParseDuration(t *testing.T) {
  235. testCases := map[string]struct {
  236. input string
  237. expected time.Duration
  238. }{
  239. "expected": {
  240. input: "3h",
  241. expected: time.Hour * 3,
  242. },
  243. "white space": {
  244. input: " 4s ",
  245. expected: time.Second * 4,
  246. },
  247. "prom prefix": {
  248. input: "offset 3m",
  249. expected: time.Minute * 3,
  250. },
  251. "prom prefix white space": {
  252. input: " offset 3d ",
  253. expected: 24.0 * time.Hour * 3,
  254. },
  255. "ms duration": {
  256. input: "100ms",
  257. expected: 100 * time.Millisecond,
  258. },
  259. "complex duration": {
  260. input: "2d3h14m2s",
  261. expected: (24 * time.Hour * 2) + (3 * time.Hour) + (14 * time.Minute) + (2 * time.Second),
  262. },
  263. "negative duration": {
  264. input: "-2d",
  265. expected: -48 * time.Hour,
  266. },
  267. "zero": {
  268. input: "0h",
  269. expected: time.Duration(0),
  270. },
  271. "empty": {
  272. input: "",
  273. expected: time.Duration(0),
  274. },
  275. "bad string": {
  276. input: "oqwd3dk5hk",
  277. expected: time.Duration(0),
  278. },
  279. "digit": {
  280. input: "3",
  281. expected: time.Duration(0),
  282. },
  283. "unit": {
  284. input: "h",
  285. expected: time.Duration(0),
  286. },
  287. }
  288. for name, test := range testCases {
  289. t.Run(name, func(t *testing.T) {
  290. dur, _ := ParseDuration(test.input)
  291. if dur != test.expected {
  292. t.Errorf("Expected duration %v did not match result %v", test.expected, dur)
  293. }
  294. })
  295. }
  296. }
  297. func Test_CleanDurationString(t *testing.T) {
  298. testCases := map[string]struct {
  299. input string
  300. expected string
  301. }{
  302. "white space": {
  303. input: " 1d ",
  304. expected: "1d",
  305. },
  306. "no change": {
  307. input: "1d",
  308. expected: "1d",
  309. },
  310. "prefix": {
  311. input: "offset 1d",
  312. expected: "1d",
  313. },
  314. "prefix white space": {
  315. input: " offset 1d ",
  316. expected: "1d",
  317. },
  318. "empty": {
  319. input: "",
  320. expected: "",
  321. },
  322. "random": {
  323. input: "oqwd3dk5hk",
  324. expected: "oqwd3dk5hk",
  325. },
  326. }
  327. for name, test := range testCases {
  328. t.Run(name, func(t *testing.T) {
  329. res := CleanDurationString(test.input)
  330. if res != test.expected {
  331. t.Errorf("Expected output %s did not match result %s", test.expected, res)
  332. }
  333. })
  334. }
  335. }
  336. func Test_FormatDurationStringDaysToHours(t *testing.T) {
  337. testCases := map[string]struct {
  338. input string
  339. expected string
  340. }{
  341. "1 day": {
  342. input: "1d",
  343. expected: "24h",
  344. },
  345. "2 days": {
  346. input: "1d",
  347. expected: "24h",
  348. },
  349. "500 days": {
  350. input: "500d",
  351. expected: "12000h",
  352. },
  353. "1h": {
  354. input: "1h",
  355. expected: "1h",
  356. },
  357. "empty": {
  358. input: "",
  359. expected: "",
  360. },
  361. "no unit": {
  362. input: "1",
  363. expected: "1",
  364. },
  365. "random": {
  366. input: "oqwd3dk5hk",
  367. expected: "oqwd3dk5hk",
  368. },
  369. }
  370. for name, test := range testCases {
  371. t.Run(name, func(t *testing.T) {
  372. res, _ := FormatDurationStringDaysToHours(test.input)
  373. if res != test.expected {
  374. t.Errorf("Expected output %s did not match result %s", test.expected, res)
  375. }
  376. })
  377. }
  378. }
  379. func TestRoundToStartOfWeek(t *testing.T) {
  380. sunday := time.Date(2023, 03, 26, 12, 12, 12, 12, time.UTC)
  381. roundedFromSunday := RoundToStartOfWeek(sunday)
  382. if roundedFromSunday.Day() != 26 || roundedFromSunday.Weekday() != time.Sunday {
  383. t.Errorf("expected date to be rounded to the same sunday, got: %d, %s", roundedFromSunday.Day(), roundedFromSunday.Weekday().String())
  384. }
  385. tuesday := time.Date(2023, 03, 28, 12, 12, 12, 12, time.UTC)
  386. roundedFromTuesday := RoundToStartOfWeek(tuesday)
  387. if roundedFromTuesday.Day() != 26 || roundedFromTuesday.Weekday() != time.Sunday {
  388. t.Errorf("expected date to be rounded to the same sunday, got: %d, %s", roundedFromTuesday.Day(), roundedFromTuesday.Weekday().String())
  389. }
  390. }
  391. func TestRoundToStartOfFollowingWeek(t *testing.T) {
  392. sunday := time.Date(2023, 03, 26, 12, 12, 12, 12, time.UTC)
  393. roundedFromSunday := RoundToStartOfFollowingWeek(sunday)
  394. if roundedFromSunday.Month() != 4 || roundedFromSunday.Day() != 2 || roundedFromSunday.Weekday() != time.Sunday {
  395. t.Errorf("expected date to be rounded to the same sunday, got: %d, %s", roundedFromSunday.Day(), roundedFromSunday.Weekday().String())
  396. }
  397. tuesday := time.Date(2023, 03, 28, 12, 12, 12, 12, time.UTC)
  398. roundedFromTuesday := RoundToStartOfFollowingWeek(tuesday)
  399. if roundedFromTuesday.Month() != 4 || roundedFromTuesday.Day() != 2 || roundedFromTuesday.Weekday() != time.Sunday {
  400. t.Errorf("expected date to be rounded to the same sunday, got: %d, %s", roundedFromTuesday.Day(), roundedFromTuesday.Weekday().String())
  401. }
  402. }