1 ;;; test-org-duration.el --- Tests for org-duration.el -*- lexical-binding: t; -*-
3 ;; Copyright (C) 2017 Nicolas Goaziou
5 ;; Author: Nicolas Goaziou <mail@nicolasgoaziou.fr>
7 ;; This program is free software; you can redistribute it and/or modify
8 ;; it under the terms of the GNU General Public License as published by
9 ;; the Free Software Foundation, either version 3 of the License, or
10 ;; (at your option) any later version.
12 ;; This program is distributed in the hope that it will be useful,
13 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
14 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 ;; GNU General Public License for more details.
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with this program. If not, see <http://www.gnu.org/licenses/>.
22 (ert-deftest test-org-duration
/to-minutes
()
23 "Test `org-duration-to-minutes' specifications."
24 ;; Raise an error for unknown duration format.
25 (should-error (org-duration-to-minutes "1:2"))
26 ;; Return number of minutes, as a float.
27 (should (= (org-duration-to-minutes "1:01") 61))
28 (should (floatp (org-duration-to-minutes "1:01")))
29 ;; Handle various duration formats.
30 (should (= (org-duration-to-minutes "1:20:30") 80.5))
31 (should (= (org-duration-to-minutes "2h 10min") 130))
32 (should (= (org-duration-to-minutes "1d 1:02") 1502))
33 (should (= (org-duration-to-minutes "2.5h") 150))
34 ;; Special case: a bare number is treated as minutes.
35 (should (= (org-duration-to-minutes "2") 2))
36 (should (= (org-duration-to-minutes "2.5") 2.5))
37 (should (= (org-duration-to-minutes 1) 1))
38 ;; Special case: the empty string is 0.0.
39 (should (= (org-duration-to-minutes "") 0.0))
40 ;; Support custom units.
42 (let ((org-duration-units '(("longmin" .
2)))
45 org-duration--mixed-re
)
46 (org-duration-set-regexps)
47 (org-duration-to-minutes "2longmin"))))
49 (let ((org-duration-units '(("h" .
61)))
52 org-duration--mixed-re
)
53 (org-duration-set-regexps)
54 (org-duration-to-minutes "1h"))))
55 ;; When CANONICAL is non-nil, ignore custom units and only recognize
56 ;; units defined in `org-duration-canonical-units'.
58 (let ((org-duration-units '(("h" .
61)))
61 org-duration--mixed-re
)
62 (org-duration-set-regexps)
63 (org-duration-to-minutes "1h" t
))))
64 (should-error (let ((org-duration-units '(("longmin" .
2)))
67 org-duration--mixed-re
)
68 (org-duration-set-regexps)
69 (org-duration-to-minutes "2longmin" t
))))
71 (ert-deftest test-org-duration
/from-minutes
()
72 "Test `org-duration-from-minutes' specifications."
73 ;; Format number of minutes according to `org-duration-format'.
75 (let ((org-duration-format 'h
:mm
))
76 (org-duration-from-minutes 60))))
77 (should (equal "1:01:30"
78 (let ((org-duration-format 'h
:mm
:ss
))
79 (org-duration-from-minutes 61.5))))
81 (let ((org-duration-format 'h
:mm
))
82 (org-duration-from-minutes 61.5))))
83 ;; Handle required parameter in advanced format specifications.
85 (let ((org-duration-format '(("h" . nil
) ("min" . nil
))))
86 (org-duration-from-minutes 60))))
87 (should (equal "1h 0min"
88 (let ((org-duration-format '(("h" . nil
) ("min" . t
))))
89 (org-duration-from-minutes 60))))
90 (should (equal "50min"
91 (let ((org-duration-format '(("h" . nil
) ("min" . nil
))))
92 (org-duration-from-minutes 50))))
93 (should (equal "0h 50min"
94 (let ((org-duration-format '(("h" . t
) ("min" . t
))))
95 (org-duration-from-minutes 50))))
97 (should (equal "1d 0:10"
98 (let ((org-duration-format '(("d" . nil
) (special . h
:mm
))))
99 (org-duration-from-minutes (+ (* 24 60) 10)))))
100 (should (equal "1d 0:12:30"
101 (let ((org-duration-format '(("d" . nil
) (special . h
:mm
:ss
))))
102 (org-duration-from-minutes (+ (* 24 60) 12.5)))))
103 ;; Handle fractional duration. Parameter is the precision.
104 (should (equal "1.5h"
105 (let ((org-duration-format '(("h" . nil
) (special .
1))))
106 (org-duration-from-minutes 90))))
107 (should (equal "1.50h"
108 (let ((org-duration-format '(("h" . nil
) (special .
2))))
109 (org-duration-from-minutes 90))))
110 ;; When using fractional duration, use first required unit or the
111 ;; first with a non-zero integer part. If none is found, refer to
112 ;; smallest unit specified in format.
113 (should (equal "0.7h"
114 (let ((org-duration-format
115 '(("h" . t
) ("min" . nil
) (special .
1))))
116 (org-duration-from-minutes 40))))
117 (should (equal "40.0min"
118 (let ((org-duration-format
119 '(("h" . nil
) ("min" . nil
) (special .
1))))
120 (org-duration-from-minutes 40))))
121 (should (equal "0.5min"
122 (let ((org-duration-format
123 '(("h" . nil
) ("min" . nil
) (special .
1))))
124 (org-duration-from-minutes 0.5)))))
126 (ert-deftest test-org-duration
/p
()
127 "Test `org-duration-p' specifications."
128 ;; Test all duration formats.
129 (should (org-duration-p "3:12"))
130 (should (org-duration-p "123:12"))
131 (should (org-duration-p "1:23:45"))
132 (should (org-duration-p "3d 3h 4min"))
133 (should (org-duration-p "3d 13:35"))
134 (should (org-duration-p "2.35h"))
135 ;; Handle custom units, but return nil for unknown units.
136 (should-not (org-duration-p "1minute"))
137 (should (let ((org-duration-units '(("minute" .
1)))
138 org-duration--unit-re
139 org-duration--full-re
140 org-duration--mixed-re
)
141 (org-duration-set-regexps)
142 (org-duration-p "2minute")))
143 ;; Tolerate white space between the number and the unit.
144 (should (org-duration-p "2 h"))
145 ;; Return nil for ill-formed H:MM:SS strings.
146 (should-not (org-duration-p "3::12"))
147 (should-not (org-duration-p "3:2"))
148 (should-not (org-duration-p "3:12:4"))
149 ;; Return nil in mixed mode if H:MM:SS part is not last.
150 (should-not (org-duration-p "3d 13:35 13h")))
152 (ert-deftest test-org-duration
/h
:mm-only-p
()
153 "Test `org-duration-h:mm-only-p' specifications."
154 (should (org-duration-h:mm-only-p
'("123:31" "1:00")))
155 (should-not (org-duration-h:mm-only-p
'("123:32" "1h")))
156 (should (eq 'h
:mm
:ss
(org-duration-h:mm-only-p
'("3:33" "1:23:45")))))
159 (provide 'test-org-duration
)
160 ;;; test-org-duration.el ends here