Line data Source code
1 : /*
2 : * Present - Date/Time Library
3 : *
4 : * Tests for the ClockTime C++ class and C-compatible methods
5 : *
6 : * Licensed under the MIT License.
7 : * For details, see LICENSE.
8 : */
9 :
10 : #include "catch.hpp"
11 : #include "test-utils.hpp"
12 :
13 : #include "present.h"
14 :
15 : /**
16 : * Shortcut macro to compare hour/minute/second/nanosecond.
17 : * Expects that the ClockTime is "c".
18 : */
19 : #define IS(test_hour, test_minute, test_second, test_nanosecond) \
20 : REQUIRE_FALSE(c.has_error); \
21 : CHECK(c.data_.seconds == test_hour*3600 + \
22 : test_minute*60 + test_second); \
23 : CHECK(c.data_.nanoseconds == test_nanosecond);
24 :
25 : /**
26 : * Shortcut macro to check if there's a certain error.
27 : * Expects that the ClockTime is "c".
28 : */
29 : #define IS_ERROR(eRR_tYPE) \
30 : CHECK(c.has_error); \
31 : CHECK(c.errors.eRR_tYPE);
32 :
33 :
34 : /**
35 : * This test case tests all the overloads of the "create" method (which also
36 : * tests the C "ClockTime_from_..." methods).
37 : */
38 8 : TEST_CASE("ClockTime creators", "[clock-time]") {
39 : ClockTime c;
40 :
41 7 : SECTION("creating from just an hour") {
42 1 : c = ClockTime::create(0);
43 1 : IS(0, 0, 0, 0);
44 1 : c = ClockTime::create(1);
45 1 : IS(1, 0, 0, 0);
46 1 : c = ClockTime::create(23);
47 1 : IS(23, 0, 0, 0);
48 1 : c = ClockTime::create(24); // 24:00 should go to 00:00
49 1 : IS(0, 0, 0, 0);
50 1 : c = ClockTime::create(25);
51 1 : IS_ERROR(hour_out_of_range);
52 1 : c = ClockTime::create(-1);
53 1 : IS_ERROR(hour_out_of_range);
54 :
55 1 : c = ClockTime_from_hour(12);
56 1 : IS(12, 0, 0, 0);
57 1 : c = ClockTime_from_hour(-14);
58 1 : IS_ERROR(hour_out_of_range);
59 :
60 1 : ClockTime_ptr_from_hour(&c, 13);
61 1 : IS(13, 0, 0, 0);
62 1 : ClockTime_ptr_from_hour(&c, 26);
63 1 : IS_ERROR(hour_out_of_range);
64 7 : }
65 :
66 7 : SECTION("creating from an hour and a minute") {
67 1 : c = ClockTime::create(0, 0);
68 1 : IS(0, 0, 0, 0);
69 1 : c = ClockTime::create(0, 1);
70 1 : IS(0, 1, 0, 0);
71 1 : c = ClockTime::create(0, 59);
72 1 : IS(0, 59, 0, 0);
73 1 : c = ClockTime::create(0, 60);
74 1 : IS_ERROR(minute_out_of_range);
75 1 : c = ClockTime::create(0, -1);
76 1 : IS_ERROR(minute_out_of_range);
77 :
78 1 : c = ClockTime_from_hour_minute(14, 45);
79 1 : IS(14, 45, 0, 0);
80 1 : c = ClockTime_from_hour_minute(0, -2);
81 1 : IS_ERROR(minute_out_of_range);
82 :
83 1 : ClockTime_ptr_from_hour_minute(&c, 15, 56);
84 1 : IS(15, 56, 0, 0);
85 1 : ClockTime_ptr_from_hour_minute(&c, 0, -12);
86 1 : IS_ERROR(minute_out_of_range);
87 7 : }
88 :
89 7 : SECTION("creating from an hour/minute/second") {
90 1 : c = ClockTime::create(0, 0, 0);
91 1 : IS(0, 0, 0, 0);
92 1 : c = ClockTime::create(0, 0, 1);
93 1 : IS(0, 0, 1, 0);
94 1 : c = ClockTime::create(0, 0, 59);
95 1 : IS(0, 0, 59, 0);
96 1 : c = ClockTime::create(0, 0, 60); // leap second
97 1 : IS(0, 0, 60, 0);
98 1 : c = ClockTime::create(0, 0, 61);
99 1 : IS_ERROR(second_out_of_range);
100 1 : c = ClockTime::create(0, 0, -1);
101 1 : IS_ERROR(second_out_of_range);
102 :
103 1 : c = ClockTime_from_hour_minute_second(8, 9, 11);
104 1 : IS(8, 9, 11, 0);
105 1 : c = ClockTime_from_hour_minute_second(0, 0, -10);
106 1 : IS_ERROR(second_out_of_range);
107 :
108 1 : ClockTime_ptr_from_hour_minute_second(&c, 12, 13, 14);
109 1 : IS(12, 13, 14, 0);
110 1 : ClockTime_ptr_from_hour_minute_second(&c, 0, 0, -11);
111 1 : IS_ERROR(second_out_of_range);
112 7 : }
113 :
114 7 : SECTION("creating from an hour/minute/second/nanosecond") {
115 1 : c = ClockTime::create(0, 0, 0, 0);
116 1 : IS(0, 0, 0, 0);
117 1 : c = ClockTime::create(0, 0, 0, 1);
118 1 : IS(0, 0, 0, 1);
119 1 : c = ClockTime::create(0, 0, 0, 999999999);
120 1 : IS(0, 0, 0, 999999999);
121 1 : c = ClockTime::create(0, 0, 0, 1000000000);
122 1 : IS_ERROR(nanosecond_out_of_range);
123 1 : c = ClockTime::create(0, 0, 0, -1);
124 1 : IS_ERROR(nanosecond_out_of_range);
125 :
126 1 : c = ClockTime_from_hour_minute_second_nanosecond(6, 7, 8, 9);
127 1 : IS(6, 7, 8, 9);
128 1 : c = ClockTime_from_hour_minute_second_nanosecond(0, 0, 0, -26);
129 1 : IS_ERROR(nanosecond_out_of_range);
130 :
131 1 : ClockTime_ptr_from_hour_minute_second_nanosecond(&c, 10, 11, 12, 13);
132 1 : IS(10, 11, 12, 13);
133 1 : ClockTime_ptr_from_hour_minute_second_nanosecond(&c, 0, 0, 0, -31);
134 1 : IS_ERROR(nanosecond_out_of_range);
135 7 : }
136 :
137 7 : SECTION("\"create\" shortcut macro for C functions") {
138 1 : c = ClockTime_create(3, 4, 5, 6);
139 1 : IS(3, 4, 5, 6);
140 1 : c = ClockTime_create(7, 8, 9);
141 1 : IS(7, 8, 9, 0);
142 1 : c = ClockTime_create(10, 11);
143 1 : IS(10, 11, 0, 0);
144 1 : c = ClockTime_create(12);
145 1 : IS(12, 0, 0, 0);
146 :
147 1 : ClockTime_ptr_create(&c, 13, 14, 15, 16);
148 1 : IS(13, 14, 15, 16);
149 1 : ClockTime_ptr_create(&c, 17, 18, 19);
150 1 : IS(17, 18, 19, 0);
151 1 : ClockTime_ptr_create(&c, 20, 21);
152 1 : IS(20, 21, 0, 0);
153 1 : ClockTime_ptr_create(&c, 22);
154 1 : IS(22, 0, 0, 0);
155 7 : }
156 :
157 7 : SECTION("creating with decimal seconds") {
158 1 : c = ClockTime::create_with_decimal_seconds(1, 2, 3.0);
159 1 : IS(1, 2, 3, 0);
160 1 : c = ClockTime::create_with_decimal_seconds(1, 2, 3.5);
161 1 : IS(1, 2, 3, 500000000.0);
162 1 : c = ClockTime::create_with_decimal_seconds(1, 2, 59.9);
163 1 : IS(1, 2, 59, 900000000.0);
164 1 : c = ClockTime::create_with_decimal_seconds(1, 2, 60); // leap second
165 1 : IS(1, 2, 60, 0);
166 1 : c = ClockTime::create_with_decimal_seconds(1, 2, 61);
167 1 : IS_ERROR(second_out_of_range);
168 1 : c = ClockTime::create_with_decimal_seconds(1, 2, -1);
169 1 : IS_ERROR(second_out_of_range);
170 :
171 1 : c = ClockTime_create_with_decimal_seconds(5, 6, 48.9);
172 1 : IS(5, 6, 48, 900000000.0);
173 1 : c = ClockTime_create_with_decimal_seconds(7, 8, -1);
174 1 : IS_ERROR(second_out_of_range);
175 :
176 1 : ClockTime_ptr_create_with_decimal_seconds(&c, 9, 10, 11.9);
177 1 : IS(9, 10, 11, 900000000.0);
178 1 : ClockTime_ptr_create_with_decimal_seconds(&c, 11, 12, -13.0);
179 1 : IS_ERROR(second_out_of_range);
180 7 : }
181 :
182 7 : SECTION("constant creators (midnight, noon)") {
183 1 : c = ClockTime::midnight();
184 1 : IS(0, 0, 0, 0);
185 1 : c = ClockTime::noon();
186 1 : IS(12, 0, 0, 0);
187 :
188 1 : c = ClockTime_midnight();
189 1 : IS(0, 0, 0, 0);
190 1 : c = ClockTime_noon();
191 1 : IS(12, 0, 0, 0);
192 :
193 1 : ClockTime_ptr_midnight(&c);
194 1 : IS(0, 0, 0, 0);
195 1 : ClockTime_ptr_noon(&c);
196 1 : IS(12, 0, 0, 0);
197 7 : }
198 7 : }
199 :
200 2 : TEST_CASE("ClockTime accessors", "[clock-time]") {
201 1 : ClockTime c1 = ClockTime::create(0, 0, 0, 0);
202 1 : ClockTime c2 = ClockTime::create(3, 5, 8, 400);
203 :
204 1 : CHECK(c1.hour() == 0);
205 1 : CHECK(c2.hour() == 3);
206 :
207 1 : CHECK(c1.minute() == 0);
208 1 : CHECK(c2.minute() == 5);
209 :
210 1 : CHECK(c1.second() == 0);
211 1 : CHECK(c2.second() == 8);
212 :
213 1 : CHECK(c1.nanosecond() == 0);
214 1 : CHECK(c2.nanosecond() == 400);
215 :
216 1 : CHECK(c1.second_decimal() == 0.0);
217 1 : CHECK(c2.second_decimal() == 8.0000004);
218 1 : }
219 :
220 2 : TEST_CASE("ClockTime::time_since_midnight function", "[clock-time]") {
221 : ClockTime c;
222 :
223 1 : c = ClockTime::create(0, 0, 0, 0);
224 1 : CHECK(c.time_since_midnight() == TimeDelta::zero());
225 :
226 1 : c = ClockTime::create(1, 15, 30);
227 1 : CHECK(c.time_since_midnight() == TimeDelta::from_seconds(4530));
228 :
229 1 : c = ClockTime::create(0, 0, 45, 7000);
230 1 : CHECK(c.time_since_midnight() == TimeDelta::from_nanoseconds(45000007000));
231 1 : }
232 :
233 7 : TEST_CASE("ClockTime arithmetic operators", "[clock-time]") {
234 12 : TimeDelta d = TimeDelta::from_hours(2) + TimeDelta::from_minutes(4) +
235 18 : TimeDelta::from_seconds(6);
236 : ClockTime c;
237 :
238 6 : SECTION("+= and -= operators") {
239 1 : c = ClockTime::create(1, 3, 5, 0);
240 1 : c += d;
241 1 : IS(3, 7, 11, 0);
242 :
243 1 : c = ClockTime::create(10, 10, 10, 0);
244 1 : c -= d;
245 1 : IS(8, 6, 4, 0);
246 6 : }
247 :
248 6 : SECTION("+ and - operators") {
249 1 : c = ClockTime::create(10, 10, 10, 0);
250 1 : ClockTime c1 = c + d;
251 1 : ClockTime c1_reverse = d + c;
252 1 : ClockTime c2 = c - d;
253 1 : IS(10, 10, 10, 0);
254 1 : c = c1;
255 1 : IS(12, 14, 16, 0);
256 1 : c = c1_reverse;
257 1 : IS(12, 14, 16, 0);
258 1 : c = c2;
259 1 : IS(8, 6, 4, 0);
260 6 : }
261 :
262 6 : SECTION("nanoseconds spilling into seconds") {
263 1 : TimeDelta d2 = TimeDelta::from_nanoseconds(5);
264 :
265 1 : c = ClockTime::create(0, 0, 0, 999999998);
266 1 : c += d2;
267 1 : IS(0, 0, 1, 3);
268 :
269 1 : c = ClockTime::create(0, 0, 1, 2);
270 1 : c -= d2;
271 1 : IS(0, 0, 0, 999999997);
272 6 : }
273 :
274 6 : SECTION("seconds spilling into minutes") {
275 1 : c = ClockTime::create(1, 2, 30);
276 1 : c += TimeDelta::from_seconds(31);
277 1 : IS(1, 3, 1, 0);
278 :
279 1 : c = ClockTime::create(1, 2, 30);
280 1 : c -= TimeDelta::from_seconds(31);
281 1 : IS(1, 1, 59, 0);
282 6 : }
283 :
284 6 : SECTION("minutes spilling into hours") {
285 1 : c = ClockTime::create(3, 40);
286 1 : c += TimeDelta::from_minutes(25);
287 1 : IS(4, 5, 0, 0);
288 :
289 1 : c = ClockTime::create(3, 40);
290 1 : c -= TimeDelta::from_minutes(45);
291 1 : IS(2, 55, 0, 0);
292 6 : }
293 :
294 6 : SECTION("wrap-around of hours") {
295 1 : c = ClockTime::create(23, 0, 0, 0);
296 1 : d = TimeDelta::from_hours(1);
297 1 : c += d;
298 1 : IS(0, 0, 0, 0);
299 :
300 1 : c = ClockTime::create(1, 0, 0, 0);
301 1 : d = TimeDelta::from_hours(2);
302 1 : c -= d;
303 1 : IS(23, 0, 0, 0);
304 6 : }
305 6 : }
306 :
307 2 : TEST_CASE("ClockTime comparison operators", "[clock-time]") {
308 1 : ClockTime c1 = ClockTime::create(0, 0, 0, 0),
309 1 : c2 = ClockTime::create(0, 0, 0, 1),
310 1 : c3 = ClockTime::create(12, 13, 14, 15),
311 1 : c4 = ClockTime::create(12, 13, 14, 15);
312 :
313 1 : CHECK(ClockTime::compare(c1, c1) == 0);
314 1 : CHECK(ClockTime::compare(c3, c4) == 0);
315 1 : CHECK(ClockTime::compare(c1, c2) < 0);
316 1 : CHECK(ClockTime::compare(c3, c2) > 0);
317 :
318 1 : CHECK(c1 == c1);
319 1 : CHECK(c3 == c4);
320 1 : CHECK(!(c1 == c3));
321 1 : CHECK(c1 != c3);
322 1 : CHECK(c1 != c2);
323 :
324 1 : CHECK(c1 < c2);
325 1 : CHECK(c1 < c3);
326 1 : CHECK(c2 < c3);
327 1 : CHECK(!(c3 < c4));
328 1 : CHECK(!(c3 < c2));
329 :
330 1 : CHECK(c1 <= c2);
331 1 : CHECK(c1 <= c2);
332 1 : CHECK(c1 <= c3);
333 1 : CHECK(c2 <= c3);
334 1 : CHECK(c3 <= c4);
335 1 : CHECK(c4 <= c3);
336 1 : CHECK(!(c2 <= c1));
337 :
338 1 : CHECK(c2 > c1);
339 1 : CHECK(c3 > c1);
340 1 : CHECK(c3 > c2);
341 1 : CHECK(!(c3 > c4));
342 1 : CHECK(!(c2 > c3));
343 :
344 1 : CHECK(c2 >= c1);
345 1 : CHECK(c3 >= c1);
346 1 : CHECK(c3 >= c2);
347 1 : CHECK(c4 >= c3);
348 1 : CHECK(c3 >= c4);
349 1 : CHECK(!(c1 >= c2));
350 4 : }
351 :
|