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