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