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 "gtest/gtest.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 class TestWithBuffer : public ::testing::Test {
94 protected:
95 static constexpr char kStartingString[] = "!@#$%^&*()!@#$%^&*()";
96 static constexpr char kUint64Max[] = "18446744073709551615";
97 static constexpr char kInt64Min[] = "-9223372036854775808";
98 static constexpr char kInt64Max[] = "9223372036854775807";
99
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
107 class IntToStringTest : public TestWithBuffer {};
108
TEST_F(IntToStringTest,Unsigned_EmptyBuffer_WritesNothing)109 TEST_F(IntToStringTest, Unsigned_EmptyBuffer_WritesNothing) {
110 auto result = IntToString(9u, span(buffer_, 0));
111 EXPECT_EQ(0u, result.size());
112 EXPECT_FALSE(result.ok());
113 EXPECT_STREQ(kStartingString, buffer_);
114 }
115
TEST_F(IntToStringTest,Unsigned_TooSmall_1Char_OnlyNullTerminates)116 TEST_F(IntToStringTest, Unsigned_TooSmall_1Char_OnlyNullTerminates) {
117 auto result = IntToString(9u, span(buffer_, 1));
118 EXPECT_EQ(0u, result.size());
119 EXPECT_FALSE(result.ok());
120 EXPECT_STREQ("", buffer_);
121 }
122
TEST_F(IntToStringTest,Unsigned_TooSmall_2Chars_OnlyNullTerminates)123 TEST_F(IntToStringTest, Unsigned_TooSmall_2Chars_OnlyNullTerminates) {
124 auto result = IntToString(10u, span(buffer_, 2));
125 EXPECT_EQ(0u, result.size());
126 EXPECT_FALSE(result.ok());
127 EXPECT_STREQ("", buffer_);
128 }
129
TEST_F(IntToStringTest,Unsigned_TooSmall_3Chars_OnlyNullTerminates)130 TEST_F(IntToStringTest, Unsigned_TooSmall_3Chars_OnlyNullTerminates) {
131 auto result = IntToString(123u, span(buffer_, 3));
132 EXPECT_EQ(0u, result.size());
133 EXPECT_FALSE(result.ok());
134 EXPECT_STREQ("", buffer_);
135 }
136
TEST_F(IntToStringTest,Unsigned_1Char_FitsExactly)137 TEST_F(IntToStringTest, Unsigned_1Char_FitsExactly) {
138 auto result = IntToString(0u, span(buffer_, 2));
139 EXPECT_EQ(1u, result.size());
140 EXPECT_TRUE(result.ok());
141 EXPECT_STREQ("0", buffer_);
142
143 result = IntToString(9u, span(buffer_, 2));
144 EXPECT_EQ(1u, result.size());
145 EXPECT_TRUE(result.ok());
146 EXPECT_STREQ("9", buffer_);
147 }
148
TEST_F(IntToStringTest,Unsigned_2Chars_FitsExactly)149 TEST_F(IntToStringTest, Unsigned_2Chars_FitsExactly) {
150 auto result = IntToString(10u, span(buffer_, 3));
151 EXPECT_EQ(2u, result.size());
152 EXPECT_STREQ("10", buffer_);
153 }
154
TEST_F(IntToStringTest,Unsigned_MaxFitsExactly)155 TEST_F(IntToStringTest, Unsigned_MaxFitsExactly) {
156 EXPECT_EQ(20u,
157 IntToString(std::numeric_limits<uint64_t>::max(),
158 span(buffer_, sizeof(kUint64Max)))
159 .size());
160 EXPECT_STREQ(kUint64Max, buffer_);
161 }
162
TEST_F(IntToStringTest,SignedPositive_EmptyBuffer_WritesNothing)163 TEST_F(IntToStringTest, SignedPositive_EmptyBuffer_WritesNothing) {
164 auto result = IntToString(9, span(buffer_, 0));
165 EXPECT_EQ(0u, result.size());
166 EXPECT_FALSE(result.ok());
167 EXPECT_STREQ(kStartingString, buffer_);
168 }
169
TEST_F(IntToStringTest,SignedPositive_TooSmall_NullTerminates)170 TEST_F(IntToStringTest, SignedPositive_TooSmall_NullTerminates) {
171 auto result = IntToString(9, span(buffer_, 1));
172 EXPECT_EQ(0u, result.size());
173 EXPECT_FALSE(result.ok());
174 EXPECT_STREQ("", buffer_);
175 }
176
TEST_F(IntToStringTest,SignedPositive_TooSmall_DoesNotWritePastEnd)177 TEST_F(IntToStringTest, SignedPositive_TooSmall_DoesNotWritePastEnd) {
178 EXPECT_EQ(0u, IntToString(9, span(buffer_, 1)).size());
179 EXPECT_EQ(0, std::memcmp("\0@#$%^&*()!@#$%^&*()", buffer_, sizeof(buffer_)));
180 }
181
TEST_F(IntToStringTest,SignedPositive_1Char_FitsExactly)182 TEST_F(IntToStringTest, SignedPositive_1Char_FitsExactly) {
183 auto result = IntToString(0, span(buffer_, 2));
184 EXPECT_EQ(1u, result.size());
185 EXPECT_TRUE(result.ok());
186 EXPECT_STREQ("0", buffer_);
187
188 result = IntToString(9, span(buffer_, 2));
189 EXPECT_EQ(1u, result.size());
190 EXPECT_TRUE(result.ok());
191 EXPECT_STREQ("9", buffer_);
192 }
193
TEST_F(IntToStringTest,SignedPositive_2Chars_FitsExactly)194 TEST_F(IntToStringTest, SignedPositive_2Chars_FitsExactly) {
195 auto result = IntToString(10, span(buffer_, 4));
196 EXPECT_EQ(2u, result.size());
197 EXPECT_TRUE(result.ok());
198 EXPECT_STREQ("10", buffer_);
199 }
200
TEST_F(IntToStringTest,SignedPositive_MaxFitsExactly)201 TEST_F(IntToStringTest, SignedPositive_MaxFitsExactly) {
202 auto result = IntToString(std::numeric_limits<int64_t>::max(),
203 span(buffer_, sizeof(kInt64Min)));
204 EXPECT_EQ(19u, result.size());
205 EXPECT_STREQ(kInt64Max, buffer_);
206 }
207
TEST_F(IntToStringTest,SignedNegative_EmptyBuffer_WritesNothing)208 TEST_F(IntToStringTest, SignedNegative_EmptyBuffer_WritesNothing) {
209 auto result = IntToString(-9, span(buffer_, 0));
210 EXPECT_EQ(0u, result.size());
211 EXPECT_FALSE(result.ok());
212 EXPECT_STREQ(kStartingString, buffer_);
213 }
214
TEST_F(IntToStringTest,SignedNegative_TooSmall_NullTerminates)215 TEST_F(IntToStringTest, SignedNegative_TooSmall_NullTerminates) {
216 auto result = IntToString(-9, span(buffer_, 1));
217 EXPECT_EQ(0u, result.size());
218 EXPECT_FALSE(result.ok());
219 EXPECT_STREQ("", buffer_);
220 }
221
TEST_F(IntToStringTest,SignedNegative_TooSmall_DoesNotWritePastEnd)222 TEST_F(IntToStringTest, SignedNegative_TooSmall_DoesNotWritePastEnd) {
223 // Note that two \0 are written due to the unsigned IntToString call.
224 EXPECT_EQ(0u, IntToString(-9, span(buffer_, 2)).size());
225 EXPECT_EQ(0, std::memcmp("\0\0#$%^&*()!@#$%^&*()", buffer_, sizeof(buffer_)));
226 }
227
TEST_F(IntToStringTest,SignedNegative_FitsExactly)228 TEST_F(IntToStringTest, SignedNegative_FitsExactly) {
229 auto result = IntToString(-9, span(buffer_, 3));
230 EXPECT_EQ(2u, result.size());
231 EXPECT_STREQ("-9", buffer_);
232 result = IntToString(-99, span(buffer_, 4));
233 EXPECT_EQ(3u, result.size());
234 EXPECT_STREQ("-99", buffer_);
235 result = IntToString(-123, span(buffer_, 5));
236 EXPECT_EQ(4u, result.size());
237 EXPECT_STREQ("-123", buffer_);
238 }
239
TEST_F(IntToStringTest,SignedNegative_MinFitsExactly)240 TEST_F(IntToStringTest, SignedNegative_MinFitsExactly) {
241 auto result = IntToString(std::numeric_limits<int64_t>::min(),
242 span(buffer_, sizeof(kInt64Min)));
243 EXPECT_EQ(20u, result.size());
244 EXPECT_STREQ(kInt64Min, buffer_);
245 }
246
TEST(IntToString,SignedSweep)247 TEST(IntToString, SignedSweep) {
248 for (int i = -1002; i <= 1002; ++i) {
249 char buffer[6];
250 char printf_buffer[6];
251 int written = std::snprintf(printf_buffer, sizeof(printf_buffer), "%d", i);
252 auto result = IntToString(i, buffer);
253 ASSERT_EQ(static_cast<size_t>(written), result.size());
254 ASSERT_STREQ(printf_buffer, buffer);
255 }
256 }
257
TEST(IntToString,UnsignedSweep)258 TEST(IntToString, UnsignedSweep) {
259 for (unsigned i = 0; i <= 1002u; ++i) {
260 char buffer[5];
261 char printf_buffer[5];
262 int written = std::snprintf(printf_buffer, sizeof(printf_buffer), "%u", i);
263 auto result = IntToString(i, buffer);
264 ASSERT_EQ(static_cast<size_t>(written), result.size());
265 ASSERT_STREQ(printf_buffer, buffer);
266 }
267 }
268
269 class IntToHexStringTest : public TestWithBuffer {};
270
TEST_F(IntToHexStringTest,Sweep)271 TEST_F(IntToHexStringTest, Sweep) {
272 for (unsigned i = 0; i < 1030; ++i) {
273 char hex[16];
274 int bytes = std::snprintf(hex, sizeof(hex), "%x", static_cast<unsigned>(i));
275
276 auto result = IntToHexString(i, buffer_);
277 EXPECT_EQ(static_cast<size_t>(bytes), result.size());
278 EXPECT_TRUE(result.ok());
279 EXPECT_STREQ(hex, buffer_);
280 }
281 }
282
TEST_F(IntToHexStringTest,MinWidth)283 TEST_F(IntToHexStringTest, MinWidth) {
284 unsigned val = 0xbeef;
285 EXPECT_TRUE(IntToHexString(val, buffer_, 8).ok());
286 EXPECT_STREQ("0000beef", buffer_);
287 }
288
TEST_F(IntToHexStringTest,Uint32Max)289 TEST_F(IntToHexStringTest, Uint32Max) {
290 EXPECT_EQ(
291 8u,
292 IntToHexString(std::numeric_limits<uint32_t>::max() - 1, buffer_).size());
293 EXPECT_STREQ("fffffffe", buffer_);
294
295 EXPECT_EQ(
296 8u, IntToHexString(std::numeric_limits<uint32_t>::max(), buffer_).size());
297 EXPECT_STREQ("ffffffff", buffer_);
298 }
299
TEST_F(IntToHexStringTest,Uint64Max)300 TEST_F(IntToHexStringTest, Uint64Max) {
301 EXPECT_EQ(
302 16u,
303 IntToHexString(std::numeric_limits<uint64_t>::max() - 1, buffer_).size());
304 EXPECT_STREQ("fffffffffffffffe", buffer_);
305
306 EXPECT_EQ(
307 16u,
308 IntToHexString(std::numeric_limits<uint64_t>::max(), buffer_).size());
309 EXPECT_STREQ("ffffffffffffffff", buffer_);
310 }
311
TEST_F(IntToHexStringTest,EmptyBuffer_WritesNothing)312 TEST_F(IntToHexStringTest, EmptyBuffer_WritesNothing) {
313 auto result = IntToHexString(0xbeef, span(buffer_, 0));
314 EXPECT_EQ(0u, result.size());
315 EXPECT_FALSE(result.ok());
316 EXPECT_STREQ(kStartingString, buffer_);
317 }
318
TEST_F(IntToHexStringTest,TooSmall_Truncates)319 TEST_F(IntToHexStringTest, TooSmall_Truncates) {
320 auto result = IntToHexString(0xbeef, span(buffer_, 3));
321 EXPECT_EQ(0u, result.size());
322 EXPECT_FALSE(result.ok());
323 EXPECT_STREQ("", buffer_);
324 }
325
326 class FloatAsIntToStringTest : public TestWithBuffer {};
327
TEST_F(FloatAsIntToStringTest,PositiveInfinity)328 TEST_F(FloatAsIntToStringTest, PositiveInfinity) {
329 EXPECT_EQ(3u, FloatAsIntToString(INFINITY, buffer_).size());
330 EXPECT_STREQ("inf", buffer_);
331 }
332
TEST_F(FloatAsIntToStringTest,NegativeInfinity)333 TEST_F(FloatAsIntToStringTest, NegativeInfinity) {
334 EXPECT_EQ(4u, FloatAsIntToString(-INFINITY, buffer_).size());
335 EXPECT_STREQ("-inf", buffer_);
336 }
337
TEST_F(FloatAsIntToStringTest,PositiveNan)338 TEST_F(FloatAsIntToStringTest, PositiveNan) {
339 EXPECT_EQ(3u, FloatAsIntToString(NAN, buffer_).size());
340 EXPECT_STREQ("NaN", buffer_);
341 }
342
TEST_F(FloatAsIntToStringTest,NegativeNan)343 TEST_F(FloatAsIntToStringTest, NegativeNan) {
344 EXPECT_EQ(4u, FloatAsIntToString(-NAN, buffer_).size());
345 EXPECT_STREQ("-NaN", buffer_);
346 }
347
TEST_F(FloatAsIntToStringTest,RoundDown_PrintsNearestInt)348 TEST_F(FloatAsIntToStringTest, RoundDown_PrintsNearestInt) {
349 EXPECT_EQ(1u, FloatAsIntToString(1.23, buffer_).size());
350 EXPECT_STREQ("1", buffer_);
351 }
352
TEST_F(FloatAsIntToStringTest,RoundUp_PrintsNearestInt)353 TEST_F(FloatAsIntToStringTest, RoundUp_PrintsNearestInt) {
354 EXPECT_EQ(4u, FloatAsIntToString(1234.5, buffer_).size());
355 EXPECT_STREQ("1235", buffer_);
356 }
357
TEST_F(FloatAsIntToStringTest,RoundsToNegativeZero_PrintsZero)358 TEST_F(FloatAsIntToStringTest, RoundsToNegativeZero_PrintsZero) {
359 EXPECT_EQ(1u, FloatAsIntToString(-3.14e-20f, buffer_).size());
360 EXPECT_STREQ("0", buffer_);
361 }
362
TEST_F(FloatAsIntToStringTest,RoundsToPositiveZero_PrintsZero)363 TEST_F(FloatAsIntToStringTest, RoundsToPositiveZero_PrintsZero) {
364 EXPECT_EQ(1u, FloatAsIntToString(3.14e-20f, buffer_).size());
365 EXPECT_STREQ("0", buffer_);
366 }
367
TEST_F(FloatAsIntToStringTest,RoundDownNegative_PrintsNearestInt)368 TEST_F(FloatAsIntToStringTest, RoundDownNegative_PrintsNearestInt) {
369 volatile float x = -5.9;
370 EXPECT_EQ(2u, FloatAsIntToString(x, buffer_).size());
371 EXPECT_STREQ("-6", buffer_);
372 }
373
TEST_F(FloatAsIntToStringTest,RoundUpNegative_PrintsNearestInt)374 TEST_F(FloatAsIntToStringTest, RoundUpNegative_PrintsNearestInt) {
375 EXPECT_EQ(9u, FloatAsIntToString(-50000000.1, buffer_).size());
376 EXPECT_STREQ("-50000000", buffer_);
377 }
378
TEST_F(FloatAsIntToStringTest,LargerThanInteger)379 TEST_F(FloatAsIntToStringTest, LargerThanInteger) {
380 EXPECT_EQ(3u, FloatAsIntToString(3.14e20f, buffer_).size());
381 EXPECT_STREQ("inf", buffer_);
382 }
383
TEST_F(FloatAsIntToStringTest,SmallerThanInteger)384 TEST_F(FloatAsIntToStringTest, SmallerThanInteger) {
385 EXPECT_EQ(4u, FloatAsIntToString(-3.14e20f, buffer_).size());
386 EXPECT_STREQ("-inf", buffer_);
387 }
388
TEST_F(FloatAsIntToStringTest,TooSmall_Numeric_NullTerminates)389 TEST_F(FloatAsIntToStringTest, TooSmall_Numeric_NullTerminates) {
390 auto result = FloatAsIntToString(-3.14e20f, span(buffer_, 1));
391 EXPECT_EQ(0u, result.size());
392 EXPECT_FALSE(result.ok());
393 EXPECT_STREQ("", buffer_);
394 }
395
TEST_F(FloatAsIntToStringTest,TooSmall_Infinity_NullTerminates)396 TEST_F(FloatAsIntToStringTest, TooSmall_Infinity_NullTerminates) {
397 auto result = FloatAsIntToString(-INFINITY, span(buffer_, 3));
398 EXPECT_EQ(0u, result.size());
399 EXPECT_FALSE(result.ok());
400 EXPECT_STREQ("", buffer_);
401 }
402
TEST_F(FloatAsIntToStringTest,TooSmall_NaN_NullTerminates)403 TEST_F(FloatAsIntToStringTest, TooSmall_NaN_NullTerminates) {
404 auto result = FloatAsIntToString(NAN, span(buffer_, 2));
405 EXPECT_EQ(0u, result.size());
406 EXPECT_FALSE(result.ok());
407 EXPECT_STREQ("", buffer_);
408 }
409
410 class CopyStringOrNullTest : public TestWithBuffer {};
411
412 using namespace std::literals::string_view_literals;
413
TEST_F(CopyStringOrNullTest,NullSource_WritesNullPointerString)414 TEST_F(CopyStringOrNullTest, NullSource_WritesNullPointerString) {
415 EXPECT_EQ(kNullPointerString.size(),
416 CopyStringOrNull(nullptr, buffer_).size());
417 EXPECT_EQ(kNullPointerString, buffer_);
418 }
419
TEST_F(CopyStringOrNullTest,EmptyStringView_WritesNullTerminator)420 TEST_F(CopyStringOrNullTest, EmptyStringView_WritesNullTerminator) {
421 EXPECT_EQ(0u, CopyStringOrNull("", buffer_).size());
422 EXPECT_EQ('\0', buffer_[0]);
423 }
424
TEST_F(CopyStringOrNullTest,EmptyBuffer_WritesNothing)425 TEST_F(CopyStringOrNullTest, EmptyBuffer_WritesNothing) {
426 auto result = CopyStringOrNull("Hello", span(buffer_, 0));
427 EXPECT_EQ(0u, result.size());
428 EXPECT_FALSE(result.ok());
429 EXPECT_STREQ(kStartingString, buffer_);
430 }
431
TEST_F(CopyStringOrNullTest,TooSmall_Truncates)432 TEST_F(CopyStringOrNullTest, TooSmall_Truncates) {
433 auto result = CopyStringOrNull("Hi!", span(buffer_, 3));
434 EXPECT_EQ(2u, result.size());
435 EXPECT_FALSE(result.ok());
436 EXPECT_STREQ("Hi", buffer_);
437 }
438
TEST_F(CopyStringOrNullTest,ExactFit)439 TEST_F(CopyStringOrNullTest, ExactFit) {
440 auto result = CopyStringOrNull("Hi!", span(buffer_, 4));
441 EXPECT_EQ(3u, result.size());
442 EXPECT_TRUE(result.ok());
443 EXPECT_STREQ("Hi!", buffer_);
444 }
445
TEST_F(CopyStringOrNullTest,NullTerminatorsInString)446 TEST_F(CopyStringOrNullTest, NullTerminatorsInString) {
447 ASSERT_EQ(4u, CopyStringOrNull("\0!\0\0"sv, span(buffer_, 5)).size());
448 EXPECT_EQ("\0!\0\0"sv, std::string_view(buffer_, 4));
449 }
450
451 class CopyEntireStringOrNullTest : public TestWithBuffer {};
452
TEST_F(CopyEntireStringOrNullTest,NullSource_WritesNullPointerString)453 TEST_F(CopyEntireStringOrNullTest, NullSource_WritesNullPointerString) {
454 EXPECT_EQ(kNullPointerString.size(),
455 CopyEntireStringOrNull(nullptr, buffer_).size());
456 EXPECT_EQ(kNullPointerString, buffer_);
457 }
458
TEST_F(CopyEntireStringOrNullTest,EmptyStringView_WritesNullTerminator)459 TEST_F(CopyEntireStringOrNullTest, EmptyStringView_WritesNullTerminator) {
460 EXPECT_EQ(0u, CopyEntireStringOrNull("", buffer_).size());
461 EXPECT_EQ('\0', buffer_[0]);
462 }
463
TEST_F(CopyEntireStringOrNullTest,EmptyBuffer_WritesNothing)464 TEST_F(CopyEntireStringOrNullTest, EmptyBuffer_WritesNothing) {
465 auto result = CopyEntireStringOrNull("Hello", span(buffer_, 0));
466 EXPECT_EQ(0u, result.size());
467 EXPECT_FALSE(result.ok());
468 EXPECT_STREQ(kStartingString, buffer_);
469 }
470
TEST_F(CopyEntireStringOrNullTest,TooSmall_WritesNothing)471 TEST_F(CopyEntireStringOrNullTest, TooSmall_WritesNothing) {
472 auto result = CopyEntireStringOrNull("Hi!", span(buffer_, 3));
473 EXPECT_EQ(0u, result.size());
474 EXPECT_FALSE(result.ok());
475 EXPECT_STREQ("", buffer_);
476 }
477
TEST_F(CopyEntireStringOrNullTest,ExactFit)478 TEST_F(CopyEntireStringOrNullTest, ExactFit) {
479 auto result = CopyEntireStringOrNull("Hi!", span(buffer_, 4));
480 EXPECT_EQ(3u, result.size());
481 EXPECT_TRUE(result.ok());
482 EXPECT_STREQ("Hi!", buffer_);
483 }
484
TEST_F(CopyEntireStringOrNullTest,NullTerminatorsInString)485 TEST_F(CopyEntireStringOrNullTest, NullTerminatorsInString) {
486 ASSERT_EQ(4u, CopyEntireStringOrNull("\0!\0\0"sv, span(buffer_, 5)).size());
487 EXPECT_EQ("\0!\0\0"sv, std::string_view(buffer_, 4));
488 }
489
490 class PointerToStringTest : public TestWithBuffer {};
491
TEST_F(PointerToStringTest,Nullptr_WritesNull)492 TEST_F(PointerToStringTest, Nullptr_WritesNull) {
493 EXPECT_EQ(6u, PointerToString(nullptr, span(buffer_, 7)).size());
494 EXPECT_STREQ("(null)", buffer_);
495 }
496
TEST_F(PointerToStringTest,WritesAddress)497 TEST_F(PointerToStringTest, WritesAddress) {
498 const void* pointer = reinterpret_cast<void*>(0xbeef);
499 EXPECT_EQ(4u, PointerToString(pointer, buffer_).size());
500 EXPECT_STREQ("beef", buffer_);
501 }
502
503 class BoolToStringTest : public TestWithBuffer {};
504
TEST_F(BoolToStringTest,ExactFit)505 TEST_F(BoolToStringTest, ExactFit) {
506 EXPECT_EQ(4u, BoolToString(true, span(buffer_, 5)).size());
507 EXPECT_STREQ("true", buffer_);
508
509 EXPECT_EQ(5u, BoolToString(false, span(buffer_, 6)).size());
510 EXPECT_STREQ("false", buffer_);
511 }
512
TEST_F(BoolToStringTest,True_TooSmall_WritesNullTerminator)513 TEST_F(BoolToStringTest, True_TooSmall_WritesNullTerminator) {
514 auto result = BoolToString(true, span(buffer_, 4));
515 EXPECT_EQ(0u, result.size());
516 EXPECT_FALSE(result.ok());
517 EXPECT_STREQ("", buffer_);
518 }
519
TEST_F(BoolToStringTest,False_TooSmall_WritesNullTerminator)520 TEST_F(BoolToStringTest, False_TooSmall_WritesNullTerminator) {
521 auto result = BoolToString(false, span(buffer_, 5));
522 EXPECT_EQ(0u, result.size());
523 EXPECT_FALSE(result.ok());
524 EXPECT_STREQ("", buffer_);
525 }
526
TEST_F(BoolToStringTest,EmptyBuffer_WritesNothing)527 TEST_F(BoolToStringTest, EmptyBuffer_WritesNothing) {
528 EXPECT_EQ(0u, BoolToString(true, span(buffer_, 0)).size());
529 EXPECT_STREQ(kStartingString, buffer_);
530
531 EXPECT_EQ(0u, BoolToString(false, span(buffer_, 0)).size());
532 EXPECT_STREQ(kStartingString, buffer_);
533 }
534
535 } // namespace
536 } // namespace pw::string
537