1 /*
2 * Copyright (C) 2020 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "common/strings.h"
18
19 #include <bluetooth/log.h>
20 #include <gmock/gmock.h>
21 #include <gtest/gtest.h>
22
23 #include <array>
24 #include <memory>
25
26 namespace testing {
27
28 using bluetooth::common::BoolFromString;
29 using bluetooth::common::FromHexString;
30 using bluetooth::common::Int64FromString;
31 using bluetooth::common::StringFormat;
32 using bluetooth::common::StringFormatTime;
33 using bluetooth::common::StringFormatTimeWithMilliseconds;
34 using bluetooth::common::StringJoin;
35 using bluetooth::common::StringSplit;
36 using bluetooth::common::StringTrim;
37 using bluetooth::common::ToHexString;
38 using bluetooth::common::ToString;
39 using bluetooth::common::Uint64FromString;
40
is_arch32()41 static inline bool is_arch32() { return sizeof(long) == 4; }
is_arch64()42 static inline bool is_arch64() { return sizeof(long) == 8; }
43
44 #pragma clang diagnostic push
45 #pragma clang diagnostic ignored "-Winteger-overflow"
TEST(StringsTest,to_hex_string_from_number)46 TEST(StringsTest, to_hex_string_from_number) {
47 ASSERT_EQ(ToHexString(0), "0x00000000");
48 ASSERT_EQ(ToHexString(3), "0x00000003");
49 ASSERT_EQ(ToHexString(25), "0x00000019");
50 ASSERT_EQ(ToHexString(-25), "-0x00000019");
51 ASSERT_EQ(ToHexString(INT_MIN + 1), "-0x7fffffff");
52 ASSERT_EQ(ToHexString(INT_MAX), "0x7fffffff");
53 ASSERT_EQ(ToHexString(INT_MIN), "INT_MIN");
54 if (is_arch32()) {
55 ASSERT_EQ(ToHexString(1 + INT_MAX), "INT_MIN");
56 ASSERT_EQ(ToHexString(2 + INT_MAX), "-0x7fffffff"); // Rolled over
57 ASSERT_EQ(ToHexString(-1 - INT_MIN), "0x7fffffff"); // Rolled over
58 ASSERT_EQ(ToHexString(LONG_MAX), "0x7fffffff");
59 ASSERT_EQ(ToHexString(LONG_MAX - 1L), "0x7ffffffe");
60 ASSERT_EQ(ToHexString(LONG_MIN), "LONG_MIN");
61 ASSERT_EQ(ToHexString(LONG_MIN + 1L), "-0x7fffffff");
62 } else if (is_arch64()) {
63 ASSERT_EQ(ToHexString((signed long)INT_MIN), "-0x0000000080000000");
64 ASSERT_EQ(ToHexString(1 + INT_MAX), "INT_MIN"); // Rolled over
65 ASSERT_EQ(ToHexString(2 + INT_MAX), "-0x7fffffff"); // Rolled over
66 ASSERT_EQ(ToHexString(1L + INT_MAX), "0x0000000080000000");
67 ASSERT_EQ(ToHexString(2L + INT_MAX), "0x0000000080000001");
68 ASSERT_EQ(ToHexString(-1L + INT_MIN), "-0x0000000080000001");
69 ASSERT_EQ(ToHexString(LONG_MAX), "0x7fffffffffffffff");
70 ASSERT_EQ(ToHexString(LONG_MAX - 1L), "0x7ffffffffffffffe");
71 ASSERT_EQ(ToHexString(LONG_MIN), "LONG_MIN");
72 ASSERT_EQ(ToHexString(LONG_MIN + 1L), "-0x7fffffffffffffff");
73 } else {
74 bluetooth::log::error("Unknown architecture");
75 FAIL();
76 }
77 ASSERT_EQ(ToHexString('a'), "0x61");
78 }
79
TEST(StringsTest,to_hex_string_from_number_unsigned_int)80 TEST(StringsTest, to_hex_string_from_number_unsigned_int) {
81 ASSERT_EQ(ToHexString(0U), "0x00000000");
82 ASSERT_EQ(ToHexString(1U), "0x00000001");
83 ASSERT_EQ(ToHexString(3U), "0x00000003");
84 ASSERT_EQ(ToHexString(25U), "0x00000019");
85 ASSERT_EQ(ToHexString(UINT_MAX), "0xffffffff");
86 ASSERT_EQ(ToHexString(1U + UINT_MAX), "0x00000000"); // Rolled over
87 ASSERT_EQ(ToHexString(2U + UINT_MAX), "0x00000001"); // Rolled over
88 }
89 #pragma clang diagnostic pop
90
TEST(StringsTest,trim_string_test)91 TEST(StringsTest, trim_string_test) {
92 ASSERT_EQ(StringTrim(" aa bb"), "aa bb");
93 ASSERT_EQ(StringTrim("aa bb "), "aa bb");
94 ASSERT_EQ(StringTrim(" aa bb "), "aa bb");
95 ASSERT_EQ(StringTrim(" aa bb \n"), "aa bb");
96 ASSERT_EQ(StringTrim(" \raa bb\t \n"), "aa bb");
97 }
98
TEST(StringsTest,split_string_test)99 TEST(StringsTest, split_string_test) {
100 ASSERT_THAT(StringSplit("", ","), ElementsAre(""));
101 ASSERT_THAT(StringSplit("1,2,3", ","), ElementsAre("1", "2", "3"));
102 ASSERT_THAT(StringSplit("1,2,3", "!"), ElementsAre("1,2,3"));
103 ASSERT_THAT(StringSplit("1,2,3", ",", 2), ElementsAre("1", "2,3"));
104 ASSERT_THAT(StringSplit("a,b,", ","), ElementsAre("a", "b", ""));
105 ASSERT_THAT(StringSplit("ab,", ",", 2), ElementsAre("ab", ""));
106 ASSERT_THAT(StringSplit("ab,,", ",", 2), ElementsAre("ab", ","));
107 ASSERT_THAT(StringSplit("ab,,", ",", 1), ElementsAre("ab,,"));
108 ASSERT_THAT(StringSplit("1,,2,,3", ",,"), ElementsAre("1", "2", "3"));
109 ASSERT_THAT(StringSplit("1,,2,,3,,", ",,"), ElementsAre("1", "2", "3", ""));
110 ASSERT_THAT(StringSplit("1,,2,,3,,", ",,", 2), ElementsAre("1", "2,,3,,"));
111 ASSERT_THAT(StringSplit("1", ",,", 2), ElementsAre("1"));
112 ASSERT_DEATH({ StringSplit("1,2,3", ""); }, "delim cannot be empty");
113 }
114
TEST(StringsTest,join_string_test)115 TEST(StringsTest, join_string_test) {
116 ASSERT_THAT(StringJoin({{"1", "2", "3"}}, ","), StrEq("1,2,3"));
117 ASSERT_THAT(StringJoin({{}}, ","), StrEq(""));
118 ASSERT_THAT(StringJoin({{"1"}}, ","), StrEq("1"));
119 ASSERT_THAT(StringJoin({{"1", "2", "3"}}, ",,"), StrEq("1,,2,,3"));
120 ASSERT_THAT(StringJoin({{"1", ",", "3"}}, ",,"), StrEq("1,,,,,3"));
121 }
122
TEST(StringsTest,to_hex_string_test)123 TEST(StringsTest, to_hex_string_test) {
124 // normal
125 ASSERT_THAT(ToHexString({0x12, 0x34, 0x56, 0xab}), Eq("123456ab"));
126 // empty
127 ASSERT_THAT(ToHexString({}), Eq(""));
128 // unary
129 ASSERT_THAT(ToHexString({0x12}), Eq("12"));
130 // half
131 ASSERT_THAT(ToHexString({0x6, 0x5, 0x56, 0xb}), Eq("0605560b"));
132 // other types
133 std::array<uint8_t, 2> a = {0x12, 0x56};
134 ASSERT_THAT(ToHexString(a.begin(), a.end()), Eq("1256"));
135 std::vector<uint8_t> b = {0x34, 0x78};
136 ASSERT_THAT(ToHexString(b.begin(), b.end()), Eq("3478"));
137 }
138
TEST(StringsTest,from_hex_string_test)139 TEST(StringsTest, from_hex_string_test) {
140 // normal
141 ASSERT_THAT(FromHexString("aabbccdd1122"),
142 Optional(ElementsAre(0xaa, 0xbb, 0xcc, 0xdd, 0x11, 0x22)));
143 // empty
144 ASSERT_THAT(FromHexString(""), Optional(IsEmpty()));
145 // unary
146 ASSERT_THAT(FromHexString("aa"), Optional(ElementsAre(0xaa)));
147 // half
148 ASSERT_THAT(FromHexString("0605560b"), Optional(ElementsAre(0x6, 0x5, 0x56, 0xb)));
149 // upper case letter
150 ASSERT_THAT(FromHexString("AABBCC"), Optional(ElementsAre(0xaa, 0xbb, 0xcc)));
151 // upper and lower case letter mixed
152 ASSERT_THAT(FromHexString("aAbbCC"), Optional(ElementsAre(0xaa, 0xbb, 0xcc)));
153 // Error: odd length
154 ASSERT_FALSE(FromHexString("0605560"));
155 // Error: non hex char
156 ASSERT_FALSE(FromHexString("060u560b"));
157 }
158
TEST(StringsTest,int64_from_and_to_string_test)159 TEST(StringsTest, int64_from_and_to_string_test) {
160 ASSERT_THAT(Int64FromString("42"), Optional(Eq(int64_t(42))));
161 ASSERT_THAT(Int64FromString("-42"), Optional(Eq(int64_t(-42))));
162 ASSERT_THAT(Int64FromString("0"), Optional(Eq(int64_t(0))));
163 ASSERT_FALSE(Int64FromString(""));
164 // only base 10 is supported
165 ASSERT_FALSE(Int64FromString("0x42ab"));
166 ASSERT_FALSE(Int64FromString("-0x42"));
167 // floating point not supported
168 ASSERT_FALSE(Int64FromString("42.0"));
169 ASSERT_FALSE(Int64FromString("-42.0"));
170 ASSERT_FALSE(Int64FromString("42abc"));
171 ASSERT_FALSE(Int64FromString(""));
172 // INT32_MAX + 1
173 ASSERT_THAT(Int64FromString("2147483648"), Optional(Eq(int64_t(2147483648))));
174 ASSERT_THAT(ToString(int64_t(2147483648)), StrEq("2147483648"));
175 // INT32_MIN - 1
176 ASSERT_THAT(Int64FromString("-2147483649"), Optional(Eq(int64_t(-2147483649))));
177 ASSERT_THAT(ToString(int64_t(-2147483649)), StrEq("-2147483649"));
178 // INT64_MAX
179 ASSERT_THAT(Int64FromString("9223372036854775807"), Optional(Eq(int64_t(9223372036854775807))));
180 ASSERT_THAT(ToString(int64_t(9223372036854775807)), StrEq("9223372036854775807"));
181 // INT64_MAX+1
182 ASSERT_FALSE(Int64FromString("9223372036854775808"));
183 // INT64_MIN
184 ASSERT_THAT(Int64FromString("-9223372036854775808"),
185 Optional(Eq(int64_t(-9223372036854775807LL - 1))));
186 ASSERT_THAT(ToString(int64_t(-9223372036854775807LL - 1)), StrEq("-9223372036854775808"));
187 // INT64_MIN-1
188 ASSERT_FALSE(Int64FromString("-9223372036854775809"));
189 }
190
TEST(StringsTest,uint64_from_and_to_string_test)191 TEST(StringsTest, uint64_from_and_to_string_test) {
192 ASSERT_THAT(Uint64FromString("42"), Optional(Eq(uint64_t(42))));
193 ASSERT_THAT(Uint64FromString("0"), Optional(Eq(uint64_t(0))));
194 ASSERT_FALSE(Uint64FromString(""));
195 // only base 10 is supported
196 ASSERT_FALSE(Uint64FromString("0x42ab"));
197 // only positive number is supported
198 ASSERT_FALSE(Uint64FromString("-42"));
199 // floating point not supported
200 ASSERT_FALSE(Uint64FromString("42.0"));
201 ASSERT_FALSE(Uint64FromString("-42.0"));
202 ASSERT_FALSE(Uint64FromString("42abc"));
203 ASSERT_FALSE(Uint64FromString(""));
204 // UINT32_MAX + 1
205 ASSERT_THAT(Uint64FromString("4294967295"), Optional(Eq(uint64_t(4294967295))));
206 ASSERT_THAT(ToString(uint64_t(4294967295)), StrEq("4294967295"));
207 // UINT64_MAX
208 ASSERT_THAT(Uint64FromString("18446744073709551615"),
209 Optional(Eq(uint64_t(18446744073709551615ULL))));
210 ASSERT_THAT(ToString(uint64_t(18446744073709551615ULL)), StrEq("18446744073709551615"));
211 // UINT64_MAX+1
212 ASSERT_FALSE(Uint64FromString("18446744073709551616"));
213 }
214
TEST(StringsTest,bool_from_and_to_string_test)215 TEST(StringsTest, bool_from_and_to_string_test) {
216 ASSERT_THAT(BoolFromString("true"), Optional(IsTrue()));
217 ASSERT_THAT(BoolFromString("false"), Optional(IsFalse()));
218 ASSERT_FALSE(BoolFromString("abc"));
219 ASSERT_FALSE(BoolFromString("FALSE"));
220 ASSERT_FALSE(BoolFromString("TRUE"));
221 ASSERT_FALSE(BoolFromString(""));
222 ASSERT_THAT(ToString(true), StrEq("true"));
223 ASSERT_THAT(ToString(false), StrEq("false"));
224 }
225
TEST(StringsTest,string_format_test)226 TEST(StringsTest, string_format_test) {
227 ASSERT_THAT(StringFormat("%s", "hello"), StrEq("hello"));
228 ASSERT_THAT(StringFormat("%d", 42), StrEq("42"));
229 ASSERT_THAT(StringFormat("%s world", "hello"), StrEq("hello world"));
230 ASSERT_THAT(StringFormat("%d %.1f 0x%02x", 42, 43.123, 0x8), StrEq("42 43.1 0x08"));
231 }
232
TEST(StringsTest,string_format_time_test)233 TEST(StringsTest, string_format_time_test) {
234 std::string format("%Y-%m-%d %H:%M:%S");
235 time_t then = 123456789;
236 struct std::tm tm;
237 gmtime_r(&then, &tm);
238 ASSERT_THAT(StringFormatTime(format, tm), StrEq("1973-11-29 21:33:09"));
239 }
240
TEST(StringsTest,string_format_time_with_ms_in_the_beginning_test)241 TEST(StringsTest, string_format_time_with_ms_in_the_beginning_test) {
242 std::string format("%Y-%m-%d %H:%M:%S");
243 std::time_t from_time = 0;
244 std::chrono::time_point<std::chrono::system_clock> time_point =
245 std::chrono::system_clock::from_time_t(from_time);
246
247 ASSERT_THAT(StringFormatTimeWithMilliseconds(format, time_point, gmtime),
248 StrEq("1970-01-01 00:00:00.000"));
249 }
250
TEST(StringsTest,string_format_time_with_ms_test)251 TEST(StringsTest, string_format_time_with_ms_test) {
252 std::string format("%Y-%m-%d %H:%M:%S");
253 std::time_t from_time1 = 1234567890;
254 std::chrono::time_point<std::chrono::system_clock> time_point1 =
255 std::chrono::system_clock::from_time_t(from_time1);
256 std::time_t from_time2 = 1234567890;
257 std::chrono::time_point<std::chrono::system_clock> time_point2 =
258 std::chrono::system_clock::from_time_t(from_time2);
259
260 time_point2 += std::chrono::milliseconds(1);
261
262 ASSERT_THAT(StringFormatTimeWithMilliseconds(format, time_point1, gmtime),
263 StrEq("2009-02-13 23:31:30.000"));
264 ASSERT_THAT(StringFormatTimeWithMilliseconds(format, time_point2, gmtime),
265 StrEq("2009-02-13 23:31:30.001"));
266 }
267
268 class ExampleClass {};
operator <<(std::ostream & os,const ExampleClass &)269 static std::ostream& operator<<(std::ostream& os, const ExampleClass& /* obj */) {
270 os << "ExampleClass";
271 return os;
272 }
273
TEST(StringsTest,example_class_to_string_test)274 TEST(StringsTest, example_class_to_string_test) {
275 ExampleClass obj;
276 ASSERT_THAT(ToString(obj), StrEq("ExampleClass"));
277 }
278
279 } // namespace testing
280