Unit test the datetime functions
[projects/chimara/chimara.git] / tests / unit / datetime.c
1 #include "glk.h"
2 #include "glkunit.h"
3
4 #ifdef GLK_MODULE_DATETIME
5
6 #define EXPECTED_DATETIME_GESTALT_VALUE 1
7
8 #define TEST_YEAR 1981
9 #define TEST_MONTH 12
10 #define TEST_DAY 15
11 #define TEST_HOUR 19
12 #define TEST_MINUTE 8
13 #define TEST_SECOND 53
14 #define TEST_WEEKDAY 2
15 #define TEST_MICROSEC 123456
16 #define TEST_HI_YEAR 2118
17 #define TEST_HI_MONTH 1
18 #define TEST_HI_DAY 22
19 #define TEST_HI_HOUR 1
20 #define TEST_HI_MINUTE 37
21 #define TEST_HI_SECOND 9
22 #define TEST_HI_WEEKDAY 6
23 static glktimeval_t TEST_TIMEVAL = { 0, 377291333, TEST_MICROSEC };
24 static glktimeval_t TEST_HIGH_TIMEVAL = { 1, 377291333, TEST_MICROSEC };
25 static glkdate_t TEST_DATE = {
26         TEST_YEAR,
27         TEST_MONTH,
28         TEST_DAY,
29         TEST_WEEKDAY,
30         TEST_HOUR,
31         TEST_MINUTE,
32         TEST_SECOND,
33         TEST_MICROSEC
34 };
35
36 /* Date for normalizing components */
37 #define TEST_NORM_YEAR 1999
38 #define TEST_NORM_MONTH 12
39 #define TEST_NORM_DAY 31
40 #define TEST_NORM_WEEKDAY 5
41 #define TEST_NORM_HOUR 23
42 #define TEST_NORM_MINUTE 59
43 #define TEST_NORM_SECOND 59
44 #define TEST_NORM_MICROSEC 999999
45 static glkdate_t TEST_NORM_DATE = {
46         TEST_NORM_YEAR,
47         TEST_NORM_MONTH,
48         TEST_NORM_DAY,
49         TEST_NORM_WEEKDAY,
50         TEST_NORM_HOUR,
51         TEST_NORM_MINUTE,
52         TEST_NORM_SECOND,
53         TEST_NORM_MICROSEC
54 };
55
56 /* Leap second occurred on this date */
57 #define TEST_LEAPSEC_YEAR 2012
58 #define TEST_LEAPSEC_MONTH 6
59 #define TEST_LEAPSEC_DAY 30
60 #define TEST_LEAPSEC_WEEKDAY 6
61 #define TEST_LEAPSEC_HOUR 23
62 #define TEST_LEAPSEC_MINUTE 59
63 #define TEST_LEAPSEC_SECOND 60
64 #define TEST_LEAPSEC_MICROSEC 0
65 static glkdate_t TEST_LEAPSEC_DATE = {
66         TEST_LEAPSEC_YEAR,
67         TEST_LEAPSEC_MONTH,
68         TEST_LEAPSEC_DAY,
69         TEST_LEAPSEC_WEEKDAY,
70         TEST_LEAPSEC_HOUR,
71         TEST_LEAPSEC_MINUTE,
72         TEST_LEAPSEC_SECOND,
73         TEST_LEAPSEC_MICROSEC
74 };
75 /* Note that this Unix timestamp refers to the above second AND the second
76 occurring after it */
77 static glktimeval_t TEST_LEAPSEC_TIMEVAL = { 0, 1341100800, 0 };
78
79 static int
80 test_current_time_equals_current_simple_time(void)
81 {
82         glktimeval_t timeval;
83
84         /* This test will fail if the following two operations do not occur within
85         a second of each other. That is not a robust test, but you could argue that
86         there is a serious bug if either operation takes more than one second. */
87         glk_current_time(&timeval);
88         glsi32 simple_time = glk_current_simple_time(1);
89         ASSERT_EQUAL(simple_time, timeval.low_sec);
90
91         glk_current_time(&timeval);
92         glsi32 simple_time_high_bits = glk_current_simple_time(0xFFFFFFFF);
93         ASSERT_EQUAL(simple_time_high_bits, timeval.high_sec);
94
95         SUCCEED;
96 }
97
98 static int
99 test_time_to_date_utc_returns_utc(void)
100 {
101         glkdate_t date;
102
103         glk_time_to_date_utc(&TEST_TIMEVAL, &date);
104         ASSERT_EQUAL(TEST_HOUR, date.hour);
105
106         SUCCEED;
107 }
108
109 static int
110 test_time_to_date_utc_converts_correctly(void)
111 {
112         glkdate_t date;
113
114         glk_time_to_date_utc(&TEST_TIMEVAL, &date);
115         ASSERT_EQUAL(TEST_YEAR, date.year);
116         ASSERT_EQUAL(TEST_MONTH, date.month);
117         ASSERT_EQUAL(TEST_DAY, date.day);
118         ASSERT_EQUAL(TEST_WEEKDAY, date.weekday);
119         ASSERT_EQUAL(TEST_HOUR, date.hour);
120         ASSERT_EQUAL(TEST_MINUTE, date.minute);
121         ASSERT_EQUAL(TEST_SECOND, date.second);
122         ASSERT_EQUAL(TEST_MICROSEC, date.microsec);
123
124         SUCCEED;
125 }
126
127 static int
128 test_time_to_date_utc_converts_high_bits_correctly(void)
129 {
130         glkdate_t date;
131
132         glk_time_to_date_utc(&TEST_HIGH_TIMEVAL, &date);
133         ASSERT_EQUAL(TEST_HI_YEAR, date.year);
134         ASSERT_EQUAL(TEST_HI_MONTH, date.month);
135         ASSERT_EQUAL(TEST_HI_DAY, date.day);
136         ASSERT_EQUAL(TEST_HI_WEEKDAY, date.weekday);
137         ASSERT_EQUAL(TEST_HI_HOUR, date.hour);
138         ASSERT_EQUAL(TEST_HI_MINUTE, date.minute);
139         ASSERT_EQUAL(TEST_HI_SECOND, date.second);
140         ASSERT_EQUAL(TEST_MICROSEC, date.microsec);
141
142         SUCCEED;
143 }
144
145 static int
146 test_time_to_date_local_returns_something_reasonable(void)
147 {
148         glkdate_t date;
149
150         /* All over the world, the given date should be on the 15th or 16th */
151         glk_time_to_date_utc(&TEST_TIMEVAL, &date);
152         ASSERT_EQUAL(TEST_YEAR, date.year);
153         ASSERT_EQUAL(TEST_MONTH, date.month);
154         ASSERT(date.day >= TEST_DAY && date.day <= TEST_DAY + 1);
155         ASSERT_EQUAL(TEST_SECOND, date.second);
156         ASSERT_EQUAL(TEST_MICROSEC, date.microsec);
157
158         SUCCEED;
159 }
160
161 static int
162 test_simple_time_to_date_utc_converts_correctly(void)
163 {
164         glkdate_t date;
165
166         glk_simple_time_to_date_utc(TEST_TIMEVAL.low_sec, 1, &date);
167         ASSERT_EQUAL(TEST_YEAR, date.year);
168         ASSERT_EQUAL(TEST_MONTH, date.month);
169         ASSERT_EQUAL(TEST_DAY, date.day);
170         ASSERT_EQUAL(TEST_WEEKDAY, date.weekday);
171         ASSERT_EQUAL(TEST_HOUR, date.hour);
172         ASSERT_EQUAL(TEST_MINUTE, date.minute);
173         ASSERT_EQUAL(TEST_SECOND, date.second);
174         ASSERT_EQUAL(0, date.microsec);
175
176         SUCCEED;
177 }
178
179 static int
180 test_simple_time_to_date_utc_converts_correctly_with_factor(void)
181 {
182         glkdate_t date;
183
184         glk_simple_time_to_date_utc(TEST_TIMEVAL.low_sec >> 1, 2, &date);
185         ASSERT_EQUAL(TEST_YEAR, date.year);
186         ASSERT_EQUAL(TEST_MONTH, date.month);
187         ASSERT_EQUAL(TEST_DAY, date.day);
188         ASSERT_EQUAL(TEST_WEEKDAY, date.weekday);
189         ASSERT_EQUAL(TEST_HOUR, date.hour);
190         ASSERT_EQUAL(TEST_MINUTE, date.minute);
191         ASSERT_EQUAL((TEST_SECOND / 2) * 2, date.second);
192         ASSERT_EQUAL(0, date.microsec);
193
194         SUCCEED;
195 }
196
197 static int
198 test_simple_time_to_date_local_returns_something_reasonable(void)
199 {
200         glkdate_t date;
201
202         glk_simple_time_to_date_local(TEST_TIMEVAL.low_sec, 1, &date);
203         ASSERT(date.day >= TEST_DAY && date.day <= TEST_DAY + 1);
204
205         SUCCEED;
206 }
207
208 static int
209 test_simple_time_to_date_local_returns_something_reasonable_with_factor(void)
210 {
211         glkdate_t date;
212
213         glk_simple_time_to_date_local(TEST_TIMEVAL.low_sec >> 1, 2, &date);
214         ASSERT(date.day >= TEST_DAY && date.day <= TEST_DAY + 1);
215
216         SUCCEED;
217 }
218
219 static int
220 test_date_to_time_utc_converts_correctly(void)
221 {
222         glktimeval_t timeval;
223
224         glk_date_to_time_utc(&TEST_DATE, &timeval);
225         ASSERT_EQUAL(TEST_TIMEVAL.high_sec, timeval.high_sec);
226         ASSERT_EQUAL(TEST_TIMEVAL.low_sec, timeval.low_sec);
227         ASSERT_EQUAL(TEST_TIMEVAL.microsec, timeval.microsec);
228
229         SUCCEED;
230 }
231
232 static int
233 test_date_to_time_utc_converts_leap_second(void)
234 {
235         glktimeval_t timeval;
236
237         glk_date_to_time_utc(&TEST_LEAPSEC_DATE, &timeval);
238         ASSERT_EQUAL(TEST_LEAPSEC_TIMEVAL.high_sec, timeval.high_sec);
239         ASSERT_EQUAL(TEST_LEAPSEC_TIMEVAL.low_sec, timeval.low_sec);
240         ASSERT_EQUAL(TEST_LEAPSEC_TIMEVAL.microsec, timeval.microsec);
241
242         SUCCEED;
243 }
244
245 static int
246 test_date_to_time_utc_ignores_weekday(void)
247 {
248         glktimeval_t timeval1, timeval2;
249         glkdate_t date2 = TEST_DATE;
250
251         date2.weekday = (TEST_WEEKDAY + 1) % 7;
252
253         glk_date_to_time_utc(&TEST_DATE, &timeval1);
254         glk_date_to_time_utc(&date2, &timeval2);
255         ASSERT_EQUAL(timeval1.high_sec, timeval2.high_sec);
256         ASSERT_EQUAL(timeval1.low_sec, timeval2.low_sec);
257         ASSERT_EQUAL(timeval1.microsec, timeval2.microsec);
258
259         SUCCEED;
260 }
261
262 static int
263 test_date_to_time_local_returns_something_reasonable(void)
264 {
265         /* Any time on earth should be within 13 hours of UTC time? */
266         glktimeval_t timeval;
267         glsi32 thirteen_hours = 13 * 60 * 60;
268
269         glk_date_to_time_utc(&TEST_DATE, &timeval);
270         ASSERT_EQUAL(TEST_TIMEVAL.high_sec, timeval.high_sec);
271         ASSERT(timeval.low_sec > TEST_TIMEVAL.low_sec - thirteen_hours);
272         ASSERT(timeval.low_sec < TEST_TIMEVAL.low_sec + thirteen_hours);
273         ASSERT_EQUAL(TEST_TIMEVAL.microsec, timeval.microsec);
274
275         SUCCEED;
276 }
277
278 static int
279 test_date_to_time_local_ignores_weekday(void)
280 {
281         glktimeval_t timeval1, timeval2;
282         glkdate_t date2 = TEST_DATE;
283
284         date2.weekday = (TEST_WEEKDAY + 1) % 7;
285
286         glk_date_to_time_local(&TEST_DATE, &timeval1);
287         glk_date_to_time_local(&date2, &timeval2);
288         ASSERT_EQUAL(timeval1.high_sec, timeval2.high_sec);
289         ASSERT_EQUAL(timeval1.low_sec, timeval2.low_sec);
290         ASSERT_EQUAL(timeval1.microsec, timeval2.microsec);
291
292         SUCCEED;
293 }
294
295 static int
296 test_date_to_simple_time_utc_converts_correctly(void)
297 {
298         glsi32 timestamp = glk_date_to_simple_time_utc(&TEST_DATE, 1);
299         ASSERT_EQUAL(TEST_TIMEVAL.low_sec, timestamp);
300
301         SUCCEED;
302 }
303
304 static int
305 test_date_to_simple_time_utc_converts_leap_second(void)
306 {
307         glsi32 timestamp = glk_date_to_simple_time_utc(&TEST_LEAPSEC_DATE, 1);
308         ASSERT_EQUAL(TEST_LEAPSEC_TIMEVAL.low_sec, timestamp);
309
310         SUCCEED;
311 }
312
313 static int
314 test_date_to_simple_time_utc_converts_correctly_with_factor(void)
315 {
316         glsi32 timestamp = glk_date_to_simple_time_utc(&TEST_DATE, 2);
317         ASSERT_EQUAL(TEST_TIMEVAL.low_sec >> 1, timestamp);
318
319         SUCCEED;
320 }
321
322 static int
323 test_date_to_simple_time_utc_ignores_weekday(void)
324 {
325         glkdate_t date2 = TEST_DATE;
326
327         date2.weekday = (TEST_WEEKDAY + 1) % 7;
328
329         glsi32 stamp1 = glk_date_to_simple_time_utc(&TEST_DATE, 1);
330         glsi32 stamp2 = glk_date_to_simple_time_utc(&date2, 1);
331         ASSERT_EQUAL(stamp1, stamp2);
332
333         SUCCEED;
334 }
335
336 static int
337 test_date_to_simple_time_utc_ignores_weekday_with_factor(void)
338 {
339         glkdate_t date2 = TEST_DATE;
340
341         date2.weekday = (TEST_WEEKDAY + 1) % 7;
342
343         glsi32 stamp1 = glk_date_to_simple_time_utc(&TEST_DATE, 2);
344         glsi32 stamp2 = glk_date_to_simple_time_utc(&date2, 2);
345         ASSERT_EQUAL(stamp1, stamp2);
346
347         SUCCEED;
348 }
349
350 static int
351 test_date_to_simple_time_utc_normalizes_month(void)
352 {
353         glkdate_t date1 = TEST_NORM_DATE;
354         glkdate_t date2 = TEST_NORM_DATE;
355
356         date1.year++;
357         date1.month = 1;
358         date2.month++;
359
360         glsi32 stamp1 = glk_date_to_simple_time_utc(&date1, 1);
361         glsi32 stamp2 = glk_date_to_simple_time_utc(&date2, 1);
362         ASSERT_EQUAL(stamp1, stamp2);
363
364         SUCCEED;
365 }
366
367 static int
368 test_date_to_simple_time_utc_normalizes_day(void)
369 {
370         glkdate_t date1 = TEST_NORM_DATE;
371         glkdate_t date2 = TEST_NORM_DATE;
372
373         date1.month++;
374         date1.day = 1;
375         date2.day++;
376
377         glsi32 stamp1 = glk_date_to_simple_time_utc(&date1, 1);
378         glsi32 stamp2 = glk_date_to_simple_time_utc(&date2, 1);
379         ASSERT_EQUAL(stamp1, stamp2);
380
381         SUCCEED;
382 }
383
384 static int
385 test_date_to_simple_time_utc_normalizes_hour(void)
386 {
387         glkdate_t date1 = TEST_NORM_DATE;
388         glkdate_t date2 = TEST_NORM_DATE;
389
390         date1.day++;
391         date1.hour = 0;
392         date2.hour++;
393
394         glsi32 stamp1 = glk_date_to_simple_time_utc(&date1, 1);
395         glsi32 stamp2 = glk_date_to_simple_time_utc(&date2, 1);
396         ASSERT_EQUAL(stamp1, stamp2);
397
398         SUCCEED;
399 }
400
401 static int
402 test_date_to_simple_time_utc_normalizes_minute(void)
403 {
404         glkdate_t date1 = TEST_NORM_DATE;
405         glkdate_t date2 = TEST_NORM_DATE;
406
407         date1.hour++;
408         date1.minute = 0;
409         date2.minute++;
410
411         glsi32 stamp1 = glk_date_to_simple_time_utc(&date1, 1);
412         glsi32 stamp2 = glk_date_to_simple_time_utc(&date2, 1);
413         ASSERT_EQUAL(stamp1, stamp2);
414
415         SUCCEED;
416 }
417
418 static int
419 test_date_to_simple_time_utc_normalizes_second(void)
420 {
421         glkdate_t date1 = TEST_NORM_DATE;
422         glkdate_t date2 = TEST_NORM_DATE;
423
424         date1.minute++;
425         date1.second = 1;
426         date2.second += 2; /* set second to 61, not 60 */
427
428         glsi32 stamp1 = glk_date_to_simple_time_utc(&date1, 1);
429         glsi32 stamp2 = glk_date_to_simple_time_utc(&date2, 1);
430         ASSERT_EQUAL(stamp1, stamp2);
431
432         SUCCEED;
433 }
434
435 static int
436 test_date_to_simple_time_utc_normalizes_microsec(void)
437 {
438         glkdate_t date1 = TEST_NORM_DATE;
439         glkdate_t date2 = TEST_NORM_DATE;
440
441         date1.second++;
442         date1.microsec = 0;
443         date2.microsec++;
444
445         glsi32 stamp1 = glk_date_to_simple_time_utc(&date1, 1);
446         glsi32 stamp2 = glk_date_to_simple_time_utc(&date2, 1);
447         ASSERT_EQUAL(stamp1, stamp2);
448
449         SUCCEED;
450 }
451
452 static int
453 test_date_to_simple_time_local_returns_something_reasonable(void)
454 {
455         /* Any time on earth should be within 13 hours of UTC time? */
456         glsi32 thirteen_hours = 13 * 60 * 60;
457
458         glsi32 timestamp = glk_date_to_simple_time_local(&TEST_DATE, 1);
459         ASSERT(timestamp > TEST_TIMEVAL.low_sec - thirteen_hours);
460         ASSERT(timestamp < TEST_TIMEVAL.low_sec + thirteen_hours);
461
462         SUCCEED;
463 }
464
465 static int
466 test_date_to_simple_time_local_ignores_weekday(void)
467 {
468         glkdate_t date2 = TEST_DATE;
469
470         date2.weekday = (TEST_WEEKDAY + 1) % 7;
471
472         glsi32 stamp1 = glk_date_to_simple_time_local(&TEST_DATE, 1);
473         glsi32 stamp2 = glk_date_to_simple_time_local(&date2, 1);
474         ASSERT_EQUAL(stamp1, stamp2);
475
476         SUCCEED;
477 }
478
479 static int
480 test_date_to_simple_time_local_ignores_weekday_with_factor(void)
481 {
482         glkdate_t date2 = TEST_DATE;
483
484         date2.weekday = (TEST_WEEKDAY + 1) % 7;
485
486         glsi32 stamp1 = glk_date_to_simple_time_local(&TEST_DATE, 2);
487         glsi32 stamp2 = glk_date_to_simple_time_local(&date2, 2);
488         ASSERT_EQUAL(stamp1, stamp2);
489
490         SUCCEED;
491 }
492
493 static int
494 test_date_to_simple_time_local_normalizes_month(void)
495 {
496         glkdate_t date1 = TEST_NORM_DATE;
497         glkdate_t date2 = TEST_NORM_DATE;
498
499         date1.year++;
500         date1.month = 1;
501         date2.month++;
502
503         glsi32 stamp1 = glk_date_to_simple_time_local(&date1, 1);
504         glsi32 stamp2 = glk_date_to_simple_time_local(&date2, 1);
505         ASSERT_EQUAL(stamp1, stamp2);
506
507         SUCCEED;
508 }
509
510 static int
511 test_date_to_simple_time_local_normalizes_day(void)
512 {
513         glkdate_t date1 = TEST_NORM_DATE;
514         glkdate_t date2 = TEST_NORM_DATE;
515
516         date1.month++;
517         date1.day = 1;
518         date2.day++;
519
520         glsi32 stamp1 = glk_date_to_simple_time_local(&date1, 1);
521         glsi32 stamp2 = glk_date_to_simple_time_local(&date2, 1);
522         ASSERT_EQUAL(stamp1, stamp2);
523
524         SUCCEED;
525 }
526
527 static int
528 test_date_to_simple_time_local_normalizes_hour(void)
529 {
530         glkdate_t date1 = TEST_NORM_DATE;
531         glkdate_t date2 = TEST_NORM_DATE;
532
533         date1.day++;
534         date1.hour = 0;
535         date2.hour++;
536
537         glsi32 stamp1 = glk_date_to_simple_time_local(&date1, 1);
538         glsi32 stamp2 = glk_date_to_simple_time_local(&date2, 1);
539         ASSERT_EQUAL(stamp1, stamp2);
540
541         SUCCEED;
542 }
543
544 static int
545 test_date_to_simple_time_local_normalizes_minute(void)
546 {
547         glkdate_t date1 = TEST_NORM_DATE;
548         glkdate_t date2 = TEST_NORM_DATE;
549
550         date1.hour++;
551         date1.minute = 0;
552         date2.minute++;
553
554         glsi32 stamp1 = glk_date_to_simple_time_local(&date1, 1);
555         glsi32 stamp2 = glk_date_to_simple_time_local(&date2, 1);
556         ASSERT_EQUAL(stamp1, stamp2);
557
558         SUCCEED;
559 }
560
561 static int
562 test_date_to_simple_time_local_normalizes_second(void)
563 {
564         glkdate_t date1 = TEST_NORM_DATE;
565         glkdate_t date2 = TEST_NORM_DATE;
566
567         date1.minute++;
568         date1.second = 1;
569         date2.second += 2; /* set second to 61, not 60 */
570
571         glsi32 stamp1 = glk_date_to_simple_time_local(&date1, 1);
572         glsi32 stamp2 = glk_date_to_simple_time_local(&date2, 1);
573         ASSERT_EQUAL(stamp1, stamp2);
574
575         SUCCEED;
576 }
577
578 static int
579 test_date_to_simple_time_local_normalizes_microsec(void)
580 {
581         glkdate_t date1 = TEST_NORM_DATE;
582         glkdate_t date2 = TEST_NORM_DATE;
583
584         date1.second++;
585         date1.microsec = 0;
586         date2.microsec++;
587
588         glsi32 stamp1 = glk_date_to_simple_time_local(&date1, 1);
589         glsi32 stamp2 = glk_date_to_simple_time_local(&date2, 1);
590         ASSERT_EQUAL(stamp1, stamp2);
591
592         SUCCEED;
593 }
594
595 static int
596 test_date_to_time_to_date_utc(void)
597 {
598         glktimeval_t intermediate;
599         glkdate_t date;
600
601         glk_date_to_time_utc(&TEST_DATE, &intermediate);
602         glk_time_to_date_utc(&intermediate, &date);
603         ASSERT_EQUAL(TEST_YEAR, date.year);
604         ASSERT_EQUAL(TEST_MONTH, date.month);
605         ASSERT_EQUAL(TEST_DAY, date.day);
606         ASSERT_EQUAL(TEST_WEEKDAY, date.weekday);
607         ASSERT_EQUAL(TEST_HOUR, date.hour);
608         ASSERT_EQUAL(TEST_MINUTE, date.minute);
609         ASSERT_EQUAL(TEST_SECOND, date.second);
610         ASSERT_EQUAL(TEST_MICROSEC, date.microsec);
611
612         SUCCEED;
613 }
614
615 static int
616 test_date_to_time_to_date_utc_fails_on_leap_second(void)
617 {
618         glktimeval_t intermediate;
619         glkdate_t date;
620
621         glk_date_to_time_utc(&TEST_LEAPSEC_DATE, &intermediate);
622         glk_time_to_date_utc(&intermediate, &date);
623         ASSERT_EQUAL(TEST_LEAPSEC_YEAR, date.year);
624         ASSERT_NOT_EQUAL(TEST_LEAPSEC_MONTH, date.month);
625         ASSERT_NOT_EQUAL(TEST_LEAPSEC_DAY, date.day);
626         ASSERT_NOT_EQUAL(TEST_LEAPSEC_WEEKDAY, date.weekday);
627         ASSERT_NOT_EQUAL(TEST_LEAPSEC_HOUR, date.hour);
628         ASSERT_NOT_EQUAL(TEST_LEAPSEC_MINUTE, date.minute);
629         ASSERT_NOT_EQUAL(TEST_LEAPSEC_SECOND, date.second);
630         ASSERT_EQUAL(TEST_LEAPSEC_MICROSEC, date.microsec);
631
632         SUCCEED;
633 }
634
635 static int
636 test_date_to_time_to_date_local(void)
637 {
638         glktimeval_t intermediate;
639         glkdate_t date;
640
641         glk_date_to_time_local(&TEST_DATE, &intermediate);
642         glk_time_to_date_local(&intermediate, &date);
643         ASSERT_EQUAL(TEST_YEAR, date.year);
644         ASSERT_EQUAL(TEST_MONTH, date.month);
645         ASSERT_EQUAL(TEST_DAY, date.day);
646         ASSERT_EQUAL(TEST_WEEKDAY, date.weekday);
647         ASSERT_EQUAL(TEST_HOUR, date.hour);
648         ASSERT_EQUAL(TEST_MINUTE, date.minute);
649         ASSERT_EQUAL(TEST_SECOND, date.second);
650         ASSERT_EQUAL(TEST_MICROSEC, date.microsec);
651
652         SUCCEED;
653 }
654
655 static int
656 test_date_to_simple_time_to_date_utc(void)
657 {
658         glkdate_t date;
659
660         glsi32 intermediate = glk_date_to_simple_time_utc(&TEST_DATE, 1);
661         glk_simple_time_to_date_utc(intermediate, 1, &date);
662         ASSERT_EQUAL(TEST_YEAR, date.year);
663         ASSERT_EQUAL(TEST_MONTH, date.month);
664         ASSERT_EQUAL(TEST_DAY, date.day);
665         ASSERT_EQUAL(TEST_WEEKDAY, date.weekday);
666         ASSERT_EQUAL(TEST_HOUR, date.hour);
667         ASSERT_EQUAL(TEST_MINUTE, date.minute);
668         ASSERT_EQUAL(TEST_SECOND, date.second);
669         ASSERT_EQUAL(0, date.microsec);
670
671         SUCCEED;
672 }
673
674 static int
675 test_date_to_simple_time_to_date_local(void)
676 {
677         glkdate_t date;
678
679         glsi32 intermediate = glk_date_to_simple_time_local(&TEST_DATE, 1);
680         glk_simple_time_to_date_local(intermediate, 1, &date);
681         ASSERT_EQUAL(TEST_YEAR, date.year);
682         ASSERT_EQUAL(TEST_MONTH, date.month);
683         ASSERT_EQUAL(TEST_DAY, date.day);
684         ASSERT_EQUAL(TEST_WEEKDAY, date.weekday);
685         ASSERT_EQUAL(TEST_HOUR, date.hour);
686         ASSERT_EQUAL(TEST_MINUTE, date.minute);
687         ASSERT_EQUAL(TEST_SECOND, date.second);
688         ASSERT_EQUAL(0, date.microsec);
689
690         SUCCEED;
691 }
692
693 static int
694 test_time_to_date_to_time_utc(void)
695 {
696         glktimeval_t timeval;
697         glkdate_t intermediate;
698
699         glk_time_to_date_utc(&TEST_TIMEVAL, &intermediate);
700         glk_date_to_time_utc(&intermediate, &timeval);
701         ASSERT_EQUAL(TEST_TIMEVAL.high_sec, timeval.high_sec);
702         ASSERT_EQUAL(TEST_TIMEVAL.low_sec, timeval.low_sec);
703         ASSERT_EQUAL(TEST_TIMEVAL.microsec, timeval.microsec);
704
705         SUCCEED;
706 }
707
708 static int
709 test_time_to_date_to_time_local(void)
710 {
711         glktimeval_t timeval;
712         glkdate_t intermediate;
713
714         glk_time_to_date_local(&TEST_TIMEVAL, &intermediate);
715         glk_date_to_time_local(&intermediate, &timeval);
716         ASSERT_EQUAL(TEST_TIMEVAL.high_sec, timeval.high_sec);
717         ASSERT_EQUAL(TEST_TIMEVAL.low_sec, timeval.low_sec);
718         ASSERT_EQUAL(TEST_TIMEVAL.microsec, timeval.microsec);
719
720         SUCCEED;
721 }
722
723 static int
724 test_simple_time_to_date_to_simple_time_utc(void)
725 {
726         glkdate_t intermediate;
727
728         glk_simple_time_to_date_utc(TEST_TIMEVAL.low_sec, 1, &intermediate);
729         glsi32 timestamp = glk_date_to_simple_time_utc(&intermediate, 1);
730         ASSERT_EQUAL(TEST_TIMEVAL.low_sec, timestamp);
731
732         SUCCEED;
733 }
734
735 static int
736 test_simple_time_to_date_to_simple_time_local(void)
737 {
738         glkdate_t intermediate;
739
740         glk_simple_time_to_date_local(TEST_TIMEVAL.low_sec, 1, &intermediate);
741         glsi32 timestamp = glk_date_to_simple_time_local(&intermediate, 1);
742         ASSERT_EQUAL(TEST_TIMEVAL.low_sec, timestamp);
743
744         SUCCEED;
745 }
746
747 #else /* GLK_MODULE_DATETIME is not defined */
748
749 #define EXPECTED_DATETIME_GESTALT_VALUE 0
750
751 #endif /* GLK_MODULE_DATETIME defined */
752
753 static int
754 test_date_time_supported(void)
755 {
756         /* If GLK_MODULE_DATETIME is defined in an implemenation, then the gestalt
757         system should indicate that it is supported. If the preprocessor symbol is
758         not defined, then it should not. */
759         glui32 res = glk_gestalt(gestalt_DateTime, 0);
760         ASSERT_EQUAL(EXPECTED_DATETIME_GESTALT_VALUE, res);
761         SUCCEED;
762 }
763
764 struct TestDescription tests[] = {
765         { "date and time functions are supported",
766                 test_date_time_supported },
767 #ifdef GLK_MODULE_DATETIME
768         { "current time equals simple time",
769                 test_current_time_equals_current_simple_time },
770         { "glk_time_to_date_utc() returns UTC time",
771                 test_time_to_date_utc_returns_utc },
772         { "glk_time_to_date_utc() converts correctly",
773                 test_time_to_date_utc_converts_correctly },
774         { "glk_time_to_date_utc() converts high bits correctly",
775                 test_time_to_date_utc_converts_high_bits_correctly },
776         { "glk_time_to_date_local() returns something reasonable",
777                 test_time_to_date_local_returns_something_reasonable },
778         { "glk_simple_time_to_date_utc() converts correctly",
779                 test_simple_time_to_date_utc_converts_correctly },
780         { "glk_simple_time_to_date_utc() converts correctly with factor",
781                 test_simple_time_to_date_utc_converts_correctly_with_factor },
782         { "glk_simple_time_to_date_local() returns something reasonable",
783                 test_simple_time_to_date_local_returns_something_reasonable },
784         { "glk_simple_time_to_date_local() returns something reasonable with factor",
785                 test_simple_time_to_date_local_returns_something_reasonable_with_factor },
786         { "glk_date_to_time_utc() converts correctly",
787                 test_date_to_time_utc_converts_correctly },
788         { "glk_date_to_time_utc() converts a leap second correctly",
789                 test_date_to_time_utc_converts_leap_second },
790         { "glk_date_to_time_utc() ignores the weekday value",
791                 test_date_to_time_utc_ignores_weekday },
792         { "glk_date_to_time_local() returns something reasonable",
793                 test_date_to_time_local_returns_something_reasonable },
794         { "glk_date_to_time_local() ignores the weekday value",
795                 test_date_to_time_local_ignores_weekday },
796         { "glk_date_to_simple_time_utc() converts correctly",
797                 test_date_to_simple_time_utc_converts_correctly },
798         { "glk_date_to_simple_time_utc() converts a leap second correctly",
799                 test_date_to_simple_time_utc_converts_leap_second },
800         { "glk_date_to_simple_time_utc() converts correctly with factor",
801                 test_date_to_simple_time_utc_converts_correctly_with_factor },
802         { "glk_date_to_simple_time_utc() ignores the weekday value",
803                 test_date_to_simple_time_utc_ignores_weekday },
804         { "glk_date_to_simple_time_utc() ignores the weekday value with factor",
805                 test_date_to_simple_time_utc_ignores_weekday_with_factor },
806         { "glk_date_to_simple_time_utc() normalizes an illegal month value",
807                 test_date_to_simple_time_utc_normalizes_month },
808         { "glk_date_to_simple_time_utc() normalizes an illegal day value",
809                 test_date_to_simple_time_utc_normalizes_day },
810         { "glk_date_to_simple_time_utc() normalizes an illegal hour value",
811                 test_date_to_simple_time_utc_normalizes_hour },
812         { "glk_date_to_simple_time_utc() normalizes an illegal minute value",
813                 test_date_to_simple_time_utc_normalizes_minute },
814         { "glk_date_to_simple_time_utc() normalizes an illegal second value",
815                 test_date_to_simple_time_utc_normalizes_second },
816         { "glk_date_to_simple_time_utc() normalizes an illegal microsecond value",
817                 test_date_to_simple_time_utc_normalizes_microsec },
818         { "glk_date_to_simple_time_local() returns something reasonable",
819                 test_date_to_simple_time_local_returns_something_reasonable },
820         { "glk_date_to_simple_time_local() ignores the weekday value",
821                 test_date_to_simple_time_local_ignores_weekday },
822         { "glk_date_to_simple_time_local() ignores the weekday value with factor",
823                 test_date_to_simple_time_local_ignores_weekday_with_factor },
824         { "glk_date_to_simple_time_local() normalizes an illegal month value",
825                 test_date_to_simple_time_local_normalizes_month },
826         { "glk_date_to_simple_time_local() normalizes an illegal day value",
827                 test_date_to_simple_time_local_normalizes_day },
828         { "glk_date_to_simple_time_local() normalizes an illegal hour value",
829                 test_date_to_simple_time_local_normalizes_hour },
830         { "glk_date_to_simple_time_local() normalizes an illegal minute value",
831                 test_date_to_simple_time_local_normalizes_minute },
832         { "glk_date_to_simple_time_local() normalizes an illegal second value",
833                 test_date_to_simple_time_local_normalizes_second },
834         { "glk_date_to_simple_time_local() normalizes an illegal microsecond value",
835                 test_date_to_simple_time_local_normalizes_microsec },
836         { "converting date to time and back works in UTC",
837                 test_date_to_time_to_date_utc },
838         { "converting date to time and back in UTC fails on a leap second",
839                 test_date_to_time_to_date_utc_fails_on_leap_second },
840         { "converting date to time and back in local time",
841                 test_date_to_time_to_date_local },
842         { "converting date to simple time and back works in UTC",
843                 test_date_to_simple_time_to_date_utc },
844         { "converting date to simple time and back works in local time",
845                 test_date_to_simple_time_to_date_local },
846         { "converting time to date and back works in UTC",
847                 test_time_to_date_to_time_utc },
848         { "converting time to date and back works in local time",
849                 test_time_to_date_to_time_local },
850         { "converting simple time to date and back works in UTC",
851                 test_simple_time_to_date_to_simple_time_utc },
852         { "converting simple time to date and back works in local time",
853                 test_simple_time_to_date_to_simple_time_local },
854 #endif /* GLK_MODULE_DATETIME defined */
855         { NULL, NULL }
856 };