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