• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2019 The Pigweed Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not
4 // use this file except in compliance with the License. You may obtain a copy of
5 // 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, WITHOUT
11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 // License for the specific language governing permissions and limitations under
13 // the License.
14 
15 #include "pw_string/type_to_string.h"
16 
17 #include <cmath>
18 #include <cstring>
19 #include <limits>
20 #include <string_view>
21 
22 #include "pw_unit_test/framework.h"
23 
24 namespace pw::string {
25 namespace {
26 
TEST(Digits,DecimalDigits_AllOneDigit)27 TEST(Digits, DecimalDigits_AllOneDigit) {
28   for (uint64_t i = 0; i < 10; ++i) {
29     ASSERT_EQ(1u, DecimalDigitCount(i));
30   }
31 }
32 
TEST(Digits,DecimalDigits_AllTwoDigit)33 TEST(Digits, DecimalDigits_AllTwoDigit) {
34   for (uint64_t i = 10; i < 100u; ++i) {
35     ASSERT_EQ(2u, DecimalDigitCount(i));
36   }
37 }
38 
TEST(Digits,DecimalDigits_1To19Digits)39 TEST(Digits, DecimalDigits_1To19Digits) {
40   uint64_t value = 1;
41   for (unsigned digits = 1; digits <= 19u; ++digits) {
42     ASSERT_EQ(digits, DecimalDigitCount(value));
43     ASSERT_EQ(digits, DecimalDigitCount(value + 1));
44 
45     value *= 10;
46     ASSERT_EQ(digits, DecimalDigitCount(value - 1));
47   }
48 }
49 
TEST(Digits,DecimalDigits_20)50 TEST(Digits, DecimalDigits_20) {
51   for (uint64_t i : {
52            10'000'000'000'000'000'000llu,
53            10'000'000'000'000'000'001llu,
54            std::numeric_limits<unsigned long long>::max(),
55        }) {
56     ASSERT_EQ(20u, DecimalDigitCount(i));
57   }
58 }
59 
TEST(Digits,HexDigits_AllOneDigit)60 TEST(Digits, HexDigits_AllOneDigit) {
61   for (uint64_t i = 0; i < 0x10; ++i) {
62     ASSERT_EQ(1u, HexDigitCount(i));
63   }
64 }
65 
TEST(Digits,HexDigits_AllTwoDigit)66 TEST(Digits, HexDigits_AllTwoDigit) {
67   for (uint64_t i = 0x10; i < 0x100u; ++i) {
68     ASSERT_EQ(2u, HexDigitCount(i));
69   }
70 }
71 
TEST(Digits,HexDigits_1To15Digits)72 TEST(Digits, HexDigits_1To15Digits) {
73   uint64_t value = 1;
74   for (unsigned digits = 1; digits <= 15u; ++digits) {
75     ASSERT_EQ(digits, HexDigitCount(value));
76     ASSERT_EQ(digits, HexDigitCount(value + 1));
77 
78     value *= 0x10;
79     ASSERT_EQ(digits, HexDigitCount(value - 1));
80   }
81 }
82 
TEST(Digits,HexDigits_16)83 TEST(Digits, HexDigits_16) {
84   for (uint64_t i : {
85            0x1000000000000000llu,
86            0x1000000000000001llu,
87            std::numeric_limits<unsigned long long>::max(),
88        }) {
89     ASSERT_EQ(16u, HexDigitCount(i));
90   }
91 }
92 
93 constexpr char kStartingString[] = "!@#$%^&*()!@#$%^&*()";
94 constexpr char kUint64Max[] = "18446744073709551615";
95 constexpr char kInt64Min[] = "-9223372036854775808";
96 constexpr char kInt64Max[] = "9223372036854775807";
97 
98 class TestWithBuffer : public ::testing::Test {
99  protected:
100   static_assert(sizeof(kStartingString) == sizeof(kUint64Max));
101 
TestWithBuffer()102   TestWithBuffer() { std::memcpy(buffer_, kStartingString, sizeof(buffer_)); }
103 
104   char buffer_[sizeof(kUint64Max)];
105 };
106 
__anon728579940202null107 static_assert([] {
108   char buffer[sizeof(kUint64Max)] = {};
109   auto result = IntToString(std::numeric_limits<uint64_t>::max(), buffer);
110   return result.ok() && std::string_view(buffer, result.size()) == kUint64Max;
111 }());
112 
__anon728579940302null113 static_assert([] {
114   char buffer[sizeof(kInt64Min)] = {};
115   auto result = IntToString(std::numeric_limits<int64_t>::min(), buffer);
116   return result.ok() && std::string_view(buffer, result.size()) == kInt64Min;
117 }());
118 
119 class IntToStringTest : public TestWithBuffer {};
120 
TEST_F(IntToStringTest,Unsigned_EmptyBuffer_WritesNothing)121 TEST_F(IntToStringTest, Unsigned_EmptyBuffer_WritesNothing) {
122   auto result = IntToString(9u, span(buffer_, 0));
123   EXPECT_EQ(0u, result.size());
124   EXPECT_FALSE(result.ok());
125   EXPECT_STREQ(kStartingString, buffer_);
126 }
127 
TEST_F(IntToStringTest,Unsigned_TooSmall_1Char_OnlyNullTerminates)128 TEST_F(IntToStringTest, Unsigned_TooSmall_1Char_OnlyNullTerminates) {
129   auto result = IntToString(9u, span(buffer_, 1));
130   EXPECT_EQ(0u, result.size());
131   EXPECT_FALSE(result.ok());
132   EXPECT_STREQ("", buffer_);
133 }
134 
TEST_F(IntToStringTest,Unsigned_TooSmall_2Chars_OnlyNullTerminates)135 TEST_F(IntToStringTest, Unsigned_TooSmall_2Chars_OnlyNullTerminates) {
136   auto result = IntToString(10u, span(buffer_, 2));
137   EXPECT_EQ(0u, result.size());
138   EXPECT_FALSE(result.ok());
139   EXPECT_STREQ("", buffer_);
140 }
141 
TEST_F(IntToStringTest,Unsigned_TooSmall_3Chars_OnlyNullTerminates)142 TEST_F(IntToStringTest, Unsigned_TooSmall_3Chars_OnlyNullTerminates) {
143   auto result = IntToString(123u, span(buffer_, 3));
144   EXPECT_EQ(0u, result.size());
145   EXPECT_FALSE(result.ok());
146   EXPECT_STREQ("", buffer_);
147 }
148 
TEST_F(IntToStringTest,Unsigned_1Char_FitsExactly)149 TEST_F(IntToStringTest, Unsigned_1Char_FitsExactly) {
150   auto result = IntToString(0u, span(buffer_, 2));
151   EXPECT_EQ(1u, result.size());
152   EXPECT_TRUE(result.ok());
153   EXPECT_STREQ("0", buffer_);
154 
155   result = IntToString(9u, span(buffer_, 2));
156   EXPECT_EQ(1u, result.size());
157   EXPECT_TRUE(result.ok());
158   EXPECT_STREQ("9", buffer_);
159 }
160 
TEST_F(IntToStringTest,Unsigned_2Chars_FitsExactly)161 TEST_F(IntToStringTest, Unsigned_2Chars_FitsExactly) {
162   auto result = IntToString(10u, span(buffer_, 3));
163   EXPECT_EQ(2u, result.size());
164   EXPECT_STREQ("10", buffer_);
165 }
166 
TEST_F(IntToStringTest,Unsigned_MaxFitsExactly)167 TEST_F(IntToStringTest, Unsigned_MaxFitsExactly) {
168   EXPECT_EQ(20u,
169             IntToString(std::numeric_limits<uint64_t>::max(),
170                         span(buffer_, sizeof(kUint64Max)))
171                 .size());
172   EXPECT_STREQ(kUint64Max, buffer_);
173 }
174 
TEST_F(IntToStringTest,SignedPositive_EmptyBuffer_WritesNothing)175 TEST_F(IntToStringTest, SignedPositive_EmptyBuffer_WritesNothing) {
176   auto result = IntToString(9, span(buffer_, 0));
177   EXPECT_EQ(0u, result.size());
178   EXPECT_FALSE(result.ok());
179   EXPECT_STREQ(kStartingString, buffer_);
180 }
181 
TEST_F(IntToStringTest,SignedPositive_TooSmall_NullTerminates)182 TEST_F(IntToStringTest, SignedPositive_TooSmall_NullTerminates) {
183   auto result = IntToString(9, span(buffer_, 1));
184   EXPECT_EQ(0u, result.size());
185   EXPECT_FALSE(result.ok());
186   EXPECT_STREQ("", buffer_);
187 }
188 
TEST_F(IntToStringTest,SignedPositive_TooSmall_DoesNotWritePastEnd)189 TEST_F(IntToStringTest, SignedPositive_TooSmall_DoesNotWritePastEnd) {
190   EXPECT_EQ(0u, IntToString(9, span(buffer_, 1)).size());
191   EXPECT_EQ(0, std::memcmp("\0@#$%^&*()!@#$%^&*()", buffer_, sizeof(buffer_)));
192 }
193 
TEST_F(IntToStringTest,SignedPositive_1Char_FitsExactly)194 TEST_F(IntToStringTest, SignedPositive_1Char_FitsExactly) {
195   auto result = IntToString(0, span(buffer_, 2));
196   EXPECT_EQ(1u, result.size());
197   EXPECT_TRUE(result.ok());
198   EXPECT_STREQ("0", buffer_);
199 
200   result = IntToString(9, span(buffer_, 2));
201   EXPECT_EQ(1u, result.size());
202   EXPECT_TRUE(result.ok());
203   EXPECT_STREQ("9", buffer_);
204 }
205 
TEST_F(IntToStringTest,SignedPositive_2Chars_FitsExactly)206 TEST_F(IntToStringTest, SignedPositive_2Chars_FitsExactly) {
207   auto result = IntToString(10, span(buffer_, 4));
208   EXPECT_EQ(2u, result.size());
209   EXPECT_TRUE(result.ok());
210   EXPECT_STREQ("10", buffer_);
211 }
212 
TEST_F(IntToStringTest,SignedPositive_MaxFitsExactly)213 TEST_F(IntToStringTest, SignedPositive_MaxFitsExactly) {
214   auto result = IntToString(std::numeric_limits<int64_t>::max(),
215                             span(buffer_, sizeof(kInt64Min)));
216   EXPECT_EQ(19u, result.size());
217   EXPECT_STREQ(kInt64Max, buffer_);
218 }
219 
TEST_F(IntToStringTest,SignedNegative_EmptyBuffer_WritesNothing)220 TEST_F(IntToStringTest, SignedNegative_EmptyBuffer_WritesNothing) {
221   auto result = IntToString(-9, span(buffer_, 0));
222   EXPECT_EQ(0u, result.size());
223   EXPECT_FALSE(result.ok());
224   EXPECT_STREQ(kStartingString, buffer_);
225 }
226 
TEST_F(IntToStringTest,SignedNegative_TooSmall_NullTerminates)227 TEST_F(IntToStringTest, SignedNegative_TooSmall_NullTerminates) {
228   auto result = IntToString(-9, span(buffer_, 1));
229   EXPECT_EQ(0u, result.size());
230   EXPECT_FALSE(result.ok());
231   EXPECT_STREQ("", buffer_);
232 }
233 
TEST_F(IntToStringTest,SignedNegative_TooSmall_DoesNotWritePastEnd)234 TEST_F(IntToStringTest, SignedNegative_TooSmall_DoesNotWritePastEnd) {
235   // Note that two \0 are written due to the unsigned IntToString call.
236   EXPECT_EQ(0u, IntToString(-9, span(buffer_, 2)).size());
237   EXPECT_EQ(0, std::memcmp("\0\0#$%^&*()!@#$%^&*()", buffer_, sizeof(buffer_)));
238 }
239 
TEST_F(IntToStringTest,SignedNegative_FitsExactly)240 TEST_F(IntToStringTest, SignedNegative_FitsExactly) {
241   auto result = IntToString(-9, span(buffer_, 3));
242   EXPECT_EQ(2u, result.size());
243   EXPECT_STREQ("-9", buffer_);
244   result = IntToString(-99, span(buffer_, 4));
245   EXPECT_EQ(3u, result.size());
246   EXPECT_STREQ("-99", buffer_);
247   result = IntToString(-123, span(buffer_, 5));
248   EXPECT_EQ(4u, result.size());
249   EXPECT_STREQ("-123", buffer_);
250 }
251 
TEST_F(IntToStringTest,SignedNegative_MinFitsExactly)252 TEST_F(IntToStringTest, SignedNegative_MinFitsExactly) {
253   auto result = IntToString(std::numeric_limits<int64_t>::min(),
254                             span(buffer_, sizeof(kInt64Min)));
255   EXPECT_EQ(20u, result.size());
256   EXPECT_STREQ(kInt64Min, buffer_);
257 }
258 
TEST(IntToString,SignedSweep)259 TEST(IntToString, SignedSweep) {
260   for (int i = -1002; i <= 1002; ++i) {
261     char buffer[6];
262     char printf_buffer[6];
263     int written = std::snprintf(printf_buffer, sizeof(printf_buffer), "%d", i);
264     auto result = IntToString(i, buffer);
265     ASSERT_EQ(static_cast<size_t>(written), result.size());
266     ASSERT_STREQ(printf_buffer, buffer);
267   }
268 }
269 
TEST(IntToString,UnsignedSweep)270 TEST(IntToString, UnsignedSweep) {
271   for (unsigned i = 0; i <= 1002u; ++i) {
272     char buffer[5];
273     char printf_buffer[5];
274     int written = std::snprintf(printf_buffer, sizeof(printf_buffer), "%u", i);
275     auto result = IntToString(i, buffer);
276     ASSERT_EQ(static_cast<size_t>(written), result.size());
277     ASSERT_STREQ(printf_buffer, buffer);
278   }
279 }
280 
281 class IntToHexStringTest : public TestWithBuffer {};
282 
TEST_F(IntToHexStringTest,Sweep)283 TEST_F(IntToHexStringTest, Sweep) {
284   for (unsigned i = 0; i < 1030; ++i) {
285     char hex[16];
286     int bytes = std::snprintf(hex, sizeof(hex), "%x", static_cast<unsigned>(i));
287 
288     auto result = IntToHexString(i, buffer_);
289     EXPECT_EQ(static_cast<size_t>(bytes), result.size());
290     EXPECT_TRUE(result.ok());
291     EXPECT_STREQ(hex, buffer_);
292   }
293 }
294 
TEST_F(IntToHexStringTest,MinWidth)295 TEST_F(IntToHexStringTest, MinWidth) {
296   unsigned val = 0xbeef;
297   EXPECT_TRUE(IntToHexString(val, buffer_, 8).ok());
298   EXPECT_STREQ("0000beef", buffer_);
299 }
300 
TEST_F(IntToHexStringTest,Uint32Max)301 TEST_F(IntToHexStringTest, Uint32Max) {
302   EXPECT_EQ(
303       8u,
304       IntToHexString(std::numeric_limits<uint32_t>::max() - 1, buffer_).size());
305   EXPECT_STREQ("fffffffe", buffer_);
306 
307   EXPECT_EQ(
308       8u, IntToHexString(std::numeric_limits<uint32_t>::max(), buffer_).size());
309   EXPECT_STREQ("ffffffff", buffer_);
310 }
311 
TEST_F(IntToHexStringTest,Uint64Max)312 TEST_F(IntToHexStringTest, Uint64Max) {
313   EXPECT_EQ(
314       16u,
315       IntToHexString(std::numeric_limits<uint64_t>::max() - 1, buffer_).size());
316   EXPECT_STREQ("fffffffffffffffe", buffer_);
317 
318   EXPECT_EQ(
319       16u,
320       IntToHexString(std::numeric_limits<uint64_t>::max(), buffer_).size());
321   EXPECT_STREQ("ffffffffffffffff", buffer_);
322 }
323 
TEST_F(IntToHexStringTest,EmptyBuffer_WritesNothing)324 TEST_F(IntToHexStringTest, EmptyBuffer_WritesNothing) {
325   auto result = IntToHexString(0xbeef, span(buffer_, 0));
326   EXPECT_EQ(0u, result.size());
327   EXPECT_FALSE(result.ok());
328   EXPECT_STREQ(kStartingString, buffer_);
329 }
330 
TEST_F(IntToHexStringTest,TooSmall_Truncates)331 TEST_F(IntToHexStringTest, TooSmall_Truncates) {
332   auto result = IntToHexString(0xbeef, span(buffer_, 3));
333   EXPECT_EQ(0u, result.size());
334   EXPECT_FALSE(result.ok());
335   EXPECT_STREQ("", buffer_);
336 }
337 
338 class FloatAsIntToStringTest : public TestWithBuffer {};
339 
TEST_F(FloatAsIntToStringTest,PositiveInfinity)340 TEST_F(FloatAsIntToStringTest, PositiveInfinity) {
341   EXPECT_EQ(3u, FloatAsIntToString(INFINITY, buffer_).size());
342   EXPECT_STREQ("inf", buffer_);
343 }
344 
TEST_F(FloatAsIntToStringTest,NegativeInfinity)345 TEST_F(FloatAsIntToStringTest, NegativeInfinity) {
346   EXPECT_EQ(4u, FloatAsIntToString(-INFINITY, buffer_).size());
347   EXPECT_STREQ("-inf", buffer_);
348 }
349 
TEST_F(FloatAsIntToStringTest,PositiveNan)350 TEST_F(FloatAsIntToStringTest, PositiveNan) {
351   EXPECT_EQ(3u, FloatAsIntToString(NAN, buffer_).size());
352   EXPECT_STREQ("NaN", buffer_);
353 }
354 
TEST_F(FloatAsIntToStringTest,NegativeNan)355 TEST_F(FloatAsIntToStringTest, NegativeNan) {
356   EXPECT_EQ(4u, FloatAsIntToString(-NAN, buffer_).size());
357   EXPECT_STREQ("-NaN", buffer_);
358 }
359 
TEST_F(FloatAsIntToStringTest,RoundDown_PrintsNearestInt)360 TEST_F(FloatAsIntToStringTest, RoundDown_PrintsNearestInt) {
361   EXPECT_EQ(1u, FloatAsIntToString(1.23f, buffer_).size());
362   EXPECT_STREQ("1", buffer_);
363 }
364 
TEST_F(FloatAsIntToStringTest,RoundUp_PrintsNearestInt)365 TEST_F(FloatAsIntToStringTest, RoundUp_PrintsNearestInt) {
366   EXPECT_EQ(4u, FloatAsIntToString(1234.5f, buffer_).size());
367   EXPECT_STREQ("1235", buffer_);
368 }
369 
TEST_F(FloatAsIntToStringTest,RoundsToNegativeZero_PrintsZero)370 TEST_F(FloatAsIntToStringTest, RoundsToNegativeZero_PrintsZero) {
371   EXPECT_EQ(1u, FloatAsIntToString(-3.14e-20f, buffer_).size());
372   EXPECT_STREQ("0", buffer_);
373 }
374 
TEST_F(FloatAsIntToStringTest,RoundsToPositiveZero_PrintsZero)375 TEST_F(FloatAsIntToStringTest, RoundsToPositiveZero_PrintsZero) {
376   EXPECT_EQ(1u, FloatAsIntToString(3.14e-20f, buffer_).size());
377   EXPECT_STREQ("0", buffer_);
378 }
379 
TEST_F(FloatAsIntToStringTest,RoundDownNegative_PrintsNearestInt)380 TEST_F(FloatAsIntToStringTest, RoundDownNegative_PrintsNearestInt) {
381   volatile float x = -5.9f;
382   EXPECT_EQ(2u, FloatAsIntToString(x, buffer_).size());
383   EXPECT_STREQ("-6", buffer_);
384 }
385 
TEST_F(FloatAsIntToStringTest,RoundUpNegative_PrintsNearestInt)386 TEST_F(FloatAsIntToStringTest, RoundUpNegative_PrintsNearestInt) {
387   EXPECT_EQ(9u, FloatAsIntToString(-50000000.1f, buffer_).size());
388   EXPECT_STREQ("-50000000", buffer_);
389 }
390 
TEST_F(FloatAsIntToStringTest,LargerThanInteger)391 TEST_F(FloatAsIntToStringTest, LargerThanInteger) {
392   EXPECT_EQ(3u, FloatAsIntToString(3.14e20f, buffer_).size());
393   EXPECT_STREQ("inf", buffer_);
394 }
395 
TEST_F(FloatAsIntToStringTest,SmallerThanInteger)396 TEST_F(FloatAsIntToStringTest, SmallerThanInteger) {
397   EXPECT_EQ(4u, FloatAsIntToString(-3.14e20f, buffer_).size());
398   EXPECT_STREQ("-inf", buffer_);
399 }
400 
TEST_F(FloatAsIntToStringTest,TooSmall_Numeric_NullTerminates)401 TEST_F(FloatAsIntToStringTest, TooSmall_Numeric_NullTerminates) {
402   auto result = FloatAsIntToString(-3.14e20f, span(buffer_, 1));
403   EXPECT_EQ(0u, result.size());
404   EXPECT_FALSE(result.ok());
405   EXPECT_STREQ("", buffer_);
406 }
407 
TEST_F(FloatAsIntToStringTest,TooSmall_Infinity_NullTerminates)408 TEST_F(FloatAsIntToStringTest, TooSmall_Infinity_NullTerminates) {
409   auto result = FloatAsIntToString(-INFINITY, span(buffer_, 3));
410   EXPECT_EQ(0u, result.size());
411   EXPECT_FALSE(result.ok());
412   EXPECT_STREQ("", buffer_);
413 }
414 
TEST_F(FloatAsIntToStringTest,TooSmall_NaN_NullTerminates)415 TEST_F(FloatAsIntToStringTest, TooSmall_NaN_NullTerminates) {
416   auto result = FloatAsIntToString(NAN, span(buffer_, 2));
417   EXPECT_EQ(0u, result.size());
418   EXPECT_FALSE(result.ok());
419   EXPECT_STREQ("", buffer_);
420 }
421 
422 class CopyStringOrNullTest : public TestWithBuffer {};
423 
424 using namespace std::literals::string_view_literals;
425 
TEST_F(CopyStringOrNullTest,NullSource_WritesNullPointerString)426 TEST_F(CopyStringOrNullTest, NullSource_WritesNullPointerString) {
427   EXPECT_EQ(kNullPointerString.size(),
428             CopyStringOrNull(nullptr, buffer_).size());
429   EXPECT_EQ(kNullPointerString, buffer_);
430 }
431 
TEST_F(CopyStringOrNullTest,EmptyStringView_WritesNullTerminator)432 TEST_F(CopyStringOrNullTest, EmptyStringView_WritesNullTerminator) {
433   EXPECT_EQ(0u, CopyStringOrNull("", buffer_).size());
434   EXPECT_EQ('\0', buffer_[0]);
435 }
436 
TEST_F(CopyStringOrNullTest,EmptyBuffer_WritesNothing)437 TEST_F(CopyStringOrNullTest, EmptyBuffer_WritesNothing) {
438   auto result = CopyStringOrNull("Hello", span(buffer_, 0));
439   EXPECT_EQ(0u, result.size());
440   EXPECT_FALSE(result.ok());
441   EXPECT_STREQ(kStartingString, buffer_);
442 }
443 
TEST_F(CopyStringOrNullTest,TooSmall_Truncates)444 TEST_F(CopyStringOrNullTest, TooSmall_Truncates) {
445   auto result = CopyStringOrNull("Hi!", span(buffer_, 3));
446   EXPECT_EQ(2u, result.size());
447   EXPECT_FALSE(result.ok());
448   EXPECT_STREQ("Hi", buffer_);
449 }
450 
TEST_F(CopyStringOrNullTest,ExactFit)451 TEST_F(CopyStringOrNullTest, ExactFit) {
452   auto result = CopyStringOrNull("Hi!", span(buffer_, 4));
453   EXPECT_EQ(3u, result.size());
454   EXPECT_TRUE(result.ok());
455   EXPECT_STREQ("Hi!", buffer_);
456 }
457 
TEST_F(CopyStringOrNullTest,NullTerminatorsInString)458 TEST_F(CopyStringOrNullTest, NullTerminatorsInString) {
459   ASSERT_EQ(4u, CopyStringOrNull("\0!\0\0"sv, span(buffer_, 5)).size());
460   EXPECT_EQ("\0!\0\0"sv, std::string_view(buffer_, 4));
461 }
462 
463 class CopyEntireStringOrNullTest : public TestWithBuffer {};
464 
TEST_F(CopyEntireStringOrNullTest,NullSource_WritesNullPointerString)465 TEST_F(CopyEntireStringOrNullTest, NullSource_WritesNullPointerString) {
466   EXPECT_EQ(kNullPointerString.size(),
467             CopyEntireStringOrNull(nullptr, buffer_).size());
468   EXPECT_EQ(kNullPointerString, buffer_);
469 }
470 
TEST_F(CopyEntireStringOrNullTest,EmptyStringView_WritesNullTerminator)471 TEST_F(CopyEntireStringOrNullTest, EmptyStringView_WritesNullTerminator) {
472   EXPECT_EQ(0u, CopyEntireStringOrNull("", buffer_).size());
473   EXPECT_EQ('\0', buffer_[0]);
474 }
475 
TEST_F(CopyEntireStringOrNullTest,EmptyBuffer_WritesNothing)476 TEST_F(CopyEntireStringOrNullTest, EmptyBuffer_WritesNothing) {
477   auto result = CopyEntireStringOrNull("Hello", span(buffer_, 0));
478   EXPECT_EQ(0u, result.size());
479   EXPECT_FALSE(result.ok());
480   EXPECT_STREQ(kStartingString, buffer_);
481 }
482 
TEST_F(CopyEntireStringOrNullTest,TooSmall_WritesNothing)483 TEST_F(CopyEntireStringOrNullTest, TooSmall_WritesNothing) {
484   auto result = CopyEntireStringOrNull("Hi!", span(buffer_, 3));
485   EXPECT_EQ(0u, result.size());
486   EXPECT_FALSE(result.ok());
487   EXPECT_STREQ("", buffer_);
488 }
489 
TEST_F(CopyEntireStringOrNullTest,ExactFit)490 TEST_F(CopyEntireStringOrNullTest, ExactFit) {
491   auto result = CopyEntireStringOrNull("Hi!", span(buffer_, 4));
492   EXPECT_EQ(3u, result.size());
493   EXPECT_TRUE(result.ok());
494   EXPECT_STREQ("Hi!", buffer_);
495 }
496 
TEST_F(CopyEntireStringOrNullTest,NullTerminatorsInString)497 TEST_F(CopyEntireStringOrNullTest, NullTerminatorsInString) {
498   ASSERT_EQ(4u, CopyEntireStringOrNull("\0!\0\0"sv, span(buffer_, 5)).size());
499   EXPECT_EQ("\0!\0\0"sv, std::string_view(buffer_, 4));
500 }
501 
502 class PointerToStringTest : public TestWithBuffer {};
503 
TEST_F(PointerToStringTest,Nullptr_WritesNull)504 TEST_F(PointerToStringTest, Nullptr_WritesNull) {
505   EXPECT_EQ(6u, PointerToString(nullptr, span(buffer_, 7)).size());
506   EXPECT_STREQ("(null)", buffer_);
507 }
508 
TEST_F(PointerToStringTest,WritesAddress)509 TEST_F(PointerToStringTest, WritesAddress) {
510   const void* pointer = reinterpret_cast<void*>(0xbeef);
511   EXPECT_EQ(4u, PointerToString(pointer, buffer_).size());
512   EXPECT_STREQ("beef", buffer_);
513 }
514 
515 class BoolToStringTest : public TestWithBuffer {};
516 
TEST_F(BoolToStringTest,ExactFit)517 TEST_F(BoolToStringTest, ExactFit) {
518   EXPECT_EQ(4u, BoolToString(true, span(buffer_, 5)).size());
519   EXPECT_STREQ("true", buffer_);
520 
521   EXPECT_EQ(5u, BoolToString(false, span(buffer_, 6)).size());
522   EXPECT_STREQ("false", buffer_);
523 }
524 
TEST_F(BoolToStringTest,True_TooSmall_WritesNullTerminator)525 TEST_F(BoolToStringTest, True_TooSmall_WritesNullTerminator) {
526   auto result = BoolToString(true, span(buffer_, 4));
527   EXPECT_EQ(0u, result.size());
528   EXPECT_FALSE(result.ok());
529   EXPECT_STREQ("", buffer_);
530 }
531 
TEST_F(BoolToStringTest,False_TooSmall_WritesNullTerminator)532 TEST_F(BoolToStringTest, False_TooSmall_WritesNullTerminator) {
533   auto result = BoolToString(false, span(buffer_, 5));
534   EXPECT_EQ(0u, result.size());
535   EXPECT_FALSE(result.ok());
536   EXPECT_STREQ("", buffer_);
537 }
538 
TEST_F(BoolToStringTest,EmptyBuffer_WritesNothing)539 TEST_F(BoolToStringTest, EmptyBuffer_WritesNothing) {
540   EXPECT_EQ(0u, BoolToString(true, span(buffer_, 0)).size());
541   EXPECT_STREQ(kStartingString, buffer_);
542 
543   EXPECT_EQ(0u, BoolToString(false, span(buffer_, 0)).size());
544   EXPECT_STREQ(kStartingString, buffer_);
545 }
546 
547 }  // namespace
548 }  // namespace pw::string
549