@@ -17,6 +17,18 @@ namespace winrt
1717 }
1818}
1919
20+ // To confirm that two clocks have the same epoch, we
21+ // capture one clock, then the other, then the first again,
22+ // and verify that the three timestamps are ordered. This avoids
23+ // spurious failures if a test machine is slow or experiences a
24+ // clock tick at just the wrong time.
25+ //
26+ // We use a duration_cast to milliseconds so that the assertion
27+ // failure message tells us how many milliseconds of error we encountered.
28+ #define REQUIRE_ORDERED (a, b, c ) \
29+ REQUIRE (duration_cast<milliseconds>((b) - (a)).count() >= 0); \
30+ REQUIRE (duration_cast<milliseconds>((c) - (b)).count() >= 0)
31+
2032namespace Catch
2133{
2234 template <typename Rep, typename Period>
@@ -46,11 +58,13 @@ namespace Catch
4658
4759TEST_CASE (" clock, now" )
4860{
49- Calendar calendar;
50- calendar.SetToNow ();
61+ // Confirm that clock::now agrees with Calendar::SetToNow.
62+ Calendar calendar1;
63+ calendar1.SetToNow ();
5164 auto time = clock::now ();
52- auto diff = calendar.GetDateTime () - time;
53- REQUIRE (abs (diff) < milliseconds{ 100 });
65+ Calendar calendar2;
66+ calendar2.SetToNow ();
67+ REQUIRE_ORDERED (calendar1.GetDateTime (), time, calendar2.GetDateTime ());
5468}
5569
5670TEST_CASE (" clock, units" )
@@ -66,73 +80,72 @@ TEST_CASE("clock, units")
6680
6781TEST_CASE (" clock, time_t" )
6882{
69- const DateTime now_dt = clock::now ();
83+ const DateTime now1_dt = clock::now ();
7084 const time_t now_tt = time (nullptr );
85+ const DateTime now2_dt = clock::now ();
7186
7287 // Round trip from DateTime to time_t and back.
7388 // confirm that nothing happens other than truncating the fractional seconds
74- REQUIRE (clock::from_time_t (clock::to_time_t (now_dt )) == time_point_cast<seconds>(now_dt ));
89+ REQUIRE (clock::from_time_t (clock::to_time_t (now1_dt )) == time_point_cast<seconds>(now1_dt ));
7590
7691 // Same thing in reverse
7792 REQUIRE (clock::to_time_t (clock::from_time_t (now_tt)) == now_tt);
7893
7994 // Conversions are verified to be consistent. Now, verify that we're correctly converting epochs
80- const auto diff = duration_cast<milliseconds>( abs (now_dt - clock::from_time_t (now_tt))). count ();
81- REQUIRE (diff < 1000 );
95+ // Note that time_t has only 1s resolution, so we need to add 1 second of slop on either side.
96+ REQUIRE_ORDERED (now1_dt - 1s, clock::from_time_t (now_tt), now2_dt + 1s );
8297}
8398
8499TEST_CASE (" clock, FILETIME" )
85100{
86- const DateTime now_dt = clock::now ();
101+ const DateTime now1_dt = clock::now ();
87102 FILETIME now_ft;
88103 ::GetSystemTimePreciseAsFileTime (&now_ft);
104+ const DateTime now2_dt = clock::now ();
89105
90106 // Round trip conversions
91- REQUIRE (clock::from_file_time (clock::to_file_time (now_dt )) == now_dt );
107+ REQUIRE (clock::from_file_time (clock::to_file_time (now1_dt )) == now1_dt );
92108
93109 REQUIRE (clock::to_file_time (clock::from_file_time (now_ft)) == now_ft);
94110
95111 // Verify epoch
96- const auto diff = abs (now_dt - clock::from_file_time (now_ft));
97- REQUIRE (diff < milliseconds{ 100 });
112+ REQUIRE_ORDERED (now1_dt, clock::from_file_time (now_ft), now2_dt);
98113}
99114
100115TEST_CASE (" clock, system_clock" )
101116{
102- DateTime const now_dt = clock::now ();
103- auto const now_sys = system_clock::now ();
117+ DateTime const now1_dt = clock::now ();
118+ auto const now1_sys = system_clock::now ();
119+ DateTime const now2_dt = clock::now ();
120+ auto const now2_sys = system_clock::now ();
104121
105122 // Round trip DateTime to std::chrono::system_clock::time_point and back
106- REQUIRE (clock::from_sys (clock::to_sys (now_dt )) == now_dt );
123+ REQUIRE (clock::from_sys (clock::to_sys (now1_dt )) == now1_dt );
107124
108125 // Round trip other direction
109- REQUIRE (clock::to_sys (clock::from_sys (now_sys )) == now_sys );
126+ REQUIRE (clock::to_sys (clock::from_sys (now1_sys )) == now1_sys );
110127
111128 // Round trip with custom resolution
112129 {
113- auto const now_dt_sec = time_point_cast<seconds>(now_dt );
130+ auto const now_dt_sec = time_point_cast<seconds>(now1_dt );
114131 REQUIRE (clock::from_sys (clock::to_sys (now_dt_sec)) == now_dt_sec);
115132 }
116133 {
117- auto const now_dt_mins = time_point_cast<minutes>(now_dt );
134+ auto const now_dt_mins = time_point_cast<minutes>(now1_dt );
118135 REQUIRE (clock::from_sys (clock::to_sys (now_dt_mins)) == now_dt_mins);
119136 }
120137 {
121- auto const now_sys_sec = time_point_cast<seconds>(now_sys );
138+ auto const now_sys_sec = time_point_cast<seconds>(now1_sys );
122139 REQUIRE (clock::to_sys (clock::from_sys (now_sys_sec)) == now_sys_sec);
123140 }
124141 {
125- auto const now_sys_mins = time_point_cast<seconds>(now_sys );
142+ auto const now_sys_mins = time_point_cast<seconds>(now1_sys );
126143 REQUIRE (clock::to_sys (clock::from_sys (now_sys_mins)) == now_sys_mins);
127144 }
128145
129146 // Verify that the epoch calculations are correct.
130147 {
131- auto const diff = now_dt - clock::from_sys (now_sys);
132- REQUIRE (abs (diff) < milliseconds{ 100 });
133- }
134- {
135- auto const diff = now_sys - clock::to_sys (now_dt);
136- REQUIRE (abs (diff) < milliseconds{ 100 });
148+ REQUIRE_ORDERED (now1_dt, clock::from_sys (now1_sys), now2_dt);
149+ REQUIRE_ORDERED (clock::from_sys (now1_sys), now2_dt, clock::from_sys (now2_sys));
137150 }
138151}
0 commit comments