userver: /data/code/userver/libraries/proto-structs/tests/time_of_day_test.cpp Source File
Loading...
Searching...
No Matches
time_of_day_test.cpp
1#include <gmock/gmock.h>
2#include <gtest/gtest.h>
3
4#include <limits>
5
6#include <userver/proto-structs/exceptions.hpp>
7#include <userver/proto-structs/time_of_day.hpp>
8#include <userver/utils/impl/internal_tag.hpp>
9
10using namespace std::literals::chrono_literals;
11
12USERVER_NAMESPACE_BEGIN
13
14namespace proto_structs::tests {
15
16TEST(TimeOfDayTest, IsValid) {
17 using OverflowingDuration = std::chrono::duration<std::chrono::seconds::rep, std::chrono::hours::period>;
18 constexpr auto kMaxInt = std::numeric_limits<std::int32_t>::max();
19 constexpr auto kMinInt = std::numeric_limits<std::int32_t>::min();
20
21 EXPECT_FALSE(TimeOfDay::IsValid(-1h, 0min, 0s, 0ns));
22 EXPECT_FALSE(TimeOfDay::IsValid(25h, 0min, 0s, 0ns));
23 EXPECT_FALSE(TimeOfDay::IsValid(24h, 0min, 0s, 1ns));
24 EXPECT_FALSE(TimeOfDay::IsValid(10h, -1min, 0s, 0ns));
25 EXPECT_FALSE(TimeOfDay::IsValid(10h, 100min, 0s, 0ns));
26 EXPECT_FALSE(TimeOfDay::IsValid(10h, 30min, -1s, 0ns));
27 EXPECT_FALSE(TimeOfDay::IsValid(10h, 30min, 100s, 0ns));
28 EXPECT_FALSE(TimeOfDay::IsValid(10h, 30min, 45s, -1ns));
29 EXPECT_FALSE(TimeOfDay::IsValid(10h, 30min, 45s, std::chrono::duration<int64_t, std::pico>{-1}));
30 EXPECT_FALSE(TimeOfDay::IsValid(10h, 30min, 45s, std::chrono::duration<int64_t, std::pico>{1'000'000'000'000LL}));
31
32 EXPECT_THROW([[maybe_unused]] auto val = TimeOfDay(-1h, 0min, 0s, 0ns), ValueError);
33 EXPECT_THROW([[maybe_unused]] auto val = TimeOfDay(std::chrono::hh_mm_ss{25h + 30min + 123ns}), ValueError);
34 EXPECT_THROW(
35 [[maybe_unused]] auto val = TimeOfDay(std::chrono::hh_mm_ss<std::chrono::minutes>{24h + 1min}),
36 ValueError
37 );
38 EXPECT_THROW(
39 [[maybe_unused]] auto val = TimeOfDay(std::chrono::duration_cast<std::chrono::milliseconds>(48h)),
40 ValueError
41 );
42 EXPECT_THROW([[maybe_unused]] auto val = TimeOfDay(OverflowingDuration::max()), ValueError);
43 EXPECT_THROW(
44 [[maybe_unused]] auto val = TimeOfDay(utils::impl::InternalTag{}, kMaxInt, kMaxInt, kMaxInt, kMaxInt),
45 ValueError
46 );
47 EXPECT_THROW(
48 [[maybe_unused]] auto val = TimeOfDay(utils::impl::InternalTag{}, kMinInt, kMinInt, kMinInt, kMinInt),
49 ValueError
50 );
51 EXPECT_THAT(
52 []() { [[maybe_unused]] TimeOfDay t(25h, 30min, 0s, 123ns); },
53 ::testing::ThrowsMessage<ValueError>(::testing::HasSubstr("25:30:0.123ns"))
54 );
55 EXPECT_THAT(
56 []() { [[maybe_unused]] TimeOfDay t(std::chrono::duration<int64_t, std::pico>{-1}); },
57 ::testing::ThrowsMessage<ValueError>(::testing::HasSubstr("negative"))
58 );
59
60 EXPECT_TRUE(TimeOfDay::IsValid(0h, 0min, 0s, 0ns));
61 EXPECT_TRUE(TimeOfDay::IsValid(23h, 59min, 59s, 999'999'999ns));
62 EXPECT_TRUE(TimeOfDay::IsValid(23h, 59min, 60s, 999'999'999ns));
63 EXPECT_TRUE(TimeOfDay::IsValid(23h, 59min, 59s, std::chrono::duration<int64_t, std::pico>{999'999'999'999LL}));
64 EXPECT_TRUE(TimeOfDay::IsValid(23h, 59min, 60s, std::chrono::duration<int64_t, std::pico>{999'999'999'999LL}));
65 EXPECT_TRUE(TimeOfDay::IsValid(24h, 0min, 0s, 0ns));
66}
67
68TEST(TimeOfDayTest, Conversions) {
69 TimeOfDay t;
70
71 EXPECT_EQ(t.Hours(), 0h);
72 EXPECT_EQ(t.Minutes(), 0min);
73 EXPECT_EQ(t.Seconds(), 0s);
74 EXPECT_EQ(t.Nanos(), 0ns);
75
76 t = TimeOfDay{12h, 30min, 45s, 123'456'789ns};
77
78 EXPECT_EQ(t.Hours(), 12h);
79 EXPECT_EQ(t.Minutes(), 30min);
80 EXPECT_EQ(t.Seconds(), 45s);
81 EXPECT_EQ(t.Nanos(), 123'456'789ns);
82 EXPECT_EQ(t.ToChronoDuration(), 12h + 30min + 45s + 123'456'789ns);
83 EXPECT_EQ(t.ToChronoDuration<std::chrono::microseconds>(), 12h + 30min + 45s + 123'456us);
84 EXPECT_EQ(static_cast<std::chrono::milliseconds>(t), 12h + 30min + 45s + 123ms);
85 EXPECT_EQ(t.ToChronoTimeOfDay().hours(), 12h);
86 EXPECT_EQ(t.ToChronoTimeOfDay().minutes(), 30min);
87 EXPECT_EQ(t.ToChronoTimeOfDay().seconds(), 45s);
88 EXPECT_EQ(t.ToChronoTimeOfDay().subseconds(), 123'456'789ns);
89 EXPECT_EQ(t.ToChronoTimeOfDay<std::chrono::milliseconds>().hours(), 12h);
90 EXPECT_EQ(t.ToChronoTimeOfDay<std::chrono::milliseconds>().minutes(), 30min);
91 EXPECT_EQ(t.ToChronoTimeOfDay<std::chrono::milliseconds>().seconds(), 45s);
92 EXPECT_EQ(t.ToChronoTimeOfDay<std::chrono::milliseconds>().subseconds(), 123ms);
93 EXPECT_EQ(static_cast<std::chrono::hh_mm_ss<std::chrono::microseconds>>(t).hours(), 12h);
94 EXPECT_EQ(static_cast<std::chrono::hh_mm_ss<std::chrono::microseconds>>(t).minutes(), 30min);
95 EXPECT_EQ(static_cast<std::chrono::hh_mm_ss<std::chrono::microseconds>>(t).seconds(), 45s);
96 EXPECT_EQ(static_cast<std::chrono::hh_mm_ss<std::chrono::microseconds>>(t).subseconds(), 123'456us);
97 EXPECT_EQ(t.ToUserverDuration().Seconds().count(), (12 * 60 * 60) + (30 * 60) + 45);
98 EXPECT_EQ(t.ToUserverDuration().Nanos(), 123'456'789ns);
99 EXPECT_EQ(static_cast<Duration>(t).Seconds().count(), (12 * 60 * 60) + (30 * 60) + 45);
100 EXPECT_EQ(static_cast<Duration>(t).Nanos(), 123'456'789ns);
101 EXPECT_EQ(t.ToUserverTimeOfDay().Hours(), 12h);
102 EXPECT_EQ(t.ToUserverTimeOfDay().Minutes(), 30min);
103 EXPECT_EQ(t.ToUserverTimeOfDay().Seconds(), 45s);
104 EXPECT_EQ(t.ToUserverTimeOfDay().Subseconds(), 123'456'789ns);
105 EXPECT_EQ(t.ToUserverTimeOfDay<std::chrono::milliseconds>().Hours(), 12h);
106 EXPECT_EQ(t.ToUserverTimeOfDay<std::chrono::milliseconds>().Minutes(), 30min);
107 EXPECT_EQ(t.ToUserverTimeOfDay<std::chrono::milliseconds>().Seconds(), 45s);
108 EXPECT_EQ(t.ToUserverTimeOfDay<std::chrono::milliseconds>().Subseconds(), 123ms);
109 EXPECT_EQ(static_cast<utils::datetime::TimeOfDay<std::chrono::microseconds>>(t).Hours(), 12h);
110 EXPECT_EQ(static_cast<utils::datetime::TimeOfDay<std::chrono::microseconds>>(t).Minutes(), 30min);
111 EXPECT_EQ(static_cast<utils::datetime::TimeOfDay<std::chrono::microseconds>>(t).Seconds(), 45s);
112 EXPECT_EQ(static_cast<utils::datetime::TimeOfDay<std::chrono::microseconds>>(t).Subseconds(), 123'456us);
113
114 t = std::chrono::hh_mm_ss{1h + 15min + 10s + 999ms};
115
116 EXPECT_EQ(t.Hours(), 1h);
117 EXPECT_EQ(t.Minutes(), 15min);
118 EXPECT_EQ(t.Seconds(), 10s);
119 EXPECT_EQ(t.Nanos(), 999'000'000ns);
120
121 t = utils::datetime::TimeOfDay<std::chrono::microseconds>{10h + 11min + 12s + 123456789ns};
122
123 EXPECT_EQ(t.Hours(), 10h);
124 EXPECT_EQ(t.Minutes(), 11min);
125 EXPECT_EQ(t.Seconds(), 12s);
126 EXPECT_EQ(t.Nanos(), 123'456'000ns);
127
128 t = TimeOfDay{1h + 2min + 3s};
129
130 EXPECT_EQ(t.Hours(), 1h);
131 EXPECT_EQ(t.Minutes(), 2min);
132 EXPECT_EQ(t.Seconds(), 3s);
133 EXPECT_EQ(t.Nanos(), 0ns);
134
135 auto point = std::chrono::time_point_cast<std::chrono::system_clock::duration>(std::chrono::sys_days{2025y / 6 / 3}
136 );
137 point += 22h + 0min + 13s + 555ms;
138 t = TimeOfDay{point};
139
140 EXPECT_EQ(t.Hours(), 22h);
141 EXPECT_EQ(t.Minutes(), 0min);
142 EXPECT_EQ(t.Seconds(), 13s);
143 EXPECT_EQ(t.Nanos(), 555'000'000ns);
144
145 t = TimeOfDay{0h, 0min, 60s, 0ns};
146
147 EXPECT_EQ(t.Seconds(), 60s);
148 EXPECT_EQ(t.ToChronoTimeOfDay().minutes(), 1min);
149 EXPECT_EQ(t.ToChronoTimeOfDay().seconds(), 0s);
150
151 t = TimeOfDay{24h, 0min, 0s, 0ns};
152
153 EXPECT_EQ(t.Hours(), 24h);
154 EXPECT_EQ(t.ToUserverTimeOfDay().Hours(), 0h);
155 EXPECT_EQ(t.ToUserverTimeOfDay().Minutes(), 0min);
156 EXPECT_EQ(t.ToUserverTimeOfDay().Seconds(), 0s);
157 EXPECT_EQ(t.ToUserverTimeOfDay().Subseconds(), 0ns);
158
159 t = TimeOfDay{utils::impl::InternalTag{}, 12, 59, 59, 123'456};
160
161 EXPECT_EQ(t.Hours(), 12h);
162 EXPECT_EQ(t.Minutes(), 59min);
163 EXPECT_EQ(t.Seconds(), 59s);
164 EXPECT_EQ(t.Nanos(), 123'456ns);
165}
166
167} // namespace proto_structs::tests
168
169USERVER_NAMESPACE_END