add more struct timespec/Time formatters
[libi2ncommon] / test / test_timefunc.cpp
1 /*
2 The software in this package is distributed under the GNU General
3 Public License version 2 (with a special exception described below).
4
5 A copy of GNU General Public License (GPL) is included in this distribution,
6 in the file COPYING.GPL.
7
8 As a special exception, if other files instantiate templates or use macros
9 or inline functions from this file, or you compile this file and link it
10 with other works to produce a work based on this file, this file
11 does not by itself cause the resulting work to be covered
12 by the GNU General Public License.
13
14 However the source code for this file must still be made available
15 in accordance with section (3) of the GNU General Public License.
16
17 This exception does not invalidate any other reasons why a work based
18 on this file might be covered by the GNU General Public License.
19 */
20 /** @file
21  * @brief unit test for time related functions.
22  *
23  * @copyright Copyright © 2001-2008 by Intra2net AG
24  *
25  */
26
27 #define BOOST_TEST_DYN_LINK
28 #include <boost/test/unit_test.hpp>
29
30 #include <timefunc.hxx>
31 #include <filefunc.hxx>
32
33 #include <unistd.h>
34 #include <set>
35
36 using namespace std;
37 using namespace I2n;
38 using namespace I2n::Time;
39
40 class TestTimeFuncFixture
41 {
42 protected:
43    typedef std::list< std::string > StringList;
44    std::set<std::string>  used_check_files;
45
46    std::string get_check_file_path(std::string tag)
47    {
48       std::string result;
49       result= "__unittest__" + tag + ".dat";
50       used_check_files.insert(result);
51       return result;
52    } // eo get_check_file_path
53
54    void remove_check_files()
55    {
56       for (std::set<std::string>::iterator it= used_check_files.begin();
57             it != used_check_files.end();
58             ++it)
59       {
60          std::string filepath(*it);
61          if (path_exists(filepath))
62          {
63             unlink(filepath);
64          }
65          //TODO
66       }
67       used_check_files.clear();
68    } // eo remove_check_files
69
70 public:
71     TestTimeFuncFixture()
72     {
73     }
74
75     ~TestTimeFuncFixture()
76     {
77         remove_check_files();
78     }
79 };
80
81 BOOST_FIXTURE_TEST_SUITE(TestTimeFunc, TestTimeFuncFixture)
82
83 BOOST_AUTO_TEST_CASE(AddIntervalsDisjoint)
84 {
85     Intervals intervals;
86
87     intervals.add( Interval( 10, 100 ) );
88     intervals.add( Interval( 600, 620 ) );
89
90     BOOST_CHECK_EQUAL( false, intervals.empty() );
91     BOOST_CHECK_EQUAL( 2u, intervals.size() );
92
93     BOOST_CHECK_EQUAL( 10u, intervals.front().lower_bound() );
94     BOOST_CHECK_EQUAL( 100u, intervals.front().upper_bound() );
95
96     BOOST_CHECK_EQUAL( 600u, intervals.back().lower_bound() );
97     BOOST_CHECK_EQUAL( 620u, intervals.back().upper_bound() );
98 } // eo AddIntervalsDisjoint()
99
100
101
102 BOOST_AUTO_TEST_CASE(AddIntervalsInclude)
103 {
104     Intervals intervals;
105
106     intervals.add( Interval( 10, 100 ) );
107     intervals.add( Interval( 10, 80 ) );
108
109     BOOST_CHECK_EQUAL( false, intervals.empty() );
110     BOOST_CHECK_EQUAL( 1u, intervals.size() );
111
112     BOOST_CHECK_EQUAL( 10u, intervals.front().lower_bound() );
113     BOOST_CHECK_EQUAL( 100u, intervals.front().upper_bound() );
114     BOOST_CHECK_EQUAL( false, intervals.front().changed() );
115 } // eo AddIntervalsInclude()
116
117
118
119 BOOST_AUTO_TEST_CASE(AddIntervalsEmbrace)
120 {
121     Intervals intervals;
122
123     intervals.add( Interval( 10, 100 ) );
124     intervals.add( Interval( 5, 120 ) );
125
126     BOOST_CHECK_EQUAL( false, intervals.empty() );
127     BOOST_CHECK_EQUAL( 1u, intervals.size() );
128
129     BOOST_CHECK_EQUAL( 5u, intervals.front().lower_bound() );
130     BOOST_CHECK_EQUAL( 120u, intervals.front().upper_bound() );
131     BOOST_CHECK_EQUAL( true, intervals.front().changed() );
132 } // eo AddIntervalsEmbrace()
133
134
135
136 BOOST_AUTO_TEST_CASE(AddIntervalsJoin1)
137 {
138     Intervals intervals;
139
140     intervals.add( Interval( 10, 100 ) );
141     intervals.add( Interval( 60, 120 ) );
142
143     BOOST_CHECK_EQUAL( false, intervals.empty() );
144     BOOST_CHECK_EQUAL( 1u, intervals.size() );
145
146     BOOST_CHECK_EQUAL( 10u, intervals.front().lower_bound() );
147     BOOST_CHECK_EQUAL( 120u, intervals.front().upper_bound() );
148     BOOST_CHECK_EQUAL( true, intervals.front().changed() );
149 } // eo AddIntervalsJoin1()
150
151
152
153 BOOST_AUTO_TEST_CASE(AddIntervalsJoin1b)
154 {
155     Intervals intervals;
156
157     intervals.add( Interval( 10, 100 ) );
158     intervals.add( Interval( 100, 120 ) );
159
160     BOOST_CHECK_EQUAL( false, intervals.empty() );
161     BOOST_CHECK_EQUAL( 1u, intervals.size() );
162
163     BOOST_CHECK_EQUAL( 10u, intervals.front().lower_bound() );
164     BOOST_CHECK_EQUAL( 120u, intervals.front().upper_bound() );
165     BOOST_CHECK_EQUAL( true, intervals.front().changed() );
166 } // eo AddIntervalsJoin1b()
167
168
169
170 BOOST_AUTO_TEST_CASE(AddIntervalsJoin2)
171 {
172     Intervals intervals;
173
174     intervals.add( Interval( 10, 100 ) );
175     intervals.add( Interval( 200, 250 ) );
176
177     BOOST_CHECK_EQUAL( false, intervals.empty() );
178     BOOST_CHECK_EQUAL( 2u, intervals.size() );
179
180     BOOST_CHECK_EQUAL( 10u, intervals.front().lower_bound() );
181     BOOST_CHECK_EQUAL( 100u, intervals.front().upper_bound() );
182     BOOST_CHECK_EQUAL( 200u, intervals.back().lower_bound() );
183     BOOST_CHECK_EQUAL( 250u, intervals.back().upper_bound() );
184
185     // now add the gap; the intervals should collapse to one covering all:
186     intervals.add( Interval(100, 200) );
187
188     BOOST_CHECK_EQUAL( false, intervals.empty() );
189     BOOST_CHECK_EQUAL( 1u, intervals.size() );
190
191     BOOST_CHECK_EQUAL( 10u, intervals.front().lower_bound() );
192     BOOST_CHECK_EQUAL( 250u, intervals.front().upper_bound() );
193     BOOST_CHECK_EQUAL( true, intervals.front().changed() );
194 } // eo AddIntervalsJoin2()
195
196
197
198 BOOST_AUTO_TEST_CASE(SubIntervalsDisjoint)
199 {
200     Intervals intervals;
201
202     intervals.add( Interval(10, 100) );
203     intervals.sub( Interval(0, 10) );
204
205     BOOST_CHECK_EQUAL( false, intervals.empty() );
206     BOOST_CHECK_EQUAL( 1u, intervals.size() );
207
208     BOOST_CHECK_EQUAL( 10u, intervals.front().lower_bound() );
209     BOOST_CHECK_EQUAL( 100u, intervals.front().upper_bound() );
210     BOOST_CHECK_EQUAL( false, intervals.front().changed() );
211 } // eo SubIntervalsDisjoint()
212
213
214
215 BOOST_AUTO_TEST_CASE(SubIntervalsExact)
216 {
217     Intervals intervals;
218
219     intervals.add( Interval(10, 100) );
220     intervals.sub( Interval(10, 100) );
221
222     BOOST_CHECK_EQUAL( true, intervals.empty() );
223     BOOST_CHECK_EQUAL( 0u, intervals.size() );
224 } // eo SubIntervalsExact()
225
226
227
228 BOOST_AUTO_TEST_CASE(SubIntervalsSplit1)
229 {
230     Intervals intervals;
231
232     intervals.add( Interval(10, 100) );
233     intervals.sub( Interval(20, 40) );
234
235     BOOST_CHECK_EQUAL( false, intervals.empty() );
236     BOOST_CHECK_EQUAL( 2u, intervals.size() );
237
238     BOOST_CHECK_EQUAL( 10u, intervals.front().lower_bound() );
239     BOOST_CHECK_EQUAL( 20u, intervals.front().upper_bound() );
240
241     BOOST_CHECK_EQUAL( 40u, intervals.back().lower_bound() );
242     BOOST_CHECK_EQUAL( 100u, intervals.back().upper_bound() );
243     BOOST_CHECK_EQUAL( false, intervals.front().changed() );
244     BOOST_CHECK_EQUAL( true, intervals.back().changed() );
245 } // eo SubIntervalsSplit1()
246
247
248 BOOST_AUTO_TEST_CASE(SubIntervalsCutFront)
249 {
250     Intervals intervals;
251
252     intervals.add( Interval(10, 100) );
253     intervals.sub( Interval(10, 20) );
254
255     BOOST_CHECK_EQUAL( false, intervals.empty() );
256     BOOST_CHECK_EQUAL( 1u, intervals.size() );
257
258     BOOST_CHECK_EQUAL( 20u, intervals.front().lower_bound() );
259     BOOST_CHECK_EQUAL( 100u, intervals.front().upper_bound() );
260     BOOST_CHECK_EQUAL( true, intervals.front().changed() );
261 } // eo SubIntervalsCutFront()
262
263
264 BOOST_AUTO_TEST_CASE(SubIntervalsCutBack)
265 {
266     Intervals intervals;
267
268     intervals.add( Interval(10, 100) );
269     intervals.sub( Interval(87, 100) );
270
271     BOOST_CHECK_EQUAL( false, intervals.empty() );
272     BOOST_CHECK_EQUAL( 1u, intervals.size() );
273
274     BOOST_CHECK_EQUAL( 10u, intervals.front().lower_bound() );
275     BOOST_CHECK_EQUAL( 87u, intervals.front().upper_bound() );
276     BOOST_CHECK_EQUAL( true, intervals.front().changed() );
277 } // eo SubIntervalsCutBack()
278
279
280
281 BOOST_AUTO_TEST_CASE(SubIntervalsCutMore)
282 {
283     Intervals intervals;
284
285     intervals.add( Interval( 10, 100) );
286     intervals.add( Interval(110, 200) );
287     intervals.add( Interval(210, 300) );
288
289     // this should remove the first 2 intervals and cut the third:
290     intervals.sub( Interval(8, 220) );
291
292     BOOST_CHECK_EQUAL( false, intervals.empty() );
293     BOOST_CHECK_EQUAL( 1u, intervals.size() );
294
295     BOOST_CHECK_EQUAL( 220u, intervals.front().lower_bound() );
296     BOOST_CHECK_EQUAL( 300u, intervals.front().upper_bound() );
297     BOOST_CHECK_EQUAL( true, intervals.front().changed() );
298 } // eo SubIntervalsCutMore()
299
300
301 BOOST_AUTO_TEST_CASE(IntervalComparisons)
302 {
303     Intervals intervals1;
304     Intervals intervals2;
305
306     intervals1.add( Interval( 10, 120) );
307
308     intervals2.add( Interval( 10, 110 ) );
309     intervals2.add( Interval( 100, 120 ) );
310
311     BOOST_CHECK_EQUAL( 1u, intervals2.size() );
312
313     BOOST_CHECK( intervals1 == intervals2 );
314     BOOST_CHECK_EQUAL( true, intervals1.contains( intervals2 ));
315     BOOST_CHECK_EQUAL( true, intervals2.contains( intervals1 ));
316
317     intervals2.sub( Interval( 40, 50) );
318
319     BOOST_CHECK( intervals1 != intervals2 );
320     BOOST_CHECK_EQUAL( true, intervals1.contains( intervals2 ));
321     BOOST_CHECK_EQUAL( false, intervals2.contains( intervals1 ));
322 } // eo IntervalComparisons()
323
324
325
326 BOOST_AUTO_TEST_CASE(MonotonicClock)
327 {
328     long sec0, nsec0;
329     long sec1, nsec1;
330
331     bool res = monotonic_clock_gettime(sec0,nsec0);
332     BOOST_CHECK_EQUAL( true, res );
333
334     usleep(250000);
335     res= monotonic_clock_gettime(sec1,nsec1);
336     BOOST_CHECK_EQUAL( true, res);
337
338     long delta_sec = sec1 - sec0;
339     long delta_nsec= nsec1 - nsec0;
340
341     long delta_millisec= ( delta_nsec / 1000000L) + delta_sec * 1000L;
342
343     BOOST_CHECK( delta_millisec >= 250 - /*fuzz*/ 1);
344     BOOST_CHECK( delta_millisec < 300 );
345 } // eo MonotonicClock()
346
347 BOOST_AUTO_TEST_CASE(WeekInvalid)
348 {
349     Week week("99999999");
350     BOOST_CHECK_EQUAL(false, week.is_valid());
351     BOOST_CHECK_EQUAL(string(""), week.get_displaystring());
352 }
353
354 BOOST_AUTO_TEST_CASE(WeekDisplayString1)
355 {
356     Week week("");
357     BOOST_CHECK_EQUAL(true, week.is_valid());
358     BOOST_CHECK_EQUAL(string(""), week.get_displaystring());
359 }
360
361 BOOST_AUTO_TEST_CASE(WeekDisplayString2)
362 {
363     Week week("0123456");
364     BOOST_CHECK_EQUAL(true, week.is_valid());
365     BOOST_CHECK_EQUAL(string("Mon-Sun"), week.get_displaystring());
366 }
367
368 BOOST_AUTO_TEST_CASE(WeekDisplayString3)
369 {
370     Week week("123456");
371     BOOST_CHECK_EQUAL(true, week.is_valid());
372     BOOST_CHECK_EQUAL(string("Mon-Sat"), week.get_displaystring());
373 }
374
375 BOOST_AUTO_TEST_CASE(WeekDisplayString4)
376 {
377     Week week("012345");
378     BOOST_CHECK_EQUAL(true, week.is_valid());
379     BOOST_CHECK_EQUAL(string("Mon-Fri, Sun"), week.get_displaystring());
380 }
381
382 BOOST_AUTO_TEST_CASE(WeekDisplayString5)
383 {
384     Week week("1256");
385     BOOST_CHECK_EQUAL(true, week.is_valid());
386     BOOST_CHECK_EQUAL(string("Mon, Tue, Fri, Sat"), week.get_displaystring());
387 }
388
389 BOOST_AUTO_TEST_CASE(WeekDisplayString6)
390 {
391     Week week("0246");
392     BOOST_CHECK_EQUAL(true, week.is_valid());
393     BOOST_CHECK_EQUAL(string("Tue, Thu, Sat, Sun"), week.get_displaystring());
394 }
395
396 BOOST_AUTO_TEST_CASE(WeekDisplayString7)
397 {
398     Week week("135");
399     BOOST_CHECK_EQUAL(true, week.is_valid());
400     BOOST_CHECK_EQUAL(string("Mon, Wed, Fri"), week.get_displaystring());
401 }
402
403 BOOST_AUTO_TEST_CASE(WeekDisplayString8)
404 {
405     Week week("15");
406     BOOST_CHECK_EQUAL(true, week.is_valid());
407     BOOST_CHECK_EQUAL(string("Mon, Fri"), week.get_displaystring());
408 }
409
410 BOOST_AUTO_TEST_CASE(WeekDisplayString9)
411 {
412     Week week("06");
413     BOOST_CHECK_EQUAL(true, week.is_valid());
414     BOOST_CHECK_EQUAL(string("Sat, Sun"), week.get_displaystring());
415 }
416
417 BOOST_AUTO_TEST_CASE(WeekDisplayString10)
418 {
419     Week week("056");
420     BOOST_CHECK_EQUAL(true, week.is_valid());
421     BOOST_CHECK_EQUAL(string("Fri-Sun"), week.get_displaystring());
422 }
423
424 BOOST_AUTO_TEST_CASE(WeekDisplayString11)
425 {
426     Week week("0");
427     BOOST_CHECK_EQUAL(true, week.is_valid());
428     BOOST_CHECK_EQUAL(string("Sun"), week.get_displaystring());
429 }
430
431 BOOST_AUTO_TEST_CASE(WeekDisplayString12)
432 {
433     Week week("6");
434     BOOST_CHECK_EQUAL(true, week.is_valid());
435     BOOST_CHECK_EQUAL(string("Sat"), week.get_displaystring());
436 }
437
438 BOOST_AUTO_TEST_CASE(WeekDisplayString13)
439 {
440     Week week("123");
441     BOOST_CHECK_EQUAL(true, week.is_valid());
442     BOOST_CHECK_EQUAL(string("Mon-Wed"), week.get_displaystring());
443 }
444
445 BOOST_AUTO_TEST_CASE(FormatFullTime)
446 {
447     time_t seconds = 1318844005;
448
449     BOOST_CHECK_EQUAL("17.10.2011 11:33", format_full_time(seconds));
450 }
451
452 BOOST_AUTO_TEST_CASE(DateToSeconds1)
453 {
454     // no DST
455     BOOST_CHECK_EQUAL(1325372400, date_to_seconds("2012-01-01"));
456 }
457
458 BOOST_AUTO_TEST_CASE(DateToSeconds2)
459 {
460     // DST
461     BOOST_CHECK_EQUAL(1341093600, date_to_seconds("2012-07-01"));
462 }
463
464 BOOST_AUTO_TEST_CASE(FormatISO8601_T)
465 {
466     const time_t moment = 1515492684;
467     BOOST_CHECK_EQUAL("10:11:24",
468                       format_iso8601 (moment, true, false, true, false));
469 }
470
471 BOOST_AUTO_TEST_CASE(FormatISO8601_TZ_local)
472 {
473     const time_t moment = 1515492684;
474     BOOST_CHECK_EQUAL("11:11:24Z+0100",
475                       format_iso8601 (moment, false, false, true, true));
476 }
477
478 BOOST_AUTO_TEST_CASE(FormatISO8601_TZ)
479 {
480     const time_t moment = 1515492684;
481     BOOST_CHECK_EQUAL("10:11:24Z+0000",
482                       format_iso8601 (moment, true, false, true, true));
483 }
484
485 BOOST_AUTO_TEST_CASE(FormatISO8601_DTZ_local)
486 {
487     const time_t moment = 1515492684;
488     BOOST_CHECK_EQUAL("2018-01-09T11:11:24Z+0100",
489                       format_iso8601 (moment, false, true, true, true));
490 }
491
492 BOOST_AUTO_TEST_CASE(FormatISO8601_DTZ)
493 {
494     const time_t moment = 1515492684;
495     BOOST_CHECK_EQUAL("2018-01-09T10:11:24Z+0000",
496                       format_iso8601 (moment, true, true, true, true));
497 }
498
499 BOOST_AUTO_TEST_CASE(FormatISO8601_DT)
500 {
501     const time_t moment = 1515492684;
502     BOOST_CHECK_EQUAL("2018-01-09T10:11:24",
503                       format_iso8601 (moment, true, true, true, false));
504 }
505
506 BOOST_AUTO_TEST_CASE(FormatISO8601_D)
507 {
508     const time_t moment = 1515492684;
509     BOOST_CHECK_EQUAL("2018-01-09",
510                       format_iso8601 (moment, true, true, false, false));
511 }
512
513 BOOST_AUTO_TEST_CASE(FormatISO8601_DTZ_struct_tm)
514 {
515     struct tm helau;
516     helau.tm_sec    = 11;
517     helau.tm_min    = 11;
518     helau.tm_hour   = 11;
519     helau.tm_mday   = 11;
520     helau.tm_mon    = 10;
521     helau.tm_year   = 2018 - 1900;
522     helau.tm_wday   = 0;
523     helau.tm_yday   = 315;
524     helau.tm_isdst  = 0;
525     helau.tm_gmtoff = 0;
526     helau.tm_zone   = NULL;
527
528     BOOST_CHECK_EQUAL("2018-11-11T11:11:11Z+0000",
529                       format_iso8601 (helau, true, true, true));
530 }
531
532 BOOST_AUTO_TEST_CASE(FormatISO8601_DTZ_struct_timespec)
533 {
534     struct timespec ts = { 1541934671, 11 };
535
536     BOOST_CHECK_EQUAL("2018-11-11T11:11:11Z+0000",
537                       format_iso8601 (ts, true, true, true, true));
538 }
539
540 BOOST_AUTO_TEST_SUITE(Clock)
541
542     BOOST_AUTO_TEST_CASE(ctor_simple)
543     {
544         I2n::clock::Time t;
545
546         BOOST_CHECK_EQUAL(t.get_sec  (), 0);
547         BOOST_CHECK_EQUAL(t.get_nsec (), 0);
548     }
549
550     BOOST_AUTO_TEST_CASE(ctor_type)
551     {
552         I2n::clock::Time t (I2n::clock::type::real);
553
554         BOOST_CHECK_EQUAL(t.get_sec  (), 0);
555         BOOST_CHECK_EQUAL(t.get_nsec (), 0);
556     }
557
558     BOOST_AUTO_TEST_CASE(ctor_variant)
559     {
560         I2n::clock::Time t (I2n::clock::type::cpu,
561                             I2n::clock::type::thread);
562
563         BOOST_CHECK_EQUAL(t.get_sec  (), 0);
564         BOOST_CHECK_EQUAL(t.get_nsec (), 0);
565     }
566
567     BOOST_AUTO_TEST_CASE(initializer_now)
568     {
569         boost::optional<I2n::clock::Time> t = I2n::clock::now ();
570
571         BOOST_CHECK(t);
572         BOOST_CHECK_GT(t->get_sec (), 0);
573         BOOST_CHECK_EQUAL(t->err, 0);
574     }
575
576     BOOST_AUTO_TEST_CASE(initializer_zero)
577     {
578         I2n::clock::Time stundenull = I2n::clock::zero ();
579
580         BOOST_CHECK_EQUAL(stundenull.get_sec  (), 0);
581         BOOST_CHECK_EQUAL(stundenull.get_nsec (), 0);
582         BOOST_CHECK_EQUAL(stundenull.err, 0);
583     }
584
585     BOOST_AUTO_TEST_CASE(member_set_now)
586     {
587         I2n::clock::Time t;
588
589         BOOST_CHECK(t.set ());
590
591         BOOST_CHECK_NE(t.get_sec (), 0);
592     }
593
594     BOOST_AUTO_TEST_CASE(member_set_value)
595     {
596         I2n::clock::Time t;
597
598         t.set (42, 42);
599
600         BOOST_CHECK_EQUAL(t.get_sec  (), 42);
601         BOOST_CHECK_EQUAL(t.get_nsec (), 42);
602     }
603
604     BOOST_AUTO_TEST_CASE(member_set_value_type)
605     {
606         I2n::clock::Time t;
607
608         t.set (42, 42, I2n::clock::type::real, I2n::clock::type::exact);
609
610         BOOST_CHECK_EQUAL(t.get_sec  (), 42);
611         BOOST_CHECK_EQUAL(t.get_nsec (), 42);
612     }
613
614     BOOST_AUTO_TEST_CASE(member_add_parts)
615     {
616         I2n::clock::Time t;
617
618         t.set (42, 42);
619         t.add (2187, 2187);
620
621         BOOST_CHECK_EQUAL(t.get_sec  (), 2229);
622         BOOST_CHECK_EQUAL(t.get_nsec (), 2229);
623     }
624
625     BOOST_AUTO_TEST_CASE(member_sub_parts)
626     {
627         I2n::clock::Time t;
628
629         t.set (2, 0L);
630         t.subtract (1, 1L);
631
632         BOOST_CHECK_EQUAL(t.get_sec  (), 0);
633         BOOST_CHECK_EQUAL(t.get_nsec (), 999999999);
634     }
635
636     BOOST_AUTO_TEST_CASE(member_sub_Time)
637     {
638         I2n::clock::Time t1;
639         I2n::clock::Time t2;
640
641         t1.set (42, 42L);
642         t2.set (42,  0L);
643
644         t1.subtract (t2);
645
646         BOOST_CHECK_EQUAL(t1.get_sec  (),  0);
647         BOOST_CHECK_EQUAL(t1.get_nsec (), 42L);
648     }
649
650     BOOST_AUTO_TEST_CASE(member_diff)
651     {
652         static const time_t five = 5 * 365 * 24 * 3600;
653
654         I2n::clock::Time t1 (42, 1337);
655         I2n::clock::Time t2 = t1 + five;;
656         I2n::clock::Time t3 = t1 - five;;
657
658         BOOST_CHECK_EQUAL(t2, I2n::clock::Time ((time_t)42 + five, 1337));
659         BOOST_CHECK_EQUAL(t3, I2n::clock::Time ((time_t)42 - five, 1337));
660         BOOST_CHECK_EQUAL(t1.difference (t3), t3.difference (t1));
661         BOOST_CHECK_EQUAL(t3.difference (t3), t3.difference (t3));
662     }
663
664     BOOST_AUTO_TEST_CASE(op_copyassign)
665     {
666         I2n::clock::Time t1;
667         I2n::clock::Time t2;
668
669         BOOST_CHECK(t1.set ());
670
671         t2 = t1;
672
673         BOOST_CHECK_EQUAL(t1.get_sec  (), t2.get_sec  ());
674         BOOST_CHECK_EQUAL(t1.get_nsec (), t2.get_nsec ());
675     }
676
677     BOOST_AUTO_TEST_CASE(op_equal)
678     {
679         I2n::clock::Time t1;
680         I2n::clock::Time t2;
681
682         BOOST_CHECK(t1.set ());
683         t2 = t1;
684
685         BOOST_CHECK_EQUAL(t1, t2);
686     }
687
688     BOOST_AUTO_TEST_CASE(op_add_Time)
689     {
690         I2n::clock::Time t1;
691         I2n::clock::Time t2;
692         I2n::clock::Time tsum;
693
694         t1.set (2187, 2187);
695         t2.set (1337, 1337);
696         tsum = t1 + t2;
697
698         BOOST_CHECK_EQUAL(tsum.get_sec  (), 3524);
699         BOOST_CHECK_EQUAL(tsum.get_nsec (), 3524);
700     }
701
702     BOOST_AUTO_TEST_CASE(op_add_Time_carry)
703     {
704         I2n::clock::Time t1;
705         I2n::clock::Time t2;
706         I2n::clock::Time tsum;
707
708         t1.set (2187, 2187);
709 # if LONG_BIT == 32
710         t2.set (1300,  2L * 1000 * 1000 * 1000 + 1337);
711 # else
712         t2.set (1300, 37L * 1000 * 1000 * 1000 + 1337);
713 # endif
714
715         tsum = t1 + t2;
716
717 # if LONG_BIT == 32
718         BOOST_CHECK_EQUAL(tsum.get_sec  (), 3489);
719         BOOST_CHECK_EQUAL(tsum.get_nsec (), 3524);
720 # else
721         BOOST_CHECK_EQUAL(tsum.get_sec  (), 3524);
722         BOOST_CHECK_EQUAL(tsum.get_nsec (), 3524);
723 # endif
724     }
725
726     BOOST_AUTO_TEST_CASE(op_add_time_t)
727     {
728         I2n::clock::Time t1 (2187, 2187);
729         time_t           t2 = 1337;
730         I2n::clock::Time tsum;
731
732         tsum = t1 + t2;
733
734         BOOST_CHECK_EQUAL(tsum.get_sec  (), 3524);
735         BOOST_CHECK_EQUAL(tsum.get_nsec (), 2187);
736     }
737
738     BOOST_AUTO_TEST_CASE(op_add_time_t_external)
739     {
740         time_t           t1 = 1337;
741         I2n::clock::Time t2 (2187, 2187);
742         I2n::clock::Time tsum;
743
744         tsum = t1 + t2;
745
746         BOOST_CHECK_EQUAL(tsum.get_sec  (), 3524);
747         BOOST_CHECK_EQUAL(tsum.get_nsec (), 2187);
748     }
749
750     BOOST_AUTO_TEST_CASE(op_incr_Time)
751     {
752         I2n::clock::Time t1 (2187, 2187);
753         I2n::clock::Time t2 (1337, 1337);
754
755         t1 += t2;
756
757         BOOST_CHECK_EQUAL(t1.get_sec  (), 3524);
758         BOOST_CHECK_EQUAL(t1.get_nsec (), 3524);
759     }
760
761     BOOST_AUTO_TEST_CASE(op_incr_time_t)
762     {
763         I2n::clock::Time t1 (2187, 2187);
764         time_t           t2 = 1337;
765
766         t1 += t2;
767
768         BOOST_CHECK_EQUAL(t1.get_sec  (), 3524);
769         BOOST_CHECK_EQUAL(t1.get_nsec (), 2187);
770     }
771
772     BOOST_AUTO_TEST_CASE(op_subtract_Time)
773     {
774         I2n::clock::Time t1;
775         I2n::clock::Time t2;
776         I2n::clock::Time tdiff;
777
778         t1.set (2187, 2187);
779         t2.set (1337, 1337);
780         tdiff = t1 - t2;
781
782         BOOST_CHECK_EQUAL(tdiff.get_sec  (), 850);
783         BOOST_CHECK_EQUAL(tdiff.get_nsec (), 850);
784     }
785
786     BOOST_AUTO_TEST_CASE(op_subtract_time_t)
787     {
788         I2n::clock::Time t1 (2187, 2187);
789         time_t           t2 = 1337;
790         I2n::clock::Time tdiff;
791
792         tdiff = t1 - t2;
793
794         BOOST_CHECK_EQUAL(tdiff.get_sec  (), 850);
795         BOOST_CHECK_EQUAL(tdiff.get_nsec (), 2187);
796     }
797
798     BOOST_AUTO_TEST_CASE(op_subtract_time_t_external)
799     {
800         time_t           t1 = 1337;
801         I2n::clock::Time t2 (2187, 2187);
802         I2n::clock::Time tdiff;
803
804         tdiff = t1 - t2;
805
806         BOOST_CHECK_EQUAL(tdiff.get_sec  (), -851);
807         BOOST_CHECK_EQUAL(tdiff.get_nsec (), 999997813);
808     }
809
810     BOOST_AUTO_TEST_CASE(op_decr_Time)
811     {
812         I2n::clock::Time t1 (2187, 2187);
813         I2n::clock::Time t2 (1337, 1337);
814
815         t1 -= t2;
816
817         BOOST_CHECK_EQUAL(t1.get_sec  (), 850);
818         BOOST_CHECK_EQUAL(t1.get_nsec (), 850);
819     }
820
821     BOOST_AUTO_TEST_CASE(op_decr_time_t)
822     {
823         I2n::clock::Time t1 (2187, 2187);
824         time_t           t2 = 1337;
825
826         t1 -= t2;
827
828         BOOST_CHECK_EQUAL(t1.get_sec  (), 850);
829         BOOST_CHECK_EQUAL(t1.get_nsec (), 2187);
830     }
831
832     BOOST_AUTO_TEST_CASE(op_mult_scale)
833     {
834         I2n::clock::Time t1;
835         I2n::clock::Time t2;
836
837         t1.set (1, 1);
838         t2 = t1 * 42;
839
840         BOOST_CHECK_EQUAL(t2.get_sec  (), 42);
841         BOOST_CHECK_EQUAL(t2.get_nsec (), 42);
842     }
843
844     BOOST_AUTO_TEST_CASE(op_mult_mutate)
845     {
846         I2n::clock::Time t1 (  42, 42);
847         I2n::clock::Time t2 (1337,  0);
848
849         t1 *=   2;
850         t2 *= -10;
851
852         BOOST_CHECK_EQUAL(t1.get_sec  (),     84);
853         BOOST_CHECK_EQUAL(t1.get_nsec (),     84);
854         BOOST_CHECK_EQUAL(t2.get_sec  (), -13370);
855     }
856
857     BOOST_AUTO_TEST_CASE(op_mult_scale_carry)
858     {
859         I2n::clock::Time t1;
860         I2n::clock::Time t2;
861
862         t1.set (1, 500 * 1000 * 1000);
863         t2 = t1 * 3;
864
865         BOOST_CHECK_EQUAL(t2.get_sec  (),  4);
866         BOOST_CHECK_EQUAL(t2.get_nsec (),  500 * 1000 * 1000);
867     }
868
869     BOOST_AUTO_TEST_CASE(op_equals)
870     {
871         I2n::clock::Time t1;
872         I2n::clock::Time t2;
873
874         t1.set (50, 50);
875         t2.set (50, 50);
876
877         BOOST_CHECK_EQUAL(t1, t2);
878     }
879
880     BOOST_AUTO_TEST_CASE(compare_equal)
881     {
882         I2n::clock::Time t1;
883         I2n::clock::Time t2;
884
885         t1.set (42, 42);
886         t2.set (42, 42);
887
888         BOOST_CHECK_EQUAL(I2n::clock::compare (t1, t2), 0);
889     }
890
891     BOOST_AUTO_TEST_CASE(compare_equal_type)
892     {
893         I2n::clock::Time t1 (42, 42, I2n::clock::type::real);
894         I2n::clock::Time t2 (42, 42, I2n::clock::type::cpu);
895         I2n::clock::Time t3 (42,  0, I2n::clock::type::real);
896         I2n::clock::Time t4 (42, 42, I2n::clock::type::real);
897
898         BOOST_CHECK_NE(t1, t2);
899         BOOST_CHECK_NE(t1, t3);
900         BOOST_CHECK_EQUAL(t1, t4);
901     }
902
903     BOOST_AUTO_TEST_CASE(compare_ne_sec)
904     {
905         I2n::clock::Time t1;
906         I2n::clock::Time t2;
907
908         t1.set (  42, 42);
909         t2.set (1337, 42);
910
911         BOOST_CHECK_EQUAL(I2n::clock::compare (t1, t2), -1);
912         BOOST_CHECK_EQUAL(I2n::clock::compare (t2, t1),  1);
913     }
914
915     BOOST_AUTO_TEST_CASE(compare_ne_nsec)
916     {
917         I2n::clock::Time t1;
918         I2n::clock::Time t2;
919
920         t1.set (42,   42);
921         t2.set (42, 1337);
922
923         BOOST_CHECK_EQUAL(I2n::clock::compare (t1, t2), -1);
924         BOOST_CHECK_EQUAL(I2n::clock::compare (t2, t1),  1);
925     }
926
927     BOOST_AUTO_TEST_CASE(compare_ne_both)
928     {
929         I2n::clock::Time t1;
930         I2n::clock::Time t2;
931
932         t1.set (42, 2187);
933         t2.set (23, 1337);
934
935         BOOST_CHECK_EQUAL(I2n::clock::compare (t1, t2),  1);
936         BOOST_CHECK_EQUAL(I2n::clock::compare (t2, t1), -1);
937     }
938
939     BOOST_AUTO_TEST_CASE(op_ineq_sec)
940     {
941         I2n::clock::Time t1 (1337);
942         I2n::clock::Time t2 (2187);
943
944         BOOST_CHECK_LT(t1, t2);
945         BOOST_CHECK_GT(t2, t1);
946     }
947
948     BOOST_AUTO_TEST_CASE(op_ineq_nsec)
949     {
950         I2n::clock::Time t1 (1337, 23);
951         I2n::clock::Time t2 (1337, 42);
952
953         BOOST_CHECK_LT(t1, t2);
954         BOOST_CHECK_GT(t2, t1);
955     }
956
957     BOOST_AUTO_TEST_CASE(op_ineq_both)
958     {
959         I2n::clock::Time t1 (2187, 23);
960         I2n::clock::Time t2 (1337, 42);
961
962         BOOST_CHECK_LT(t2, t1);
963         BOOST_CHECK_GT(t1, t2);
964     }
965
966     BOOST_AUTO_TEST_CASE(op_eq_time_t)
967     {
968         boost::optional<I2n::clock::Time> t1  = I2n::clock::now ();
969         const time_t                      t2  = time (NULL); /* race here */
970
971         *t1 -= (time_t)42;
972
973         BOOST_CHECK_NE(*t1,  t2);
974         BOOST_CHECK_LT(*t1,  t2);
975         BOOST_CHECK_GT( t2, *t1);
976     }
977
978     BOOST_AUTO_TEST_CASE(Format_sec_msec)
979     {
980         I2n::clock::Time t1 (42, 42);
981         I2n::clock::Time t2 ( 4, 242424242);
982         I2n::clock::Time t3 ( 0, 133713371);
983         I2n::clock::Time t4 ( 0, 0);
984
985         std::string s1 = t1.format_sec_msec ();
986         std::string s2 = t2.format_sec_msec ();
987         std::string s3 = t3.format_sec_msec ();
988         std::string s4 = t4.format_sec_msec ();
989
990         BOOST_CHECK_EQUAL("42s 0ms"  , s1);
991         BOOST_CHECK_EQUAL( "4s 242ms", s2);
992         BOOST_CHECK_EQUAL( "0s 133ms", s3);
993         BOOST_CHECK_EQUAL( "0s 0ms"  , s4);
994     }
995
996     BOOST_AUTO_TEST_CASE(Format_min_sec_msec)
997     {
998         I2n::clock::Time t1 (42*60 + 42, 42);
999         I2n::clock::Time t2 ( 4*60 + 42, 242424242);
1000         I2n::clock::Time t3 ( 0*60 + 42, 133713371);
1001         I2n::clock::Time t4 (    0 +  0,  0);
1002
1003         std::string s1 = *t1.format_min_sec_msec ();
1004         std::string s2 = *t2.format_min_sec_msec ();
1005         std::string s3 = *t3.format_min_sec_msec ();
1006         std::string s4 = *t4.format_min_sec_msec ();
1007
1008         BOOST_CHECK_EQUAL("42m42.000s", s1);
1009         BOOST_CHECK_EQUAL( "4m42.242s", s2);
1010         BOOST_CHECK_EQUAL( "0m42.133s", s3);
1011         BOOST_CHECK_EQUAL(  "0m0.000s", s4);
1012     }
1013
1014     BOOST_AUTO_TEST_CASE(FormatISO8601_T)
1015     {
1016         I2n::clock::Time t (42, 42);
1017         boost::optional<std::string> s = t.format_iso8601 (true, false, true, false);
1018
1019         BOOST_CHECK_EQUAL("00:00:42", *s);
1020     }
1021
1022     BOOST_AUTO_TEST_CASE(FormatISO8601_DT)
1023     {
1024         I2n::clock::Time t (1541934671, 0);
1025         boost::optional<std::string> s = t.format_iso8601 (true, true, true, false);
1026
1027         BOOST_CHECK_EQUAL("2018-11-11T11:11:11", *s);
1028     }
1029
1030     BOOST_AUTO_TEST_CASE(FormatISO8601_DTZ)
1031     {
1032         I2n::clock::Time t (1541934671, 0);
1033         boost::optional<std::string> s = t.format_iso8601 (true, true, true, true);
1034
1035         BOOST_CHECK_EQUAL("2018-11-11T11:11:11Z+0000", *s);
1036     }
1037
1038     BOOST_AUTO_TEST_CASE(Format_make_nice_time)
1039     {
1040         I2n::clock::Time t (111111, 0);
1041         boost::optional<std::string> s = t.make_nice_time ();
1042
1043         BOOST_CHECK_EQUAL("1 day, 06:51:51", *s);
1044     }
1045
1046     BOOST_AUTO_TEST_CASE(Format_format_full_time)
1047     {
1048         I2n::clock::Time t (1541934671, 0);
1049         /*
1050          * brr, the old formatters use localtime without a way to opt out of
1051          * it!
1052          */
1053         setenv ("TZ", "UTC", 1);
1054         tzset();
1055         boost::optional<std::string> s = t.format_full_time ();
1056
1057         BOOST_CHECK_EQUAL("11.11.2018 11:11", *s);
1058     }
1059
1060     BOOST_AUTO_TEST_CASE(Format_format_date)
1061     {
1062         I2n::clock::Time t (1541934671, 0);
1063         boost::optional<std::string> s = t.format_date ();
1064
1065         BOOST_CHECK_EQUAL("11.11.2018", *s);
1066     }
1067
1068     BOOST_AUTO_TEST_CASE(FromString_iso8601_full)
1069     {
1070         const std::string in1 ("0001-01-01T00:00:00Z+0000");
1071         const std::string in2 ("2018-11-11T11:11:11Z+0000");
1072
1073         boost::optional<I2n::clock::Time> t1 = I2n::clock::time_of_iso8601 (in1);
1074         boost::optional<I2n::clock::Time> t2 = I2n::clock::time_of_iso8601 (in2);
1075
1076 # if LONG_BIT == 32
1077         BOOST_CHECK(!t1);
1078 # else
1079         BOOST_CHECK(t1);
1080         BOOST_CHECK_EQUAL(*t1->format_iso8601 (), in1);
1081 # endif
1082
1083         BOOST_CHECK(t2);
1084         BOOST_CHECK_EQUAL(*t2->format_iso8601 (), in2);
1085     }
1086
1087     BOOST_AUTO_TEST_CASE(FromString_iso8601_full_negyear)
1088     {
1089         const std::string in1 ("-0001-01-01T00:00:00Z+0000");
1090         const std::string in2 ("-2018-11-11T11:11:11Z+0000");
1091
1092         boost::optional<I2n::clock::Time> t1 = I2n::clock::time_of_iso8601 (in1);
1093         boost::optional<I2n::clock::Time> t2 = I2n::clock::time_of_iso8601 (in2);
1094
1095 # if LONG_BIT == 32
1096         BOOST_CHECK(!t1);
1097         BOOST_CHECK(!t2);
1098 # else
1099         BOOST_CHECK(t1);
1100         BOOST_CHECK(t2);
1101         BOOST_CHECK_EQUAL(*t1->format_iso8601 (), in1);
1102         BOOST_CHECK_EQUAL(*t2->format_iso8601 (), in2);
1103 # endif
1104     }
1105
1106     BOOST_AUTO_TEST_CASE(FromString_iso8601_partial)
1107     {
1108         const std::string in1 ("2018-11-11T11:11:11");
1109         const std::string in2 ("2018-11-11");
1110
1111         setenv ("TZ", "UTC", 1);
1112         tzset();
1113
1114         boost::optional<I2n::clock::Time> t1 =
1115             I2n::clock::time_of_iso8601 (in1, true, true, false);
1116         boost::optional<I2n::clock::Time> t2 =
1117             I2n::clock::time_of_iso8601 (in2, true, false, false);
1118
1119         BOOST_CHECK(t1);
1120         BOOST_CHECK(t2);
1121         /*
1122          * We test for the difference here which is zero if the number is
1123          * correct but causes the difference from the expected value to be
1124          * printed in case the test fails.
1125          */
1126         BOOST_CHECK_EQUAL(*t1->format_iso8601 (true,  true,  true, false), in1);
1127         BOOST_CHECK_EQUAL(*t2->format_iso8601 (true,  true, false, false), in2);
1128     }
1129
1130     BOOST_AUTO_TEST_CASE(FromString_iso8601_32bit_time_t_err)
1131     {
1132         const std::string timeless ("11:11:11");
1133         boost::optional<I2n::clock::Time> untimely = boost::none;
1134
1135         untimely = I2n::clock::time_of_iso8601 (timeless, false, true, false);
1136
1137 # if LONG_BIT == 32
1138         BOOST_CHECK(!untimely);
1139 # else
1140         BOOST_CHECK(untimely);
1141         BOOST_CHECK_EQUAL(*untimely->format_iso8601 (true, false,  true, false),
1142                           timeless);
1143 # endif
1144     }
1145
1146     BOOST_AUTO_TEST_CASE(Ctor_32bit_time_t_err)
1147     {
1148         boost::optional<std::string> threw = boost::none;
1149
1150         struct tm tm;
1151         memset (&tm, 0, sizeof (tm));
1152
1153         tm.tm_sec    = 11;
1154         tm.tm_min    = 11;
1155         tm.tm_hour   = 11;
1156         tm.tm_mday   = 11;
1157         tm.tm_mon    = 10;
1158         tm.tm_year   = -789;
1159         tm.tm_gmtoff = 0;
1160
1161         try {
1162             I2n::clock::Time untimely (tm);
1163         } catch (I2n::clock::conversion_error &exn) {
1164             threw = std::string (exn);
1165         }
1166
1167
1168 # if LONG_BIT == 32
1169         BOOST_CHECK_EQUAL(*threw,
1170                           "errno=0 [mktime: from struct tm {Sun Nov 11 11:11:11 1111}]");
1171 # else
1172         BOOST_CHECK(!threw);
1173 # endif
1174     }
1175
1176     BOOST_AUTO_TEST_CASE(containers_list)
1177     {
1178         std::list<I2n::clock::Time> ts;
1179
1180         ts.push_back (I2n::clock::zero ());
1181         ts.push_back (I2n::clock::zero ());
1182
1183         BOOST_CHECK_EQUAL(ts.size (), 2);
1184     }
1185
1186     BOOST_AUTO_TEST_CASE(containers_vec)
1187     {
1188         std::vector<I2n::clock::Time> ts;
1189
1190         ts.push_back (I2n::clock::zero ());
1191         ts.push_back (I2n::clock::zero ());
1192
1193         BOOST_CHECK_EQUAL(ts.size (), 2);
1194     }
1195
1196     BOOST_AUTO_TEST_CASE(containers_set)
1197     {
1198         std::set<I2n::clock::Time> ts;
1199
1200         ts.insert (I2n::clock::zero ());
1201         ts.insert (I2n::clock::Time (42, 2187));
1202         ts.insert (I2n::clock::zero ());
1203
1204         BOOST_CHECK_EQUAL(ts.size (), 2);
1205     }
1206
1207     BOOST_AUTO_TEST_CASE(containers_list_mean)
1208     {
1209         std::list<I2n::clock::Time> ts;
1210
1211         ts.push_back (I2n::clock::Time (42, 42));
1212         ts.push_back (I2n::clock::Time (1337, 1337));
1213
1214         BOOST_CHECK_EQUAL(I2n::clock::mean (ts),
1215                           I2n::clock::Time (689, 500000689));
1216     }
1217
1218     BOOST_AUTO_TEST_CASE(containers_list_mean_zero)
1219     {
1220         std::list<I2n::clock::Time> ts;
1221
1222         ts.push_back (I2n::clock::Time (0, 0));
1223         ts.push_back (I2n::clock::Time (0, 0));
1224         ts.push_back (I2n::clock::Time (0, 0));
1225         ts.push_back (I2n::clock::Time (0, 0));
1226
1227         BOOST_CHECK_EQUAL(I2n::clock::mean (ts),
1228                           I2n::clock::zero ());
1229     }
1230
1231     BOOST_AUTO_TEST_CASE(containers_list_mean_empty)
1232     {
1233         std::list<I2n::clock::Time> ts;
1234
1235         BOOST_CHECK_EQUAL(I2n::clock::mean (ts), I2n::clock::Time (0, 0));
1236     }
1237
1238     BOOST_AUTO_TEST_CASE(containers_set_mean)
1239     {
1240         std::set<I2n::clock::Time> ts;
1241
1242         ts.insert (I2n::clock::Time (42));
1243         ts.insert (I2n::clock::Time (1337));
1244         ts.insert (I2n::clock::Time (2187));
1245
1246         BOOST_CHECK_EQUAL(I2n::clock::mean (ts),
1247                           I2n::clock::Time (1188, 666666666));
1248     }
1249
1250     BOOST_AUTO_TEST_CASE(containers_set_median_empty)
1251     {
1252         std::set<I2n::clock::Time> ts;
1253
1254         BOOST_CHECK_EQUAL(I2n::clock::median (ts), I2n::clock::Time (0, 0));
1255     }
1256
1257     BOOST_AUTO_TEST_CASE(containers_set_median_one)
1258     {
1259         std::set<I2n::clock::Time> ts;
1260
1261         ts.insert (I2n::clock::Time (42, 0));
1262
1263         BOOST_CHECK_EQUAL(I2n::clock::median (ts),
1264                           I2n::clock::Time (42, 0));
1265     }
1266
1267     BOOST_AUTO_TEST_CASE(containers_set_median_multi)
1268     {
1269         std::set<I2n::clock::Time> ts;
1270
1271         ts.insert (I2n::clock::Time (42));
1272         ts.insert (I2n::clock::Time (1337));
1273         ts.insert (I2n::clock::Time (2187));
1274
1275         BOOST_CHECK_EQUAL(I2n::clock::median (ts), I2n::clock::Time (1337));
1276     }
1277
1278     BOOST_AUTO_TEST_CASE(containers_vec_median_multi)
1279     {
1280         std::vector<I2n::clock::Time> ts;
1281
1282         ts.push_back (I2n::clock::Time (42));
1283         ts.push_back (I2n::clock::Time (1337));
1284         ts.push_back (I2n::clock::Time (2187));
1285
1286         BOOST_CHECK_EQUAL(I2n::clock::median (ts), I2n::clock::Time (1337));
1287     }
1288
1289     BOOST_AUTO_TEST_CASE(containers_list_median_multi)
1290     {
1291         std::list<I2n::clock::Time> ts;
1292
1293         ts.push_back (I2n::clock::Time (42));
1294         ts.push_back (I2n::clock::Time (1337));
1295         ts.push_back (I2n::clock::Time (2187));
1296         ts.push_back (I2n::clock::Time (0xdead));
1297         ts.push_back (I2n::clock::Time (0xbeef));
1298
1299         BOOST_CHECK_EQUAL(I2n::clock::median (ts),
1300                           I2n::clock::Time (2187));
1301     }
1302
1303     BOOST_AUTO_TEST_CASE(containers_list_median_multi_evensize)
1304     {
1305         std::list<I2n::clock::Time> ts;
1306
1307         ts.push_back (I2n::clock::Time (42));
1308         ts.push_back (I2n::clock::Time (1337));
1309         ts.push_back (I2n::clock::Time (2187));
1310         ts.push_back (I2n::clock::Time (0xf00d));
1311         ts.push_back (I2n::clock::Time (0xfeed));
1312         ts.push_back (I2n::clock::Time (0xdeadf0e));
1313
1314         BOOST_CHECK_EQUAL(I2n::clock::median (ts), I2n::clock::Time (0xf00d));
1315     }
1316
1317 BOOST_AUTO_TEST_SUITE_END() /* [Clock] */
1318
1319 BOOST_AUTO_TEST_SUITE_END()