xref: /aosp_15_r20/external/pigweed/pw_bluetooth_sapphire/lib/cpp-string/string_printf_test.cc (revision 61c4878ac05f98d0ceed94b57d316916de578985)
1 // Copyright 2023 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 <cpp-string/string_printf.h>
16 #include <errno.h>
17 #include <stdarg.h>
18 
19 #include <string>
20 
21 #include "pw_unit_test/framework.h"
22 
23 namespace bt_lib_cpp_string {
24 namespace {
25 
26 constexpr size_t kStackBufferSize = 1024u;
27 
28 // Note: |runnable| can't be a reference since that'd make the behavior of
29 // |va_start()| undefined.
30 template <typename Runnable>
VAListHelper(Runnable runnable,...)31 std::string VAListHelper(Runnable runnable, ...) {
32   va_list ap;
33   va_start(ap, runnable);
34   std::string rv = runnable(ap);
35   va_end(ap);
36   return rv;
37 }
38 
TEST(StringPrintfTest,StringPrintfBasic)39 TEST(StringPrintfTest, StringPrintfBasic) {
40   EXPECT_EQ("", StringPrintf(""));
41   EXPECT_EQ("hello", StringPrintf("hello"));
42   EXPECT_EQ("hello-123", StringPrintf("hello%d", -123));
43   EXPECT_EQ("hello0123FACE", StringPrintf("%s%04d%X", "hello", 123, 0xfaceU));
44 }
45 
TEST(StringPrintfTest,StringVPrintf_Basic)46 TEST(StringPrintfTest, StringVPrintf_Basic) {
47   EXPECT_EQ("", VAListHelper([](va_list ap) -> std::string {
48               return StringVPrintf("", ap);
49             }));
50   EXPECT_EQ("hello", VAListHelper([](va_list ap) -> std::string {
51               return StringVPrintf("hello", ap);
52             }));
53   EXPECT_EQ("hello-123",
54             VAListHelper(
55                 [](va_list ap) -> std::string {
56                   return StringVPrintf("hello%d", ap);
57                 },
58                 -123));
59   EXPECT_EQ("hello0123FACE",
60             VAListHelper(
61                 [](va_list ap) -> std::string {
62                   return StringVPrintf("%s%04d%X", ap);
63                 },
64                 "hello",
65                 123,
66                 0xfaceU));
67 }
68 
TEST(StringPrintfTest,StringAppendfBasic)69 TEST(StringPrintfTest, StringAppendfBasic) {
70   {
71     std::string s = "existing";
72     StringAppendf(&s, "");
73     EXPECT_EQ("existing", s);
74   }
75   {
76     std::string s = "existing";
77     StringAppendf(&s, "hello");
78     EXPECT_EQ("existinghello", s);
79   }
80   {
81     std::string s = "existing";
82     StringAppendf(&s, "hello%d", -123);
83     EXPECT_EQ("existinghello-123", s);
84   }
85   {
86     std::string s = "existing";
87     StringAppendf(&s, "%s%04d%X", "hello", 123, 0xfaceU);
88     EXPECT_EQ("existinghello0123FACE", s);
89   }
90 }
91 
TEST(StringPrintfTest,StringVAppendfBasic)92 TEST(StringPrintfTest, StringVAppendfBasic) {
93   EXPECT_EQ("existing", VAListHelper([](va_list ap) -> std::string {
94               std::string s = "existing";
95               StringVAppendf(&s, "", ap);
96               return s;
97             }));
98   EXPECT_EQ("existinghello", VAListHelper([](va_list ap) -> std::string {
99               std::string s = "existing";
100               StringVAppendf(&s, "hello", ap);
101               return s;
102             }));
103   EXPECT_EQ("existinghello-123",
104             VAListHelper(
105                 [](va_list ap) -> std::string {
106                   std::string s = "existing";
107                   StringVAppendf(&s, "hello%d", ap);
108                   return s;
109                 },
110                 -123));
111   EXPECT_EQ("existinghello0123FACE",
112             VAListHelper(
113                 [](va_list ap) -> std::string {
114                   std::string s = "existing";
115                   StringVAppendf(&s, "%s%04d%X", ap);
116                   return s;
117                 },
118                 "hello",
119                 123,
120                 0xfaceU));
121 }
122 
123 // Generally, we assume that everything forwards to |StringVAppendf()|, so
124 // testing |StringPrintf()| more carefully suffices.
125 
TEST(StringPrintfTest,StringPrintfMaxSize)126 TEST(StringPrintfTest, StringPrintfMaxSize) {
127   std::string stuff(kStackBufferSize - 1, 'x');
128   std::string format = "%s";
129   EXPECT_EQ(stuff, StringPrintf(format.c_str(), stuff.c_str()));
130 }
131 
TEST(StringPrintfTest,StringPrintfTruncated)132 TEST(StringPrintfTest, StringPrintfTruncated) {
133   std::string stuff(kStackBufferSize, 'x');
134   std::string format = "%s";
135   // One char in kStackBufferSize will be used for null terminator, so one char
136   // in |stuff| will be truncated.
137   std::string expected(kStackBufferSize - 1, 'x');
138   EXPECT_EQ(expected, StringPrintf(format.c_str(), stuff.c_str()));
139 }
140 
141 }  // namespace
142 }  // namespace bt_lib_cpp_string
143