Skip to content

Commit 4bc7568

Browse files
rogeeffcopybara-github
authored andcommitted
Eliminate use of internal interfaces and make the test portable and expose it to OSS.
PiperOrigin-RevId: 481865072 Change-Id: I46364ec07df6aaff25911f8bd9e40dfee6c60626
1 parent 94433ef commit 4bc7568

File tree

5 files changed

+237
-0
lines changed

5 files changed

+237
-0
lines changed

absl/time/BUILD.bazel

+26
Original file line numberDiff line numberDiff line change
@@ -45,12 +45,14 @@ cc_library(
4545
linkopts = ABSL_DEFAULT_LINKOPTS,
4646
deps = [
4747
"//absl/base",
48+
"//absl/base:config",
4849
"//absl/base:core_headers",
4950
"//absl/base:raw_logging_internal",
5051
"//absl/numeric:int128",
5152
"//absl/strings",
5253
"//absl/time/internal/cctz:civil_time",
5354
"//absl/time/internal/cctz:time_zone",
55+
"//absl/types:optional",
5456
],
5557
)
5658

@@ -97,6 +99,30 @@ cc_test(
9799
],
98100
)
99101

102+
cc_test(
103+
name = "flag_test",
104+
srcs = [
105+
"flag_test.cc",
106+
],
107+
copts = ABSL_TEST_COPTS,
108+
linkopts = ABSL_DEFAULT_LINKOPTS,
109+
tags = [
110+
"no_test_android_arm",
111+
"no_test_android_arm64",
112+
"no_test_android_x86",
113+
"no_test_ios_x86_64",
114+
"no_test_loonix",
115+
"no_test_msvc_x64",
116+
"no_test_wasm",
117+
],
118+
deps = [
119+
":time",
120+
"//absl/flags:flag",
121+
"//absl/flags:reflection",
122+
"@com_google_googletest//:gtest_main",
123+
],
124+
)
125+
100126
cc_test(
101127
name = "time_benchmark",
102128
srcs = [

absl/time/CMakeLists.txt

+13
Original file line numberDiff line numberDiff line change
@@ -127,3 +127,16 @@ absl_cc_test(
127127
absl::time_zone
128128
GTest::gmock_main
129129
)
130+
131+
absl_cc_test(
132+
NAME
133+
flag_test
134+
SRCS
135+
"flag_test.cc"
136+
COPTS
137+
${ABSL_TEST_COPTS}
138+
DEPS
139+
absl::flags
140+
absl::flags_reflection
141+
GTest::gmock_main
142+
)

absl/time/civil_time.cc

+26
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include "absl/time/civil_time.h"
1616

1717
#include <cstdlib>
18+
#include <ostream>
1819
#include <string>
1920

2021
#include "absl/strings/str_cat.h"
@@ -167,6 +168,31 @@ std::ostream& operator<<(std::ostream& os, CivilSecond s) {
167168
return os << FormatCivilTime(s);
168169
}
169170

171+
bool AbslParseFlag(string_view s, CivilSecond* c, std::string*) {
172+
return ParseLenientCivilTime(s, c);
173+
}
174+
bool AbslParseFlag(string_view s, CivilMinute* c, std::string*) {
175+
return ParseLenientCivilTime(s, c);
176+
}
177+
bool AbslParseFlag(string_view s, CivilHour* c, std::string*) {
178+
return ParseLenientCivilTime(s, c);
179+
}
180+
bool AbslParseFlag(string_view s, CivilDay* c, std::string*) {
181+
return ParseLenientCivilTime(s, c);
182+
}
183+
bool AbslParseFlag(string_view s, CivilMonth* c, std::string*) {
184+
return ParseLenientCivilTime(s, c);
185+
}
186+
bool AbslParseFlag(string_view s, CivilYear* c, std::string*) {
187+
return ParseLenientCivilTime(s, c);
188+
}
189+
std::string AbslUnparseFlag(CivilSecond c) { return FormatCivilTime(c); }
190+
std::string AbslUnparseFlag(CivilMinute c) { return FormatCivilTime(c); }
191+
std::string AbslUnparseFlag(CivilHour c) { return FormatCivilTime(c); }
192+
std::string AbslUnparseFlag(CivilDay c) { return FormatCivilTime(c); }
193+
std::string AbslUnparseFlag(CivilMonth c) { return FormatCivilTime(c); }
194+
std::string AbslUnparseFlag(CivilYear c) { return FormatCivilTime(c); }
195+
170196
} // namespace time_internal
171197

172198
ABSL_NAMESPACE_END

absl/time/civil_time.h

+25
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,10 @@
7070
#ifndef ABSL_TIME_CIVIL_TIME_H_
7171
#define ABSL_TIME_CIVIL_TIME_H_
7272

73+
#include <iosfwd>
7374
#include <string>
7475

76+
#include "absl/base/config.h"
7577
#include "absl/strings/string_view.h"
7678
#include "absl/time/internal/cctz/include/cctz/civil_time.h"
7779

@@ -530,6 +532,29 @@ std::ostream& operator<<(std::ostream& os, CivilHour h);
530532
std::ostream& operator<<(std::ostream& os, CivilMinute m);
531533
std::ostream& operator<<(std::ostream& os, CivilSecond s);
532534

535+
// AbslParseFlag()
536+
//
537+
// Parses the command-line flag string representation `s` into a civil-time
538+
// value. Flags must be specified in a format that is valid for
539+
// `absl::ParseLenientCivilTime()`.
540+
bool AbslParseFlag(absl::string_view s, CivilSecond* c, std::string* error);
541+
bool AbslParseFlag(absl::string_view s, CivilMinute* c, std::string* error);
542+
bool AbslParseFlag(absl::string_view s, CivilHour* c, std::string* error);
543+
bool AbslParseFlag(absl::string_view s, CivilDay* c, std::string* error);
544+
bool AbslParseFlag(absl::string_view s, CivilMonth* c, std::string* error);
545+
bool AbslParseFlag(absl::string_view s, CivilYear* c, std::string* error);
546+
547+
// AbslUnparseFlag()
548+
//
549+
// Unparses a civil-time value into a command-line string representation using
550+
// the format specified by `absl::ParseCivilTime()`.
551+
std::string AbslUnparseFlag(CivilSecond c);
552+
std::string AbslUnparseFlag(CivilMinute c);
553+
std::string AbslUnparseFlag(CivilHour c);
554+
std::string AbslUnparseFlag(CivilDay c);
555+
std::string AbslUnparseFlag(CivilMonth c);
556+
std::string AbslUnparseFlag(CivilYear c);
557+
533558
} // namespace time_internal
534559

