1*61c4878aSAndroid Build Coastguard Worker // Copyright 2019 The Pigweed Authors
2*61c4878aSAndroid Build Coastguard Worker //
3*61c4878aSAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License"); you may not
4*61c4878aSAndroid Build Coastguard Worker // use this file except in compliance with the License. You may obtain a copy of
5*61c4878aSAndroid Build Coastguard Worker // the License at
6*61c4878aSAndroid Build Coastguard Worker //
7*61c4878aSAndroid Build Coastguard Worker // https://www.apache.org/licenses/LICENSE-2.0
8*61c4878aSAndroid Build Coastguard Worker //
9*61c4878aSAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software
10*61c4878aSAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11*61c4878aSAndroid Build Coastguard Worker // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12*61c4878aSAndroid Build Coastguard Worker // License for the specific language governing permissions and limitations under
13*61c4878aSAndroid Build Coastguard Worker // the License.
14*61c4878aSAndroid Build Coastguard Worker
15*61c4878aSAndroid Build Coastguard Worker #include "pw_string/to_string.h"
16*61c4878aSAndroid Build Coastguard Worker
17*61c4878aSAndroid Build Coastguard Worker #include <array>
18*61c4878aSAndroid Build Coastguard Worker #include <cinttypes>
19*61c4878aSAndroid Build Coastguard Worker #include <cmath>
20*61c4878aSAndroid Build Coastguard Worker #include <cstring>
21*61c4878aSAndroid Build Coastguard Worker #include <string>
22*61c4878aSAndroid Build Coastguard Worker
23*61c4878aSAndroid Build Coastguard Worker #include "pw_result/result.h"
24*61c4878aSAndroid Build Coastguard Worker #include "pw_span/span.h"
25*61c4878aSAndroid Build Coastguard Worker #include "pw_status/status.h"
26*61c4878aSAndroid Build Coastguard Worker #include "pw_string/internal/config.h"
27*61c4878aSAndroid Build Coastguard Worker #include "pw_string/type_to_string.h"
28*61c4878aSAndroid Build Coastguard Worker #include "pw_unit_test/framework.h"
29*61c4878aSAndroid Build Coastguard Worker
30*61c4878aSAndroid Build Coastguard Worker namespace pw {
31*61c4878aSAndroid Build Coastguard Worker
32*61c4878aSAndroid Build Coastguard Worker struct CustomType {
33*61c4878aSAndroid Build Coastguard Worker unsigned a;
34*61c4878aSAndroid Build Coastguard Worker unsigned b;
35*61c4878aSAndroid Build Coastguard Worker
36*61c4878aSAndroid Build Coastguard Worker static constexpr const char* kToString = "This is a CustomType";
37*61c4878aSAndroid Build Coastguard Worker
CustomTypepw::CustomType38*61c4878aSAndroid Build Coastguard Worker CustomType() : a(0), b(0) {}
39*61c4878aSAndroid Build Coastguard Worker
40*61c4878aSAndroid Build Coastguard Worker // Non-copyable to verify that ToString doesn't copy it.
41*61c4878aSAndroid Build Coastguard Worker CustomType(const CustomType&) = delete;
42*61c4878aSAndroid Build Coastguard Worker CustomType& operator=(const CustomType&) = delete;
43*61c4878aSAndroid Build Coastguard Worker };
44*61c4878aSAndroid Build Coastguard Worker
ToString(const CustomType &,span<char> buffer)45*61c4878aSAndroid Build Coastguard Worker StatusWithSize ToString(const CustomType&, span<char> buffer) {
46*61c4878aSAndroid Build Coastguard Worker int result =
47*61c4878aSAndroid Build Coastguard Worker std::snprintf(buffer.data(), buffer.size(), CustomType::kToString);
48*61c4878aSAndroid Build Coastguard Worker if (result < 0) {
49*61c4878aSAndroid Build Coastguard Worker return StatusWithSize::Unknown();
50*61c4878aSAndroid Build Coastguard Worker }
51*61c4878aSAndroid Build Coastguard Worker if (static_cast<size_t>(result) < buffer.size()) {
52*61c4878aSAndroid Build Coastguard Worker return StatusWithSize(result);
53*61c4878aSAndroid Build Coastguard Worker }
54*61c4878aSAndroid Build Coastguard Worker return StatusWithSize::ResourceExhausted(buffer.empty() ? 0u
55*61c4878aSAndroid Build Coastguard Worker : buffer.size() - 1);
56*61c4878aSAndroid Build Coastguard Worker }
57*61c4878aSAndroid Build Coastguard Worker
58*61c4878aSAndroid Build Coastguard Worker namespace {
59*61c4878aSAndroid Build Coastguard Worker
60*61c4878aSAndroid Build Coastguard Worker char buffer[128] = {};
61*61c4878aSAndroid Build Coastguard Worker char expected[128] = {};
62*61c4878aSAndroid Build Coastguard Worker
TEST(ToString,Bool)63*61c4878aSAndroid Build Coastguard Worker TEST(ToString, Bool) {
64*61c4878aSAndroid Build Coastguard Worker const volatile bool b = true;
65*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(4u, ToString(b, buffer).size());
66*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ("true", buffer);
67*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(5u, ToString(false, buffer).size());
68*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ("false", buffer);
69*61c4878aSAndroid Build Coastguard Worker }
70*61c4878aSAndroid Build Coastguard Worker
TEST(ToString,Char)71*61c4878aSAndroid Build Coastguard Worker TEST(ToString, Char) {
72*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(1u, ToString('%', buffer).size());
73*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ("%", buffer);
74*61c4878aSAndroid Build Coastguard Worker }
75*61c4878aSAndroid Build Coastguard Worker
76*61c4878aSAndroid Build Coastguard Worker template <typename T>
77*61c4878aSAndroid Build Coastguard Worker constexpr T kInteger = 127;
78*61c4878aSAndroid Build Coastguard Worker
TEST(ToString,Integer_AllTypesAreSupported)79*61c4878aSAndroid Build Coastguard Worker TEST(ToString, Integer_AllTypesAreSupported) {
80*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(3u, ToString(kInteger<unsigned char>, buffer).size());
81*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ("127", buffer);
82*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(3u, ToString(kInteger<signed char>, buffer).size());
83*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ("127", buffer);
84*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(3u, ToString(kInteger<unsigned short>, buffer).size());
85*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ("127", buffer);
86*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(3u, ToString(kInteger<signed short>, buffer).size());
87*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ("127", buffer);
88*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(3u, ToString(kInteger<unsigned int>, buffer).size());
89*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ("127", buffer);
90*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(3u, ToString(kInteger<signed int>, buffer).size());
91*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ("127", buffer);
92*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(3u, ToString(kInteger<unsigned long>, buffer).size());
93*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ("127", buffer);
94*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(3u, ToString(kInteger<signed long>, buffer).size());
95*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ("127", buffer);
96*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(3u, ToString(kInteger<unsigned long long>, buffer).size());
97*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ("127", buffer);
98*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(3u, ToString(kInteger<signed long long>, buffer).size());
99*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ("127", buffer);
100*61c4878aSAndroid Build Coastguard Worker }
101*61c4878aSAndroid Build Coastguard Worker
TEST(ToString,ScopedEnum)102*61c4878aSAndroid Build Coastguard Worker TEST(ToString, ScopedEnum) {
103*61c4878aSAndroid Build Coastguard Worker enum class MyEnum : short { kLuckyNumber = 8 };
104*61c4878aSAndroid Build Coastguard Worker
105*61c4878aSAndroid Build Coastguard Worker auto result = ToString(MyEnum::kLuckyNumber, buffer);
106*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(1u, result.size());
107*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(OkStatus(), result.status());
108*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ("8", buffer);
109*61c4878aSAndroid Build Coastguard Worker }
110*61c4878aSAndroid Build Coastguard Worker
TEST(ToString,Integer_EmptyBuffer_WritesNothing)111*61c4878aSAndroid Build Coastguard Worker TEST(ToString, Integer_EmptyBuffer_WritesNothing) {
112*61c4878aSAndroid Build Coastguard Worker auto result = ToString(-1234, span(buffer, 0));
113*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(0u, result.size());
114*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(Status::ResourceExhausted(), result.status());
115*61c4878aSAndroid Build Coastguard Worker }
116*61c4878aSAndroid Build Coastguard Worker
TEST(ToString,Integer_BufferTooSmall_WritesNullTerminator)117*61c4878aSAndroid Build Coastguard Worker TEST(ToString, Integer_BufferTooSmall_WritesNullTerminator) {
118*61c4878aSAndroid Build Coastguard Worker auto result = ToString(-1234, span(buffer, 5));
119*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(0u, result.size());
120*61c4878aSAndroid Build Coastguard Worker EXPECT_FALSE(result.ok());
121*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ("", buffer);
122*61c4878aSAndroid Build Coastguard Worker }
123*61c4878aSAndroid Build Coastguard Worker
TEST(ToString,Float)124*61c4878aSAndroid Build Coastguard Worker TEST(ToString, Float) {
125*61c4878aSAndroid Build Coastguard Worker if (string::internal::config::kEnableDecimalFloatExpansion) {
126*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(5u, ToString(0.0f, buffer).size());
127*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ("0.000", buffer);
128*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(6u, ToString(33.444f, buffer).size());
129*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ("33.444", buffer);
130*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(3u, ToString(INFINITY, buffer).size());
131*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ("inf", buffer);
132*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(3u, ToString(NAN, buffer).size());
133*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ("nan", buffer);
134*61c4878aSAndroid Build Coastguard Worker } else {
135*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(1u, ToString(0.0f, buffer).size());
136*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ("0", buffer);
137*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(3u, ToString(INFINITY, buffer).size());
138*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ("inf", buffer);
139*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(4u, ToString(-NAN, buffer).size());
140*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ("-NaN", buffer);
141*61c4878aSAndroid Build Coastguard Worker }
142*61c4878aSAndroid Build Coastguard Worker }
143*61c4878aSAndroid Build Coastguard Worker
TEST(ToString,Pointer_NonNull_WritesValue)144*61c4878aSAndroid Build Coastguard Worker TEST(ToString, Pointer_NonNull_WritesValue) {
145*61c4878aSAndroid Build Coastguard Worker CustomType custom;
146*61c4878aSAndroid Build Coastguard Worker const size_t length =
147*61c4878aSAndroid Build Coastguard Worker static_cast<size_t>(std::snprintf(expected,
148*61c4878aSAndroid Build Coastguard Worker sizeof(expected),
149*61c4878aSAndroid Build Coastguard Worker "%" PRIxPTR,
150*61c4878aSAndroid Build Coastguard Worker reinterpret_cast<intptr_t>(&custom)));
151*61c4878aSAndroid Build Coastguard Worker
152*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(length, ToString(&custom, buffer).size());
153*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ(expected, buffer);
154*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(length, ToString(static_cast<void*>(&custom), buffer).size());
155*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ(expected, buffer);
156*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(1u, ToString(reinterpret_cast<int*>(4), buffer).size());
157*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ("4", buffer);
158*61c4878aSAndroid Build Coastguard Worker }
159*61c4878aSAndroid Build Coastguard Worker
TEST(ToString,Pointer_Nullptr_WritesNull)160*61c4878aSAndroid Build Coastguard Worker TEST(ToString, Pointer_Nullptr_WritesNull) {
161*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(string::kNullPointerString.size(),
162*61c4878aSAndroid Build Coastguard Worker ToString(nullptr, buffer).size());
163*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(string::kNullPointerString, buffer);
164*61c4878aSAndroid Build Coastguard Worker }
165*61c4878aSAndroid Build Coastguard Worker
TEST(ToString,Pointer_NullValuedPointer_WritesNull)166*61c4878aSAndroid Build Coastguard Worker TEST(ToString, Pointer_NullValuedPointer_WritesNull) {
167*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(string::kNullPointerString.size(),
168*61c4878aSAndroid Build Coastguard Worker ToString(static_cast<const CustomType*>(nullptr), buffer).size());
169*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(string::kNullPointerString, buffer);
170*61c4878aSAndroid Build Coastguard Worker }
171*61c4878aSAndroid Build Coastguard Worker
TEST(ToString,Pointer_NullValuedCString_WritesNull)172*61c4878aSAndroid Build Coastguard Worker TEST(ToString, Pointer_NullValuedCString_WritesNull) {
173*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(string::kNullPointerString.size(),
174*61c4878aSAndroid Build Coastguard Worker ToString(static_cast<char*>(nullptr), buffer).size());
175*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(string::kNullPointerString, buffer);
176*61c4878aSAndroid Build Coastguard Worker
177*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(string::kNullPointerString.size(),
178*61c4878aSAndroid Build Coastguard Worker ToString(static_cast<const char*>(nullptr), buffer).size());
179*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(string::kNullPointerString, buffer);
180*61c4878aSAndroid Build Coastguard Worker }
181*61c4878aSAndroid Build Coastguard Worker
TEST(ToString,String_Literal)182*61c4878aSAndroid Build Coastguard Worker TEST(ToString, String_Literal) {
183*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(0u, ToString("", buffer).size());
184*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ("", buffer);
185*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(5u, ToString("hello", buffer).size());
186*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ("hello", buffer);
187*61c4878aSAndroid Build Coastguard Worker }
188*61c4878aSAndroid Build Coastguard Worker
TEST(ToString,String_Pointer)189*61c4878aSAndroid Build Coastguard Worker TEST(ToString, String_Pointer) {
190*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(0u, ToString(static_cast<const char*>(""), buffer).size());
191*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ("", buffer);
192*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(5u, ToString(static_cast<const char*>("hello"), buffer).size());
193*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ("hello", buffer);
194*61c4878aSAndroid Build Coastguard Worker }
195*61c4878aSAndroid Build Coastguard Worker
TEST(ToString,String_MutableBuffer)196*61c4878aSAndroid Build Coastguard Worker TEST(ToString, String_MutableBuffer) {
197*61c4878aSAndroid Build Coastguard Worker char chars[] = {'C', 'o', 'o', 'l', '\0'};
198*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(sizeof(chars) - 1, ToString(chars, buffer).size());
199*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ("Cool", buffer);
200*61c4878aSAndroid Build Coastguard Worker }
201*61c4878aSAndroid Build Coastguard Worker
TEST(ToString,String_MutablePointer)202*61c4878aSAndroid Build Coastguard Worker TEST(ToString, String_MutablePointer) {
203*61c4878aSAndroid Build Coastguard Worker char chars[] = {'b', 'o', 'o', 'l', '\0'};
204*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(sizeof(chars) - 1,
205*61c4878aSAndroid Build Coastguard Worker ToString(static_cast<char*>(chars), buffer).size());
206*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ("bool", buffer);
207*61c4878aSAndroid Build Coastguard Worker }
208*61c4878aSAndroid Build Coastguard Worker
TEST(ToString,Object)209*61c4878aSAndroid Build Coastguard Worker TEST(ToString, Object) {
210*61c4878aSAndroid Build Coastguard Worker CustomType custom;
211*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(std::strlen(CustomType::kToString),
212*61c4878aSAndroid Build Coastguard Worker ToString(custom, buffer).size());
213*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ(CustomType::kToString, buffer);
214*61c4878aSAndroid Build Coastguard Worker }
215*61c4878aSAndroid Build Coastguard Worker
216*61c4878aSAndroid Build Coastguard Worker enum Foo : uint8_t {
217*61c4878aSAndroid Build Coastguard Worker BAR = 32,
218*61c4878aSAndroid Build Coastguard Worker BAZ = 100,
219*61c4878aSAndroid Build Coastguard Worker };
220*61c4878aSAndroid Build Coastguard Worker
TEST(ToString,Enum)221*61c4878aSAndroid Build Coastguard Worker TEST(ToString, Enum) {
222*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(2u, ToString(Foo::BAR, buffer).size());
223*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ("32", buffer);
224*61c4878aSAndroid Build Coastguard Worker
225*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(3u, ToString(Foo::BAZ, buffer).size());
226*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ("100", buffer);
227*61c4878aSAndroid Build Coastguard Worker }
228*61c4878aSAndroid Build Coastguard Worker
TEST(ToString,Status)229*61c4878aSAndroid Build Coastguard Worker TEST(ToString, Status) {
230*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(2u, ToString(Status(), buffer).size());
231*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ(Status().str(), buffer);
232*61c4878aSAndroid Build Coastguard Worker }
233*61c4878aSAndroid Build Coastguard Worker
TEST(ToString,StatusCode)234*61c4878aSAndroid Build Coastguard Worker TEST(ToString, StatusCode) {
235*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(sizeof("UNAVAILABLE") - 1,
236*61c4878aSAndroid Build Coastguard Worker ToString(Status::Unavailable(), buffer).size());
237*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ("UNAVAILABLE", buffer);
238*61c4878aSAndroid Build Coastguard Worker }
239*61c4878aSAndroid Build Coastguard Worker
TEST(ToString,StdArrayAsBuffer)240*61c4878aSAndroid Build Coastguard Worker TEST(ToString, StdArrayAsBuffer) {
241*61c4878aSAndroid Build Coastguard Worker std::array<char, 128> test_buffer;
242*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(5u, ToString(false, test_buffer).size());
243*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ("false", test_buffer.data());
244*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(2u, ToString("Hi", test_buffer).size());
245*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ("Hi", test_buffer.data());
246*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(string::kNullPointerString.size(),
247*61c4878aSAndroid Build Coastguard Worker ToString(static_cast<void*>(nullptr), test_buffer).size());
248*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(string::kNullPointerString, test_buffer.data());
249*61c4878aSAndroid Build Coastguard Worker }
250*61c4878aSAndroid Build Coastguard Worker
TEST(ToString,StringView)251*61c4878aSAndroid Build Coastguard Worker TEST(ToString, StringView) {
252*61c4878aSAndroid Build Coastguard Worker std::string_view view = "cool";
253*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(4u, ToString(view, buffer).size());
254*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ("cool", buffer);
255*61c4878aSAndroid Build Coastguard Worker }
256*61c4878aSAndroid Build Coastguard Worker
TEST(ToString,StringView_TooSmall_Truncates)257*61c4878aSAndroid Build Coastguard Worker TEST(ToString, StringView_TooSmall_Truncates) {
258*61c4878aSAndroid Build Coastguard Worker std::string_view view = "kale!";
259*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(3u, ToString(view, span(buffer, 4)).size());
260*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ("kal", buffer);
261*61c4878aSAndroid Build Coastguard Worker }
262*61c4878aSAndroid Build Coastguard Worker
TEST(ToString,StringView_EmptyBuffer_WritesNothing)263*61c4878aSAndroid Build Coastguard Worker TEST(ToString, StringView_EmptyBuffer_WritesNothing) {
264*61c4878aSAndroid Build Coastguard Worker constexpr char kOriginal[] = {'@', '#', '$', '%'};
265*61c4878aSAndroid Build Coastguard Worker char test_buffer[sizeof(kOriginal)];
266*61c4878aSAndroid Build Coastguard Worker std::memcpy(test_buffer, kOriginal, sizeof(kOriginal));
267*61c4878aSAndroid Build Coastguard Worker
268*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(0u,
269*61c4878aSAndroid Build Coastguard Worker ToString(std::string_view("Hello!"), span(test_buffer, 0)).size());
270*61c4878aSAndroid Build Coastguard Worker ASSERT_EQ(0, std::memcmp(kOriginal, test_buffer, sizeof(kOriginal)));
271*61c4878aSAndroid Build Coastguard Worker }
272*61c4878aSAndroid Build Coastguard Worker
TEST(ToString,StdString)273*61c4878aSAndroid Build Coastguard Worker TEST(ToString, StdString) {
274*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(5u, ToString(std::string("Whoa!"), buffer).size());
275*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ("Whoa!", buffer);
276*61c4878aSAndroid Build Coastguard Worker
277*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(0u, ToString(std::string(), buffer).size());
278*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ("", buffer);
279*61c4878aSAndroid Build Coastguard Worker }
280*61c4878aSAndroid Build Coastguard Worker
TEST(ToString,StdNullopt)281*61c4878aSAndroid Build Coastguard Worker TEST(ToString, StdNullopt) {
282*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(12u, ToString(std::nullopt, buffer).size());
283*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ("std::nullopt", buffer);
284*61c4878aSAndroid Build Coastguard Worker }
285*61c4878aSAndroid Build Coastguard Worker
TEST(ToString,StdOptionalWithoutValue)286*61c4878aSAndroid Build Coastguard Worker TEST(ToString, StdOptionalWithoutValue) {
287*61c4878aSAndroid Build Coastguard Worker std::optional<uint16_t> v = std::nullopt;
288*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(12u, ToString(v, buffer).size());
289*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ("std::nullopt", buffer);
290*61c4878aSAndroid Build Coastguard Worker }
291*61c4878aSAndroid Build Coastguard Worker
TEST(ToString,StdOptionalWithValue)292*61c4878aSAndroid Build Coastguard Worker TEST(ToString, StdOptionalWithValue) {
293*61c4878aSAndroid Build Coastguard Worker std::optional<uint16_t> v = 5;
294*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(1u, ToString(v, buffer).size());
295*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ("5", buffer);
296*61c4878aSAndroid Build Coastguard Worker }
297*61c4878aSAndroid Build Coastguard Worker
TEST(ToString,ResultWithNonOkStatus)298*61c4878aSAndroid Build Coastguard Worker TEST(ToString, ResultWithNonOkStatus) {
299*61c4878aSAndroid Build Coastguard Worker Result<int> v = Status::ResourceExhausted();
300*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(18u, ToString(v, buffer).size());
301*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ("RESOURCE_EXHAUSTED", buffer);
302*61c4878aSAndroid Build Coastguard Worker }
303*61c4878aSAndroid Build Coastguard Worker
TEST(ToString,ResultWithValue)304*61c4878aSAndroid Build Coastguard Worker TEST(ToString, ResultWithValue) {
305*61c4878aSAndroid Build Coastguard Worker Result<int> v = 27;
306*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(6u, ToString(v, buffer).size());
307*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ("Ok(27)", buffer);
308*61c4878aSAndroid Build Coastguard Worker }
309*61c4878aSAndroid Build Coastguard Worker
TEST(ToString,EmptyArrayUsesIterableFormat)310*61c4878aSAndroid Build Coastguard Worker TEST(ToString, EmptyArrayUsesIterableFormat) {
311*61c4878aSAndroid Build Coastguard Worker std::array<int, 0> v = {};
312*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(2u, ToString(v, buffer).size());
313*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ("[]", buffer);
314*61c4878aSAndroid Build Coastguard Worker }
315*61c4878aSAndroid Build Coastguard Worker
TEST(ToString,ArrayUsesIterableFormat)316*61c4878aSAndroid Build Coastguard Worker TEST(ToString, ArrayUsesIterableFormat) {
317*61c4878aSAndroid Build Coastguard Worker std::array<int, 3> v = {1, 2, 3};
318*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(9u, ToString(v, buffer).size());
319*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ("[1, 2, 3]", buffer);
320*61c4878aSAndroid Build Coastguard Worker }
321*61c4878aSAndroid Build Coastguard Worker
TEST(ToString,SpanUsesIterableFormat)322*61c4878aSAndroid Build Coastguard Worker TEST(ToString, SpanUsesIterableFormat) {
323*61c4878aSAndroid Build Coastguard Worker std::array<int, 3> arr = {1, 2, 3};
324*61c4878aSAndroid Build Coastguard Worker span v(arr);
325*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(9u, ToString(v, buffer).size());
326*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ("[1, 2, 3]", buffer);
327*61c4878aSAndroid Build Coastguard Worker }
328*61c4878aSAndroid Build Coastguard Worker
TEST(ToString,ArrayOfStringsUsesIterableFormat)329*61c4878aSAndroid Build Coastguard Worker TEST(ToString, ArrayOfStringsUsesIterableFormat) {
330*61c4878aSAndroid Build Coastguard Worker std::array<const char*, 3> v({"foo", "bar", "baz"});
331*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(15u, ToString(v, buffer).size());
332*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ("[foo, bar, baz]", buffer);
333*61c4878aSAndroid Build Coastguard Worker }
334*61c4878aSAndroid Build Coastguard Worker
TEST(ToString,TimeVerySmallEndsInNsOrUnrepresentable)335*61c4878aSAndroid Build Coastguard Worker TEST(ToString, TimeVerySmallEndsInNsOrUnrepresentable) {
336*61c4878aSAndroid Build Coastguard Worker size_t size =
337*61c4878aSAndroid Build Coastguard Worker ToString(std::chrono::system_clock::time_point::min(), buffer).size();
338*61c4878aSAndroid Build Coastguard Worker ASSERT_GE(size, 3u);
339*61c4878aSAndroid Build Coastguard Worker if (std::strcmp("ns", &buffer[size - 2]) != 0) {
340*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ("An unrepresentably long time ago (>292 years).", buffer);
341*61c4878aSAndroid Build Coastguard Worker }
342*61c4878aSAndroid Build Coastguard Worker }
343*61c4878aSAndroid Build Coastguard Worker
TEST(ToString,TimeVeryBigEndsInNsOrUnrepresentable)344*61c4878aSAndroid Build Coastguard Worker TEST(ToString, TimeVeryBigEndsInNsOrUnrepresentable) {
345*61c4878aSAndroid Build Coastguard Worker size_t size =
346*61c4878aSAndroid Build Coastguard Worker ToString(std::chrono::system_clock::time_point::max(), buffer).size();
347*61c4878aSAndroid Build Coastguard Worker ASSERT_GE(size, 3u);
348*61c4878aSAndroid Build Coastguard Worker if (std::strcmp("ns", &buffer[size - 2]) != 0) {
349*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ("An unrepresentably long time in the future (>292 years).",
350*61c4878aSAndroid Build Coastguard Worker buffer);
351*61c4878aSAndroid Build Coastguard Worker }
352*61c4878aSAndroid Build Coastguard Worker }
353*61c4878aSAndroid Build Coastguard Worker
TEST(ToString,TimeJustRight)354*61c4878aSAndroid Build Coastguard Worker TEST(ToString, TimeJustRight) {
355*61c4878aSAndroid Build Coastguard Worker EXPECT_TRUE(ToString(std::chrono::system_clock::time_point(), buffer).ok());
356*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ("0ns", buffer);
357*61c4878aSAndroid Build Coastguard Worker }
358*61c4878aSAndroid Build Coastguard Worker
359*61c4878aSAndroid Build Coastguard Worker int64_t sensor_clock_tick_count;
360*61c4878aSAndroid Build Coastguard Worker
361*61c4878aSAndroid Build Coastguard Worker struct SensorClock {
362*61c4878aSAndroid Build Coastguard Worker using rep = int64_t;
363*61c4878aSAndroid Build Coastguard Worker using period = std::ratio<1, 32768>;
364*61c4878aSAndroid Build Coastguard Worker using duration = std::chrono::duration<rep, period>;
365*61c4878aSAndroid Build Coastguard Worker using time_point = std::chrono::time_point<SensorClock>;
nowpw::__anon3f2f52730111::SensorClock366*61c4878aSAndroid Build Coastguard Worker static time_point now() noexcept {
367*61c4878aSAndroid Build Coastguard Worker return time_point(duration(sensor_clock_tick_count));
368*61c4878aSAndroid Build Coastguard Worker }
369*61c4878aSAndroid Build Coastguard Worker };
370*61c4878aSAndroid Build Coastguard Worker
TEST(ToString,TimeSensorClockZero)371*61c4878aSAndroid Build Coastguard Worker TEST(ToString, TimeSensorClockZero) {
372*61c4878aSAndroid Build Coastguard Worker sensor_clock_tick_count = 0;
373*61c4878aSAndroid Build Coastguard Worker EXPECT_TRUE(ToString(SensorClock::now(), buffer).ok());
374*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ("0ns", buffer);
375*61c4878aSAndroid Build Coastguard Worker }
376*61c4878aSAndroid Build Coastguard Worker
TEST(ToString,TimeSensorClockMax)377*61c4878aSAndroid Build Coastguard Worker TEST(ToString, TimeSensorClockMax) {
378*61c4878aSAndroid Build Coastguard Worker sensor_clock_tick_count = std::numeric_limits<int64_t>::max();
379*61c4878aSAndroid Build Coastguard Worker EXPECT_TRUE(ToString(SensorClock::now(), buffer).ok());
380*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ("An unrepresentably long time in the future (>292 years).",
381*61c4878aSAndroid Build Coastguard Worker buffer);
382*61c4878aSAndroid Build Coastguard Worker }
383*61c4878aSAndroid Build Coastguard Worker
TEST(ToString,TimeSensorClockMin)384*61c4878aSAndroid Build Coastguard Worker TEST(ToString, TimeSensorClockMin) {
385*61c4878aSAndroid Build Coastguard Worker sensor_clock_tick_count = std::numeric_limits<int64_t>::min();
386*61c4878aSAndroid Build Coastguard Worker EXPECT_TRUE(ToString(SensorClock::now(), buffer).ok());
387*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ("An unrepresentably long time ago (>292 years).", buffer);
388*61c4878aSAndroid Build Coastguard Worker }
389*61c4878aSAndroid Build Coastguard Worker
TEST(ToString,DurationEndsInNs)390*61c4878aSAndroid Build Coastguard Worker TEST(ToString, DurationEndsInNs) {
391*61c4878aSAndroid Build Coastguard Worker EXPECT_TRUE(ToString(std::chrono::nanoseconds::zero(), buffer).ok());
392*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ("0ns", buffer);
393*61c4878aSAndroid Build Coastguard Worker }
394*61c4878aSAndroid Build Coastguard Worker
395*61c4878aSAndroid Build Coastguard Worker } // namespace
396*61c4878aSAndroid Build Coastguard Worker } // namespace pw
397