test-org-clock.el 38 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240
  1. ;;; test-org-clock.el --- Tests for org-clock.el -*- lexical-binding: t; -*-
  2. ;; Copyright (C) 2012, 2014, 2015, 2019 Nicolas Goaziou
  3. ;; Author: Nicolas Goaziou <n.goaziou at gmail dot com>
  4. ;; Released under the GNU General Public License version 3
  5. ;; see: https://www.gnu.org/licenses/gpl-3.0.html
  6. ;;;; Comments
  7. ;;; Code:
  8. (require 'org-duration)
  9. (require 'org-clock)
  10. (defun org-test-clock-create-timestamp (input &optional inactive with-time)
  11. "Create a timestamp out of a date/time prompt string.
  12. INPUT is a string as expected in a date/time prompt, i.e \"+2d\"
  13. or \"2/5\".
  14. When optional argument INACTIVE is non-nil, return an inactive
  15. timestamp. When optional argument WITH-TIME is non-nil, also
  16. insert hours and minutes.
  17. Return the timestamp as a string."
  18. (org-element-interpret-data
  19. (let ((time (decode-time
  20. (org-encode-time
  21. (org-fix-decoded-time
  22. (org-read-date-analyze
  23. input nil (decode-time (current-time))))))))
  24. (list 'timestamp
  25. (list :type (if inactive 'inactive 'active)
  26. :minute-start (and with-time (nth 1 time))
  27. :hour-start (and with-time (nth 2 time))
  28. :day-start (nth 3 time)
  29. :month-start (nth 4 time)
  30. :year-start (nth 5 time))))))
  31. (defun org-test-clock-create-clock (input1 &optional input2)
  32. "Create a clock line out of two date/time prompts.
  33. INPUT1 and INPUT2 are strings as expected in a date/time prompt,
  34. i.e \"+2d\" or \"2/5\". They respectively refer to start and end
  35. range. INPUT2 can be omitted if clock hasn't finished yet.
  36. Return the clock line as a string."
  37. (let* ((beg (org-test-clock-create-timestamp input1 t t))
  38. (end (and input2 (org-test-clock-create-timestamp input2 t t)))
  39. (sec-diff (and input2
  40. (floor (- (org-time-string-to-seconds end)
  41. (org-time-string-to-seconds beg))))))
  42. (concat org-clock-string " " beg
  43. (when end
  44. (concat "--" end " => "
  45. (format "%2d:%02d"
  46. (/ sec-diff 3600)
  47. (/ (mod sec-diff 3600) 60))))
  48. "\n")))
  49. (defun test-org-clock-clocktable-contents (options &optional initial)
  50. "Return contents of a Clock table for current buffer
  51. OPTIONS is a string of Clock table options. Optional argument
  52. INITIAL is a string specifying initial contents within the Clock
  53. table.
  54. Caption is ignored in contents. The clocktable doesn't appear in
  55. the buffer."
  56. (declare (indent 2))
  57. (goto-char (point-min))
  58. (save-excursion
  59. (insert "#+BEGIN: clocktable " options "\n")
  60. (when initial (insert initial))
  61. (unless (string-suffix-p "\n" initial) (insert "\n"))
  62. (insert "#+END:\n"))
  63. (unwind-protect
  64. (save-excursion
  65. (let ((org-duration-format 'h:mm)) (org-update-dblock))
  66. (forward-line)
  67. ;; Skip caption.
  68. (when (looking-at "#\\+CAPTION:") (forward-line))
  69. (buffer-substring-no-properties
  70. (point) (progn (search-forward "#+END:") (line-end-position 0))))
  71. ;; Remove clocktable.
  72. (delete-region (point) (search-forward "#+END:\n"))))
  73. ;;; Clock drawer
  74. (ert-deftest test-org-clock/into-drawer ()
  75. "Test `org-clock-into-drawer' specifications."
  76. ;; When `org-clock-into-drawer' is nil, do not use a clock drawer.
  77. (should-not
  78. (org-test-with-temp-text "* H"
  79. (let ((org-clock-into-drawer nil)
  80. (org-log-into-drawer nil))
  81. (org-clock-into-drawer))))
  82. (should-not
  83. (org-test-with-temp-text "* H"
  84. (let ((org-clock-into-drawer nil)
  85. (org-log-into-drawer t))
  86. (org-clock-into-drawer))))
  87. (should-not
  88. (org-test-with-temp-text "* H"
  89. (let ((org-clock-into-drawer nil)
  90. (org-log-into-drawer "BAR"))
  91. (org-clock-into-drawer))))
  92. ;; When `org-clock-into-drawer' is a string, use it
  93. ;; unconditionally.
  94. (should
  95. (equal "FOO"
  96. (org-test-with-temp-text "* H"
  97. (let ((org-clock-into-drawer "FOO")
  98. (org-log-into-drawer nil))
  99. (org-clock-into-drawer)))))
  100. (should
  101. (equal "FOO"
  102. (org-test-with-temp-text "* H"
  103. (let ((org-clock-into-drawer "FOO")
  104. (org-log-into-drawer t))
  105. (org-clock-into-drawer)))))
  106. (should
  107. (equal "FOO"
  108. (org-test-with-temp-text "* H"
  109. (let ((org-clock-into-drawer "FOO")
  110. (org-log-into-drawer "BAR"))
  111. (org-clock-into-drawer)))))
  112. ;; When `org-clock-into-drawer' is an integer, return it.
  113. (should
  114. (= 1
  115. (org-test-with-temp-text "* H"
  116. (let ((org-clock-into-drawer 1)
  117. (org-log-into-drawer nil))
  118. (org-clock-into-drawer)))))
  119. (should
  120. (= 1
  121. (org-test-with-temp-text "* H"
  122. (let ((org-clock-into-drawer 1)
  123. (org-log-into-drawer t))
  124. (org-clock-into-drawer)))))
  125. (should
  126. (= 1
  127. (org-test-with-temp-text "* H"
  128. (let ((org-clock-into-drawer 1)
  129. (org-log-into-drawer "BAR"))
  130. (org-clock-into-drawer)))))
  131. ;; Otherwise, any non-nil value defaults to `org-log-into-drawer' or
  132. ;; "LOGBOOK" if it is nil.
  133. (should
  134. (equal "LOGBOOK"
  135. (org-test-with-temp-text "* H"
  136. (let ((org-clock-into-drawer t)
  137. (org-log-into-drawer nil))
  138. (org-clock-into-drawer)))))
  139. (should
  140. (equal "LOGBOOK"
  141. (org-test-with-temp-text "* H"
  142. (let ((org-clock-into-drawer t)
  143. (org-log-into-drawer t))
  144. (org-clock-into-drawer)))))
  145. (should
  146. (equal "FOO"
  147. (org-test-with-temp-text "* H"
  148. (let ((org-clock-into-drawer t)
  149. (org-log-into-drawer "FOO"))
  150. (org-clock-into-drawer)))))
  151. ;; A non-nil "CLOCK_INTO_DRAWER" property overrides
  152. ;; `org-clock-into-drawer' value.
  153. (should
  154. (equal "LOGBOOK"
  155. (org-test-with-temp-text
  156. "* H\n:PROPERTIES:\n:CLOCK_INTO_DRAWER: t\n:END:"
  157. (let ((org-clock-into-drawer nil)
  158. (org-log-into-drawer nil))
  159. (org-clock-into-drawer)))))
  160. (should
  161. (equal "FOO"
  162. (org-test-with-temp-text
  163. "* H\n:PROPERTIES:\n:CLOCK_INTO_DRAWER: FOO\n:END:"
  164. (let ((org-clock-into-drawer nil)
  165. (org-log-into-drawer nil))
  166. (org-clock-into-drawer)))))
  167. (should-not
  168. (org-test-with-temp-text
  169. "* H\n:PROPERTIES:\n:CLOCK_INTO_DRAWER: nil\n:END:"
  170. (let ((org-clock-into-drawer t)
  171. (org-log-into-drawer nil))
  172. (org-clock-into-drawer))))
  173. ;; "CLOCK_INTO_DRAWER" can be inherited.
  174. (should
  175. (equal "LOGBOOK"
  176. (org-test-with-temp-text
  177. "* H\n:PROPERTIES:\n:CLOCK_INTO_DRAWER: t\n:END:\n** H2<point>"
  178. (let ((org-clock-into-drawer nil)
  179. (org-log-into-drawer nil))
  180. (org-clock-into-drawer)))))
  181. (should
  182. (equal "FOO"
  183. (org-test-with-temp-text
  184. "* H\n:PROPERTIES:\n:CLOCK_INTO_DRAWER: FOO\n:END:\n** H2<point>"
  185. (let ((org-clock-into-drawer nil)
  186. (org-log-into-drawer nil))
  187. (org-clock-into-drawer)))))
  188. (should-not
  189. (org-test-with-temp-text
  190. "* H\n:PROPERTIES:\n:CLOCK_INTO_DRAWER: nil\n:END:\n** H2<point>"
  191. (let ((org-clock-into-drawer t)
  192. (org-log-into-drawer nil))
  193. (org-clock-into-drawer)))))
  194. (ert-deftest test-org-clock/drawer-name ()
  195. "Test `org-clock-drawer-name' specifications."
  196. ;; A nil value for `org-clock-into-drawer' means no drawer is
  197. ;; expected whatsoever.
  198. (should-not
  199. (org-test-with-temp-text "* H"
  200. (let ((org-clock-into-drawer nil)
  201. (org-log-into-drawer nil))
  202. (org-clock-drawer-name))))
  203. (should-not
  204. (org-test-with-temp-text "* H"
  205. (let ((org-clock-into-drawer nil)
  206. (org-log-into-drawer t))
  207. (org-clock-drawer-name))))
  208. (should-not
  209. (org-test-with-temp-text "* H"
  210. (let ((org-clock-into-drawer nil)
  211. (org-log-into-drawer "FOO"))
  212. (org-clock-drawer-name))))
  213. ;; A string value for `org-clock-into-drawer' means to use it
  214. ;; unconditionally.
  215. (should
  216. (equal "FOO"
  217. (org-test-with-temp-text "* H"
  218. (let ((org-clock-into-drawer "FOO")
  219. (org-log-into-drawer nil))
  220. (org-clock-drawer-name)))))
  221. (should
  222. (equal "FOO"
  223. (org-test-with-temp-text "* H"
  224. (let ((org-clock-into-drawer "FOO")
  225. (org-log-into-drawer t))
  226. (org-clock-drawer-name)))))
  227. (should
  228. (equal "FOO"
  229. (org-test-with-temp-text "* H"
  230. (let ((org-clock-into-drawer "FOO")
  231. (org-log-into-drawer "BAR"))
  232. (org-clock-drawer-name)))))
  233. ;; When the value in `org-clock-into-drawer' is a number, re-use
  234. ;; `org-log-into-drawer' or use default "LOGBOOK" value.
  235. (should
  236. (equal "FOO"
  237. (org-test-with-temp-text "* H"
  238. (let ((org-clock-into-drawer 1)
  239. (org-log-into-drawer "FOO"))
  240. (org-clock-drawer-name)))))
  241. (should
  242. (equal "LOGBOOK"
  243. (org-test-with-temp-text "* H"
  244. (let ((org-clock-into-drawer 1)
  245. (org-log-into-drawer t))
  246. (org-clock-drawer-name)))))
  247. (should
  248. (equal "LOGBOOK"
  249. (org-test-with-temp-text "* H"
  250. (let ((org-clock-into-drawer 1)
  251. (org-log-into-drawer nil))
  252. (org-clock-drawer-name))))))
  253. ;;; Clocktable
  254. (ert-deftest test-org-clock/clocktable/insert ()
  255. "Test insert clocktable dynamic block with `org-dynamic-block-insert-dblock'."
  256. (should
  257. (equal
  258. "| Headline | Time |
  259. |--------------+--------|
  260. | *Total time* | *1:00* |
  261. |--------------+--------|
  262. | H1 | 1:00 |"
  263. (org-test-with-temp-text "* H1\n<point>"
  264. (insert (org-test-clock-create-clock ". 1:00" ". 2:00"))
  265. (goto-line 2)
  266. (require 'org-clock)
  267. (org-dynamic-block-insert-dblock "clocktable")
  268. (goto-line 1)
  269. (unwind-protect
  270. (save-excursion
  271. (when (search-forward "#+CAPTION:") (forward-line))
  272. (buffer-substring-no-properties
  273. (point) (progn (search-forward "#+END:") (line-end-position 0))))
  274. (delete-region (point) (search-forward "#+END:\n")))))))
  275. (ert-deftest test-org-clock/clocktable/ranges ()
  276. "Test ranges in Clock table."
  277. ;; Relative time: Previous two days.
  278. (should
  279. (equal
  280. "| Headline | Time | |
  281. |------------------------------+--------+------|
  282. | *Total time* | *8:00* | |
  283. |------------------------------+--------+------|
  284. | Relative times in clocktable | 8:00 | |
  285. | Foo | | 8:00 |"
  286. (org-test-with-temp-text
  287. "* Relative times in clocktable\n** Foo\n<point>"
  288. (insert (org-test-clock-create-clock "-3d 8:00" "-3d 12:00"))
  289. (insert (org-test-clock-create-clock "-2d 15:00" "-2d 18:00"))
  290. (insert (org-test-clock-create-clock "-1d 8:00" "-1d 13:00"))
  291. (test-org-clock-clocktable-contents
  292. ":tstart \"<-2d>\" :tend \"<today>\" :indent nil"))))
  293. ;; Relative time: Yesterday until now.
  294. (should
  295. (equal
  296. "| Headline | Time | |
  297. |------------------------------+--------+------|
  298. | *Total time* | *6:00* | |
  299. |------------------------------+--------+------|
  300. | Relative times in clocktable | 6:00 | |
  301. | Foo | | 6:00 |"
  302. (org-test-with-temp-text
  303. "* Relative times in clocktable\n** Foo\n<point>"
  304. (insert (org-test-clock-create-clock "-2d 15:00" "-2d 18:00"))
  305. (insert (org-test-clock-create-clock "-1d 8:00" "-1d 13:00"))
  306. (insert (org-test-clock-create-clock ". 1:00" ". 2:00"))
  307. (test-org-clock-clocktable-contents
  308. ":tstart \"<yesterday>\" :tend \"<tomorrow>\" :indent nil"))))
  309. ;; Test `untilnow' block.
  310. (should
  311. (equal
  312. "| Headline | Time | |
  313. |------------------------------+--------+------|
  314. | *Total time* | *6:00* | |
  315. |------------------------------+--------+------|
  316. | Relative times in clocktable | 6:00 | |
  317. | Foo | | 6:00 |"
  318. (org-test-with-temp-text
  319. "* Relative times in clocktable\n** Foo\n<point>"
  320. (insert (org-test-clock-create-clock "-10y 15:00" "-10y 18:00"))
  321. (insert (org-test-clock-create-clock "-2d 15:00" "-2d 18:00"))
  322. (test-org-clock-clocktable-contents ":block untilnow :indent nil")))))
  323. (ert-deftest test-org-clock/clocktable/match ()
  324. "Test \":match\" parameter in Clock table."
  325. ;; Test match filtering.
  326. (should
  327. (equal
  328. "| Headline | Time | |
  329. |--------------+--------+------|
  330. | *Total time* | *2:00* | |
  331. |--------------+--------+------|
  332. | H1 | | 2:00 |"
  333. (org-test-with-temp-text "** H1\n\n*** H2 :tag:\n\n*** H3\n<point>"
  334. (insert (org-test-clock-create-clock ". 8:00" ". 9:00"))
  335. (goto-line 4)
  336. (insert (org-test-clock-create-clock ". 9:00" ". 11:00"))
  337. (test-org-clock-clocktable-contents ":match \"tag\" :indent nil")))))
  338. (ert-deftest test-org-clock/clocktable/tags ()
  339. "Test \":tags\" parameter in Clock table."
  340. ;; Test tags column.
  341. (should
  342. (equal
  343. "| Tags | Headline | Time | |
  344. |------+--------------+--------+------|
  345. | | *Total time* | *1:00* | |
  346. |------+--------------+--------+------|
  347. | tag | H1 | | 1:00 |"
  348. (org-test-with-temp-text "** H1 :tag:\n\n*** H2 \n<point>"
  349. (insert (org-test-clock-create-clock ". 1:00" ". 2:00"))
  350. (goto-line 4)
  351. (test-org-clock-clocktable-contents ":tags t :indent nil")))))
  352. (ert-deftest test-org-clock/clocktable/scope ()
  353. "Test \":scope\" parameter in Clock table."
  354. ;; Test `file-with-archives' scope. In particular, preserve "TBLFM"
  355. ;; line, and ignore "file" column.
  356. (should
  357. (equal
  358. "| Headline | Time | |
  359. |--------------+--------+-----|
  360. | *Total time* | *8:40* | foo |
  361. |--------------+--------+-----|
  362. | Test | 8:40 | foo |
  363. #+TBLFM: $3=string(\"foo\")"
  364. (org-test-with-temp-text-in-file
  365. "* Test
  366. CLOCK: [2012-03-29 Thu 8:00]--[2012-03-29 Thu 16:40] => 8:40"
  367. (test-org-clock-clocktable-contents ":scope file-with-archives"
  368. "#+TBLFM: $3=string(\"foo\")"))))
  369. ;; Test "function" scope.
  370. (should
  371. (string-match-p
  372. (regexp-quote "| ALL *Total time* | *1:00* |")
  373. (org-test-with-temp-text-in-file
  374. "* Test
  375. CLOCK: [2012-03-29 Thu 16:00]--[2012-03-29 Thu 17:00] => 1:00"
  376. (let ((the-file (buffer-file-name)))
  377. (org-test-with-temp-text-in-file ""
  378. (test-org-clock-clocktable-contents
  379. (format ":scope (lambda () (list %S))" the-file))))))))
  380. (ert-deftest test-org-clock/clocktable/maxlevel ()
  381. "Test \":maxlevel\" parameter in Clock table."
  382. (should
  383. (equal "| Headline | Time | |
  384. |--------------+--------+------|
  385. | *Total time* | *6:00* | |
  386. |--------------+--------+------|
  387. | Foo | 6:00 | |
  388. | \\_ Bar | | 2:00 |"
  389. (org-test-with-temp-text
  390. "* Foo
  391. CLOCK: [2016-12-28 Wed 11:09]--[2016-12-28 Wed 15:09] => 4:00
  392. ** Bar
  393. CLOCK: [2016-12-28 Wed 13:09]--[2016-12-28 Wed 15:09] => 2:00"
  394. (test-org-clock-clocktable-contents ":maxlevel 3"))))
  395. (should
  396. (equal "| Headline | Time | |
  397. |--------------+--------+------|
  398. | *Total time* | *6:00* | |
  399. |--------------+--------+------|
  400. | Foo | 6:00 | |
  401. | \\_ Bar | | 2:00 |"
  402. (org-test-with-temp-text
  403. "* Foo
  404. CLOCK: [2016-12-28 Wed 11:09]--[2016-12-28 Wed 15:09] => 4:00
  405. ** Bar
  406. CLOCK: [2016-12-28 Wed 13:09]--[2016-12-28 Wed 15:09] => 2:00"
  407. (test-org-clock-clocktable-contents ":maxlevel 2"))))
  408. (should
  409. (equal "| Headline | Time |
  410. |--------------+--------|
  411. | *Total time* | *6:00* |
  412. |--------------+--------|
  413. | Foo | 6:00 |"
  414. (org-test-with-temp-text
  415. "* Foo
  416. CLOCK: [2016-12-28 Wed 11:09]--[2016-12-28 Wed 15:09] => 4:00
  417. ** Bar
  418. CLOCK: [2016-12-28 Wed 13:09]--[2016-12-28 Wed 15:09] => 2:00"
  419. (test-org-clock-clocktable-contents ":maxlevel 1"))))
  420. ;; Special ":maxlevel 0" case: only report total file time.
  421. (should
  422. (equal "| Headline | Time |
  423. |--------------+--------|
  424. | *Total time* | *6:00* |
  425. |--------------+--------|"
  426. (org-test-with-temp-text
  427. "* Foo
  428. CLOCK: [2016-12-28 Wed 11:09]--[2016-12-28 Wed 15:09] => 4:00
  429. ** Bar
  430. CLOCK: [2016-12-28 Wed 13:09]--[2016-12-28 Wed 15:09] => 2:00"
  431. (test-org-clock-clocktable-contents ":maxlevel 0")))))
  432. (ert-deftest test-org-clock/clocktable/formula ()
  433. "Test \":formula\" parameter in Clock table."
  434. ;; Test ":formula %". Handle various duration formats.
  435. (should
  436. (equal
  437. "| Headline | Time | % |
  438. |--------------+--------+-------|
  439. | *Total time* | *6:00* | 100.0 |
  440. |--------------+--------+-------|
  441. | Foo | 4:00 | 66.7 |
  442. | Bar | 2:00 | 33.3 |"
  443. (org-test-with-temp-text
  444. "* Foo
  445. CLOCK: [2016-12-28 Wed 11:09]--[2016-12-28 Wed 15:09] => 4:00
  446. * Bar
  447. CLOCK: [2016-12-28 Wed 13:09]--[2016-12-28 Wed 15:09] => 2:00"
  448. (test-org-clock-clocktable-contents ":maxlevel 1 :formula %"))))
  449. (should
  450. (equal
  451. "| Headline | Time | % |
  452. |--------------+---------+-------|
  453. | *Total time* | *28:00* | 100.0 |
  454. |--------------+---------+-------|
  455. | Foo | 26:00 | 92.9 |
  456. | Bar | 2:00 | 7.1 |"
  457. (org-test-with-temp-text
  458. "* Foo
  459. CLOCK: [2016-12-27 Wed 13:09]--[2016-12-28 Wed 15:09] => 26:00
  460. * Bar
  461. CLOCK: [2016-12-28 Wed 13:09]--[2016-12-28 Wed 15:09] => 2:00"
  462. (test-org-clock-clocktable-contents ":maxlevel 1 :formula %"))))
  463. ;; Properly align column with different depths.
  464. (should
  465. (equal "| Headline | Time | | | % |
  466. |---------------+--------+------+------+-------|
  467. | *Total time* | *1:00* | | | 100.0 |
  468. |---------------+--------+------+------+-------|
  469. | foo | 1:00 | | | 100.0 |
  470. | \\_ sub | | 0:15 | | 25.0 |
  471. | \\_ sub2 | | 0:15 | | 25.0 |
  472. | \\_ sub3 | | 0:30 | | 50.0 |
  473. | \\_ subsub1 | | | 0:15 | 25.0 |
  474. | \\_ subsub1 | | | 0:15 | 25.0 |"
  475. (org-test-with-temp-text
  476. "* foo
  477. ** sub
  478. :LOGBOOK:
  479. CLOCK: [2017-03-18 Sat 15:00]--[2017-03-18 Sat 15:15] => 0:15
  480. :END:
  481. ** sub2
  482. :LOGBOOK:
  483. CLOCK: [2017-03-18 Sat 15:15]--[2017-03-18 Sat 15:30] => 0:15
  484. :END:
  485. ** sub3
  486. *** subsub1
  487. :LOGBOOK:
  488. CLOCK: [2017-03-18 Sat 13:00]--[2017-03-18 Sat 13:15] => 0:15
  489. :END:
  490. *** subsub1
  491. :LOGBOOK:
  492. CLOCK: [2017-03-18 Sat 14:00]--[2017-03-18 Sat 14:15] => 0:15
  493. :END:"
  494. (test-org-clock-clocktable-contents ":maxlevel 3 :formula %")))))
  495. (ert-deftest test-org-clock/clocktable/lang ()
  496. "Test \":lang\" parameter in Clock table."
  497. ;; Test foreign translation
  498. (should
  499. (equal
  500. "| Headline | Time |
  501. |--------------+---------|
  502. | *Total time* | *26:00* |
  503. |--------------+---------|
  504. | Foo | 26:00 |"
  505. (org-test-with-temp-text
  506. "* Foo
  507. CLOCK: [2016-12-27 Wed 13:09]--[2016-12-28 Wed 15:09] => 26:00"
  508. (test-org-clock-clocktable-contents ":maxlevel 1 :lang en"))))
  509. (should
  510. (equal
  511. "| En-tête | Durée |
  512. |----------------+---------|
  513. | *Durée totale* | *26:00* |
  514. |----------------+---------|
  515. | Foo | 26:00 |"
  516. (org-test-with-temp-text
  517. "* Foo
  518. CLOCK: [2016-12-27 Wed 13:09]--[2016-12-28 Wed 15:09] => 26:00"
  519. (test-org-clock-clocktable-contents ":maxlevel 1 :lang fr"))))
  520. ;; No :lang parameter is equivalent to "en".
  521. (should
  522. (equal
  523. (org-test-with-temp-text
  524. "* Foo
  525. CLOCK: [2016-12-27 Wed 13:09]--[2016-12-28 Wed 15:09] => 26:00"
  526. (test-org-clock-clocktable-contents ":maxlevel 1 :lang en"))
  527. (org-test-with-temp-text
  528. "* Foo
  529. CLOCK: [2016-12-27 Wed 13:09]--[2016-12-28 Wed 15:09] => 26:00"
  530. (test-org-clock-clocktable-contents ":maxlevel 1"))))
  531. ;; Unknown translation fall backs to "en".
  532. (should
  533. (equal
  534. "| Headline | Time |
  535. |--------------+---------|
  536. | *Total time* | *26:00* |
  537. |--------------+---------|
  538. | Foo | 26:00 |"
  539. (org-test-with-temp-text
  540. "* Foo
  541. CLOCK: [2016-12-27 Wed 13:09]--[2016-12-28 Wed 15:09] => 26:00"
  542. (test-org-clock-clocktable-contents ":maxlevel 1 :lang foo")))))
  543. (ert-deftest test-org-clock/clocktable/link ()
  544. "Test \":link\" parameter in Clock table."
  545. ;; If there is no file attached to the document, link directly to
  546. ;; the headline.
  547. (should
  548. (string-match-p "| +\\[\\[\\*Foo]\\[Foo]] +| 26:00 +|"
  549. (org-test-with-temp-text
  550. "* Foo
  551. CLOCK: [2016-12-27 Wed 13:09]--[2016-12-28 Wed 15:09] => 26:00"
  552. (test-org-clock-clocktable-contents ":link t"))))
  553. ;; Otherwise, link to the headline in the current file.
  554. (should
  555. (string-match-p
  556. "| \\[\\[file:filename::\\*Foo]\\[Foo]] +| 26:00 +|"
  557. (org-test-with-temp-text
  558. (org-test-with-temp-text-in-file
  559. "* Foo
  560. CLOCK: [2016-12-27 Wed 13:09]--[2016-12-28 Wed 15:09] => 26:00"
  561. (let ((file (buffer-file-name)))
  562. (replace-regexp-in-string
  563. (regexp-quote file) "filename"
  564. (test-org-clock-clocktable-contents ":link t :lang en"))))
  565. (org-table-align)
  566. (buffer-substring-no-properties (point-min) (point-max)))))
  567. ;; Ignore TODO keyword, priority cookie, COMMENT and tags in
  568. ;; headline.
  569. (should
  570. (string-match-p
  571. "| \\[\\[\\*Foo]\\[Foo]] +| 26:00 +|"
  572. (org-test-with-temp-text
  573. "* TODO Foo
  574. CLOCK: [2016-12-27 Wed 13:09]--[2016-12-28 Wed 15:09] => 26:00"
  575. (test-org-clock-clocktable-contents ":link t :lang en"))))
  576. (should
  577. (string-match-p
  578. "| \\[\\[\\*Foo]\\[Foo]] +| 26:00 +|"
  579. (org-test-with-temp-text
  580. "* [#A] Foo
  581. CLOCK: [2016-12-27 Wed 13:09]--[2016-12-28 Wed 15:09] => 26:00"
  582. (test-org-clock-clocktable-contents ":link t :lang en"))))
  583. (should
  584. (string-match-p
  585. "| \\[\\[\\*Foo]\\[Foo]] +| 26:00 +|"
  586. (org-test-with-temp-text
  587. "* COMMENT Foo
  588. CLOCK: [2016-12-27 Wed 13:09]--[2016-12-28 Wed 15:09] => 26:00"
  589. (test-org-clock-clocktable-contents ":link t"))))
  590. (should
  591. (string-match-p
  592. "| \\[\\[\\*Foo]\\[Foo]] +| 26:00 +|"
  593. (org-test-with-temp-text
  594. "* Foo :tag:
  595. CLOCK: [2016-12-27 Wed 13:09]--[2016-12-28 Wed 15:09] => 26:00"
  596. (test-org-clock-clocktable-contents ":link t :lang en"))))
  597. ;; Remove statistics cookie from headline description.
  598. (should
  599. (string-match-p
  600. "| \\[\\[\\*Foo]\\[Foo]] +| 26:00 +|"
  601. (org-test-with-temp-text
  602. "* Foo [50%]
  603. CLOCK: [2016-12-27 Wed 13:09]--[2016-12-28 Wed 15:09] => 26:00"
  604. (test-org-clock-clocktable-contents ":link t :lang en"))))
  605. (should
  606. (string-match-p
  607. "| \\[\\[\\*Foo]\\[Foo]] +| 26:00 +|"
  608. (org-test-with-temp-text
  609. "* Foo [1/2]
  610. CLOCK: [2016-12-27 Wed 13:09]--[2016-12-28 Wed 15:09] => 26:00"
  611. (test-org-clock-clocktable-contents ":link t :lang en"))))
  612. ;; Replace links with their description, or turn them into plain
  613. ;; links if there is no description.
  614. (should
  615. (string-match-p
  616. "| \\[\\[\\*Foo \\\\\\[\\\\\\[https://orgmode\\.org\\\\]\\\\\\[Org mode\\\\]\\\\]]\\[Foo Org mode]] +| 26:00 +|"
  617. (org-test-with-temp-text
  618. "* Foo [[https://orgmode.org][Org mode]]
  619. CLOCK: [2016-12-27 Wed 13:09]--[2016-12-28 Wed 15:09] => 26:00"
  620. (test-org-clock-clocktable-contents ":link t :lang en"))))
  621. (should
  622. (string-match-p
  623. "| \\[\\[\\*Foo \\\\\\[\\\\\\[https://orgmode\\.org\\\\]\\\\]]\\[Foo https://orgmode\\.org]] +| 26:00 +|"
  624. (org-test-with-temp-text
  625. "* Foo [[https://orgmode.org]]
  626. CLOCK: [2016-12-27 Wed 13:09]--[2016-12-28 Wed 15:09] => 26:00"
  627. (test-org-clock-clocktable-contents ":link t :lang en")))))
  628. (ert-deftest test-org-clock/clocktable/compact ()
  629. "Test \":compact\" parameter in Clock table."
  630. ;; With :compact, all headlines are in the same column.
  631. (should
  632. (equal
  633. "| Headline | Time |
  634. |--------------+---------|
  635. | *Total time* | *26:00* |
  636. |--------------+---------|
  637. | Foo | 26:00 |"
  638. (org-test-with-temp-text
  639. "* Foo
  640. CLOCK: [2016-12-27 Wed 13:09]--[2016-12-28 Wed 15:09] => 26:00"
  641. (test-org-clock-clocktable-contents ":compact t"))))
  642. (should
  643. (equal
  644. "| Headline | Time |
  645. |--------------+---------|
  646. | *Total time* | *52:00* |
  647. |--------------+---------|
  648. | Foo | 52:00 |
  649. | \\_ Bar | 26:00 |"
  650. (org-test-with-temp-text
  651. "* Foo
  652. CLOCK: [2016-12-27 Wed 13:09]--[2016-12-28 Wed 15:09] => 26:00
  653. ** Bar
  654. CLOCK: [2016-12-27 Wed 13:09]--[2016-12-28 Wed 15:09] => 26:00"
  655. (test-org-clock-clocktable-contents ":compact t"))))
  656. ;; :maxlevel does not affect :compact parameter.
  657. (should
  658. (equal
  659. "| Headline | Time |
  660. |--------------+---------|
  661. | *Total time* | *52:00* |
  662. |--------------+---------|
  663. | Foo | 52:00 |
  664. | \\_ Bar | 26:00 |"
  665. (org-test-with-temp-text
  666. "* Foo
  667. CLOCK: [2016-12-27 Wed 13:09]--[2016-12-28 Wed 15:09] => 26:00
  668. ** Bar
  669. CLOCK: [2016-12-27 Wed 13:09]--[2016-12-28 Wed 15:09] => 26:00"
  670. (test-org-clock-clocktable-contents ":compact t :maxlevel 2"))))
  671. ;; :compact implies a non-nil :indent parameter.
  672. (should
  673. (equal
  674. "| Headline | Time |
  675. |--------------+---------|
  676. | *Total time* | *52:00* |
  677. |--------------+---------|
  678. | Foo | 52:00 |
  679. | \\_ Bar | 26:00 |"
  680. (org-test-with-temp-text
  681. "* Foo
  682. CLOCK: [2016-12-27 Wed 13:09]--[2016-12-28 Wed 15:09] => 26:00
  683. ** Bar
  684. CLOCK: [2016-12-27 Wed 13:09]--[2016-12-28 Wed 15:09] => 26:00"
  685. (test-org-clock-clocktable-contents ":compact t :indent nil"))))
  686. ;; :compact implies a nil :level parameter.
  687. (should
  688. (equal
  689. "| Headline | Time |
  690. |--------------+---------|
  691. | *Total time* | *52:00* |
  692. |--------------+---------|
  693. | Foo | 52:00 |
  694. | \\_ Bar | 26:00 |"
  695. (org-test-with-temp-text
  696. "* Foo
  697. CLOCK: [2016-12-27 Wed 13:09]--[2016-12-28 Wed 15:09] => 26:00
  698. ** Bar
  699. CLOCK: [2016-12-27 Wed 13:09]--[2016-12-28 Wed 15:09] => 26:00"
  700. (test-org-clock-clocktable-contents ":compact t :level t")))))
  701. (ert-deftest test-org-clock/clocktable/properties ()
  702. "Test \":properties\" parameter in Clock table."
  703. ;; Include a new column with list properties.
  704. (should
  705. (equal
  706. "| A | Headline | Time |
  707. |---+--------------+---------|
  708. | | *Total time* | *26:00* |
  709. |---+--------------+---------|
  710. | 1 | Foo | 26:00 |"
  711. (org-test-with-temp-text
  712. "* Foo
  713. :PROPERTIES:
  714. :A: 1
  715. :END:
  716. CLOCK: [2016-12-27 Wed 13:09]--[2016-12-28 Wed 15:09] => 26:00"
  717. (test-org-clock-clocktable-contents ":properties (\"A\")"))))
  718. (should
  719. (equal
  720. "| A | Headline | Time | |
  721. |---+--------------+---------+-------|
  722. | | *Total time* | *52:00* | |
  723. |---+--------------+---------+-------|
  724. | | Foo | 52:00 | |
  725. | 1 | \\_ Bar | | 26:00 |"
  726. (org-test-with-temp-text
  727. "* Foo
  728. CLOCK: [2016-12-27 Wed 13:09]--[2016-12-28 Wed 15:09] => 26:00
  729. ** Bar
  730. :PROPERTIES:
  731. :A: 1
  732. :END:
  733. CLOCK: [2016-12-27 Wed 13:09]--[2016-12-28 Wed 15:09] => 26:00"
  734. (test-org-clock-clocktable-contents ":properties (\"A\")"))))
  735. ;; Handle missing properties.
  736. (should
  737. (equal
  738. "| A | Headline | Time |
  739. |---+--------------+---------|
  740. | | *Total time* | *26:00* |
  741. |---+--------------+---------|
  742. | 1 | Foo | 26:00 |"
  743. (org-test-with-temp-text
  744. "* Foo
  745. :PROPERTIES:
  746. :A: 1
  747. :END:
  748. CLOCK: [2016-12-27 Wed 13:09]--[2016-12-28 Wed 15:09] => 26:00"
  749. (test-org-clock-clocktable-contents ":properties (\"A\")")))))
  750. (ert-deftest test-org-clock/clocktable/tcolumns ()
  751. "Test \":tcolumns\" parameter in Clock table."
  752. ;; When :tcolumns is smaller than the deepest headline level, lump
  753. ;; lower levels in the last column.
  754. (should
  755. (equal
  756. "| Headline | Time |
  757. |--------------+---------|
  758. | *Total time* | *52:00* |
  759. |--------------+---------|
  760. | Foo | 52:00 |
  761. | \\_ Bar | 26:00 |"
  762. (org-test-with-temp-text
  763. "* Foo
  764. CLOCK: [2016-12-27 Wed 13:09]--[2016-12-28 Wed 15:09] => 26:00
  765. ** Bar
  766. CLOCK: [2016-12-27 Wed 13:09]--[2016-12-28 Wed 15:09] => 26:00"
  767. (test-org-clock-clocktable-contents ":tcolumns 1"))))
  768. ;; :tcolumns cannot create more columns than the deepest headline
  769. ;; level.
  770. (should
  771. (equal
  772. "| Headline | Time | |
  773. |--------------+---------+-------|
  774. | *Total time* | *52:00* | |
  775. |--------------+---------+-------|
  776. | Foo | 52:00 | |
  777. | \\_ Bar | | 26:00 |"
  778. (org-test-with-temp-text
  779. "* Foo
  780. CLOCK: [2016-12-27 Wed 13:09]--[2016-12-28 Wed 15:09] => 26:00
  781. ** Bar
  782. CLOCK: [2016-12-27 Wed 13:09]--[2016-12-28 Wed 15:09] => 26:00"
  783. (test-org-clock-clocktable-contents ":tcolumns 3"))))
  784. ;; Pathological case: when no headline contributes to the total
  785. ;; time, there is only one time column.
  786. (should
  787. (equal "| Headline | Time |
  788. |--------------+--------|
  789. | *Total time* | *0:00* |"
  790. (org-test-with-temp-text
  791. "* Foo
  792. CLOCK: [2016-12-28 Wed 11:09]--[2016-12-28 Wed 11:09] => 0:00
  793. ** Bar
  794. CLOCK: [2016-12-28 Wed 13:09]--[2016-12-28 Wed 13:09] => 0:00"
  795. (test-org-clock-clocktable-contents ":tcolumns 2")))))
  796. (ert-deftest test-org-clock/clocktable/step ()
  797. "Test \":step\" parameter in Clock table."
  798. ;; Regression test: week crossing month boundary before :wstart
  799. ;; day-of-week.
  800. (should
  801. (string-match-p
  802. "
  803. .*?\\[2017-09-25 .*
  804. .*
  805. .*
  806. |.*?| \\*1:00\\* |
  807. .*
  808. | Foo +| 1:00 +|"
  809. (org-test-with-temp-text
  810. "* Foo
  811. CLOCK: [2017-09-30 Sat 12:00]--[2017-09-30 Sat 13:00] => 1:00
  812. CLOCK: [2017-10-01 Sun 11:00]--[2017-10-01 Sun 13:00] => 2:00
  813. CLOCK: [2017-10-02 Mon 11:00]--[2017-10-02 Mon 14:00] => 3:00"
  814. (let ((system-time-locale "en_US"))
  815. (test-org-clock-clocktable-contents
  816. ":step week :block 2017-09 :stepskip0 t")))))
  817. (should
  818. (string-match-p
  819. "
  820. .*?\\[2017-10-01 .*
  821. .*
  822. .*
  823. |.*?| \\*2:00\\* |
  824. .*
  825. | Foo +| 2:00 |
  826. .*?\\[2017-10-02 .*
  827. .*
  828. .*
  829. |.*?| \\*7:00\\* |
  830. .*
  831. | Foo +| 7:00 +|
  832. .*?\\[2017-10-09 .*
  833. .*
  834. .*
  835. |.*?| \\*5:00\\* |
  836. .*
  837. | Foo +| 5:00 +|
  838. "
  839. (org-test-with-temp-text
  840. "* Foo
  841. CLOCK: [2017-09-30 Sat 12:00]--[2017-09-30 Sat 13:00] => 1:00
  842. CLOCK: [2017-10-01 Sun 11:00]--[2017-10-01 Sun 13:00] => 2:00
  843. CLOCK: [2017-10-02 Mon 11:00]--[2017-10-02 Mon 14:00] => 3:00
  844. CLOCK: [2017-10-08 Sun 09:00]--[2017-10-08 Sun 13:00] => 4:00
  845. CLOCK: [2017-10-09 Mon 09:00]--[2017-10-09 Mon 14:00] => 5:00"
  846. (let ((system-time-locale "en_US"))
  847. (test-org-clock-clocktable-contents
  848. ":step week :block 2017-10 :stepskip0 t")))))
  849. ;; :step day
  850. (should
  851. (string-match-p
  852. "
  853. .*?\\[2017-10-02 .*
  854. .*
  855. .*
  856. |.*?| \\*3:00\\* |
  857. .*
  858. | Foo +| 3:00 +|
  859. .*?\\[2017-10-03 .*
  860. .*
  861. .*
  862. |.*?| \\*0:00\\* |
  863. .*?\\[2017-10-04 .*
  864. .*
  865. .*
  866. |.*?| \\*0:00\\* |
  867. .*?\\[2017-10-05 .*
  868. .*
  869. .*
  870. |.*?| \\*0:00\\* |
  871. .*?\\[2017-10-06 .*
  872. .*
  873. .*
  874. |.*?| \\*0:00\\* |
  875. .*?\\[2017-10-07 .*
  876. .*
  877. .*
  878. |.*?| \\*0:00\\* |
  879. .*?\\[2017-10-08 .*
  880. .*
  881. .*
  882. |.*?| \\*4:00\\* |
  883. .*
  884. | Foo +| 4:00 +|"
  885. (org-test-with-temp-text
  886. "* Foo
  887. CLOCK: [2017-09-30 Sat 12:00]--[2017-09-30 Sat 13:00] => 1:00
  888. CLOCK: [2017-10-01 Sun 11:00]--[2017-10-01 Sun 13:00] => 2:00
  889. CLOCK: [2017-10-02 Mon 11:00]--[2017-10-02 Mon 14:00] => 3:00
  890. CLOCK: [2017-10-08 Sun 09:00]--[2017-10-08 Sun 13:00] => 4:00
  891. CLOCK: [2017-10-09 Mon 09:00]--[2017-10-09 Mon 14:00] => 5:00"
  892. (let ((system-time-locale "en_US"))
  893. (test-org-clock-clocktable-contents
  894. ":step day :block 2017-W40")))))
  895. ;; Regression test: take :tstart and :tend hours into consideration.
  896. (should
  897. (string-match-p
  898. "
  899. .*?\\[2017-12-25 .*
  900. .*
  901. .*
  902. |.*?| \\*8:00\\* |
  903. .*
  904. | Foo +| 8:00 +|"
  905. (org-test-with-temp-text
  906. "* Foo
  907. CLOCK: [2017-12-27 Wed 08:00]--[2017-12-27 Wed 16:00] => 8:00"
  908. (let ((system-time-locale "en_US"))
  909. (test-org-clock-clocktable-contents
  910. (concat ":step week :tstart \"<2017-12-25 Mon>\" "
  911. ":tend \"<2017-12-27 Wed 23:59>\""))))))
  912. (should
  913. (string-match-p
  914. "
  915. .*?\\[2017-12-27 .*
  916. .*
  917. .*
  918. |.*?| \\*8:00\\* |
  919. .*
  920. | Foo +| 8:00 +|"
  921. (org-test-with-temp-text
  922. "* Foo
  923. CLOCK: [2017-12-27 Wed 08:00]--[2017-12-27 Wed 16:00] => 8:00"
  924. (let ((system-time-locale "en_US"))
  925. (test-org-clock-clocktable-contents
  926. (concat ":step day :tstart \"<2017-12-25 Mon>\" "
  927. ":tend \"<2017-12-27 Wed 23:59>\" :stepskip0 t"))))))
  928. ;; Test :step week", without or with ":wstart" parameter.
  929. (should
  930. (string-match-p
  931. "
  932. .*?\\[2012-03-26 .*
  933. .*
  934. .*
  935. |.*?| \\*8:00\\* |
  936. .*
  937. | Foo +| 8:00 +|
  938. .*?\\[2012-04-02 .*
  939. .*
  940. .*
  941. |.*?| \\*8:00\\* |
  942. .*
  943. | Foo +| 8:00 +|
  944. "
  945. (org-test-with-temp-text
  946. "* Foo
  947. CLOCK: [2012-03-29 Thu 08:00]--[2012-03-29 Thu 16:00] => 8:00
  948. CLOCK: [2012-04-03 Thu 08:00]--[2012-04-03 Thu 16:00] => 8:00"
  949. (let ((system-time-locale "en_US"))
  950. (test-org-clock-clocktable-contents
  951. ":step week :block 2012 :stepskip0 t")))))
  952. (should
  953. (string-match-p
  954. "
  955. .*?\\[2012-03-29 .*
  956. .*
  957. .*
  958. |.*?| \\*16:00\\* |
  959. .*
  960. | Foo +| 16:00 +|
  961. "
  962. (org-test-with-temp-text
  963. "* Foo
  964. CLOCK: [2012-03-29 Thu 08:00]--[2012-03-29 Thu 16:00] => 8:00
  965. CLOCK: [2012-04-03 Thu 08:00]--[2012-04-03 Thu 16:00] => 8:00"
  966. (let ((system-time-locale "en_US"))
  967. (test-org-clock-clocktable-contents
  968. ":step week :wstart 4 :block 2012 :stepskip0 t")))))
  969. ;; Test ":step month" without and with ":mstart".
  970. (should
  971. (string-match-p
  972. "
  973. .*?\\[2014-03-01 .*
  974. .*
  975. .*
  976. |.*?| \\*8:00\\* |
  977. .*
  978. | Foo +| 8:00 +|
  979. .*?\\[2014-04-01 .*
  980. .*
  981. .*
  982. |.*?| \\*8:00\\* |
  983. .*
  984. | Foo +| 8:00 +|
  985. "
  986. (org-test-with-temp-text
  987. "* Foo
  988. CLOCK: [2014-03-04 Tue 08:00]--[2014-03-04 Tue 16:00] => 8:00
  989. CLOCK: [2014-04-03 Thu 08:00]--[2014-04-03 Thu 16:00] => 8:00"
  990. (let ((system-time-locale "en_US"))
  991. (test-org-clock-clocktable-contents
  992. ":step month :block 2014 :stepskip0 t")))))
  993. (should
  994. (string-match-p
  995. "
  996. .*?\\[2014-03-04 .*
  997. .*
  998. .*
  999. |.*?| \\*16:00\\* |
  1000. .*
  1001. | Foo +| 16:00 +|
  1002. "
  1003. (org-test-with-temp-text
  1004. "* Foo
  1005. CLOCK: [2014-03-04 Tue 08:00]--[2014-03-04 Tue 16:00] => 8:00
  1006. CLOCK: [2014-04-03 Thu 08:00]--[2014-04-03 Thu 16:00] => 8:00"
  1007. (let ((system-time-locale "en_US"))
  1008. (test-org-clock-clocktable-contents
  1009. ":step month :mstart 4 :block 2014 :stepskip0 t")))))
  1010. ;; Test ":step quarter".
  1011. (should
  1012. (string-match-p
  1013. "
  1014. Quarterly report starting on:.*?\\[2014-01-01 .*
  1015. .*
  1016. .*
  1017. |.*?| \\*8:00\\* |
  1018. .*
  1019. | Foo +| 8:00 +|
  1020. .*?\\[2014-04-01 .*
  1021. .*
  1022. .*
  1023. |.*?| \\*16:00\\* |
  1024. .*
  1025. | Foo +| 16:00 +|
  1026. .*?\\[2014-07-01 .*
  1027. .*
  1028. .*
  1029. |.*?| \\*8:00\\* |
  1030. .*
  1031. | Foo +| 8:00 +|
  1032. "
  1033. (org-test-with-temp-text
  1034. "* Foo
  1035. CLOCK: [2014-03-04 Tue 08:00]--[2014-03-04 Tue 16:00] => 8:00
  1036. CLOCK: [2014-04-03 Thu 08:00]--[2014-04-03 Thu 16:00] => 8:00
  1037. CLOCK: [2014-06-04 Wed 08:00]--[2014-06-04 Wed 16:00] => 8:00
  1038. CLOCK: [2014-07-03 Thu 08:00]--[2014-07-03 Thu 16:00] => 8:00"
  1039. (let ((system-time-locale "en_US"))
  1040. (test-org-clock-clocktable-contents
  1041. ":step quarter :block 2014 :stepskip0 t")))))
  1042. ;; Test ":step semimonth".
  1043. (should
  1044. (string-match-p
  1045. "
  1046. .*?\\[2014-03-01 .*
  1047. .*
  1048. .*
  1049. |.*?| \\*8:00\\* |
  1050. .*
  1051. | Foo +| 8:00 +|
  1052. .*?\\[2014-03-16 .*
  1053. .*
  1054. .*
  1055. |.*?| \\*2:00\\* |
  1056. .*
  1057. | Foo +| 2:00 +|
  1058. .*?\\[2014-04-01 .*
  1059. .*
  1060. .*
  1061. |.*?| \\*7:00\\* |
  1062. .*
  1063. | Foo +| 7:00 +|
  1064. "
  1065. (org-test-with-temp-text
  1066. "* Foo
  1067. CLOCK: [2014-03-04 Tue 08:00]--[2014-03-04 Tue 16:00] => 8:00
  1068. CLOCK: [2014-03-24 Mon 08:00]--[2014-03-24 Mon 10:00] => 2:00
  1069. CLOCK: [2014-04-03 Thu 08:00]--[2014-04-03 Thu 15:00] => 7:00"
  1070. (let ((system-time-locale "en_US"))
  1071. (test-org-clock-clocktable-contents
  1072. ":step semimonth :block 2014 :stepskip0 t")))))
  1073. ;; Test ":step year".
  1074. (should
  1075. (string-match-p
  1076. "
  1077. .*?\\[2012-01-01 .*
  1078. .*
  1079. .*
  1080. |.*?| \\*8:00\\* |
  1081. .*
  1082. | Foo +| 8:00 +|
  1083. .*?\\[2014-01-01 .*
  1084. .*
  1085. .*
  1086. |.*?| \\*8:00\\* |
  1087. .*
  1088. | Foo +| 8:00 +|
  1089. "
  1090. (org-test-with-temp-text
  1091. "* Foo
  1092. CLOCK: [2012-03-29 Thu 08:00]--[2012-03-29 Thu 16:00] => 8:00
  1093. CLOCK: [2014-03-04 Tue 08:00]--[2014-03-04 Tue 16:00] => 8:00"
  1094. (let ((system-time-locale "en_US"))
  1095. (test-org-clock-clocktable-contents
  1096. ":step year :block untilnow :stepskip0 t")))))
  1097. ;; Regression test: Respect DST
  1098. (should
  1099. (string-match-p
  1100. "
  1101. .*?\\[2018-10-29 .*
  1102. .*
  1103. .*
  1104. |.*?| \\*8:00\\* |
  1105. .*
  1106. | Foo +| 8:00 +|
  1107. "
  1108. (org-test-with-temp-text
  1109. "* Foo
  1110. CLOCK: [2018-10-29 Mon 08:00]--[2018-10-29 Mon 16:00] => 8:00"
  1111. (let ((system-time-locale "en_US"))
  1112. (test-org-clock-clocktable-contents
  1113. (concat ":step day "
  1114. ":stepskip0 t "
  1115. ":tstart \"2018-10-01\" "
  1116. ":tend \"2018-11-01\"")))))))
  1117. (ert-deftest test-org-clock/clocktable/extend-today-until ()
  1118. "Test assignment of clock time to days in presence of \"org-extend-today-until\"."
  1119. ;; Basic test of :block with org-extend-today-until - the report for
  1120. ;; 2017-09-30 should include the time clocked on 2017-10-01 before
  1121. ;; 04:00.
  1122. (should
  1123. (equal "| Headline | Time |
  1124. |--------------+--------|
  1125. | *Total time* | *2:00* |
  1126. |--------------+--------|
  1127. | Foo | 2:00 |"
  1128. (org-test-with-temp-text
  1129. "* Foo
  1130. CLOCK: [2017-09-30 Sat 12:00]--[2017-09-30 Sat 13:00] => 1:00
  1131. CLOCK: [2017-10-01 Sun 02:00]--[2017-10-01 Sun 03:00] => 1:00
  1132. CLOCK: [2017-10-01 Sun 11:00]--[2017-10-01 Sun 13:00] => 2:00"
  1133. (setq-local org-extend-today-until 4)
  1134. (let ((system-time-locale "en_US"))
  1135. (test-org-clock-clocktable-contents
  1136. ":block 2017-09-30")))))
  1137. ;; Week-length block - time on Monday before 04:00 should be
  1138. ;; assigned to previous week.
  1139. (should
  1140. (string-match-p "
  1141. .*? \\[2017-10-01 .*
  1142. .*
  1143. .*
  1144. |.*?| \\*2:00\\* |
  1145. .*
  1146. | Foo +| 2:00 |
  1147. .*? \\[2017-10-02 .*
  1148. .*
  1149. .*
  1150. |.*?| \\*2:00\\* |
  1151. .*
  1152. | Foo +| 2:00 |
  1153. "
  1154. (org-test-with-temp-text
  1155. "* Foo
  1156. CLOCK: [2017-10-01 Sun 12:00]--[2017-10-01 Sun 13:00] => 1:00
  1157. CLOCK: [2017-10-02 Mon 02:00]--[2017-10-02 Mon 03:00] => 1:00
  1158. CLOCK: [2017-10-02 Mon 11:00]--[2017-10-02 Mon 13:00] => 2:00"
  1159. (setq-local org-extend-today-until 4)
  1160. (let ((system-time-locale "en_US"))
  1161. (test-org-clock-clocktable-contents
  1162. ":step week :block 2017-10 :stepskip0 t"))))))
  1163. (ert-deftest test-org-clock/clocktable/hidefiles ()
  1164. "Test \":hidefiles\" parameter in Clock table."
  1165. ;; Test that hidefiles removes the file column.
  1166. (should
  1167. (equal
  1168. "| Headline | Time |
  1169. |--------------+--------|
  1170. | *Total time* | *1:00* |
  1171. |--------------+--------|
  1172. | Test | 1:00 |"
  1173. (org-test-with-temp-text-in-file
  1174. "* Test
  1175. CLOCK: [2012-03-29 Thu 16:00]--[2012-03-29 Thu 17:00] => 1:00"
  1176. (let ((the-file (buffer-file-name)))
  1177. (org-test-with-temp-text-in-file ""
  1178. (test-org-clock-clocktable-contents
  1179. (format ":hidefiles t :scope (lambda () (list %S))" the-file))))))))
  1180. (provide 'test-org-clock)
  1181. ;;; test-org-clock.el end here