535560
ABSL_NAMESPACE_END

absl/time/flag_test.cc

+147
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
// Copyright 2018 The Abseil Authors.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// https://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#include "absl/flags/flag.h"
16+
17+
#include <string>
18+
19+
#include "gtest/gtest.h"
20+
#include "absl/flags/reflection.h"
21+
#include "absl/time/civil_time.h"
22+
#include "absl/time/time.h"
23+
24+
ABSL_FLAG(absl::CivilSecond, test_flag_civil_second,
25+
absl::CivilSecond(2015, 1, 2, 3, 4, 5), "");
26+
ABSL_FLAG(absl::CivilMinute, test_flag_civil_minute,
27+
absl::CivilMinute(2015, 1, 2, 3, 4), "");
28+
ABSL_FLAG(absl::CivilHour, test_flag_civil_hour, absl::CivilHour(2015, 1, 2, 3),
29+
"");
30+
ABSL_FLAG(absl::CivilDay, test_flag_civil_day, absl::CivilDay(2015, 1, 2), "");
31+
ABSL_FLAG(absl::CivilMonth, test_flag_civil_month, absl::CivilMonth(2015, 1),
32+
"");
33+
ABSL_FLAG(absl::CivilYear, test_flag_civil_year, absl::CivilYear(2015), "");
34+
35+
ABSL_FLAG(absl::Duration, test_duration_flag, absl::Seconds(5),
36+
"For testing support for Duration flags");
37+
ABSL_FLAG(absl::Time, test_time_flag, absl::InfinitePast(),
38+
"For testing support for Time flags");
39+
40+
namespace {
41+
42+
bool SetFlagValue(absl::string_view flag_name, absl::string_view value) {
43+
auto* flag = absl::FindCommandLineFlag(flag_name);
44+
if (!flag) return false;
45+
std::string err;
46+
return flag->ParseFrom(value, &err);
47+
}
48+
49+
bool GetFlagValue(absl::string_view flag_name, std::string& value) {
50+
auto* flag = absl::FindCommandLineFlag(flag_name);
51+
if (!flag) return false;
52+
value = flag->CurrentValue();
53+
return true;
54+
}
55+
56+
TEST(CivilTime, FlagSupport) {
57+
// Tests the default setting of the flags.
58+
const absl::CivilSecond kDefaultSec(2015, 1, 2, 3, 4, 5);
59+
EXPECT_EQ(absl::CivilSecond(kDefaultSec),
60+
absl::GetFlag(FLAGS_test_flag_civil_second));
61+
EXPECT_EQ(absl::CivilMinute(kDefaultSec),
62+
absl::GetFlag(FLAGS_test_flag_civil_minute));
63+
EXPECT_EQ(absl::CivilHour(kDefaultSec),
64+
absl::GetFlag(FLAGS_test_flag_civil_hour));
65+
EXPECT_EQ(absl::CivilDay(kDefaultSec),
66+
absl::GetFlag(FLAGS_test_flag_civil_day));
67+
EXPECT_EQ(absl::CivilMonth(kDefaultSec),
68+
absl::GetFlag(FLAGS_test_flag_civil_month));
69+
EXPECT_EQ(absl::CivilYear(kDefaultSec),
70+
absl::GetFlag(FLAGS_test_flag_civil_year));
71+
72+
// Sets flags to a new value.
73+
const absl::CivilSecond kNewSec(2016, 6, 7, 8, 9, 10);
74+
absl::SetFlag(&FLAGS_test_flag_civil_second, absl::CivilSecond(kNewSec));
75+
absl::SetFlag(&FLAGS_test_flag_civil_minute, absl::CivilMinute(kNewSec));
76+
absl::SetFlag(&FLAGS_test_flag_civil_hour, absl::CivilHour(kNewSec));
77+
absl::SetFlag(&FLAGS_test_flag_civil_day, absl::CivilDay(kNewSec));
78+
absl::SetFlag(&FLAGS_test_flag_civil_month, absl::CivilMonth(kNewSec));
79+
absl::SetFlag(&FLAGS_test_flag_civil_year, absl::CivilYear(kNewSec));
80+
81+
EXPECT_EQ(absl::CivilSecond(kNewSec),
82+
absl::GetFlag(FLAGS_test_flag_civil_second));
83+
EXPECT_EQ(absl::CivilMinute(kNewSec),
84+
absl::GetFlag(FLAGS_test_flag_civil_minute));
85+
EXPECT_EQ(absl::CivilHour(kNewSec),
86+
absl::GetFlag(FLAGS_test_flag_civil_hour));
87+
EXPECT_EQ(absl::CivilDay(kNewSec), absl::GetFlag(FLAGS_test_flag_civil_day));
88+
EXPECT_EQ(absl::CivilMonth(kNewSec),
89+
absl::GetFlag(FLAGS_test_flag_civil_month));
90+
EXPECT_EQ(absl::CivilYear(kNewSec),
91+
absl::GetFlag(FLAGS_test_flag_civil_year));
92+
}
93+
94+
TEST(Duration, FlagSupport) {
95+
EXPECT_EQ(absl::Seconds(5), absl::GetFlag(FLAGS_test_duration_flag));
96+
97+
absl::SetFlag(&FLAGS_test_duration_flag, absl::Seconds(10));
98+
EXPECT_EQ(absl::Seconds(10), absl::GetFlag(FLAGS_test_duration_flag));
99+
100+
EXPECT_TRUE(SetFlagValue("test_duration_flag", "20s"));
101+
EXPECT_EQ(absl::Seconds(20), absl::GetFlag(FLAGS_test_duration_flag));
102+
103+
std::string current_flag_value;
104+
EXPECT_TRUE(GetFlagValue("test_duration_flag", current_flag_value));
105+
EXPECT_EQ("20s", current_flag_value);
106+
}
107+
108+
TEST(Time, FlagSupport) {
109+
EXPECT_EQ(absl::InfinitePast(), absl::GetFlag(FLAGS_test_time_flag));
110+
111+
const absl::Time t = absl::FromCivil(absl::CivilSecond(2016, 1, 2, 3, 4, 5),
112+
absl::UTCTimeZone());
113+
absl::SetFlag(&FLAGS_test_time_flag, t);
114+
EXPECT_EQ(t, absl::GetFlag(FLAGS_test_time_flag));
115+
116+
// Successful parse
117+
EXPECT_TRUE(SetFlagValue("test_time_flag", "2016-01-02T03:04:06Z"));
118+
EXPECT_EQ(t + absl::Seconds(1), absl::GetFlag(FLAGS_test_time_flag));
119+
EXPECT_TRUE(SetFlagValue("test_time_flag", "2016-01-02T03:04:07.0Z"));
120+
EXPECT_EQ(t + absl::Seconds(2), absl::GetFlag(FLAGS_test_time_flag));
121+
EXPECT_TRUE(SetFlagValue("test_time_flag", "2016-01-02T03:04:08.000Z"));
122+
EXPECT_EQ(t + absl::Seconds(3), absl::GetFlag(FLAGS_test_time_flag));
123+
EXPECT_TRUE(SetFlagValue("test_time_flag", "2016-01-02T03:04:09+00:00"));
124+
EXPECT_EQ(t + absl::Seconds(4), absl::GetFlag(FLAGS_test_time_flag));
125+
EXPECT_TRUE(SetFlagValue("test_time_flag", "2016-01-02T03:04:05.123+00:00"));
126+
EXPECT_EQ(t + absl::Milliseconds(123), absl::GetFlag(FLAGS_test_time_flag));
127+
EXPECT_TRUE(SetFlagValue("test_time_flag", "2016-01-02T03:04:05.123+08:00"));
128+
EXPECT_EQ(t + absl::Milliseconds(123) - absl::Hours(8),
129+
absl::GetFlag(FLAGS_test_time_flag));
130+
EXPECT_TRUE(SetFlagValue("test_time_flag", "infinite-future"));
131+
EXPECT_EQ(absl::InfiniteFuture(), absl::GetFlag(FLAGS_test_time_flag));
132+
EXPECT_TRUE(SetFlagValue("test_time_flag", "infinite-past"));
133+
EXPECT_EQ(absl::InfinitePast(), absl::GetFlag(FLAGS_test_time_flag));
134+
135+
EXPECT_FALSE(SetFlagValue("test_time_flag", "2016-01-02T03:04:06"));
136+
EXPECT_FALSE(SetFlagValue("test_time_flag", "2016-01-02"));
137+
EXPECT_FALSE(SetFlagValue("test_time_flag", "2016-01-02Z"));
138+
EXPECT_FALSE(SetFlagValue("test_time_flag", "2016-01-02+00:00"));
139+
EXPECT_FALSE(SetFlagValue("test_time_flag", "2016-99-99T03:04:06Z"));
140+
141+
EXPECT_TRUE(SetFlagValue("test_time_flag", "2016-01-02T03:04:05Z"));
142+
std::string current_flag_value;
143+
EXPECT_TRUE(GetFlagValue("test_time_flag", current_flag_value));
144+
EXPECT_EQ("2016-01-02T03:04:05+00:00", current_flag_value);
145+
}
146+
147+
} // namespace

0 commit comments

Comments
 (0)