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/string_builder.h"
16*61c4878aSAndroid Build Coastguard Worker
17*61c4878aSAndroid Build Coastguard Worker #include <cinttypes>
18*61c4878aSAndroid Build Coastguard Worker #include <cmath>
19*61c4878aSAndroid Build Coastguard Worker #include <cstdint>
20*61c4878aSAndroid Build Coastguard Worker #include <cstring>
21*61c4878aSAndroid Build Coastguard Worker #include <string_view>
22*61c4878aSAndroid Build Coastguard Worker
23*61c4878aSAndroid Build Coastguard Worker #include "pw_span/span.h"
24*61c4878aSAndroid Build Coastguard Worker #include "pw_string/format.h"
25*61c4878aSAndroid Build Coastguard Worker #include "pw_unit_test/framework.h"
26*61c4878aSAndroid Build Coastguard Worker
27*61c4878aSAndroid Build Coastguard Worker namespace this_pw_test {
28*61c4878aSAndroid Build Coastguard Worker
29*61c4878aSAndroid Build Coastguard Worker struct CustomType {
30*61c4878aSAndroid Build Coastguard Worker uint32_t a;
31*61c4878aSAndroid Build Coastguard Worker uint32_t b;
32*61c4878aSAndroid Build Coastguard Worker
33*61c4878aSAndroid Build Coastguard Worker static constexpr const char* kToString = "This is a CustomType";
34*61c4878aSAndroid Build Coastguard Worker
35*61c4878aSAndroid Build Coastguard Worker CustomType() = default;
36*61c4878aSAndroid Build Coastguard Worker
37*61c4878aSAndroid Build Coastguard Worker // Non-copyable to verify StringBuffer's << operator doesn't copy it.
38*61c4878aSAndroid Build Coastguard Worker CustomType(const CustomType&) = delete;
39*61c4878aSAndroid Build Coastguard Worker CustomType& operator=(const CustomType&) = delete;
40*61c4878aSAndroid Build Coastguard Worker };
41*61c4878aSAndroid Build Coastguard Worker
42*61c4878aSAndroid Build Coastguard Worker } // namespace this_pw_test
43*61c4878aSAndroid Build Coastguard Worker
44*61c4878aSAndroid Build Coastguard Worker namespace pw {
45*61c4878aSAndroid Build Coastguard Worker
46*61c4878aSAndroid Build Coastguard Worker template <>
ToString(const this_pw_test::CustomType &,span<char> buffer)47*61c4878aSAndroid Build Coastguard Worker StatusWithSize ToString<this_pw_test::CustomType>(
48*61c4878aSAndroid Build Coastguard Worker const this_pw_test::CustomType&, span<char> buffer) {
49*61c4878aSAndroid Build Coastguard Worker return string::Format(buffer, this_pw_test::CustomType::kToString);
50*61c4878aSAndroid Build Coastguard Worker }
51*61c4878aSAndroid Build Coastguard Worker
52*61c4878aSAndroid Build Coastguard Worker } // namespace pw
53*61c4878aSAndroid Build Coastguard Worker
54*61c4878aSAndroid Build Coastguard Worker namespace pw {
55*61c4878aSAndroid Build Coastguard Worker namespace {
56*61c4878aSAndroid Build Coastguard Worker
57*61c4878aSAndroid Build Coastguard Worker using this_pw_test::CustomType;
58*61c4878aSAndroid Build Coastguard Worker
TEST(StringBuilder,EmptyBuffer_SizeAndMaxSizeAreCorrect)59*61c4878aSAndroid Build Coastguard Worker TEST(StringBuilder, EmptyBuffer_SizeAndMaxSizeAreCorrect) {
60*61c4878aSAndroid Build Coastguard Worker StringBuilder sb(span<char>{});
61*61c4878aSAndroid Build Coastguard Worker
62*61c4878aSAndroid Build Coastguard Worker EXPECT_TRUE(sb.empty());
63*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(0u, sb.size());
64*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(0u, sb.max_size());
65*61c4878aSAndroid Build Coastguard Worker }
66*61c4878aSAndroid Build Coastguard Worker
67*61c4878aSAndroid Build Coastguard Worker using namespace std::literals::string_view_literals;
68*61c4878aSAndroid Build Coastguard Worker
69*61c4878aSAndroid Build Coastguard Worker constexpr std::string_view kNoTouch = "DO NOT TOUCH\0VALUE SHOULD NOT CHANGE"sv;
70*61c4878aSAndroid Build Coastguard Worker
TEST(StringBuilder,EmptyBuffer_StreamOutput_WritesNothing)71*61c4878aSAndroid Build Coastguard Worker TEST(StringBuilder, EmptyBuffer_StreamOutput_WritesNothing) {
72*61c4878aSAndroid Build Coastguard Worker char buffer[kNoTouch.size()];
73*61c4878aSAndroid Build Coastguard Worker std::memcpy(buffer, kNoTouch.data(), sizeof(buffer));
74*61c4878aSAndroid Build Coastguard Worker
75*61c4878aSAndroid Build Coastguard Worker StringBuilder sb(span(buffer, 0));
76*61c4878aSAndroid Build Coastguard Worker
77*61c4878aSAndroid Build Coastguard Worker sb << CustomType() << " is " << 12345;
78*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(Status::ResourceExhausted(), sb.status());
79*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(kNoTouch, std::string_view(buffer, sizeof(buffer)));
80*61c4878aSAndroid Build Coastguard Worker }
81*61c4878aSAndroid Build Coastguard Worker
TEST(StringBuilder,EmptyBuffer_Append_WritesNothing)82*61c4878aSAndroid Build Coastguard Worker TEST(StringBuilder, EmptyBuffer_Append_WritesNothing) {
83*61c4878aSAndroid Build Coastguard Worker char buffer[kNoTouch.size()];
84*61c4878aSAndroid Build Coastguard Worker std::memcpy(buffer, kNoTouch.data(), sizeof(buffer));
85*61c4878aSAndroid Build Coastguard Worker
86*61c4878aSAndroid Build Coastguard Worker StringBuilder sb(span(buffer, 0));
87*61c4878aSAndroid Build Coastguard Worker
88*61c4878aSAndroid Build Coastguard Worker EXPECT_FALSE(sb.append("Hello").ok());
89*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(kNoTouch, std::string_view(buffer, sizeof(buffer)));
90*61c4878aSAndroid Build Coastguard Worker }
91*61c4878aSAndroid Build Coastguard Worker
TEST(StringBuilder,EmptyBuffer_Resize_WritesNothing)92*61c4878aSAndroid Build Coastguard Worker TEST(StringBuilder, EmptyBuffer_Resize_WritesNothing) {
93*61c4878aSAndroid Build Coastguard Worker char buffer[kNoTouch.size()];
94*61c4878aSAndroid Build Coastguard Worker std::memcpy(buffer, kNoTouch.data(), sizeof(buffer));
95*61c4878aSAndroid Build Coastguard Worker
96*61c4878aSAndroid Build Coastguard Worker StringBuilder sb(span(buffer, 0));
97*61c4878aSAndroid Build Coastguard Worker
98*61c4878aSAndroid Build Coastguard Worker sb.resize(0);
99*61c4878aSAndroid Build Coastguard Worker EXPECT_TRUE(sb.ok());
100*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(kNoTouch, std::string_view(buffer, sizeof(buffer)));
101*61c4878aSAndroid Build Coastguard Worker }
102*61c4878aSAndroid Build Coastguard Worker
TEST(StringBuilder,EmptyBuffer_AppendEmpty_ResourceExhausted)103*61c4878aSAndroid Build Coastguard Worker TEST(StringBuilder, EmptyBuffer_AppendEmpty_ResourceExhausted) {
104*61c4878aSAndroid Build Coastguard Worker StringBuilder sb(span<char>{});
105*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(OkStatus(), sb.last_status());
106*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(OkStatus(), sb.status());
107*61c4878aSAndroid Build Coastguard Worker
108*61c4878aSAndroid Build Coastguard Worker sb << "";
109*61c4878aSAndroid Build Coastguard Worker
110*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(Status::ResourceExhausted(), sb.last_status());
111*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(Status::ResourceExhausted(), sb.status());
112*61c4878aSAndroid Build Coastguard Worker }
113*61c4878aSAndroid Build Coastguard Worker
TEST(StringBuilder,Status_StartsOk)114*61c4878aSAndroid Build Coastguard Worker TEST(StringBuilder, Status_StartsOk) {
115*61c4878aSAndroid Build Coastguard Worker StringBuffer<16> sb;
116*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(OkStatus(), sb.status());
117*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(OkStatus(), sb.last_status());
118*61c4878aSAndroid Build Coastguard Worker }
119*61c4878aSAndroid Build Coastguard Worker
TEST(StringBuilder,Status_StatusAndLastStatusUpdate)120*61c4878aSAndroid Build Coastguard Worker TEST(StringBuilder, Status_StatusAndLastStatusUpdate) {
121*61c4878aSAndroid Build Coastguard Worker StringBuffer<16> sb;
122*61c4878aSAndroid Build Coastguard Worker sb << "Well, if only there were enough room in here for this string";
123*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(Status::ResourceExhausted(), sb.status());
124*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(Status::ResourceExhausted(), sb.last_status());
125*61c4878aSAndroid Build Coastguard Worker
126*61c4878aSAndroid Build Coastguard Worker sb.resize(1029);
127*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(Status::OutOfRange(), sb.status());
128*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(Status::OutOfRange(), sb.last_status());
129*61c4878aSAndroid Build Coastguard Worker
130*61c4878aSAndroid Build Coastguard Worker sb << "";
131*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(Status::OutOfRange(), sb.status());
132*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(OkStatus(), sb.last_status());
133*61c4878aSAndroid Build Coastguard Worker }
134*61c4878aSAndroid Build Coastguard Worker
TEST(StringBuilder,Status_ClearStatus_SetsStatuesToOk)135*61c4878aSAndroid Build Coastguard Worker TEST(StringBuilder, Status_ClearStatus_SetsStatuesToOk) {
136*61c4878aSAndroid Build Coastguard Worker StringBuffer<2> sb = MakeString<2>("Won't fit!!!!!");
137*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(Status::ResourceExhausted(), sb.status());
138*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(Status::ResourceExhausted(), sb.last_status());
139*61c4878aSAndroid Build Coastguard Worker
140*61c4878aSAndroid Build Coastguard Worker sb.clear_status();
141*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(OkStatus(), sb.status());
142*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(OkStatus(), sb.last_status());
143*61c4878aSAndroid Build Coastguard Worker }
144*61c4878aSAndroid Build Coastguard Worker
TEST(StringBuilder,StreamOutput_OutputSelf)145*61c4878aSAndroid Build Coastguard Worker TEST(StringBuilder, StreamOutput_OutputSelf) {
146*61c4878aSAndroid Build Coastguard Worker auto sb = MakeString<32>("echo!");
147*61c4878aSAndroid Build Coastguard Worker sb << sb;
148*61c4878aSAndroid Build Coastguard Worker
149*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ("echo!echo!", sb.data());
150*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(10u, sb.size());
151*61c4878aSAndroid Build Coastguard Worker }
152*61c4878aSAndroid Build Coastguard Worker
TEST(StringBuilder,PushBack)153*61c4878aSAndroid Build Coastguard Worker TEST(StringBuilder, PushBack) {
154*61c4878aSAndroid Build Coastguard Worker StringBuffer<12> sb;
155*61c4878aSAndroid Build Coastguard Worker sb.push_back('?');
156*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(OkStatus(), sb.last_status());
157*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(1u, sb.size());
158*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ("?", sb.data());
159*61c4878aSAndroid Build Coastguard Worker }
160*61c4878aSAndroid Build Coastguard Worker
TEST(StringBuilder,PushBack_Full)161*61c4878aSAndroid Build Coastguard Worker TEST(StringBuilder, PushBack_Full) {
162*61c4878aSAndroid Build Coastguard Worker StringBuffer<1> sb;
163*61c4878aSAndroid Build Coastguard Worker sb.push_back('!');
164*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(Status::ResourceExhausted(), sb.last_status());
165*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(0u, sb.size());
166*61c4878aSAndroid Build Coastguard Worker }
167*61c4878aSAndroid Build Coastguard Worker
TEST(StringBuilder,PopBack)168*61c4878aSAndroid Build Coastguard Worker TEST(StringBuilder, PopBack) {
169*61c4878aSAndroid Build Coastguard Worker auto sb = MakeString<12>("Welcome!");
170*61c4878aSAndroid Build Coastguard Worker sb.pop_back();
171*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(OkStatus(), sb.last_status());
172*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(7u, sb.size());
173*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ("Welcome", sb.data());
174*61c4878aSAndroid Build Coastguard Worker }
175*61c4878aSAndroid Build Coastguard Worker
TEST(StringBuilder,PopBack_Empty)176*61c4878aSAndroid Build Coastguard Worker TEST(StringBuilder, PopBack_Empty) {
177*61c4878aSAndroid Build Coastguard Worker StringBuffer<12> sb;
178*61c4878aSAndroid Build Coastguard Worker sb.pop_back();
179*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(Status::OutOfRange(), sb.last_status());
180*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(0u, sb.size());
181*61c4878aSAndroid Build Coastguard Worker }
182*61c4878aSAndroid Build Coastguard Worker
TEST(StringBuilder,Append_NonTerminatedString)183*61c4878aSAndroid Build Coastguard Worker TEST(StringBuilder, Append_NonTerminatedString) {
184*61c4878aSAndroid Build Coastguard Worker static char bad_string[256];
185*61c4878aSAndroid Build Coastguard Worker std::memset(bad_string, '?', sizeof(bad_string));
186*61c4878aSAndroid Build Coastguard Worker
187*61c4878aSAndroid Build Coastguard Worker StringBuffer<6> sb;
188*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(Status::ResourceExhausted(), sb.append(bad_string).last_status());
189*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ("?????", sb.data());
190*61c4878aSAndroid Build Coastguard Worker }
191*61c4878aSAndroid Build Coastguard Worker
TEST(StringBuilder,Append_Chars)192*61c4878aSAndroid Build Coastguard Worker TEST(StringBuilder, Append_Chars) {
193*61c4878aSAndroid Build Coastguard Worker StringBuffer<8> sb;
194*61c4878aSAndroid Build Coastguard Worker
195*61c4878aSAndroid Build Coastguard Worker size_t count = 7;
196*61c4878aSAndroid Build Coastguard Worker EXPECT_TRUE(sb.append(count, '?').ok());
197*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ("???????", sb.data());
198*61c4878aSAndroid Build Coastguard Worker }
199*61c4878aSAndroid Build Coastguard Worker
TEST(StringBuilder,Append_Chars_Full)200*61c4878aSAndroid Build Coastguard Worker TEST(StringBuilder, Append_Chars_Full) {
201*61c4878aSAndroid Build Coastguard Worker StringBuffer<8> sb;
202*61c4878aSAndroid Build Coastguard Worker
203*61c4878aSAndroid Build Coastguard Worker size_t count = 8;
204*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(Status::ResourceExhausted(), sb.append(count, '?').last_status());
205*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ("???????", sb.data());
206*61c4878aSAndroid Build Coastguard Worker }
207*61c4878aSAndroid Build Coastguard Worker
TEST(StringBuilder,Append_Chars_ToEmpty)208*61c4878aSAndroid Build Coastguard Worker TEST(StringBuilder, Append_Chars_ToEmpty) {
209*61c4878aSAndroid Build Coastguard Worker StringBuilder sb(span<char>{});
210*61c4878aSAndroid Build Coastguard Worker
211*61c4878aSAndroid Build Coastguard Worker size_t count = 1;
212*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(Status::ResourceExhausted(), sb.append(count, '?').last_status());
213*61c4878aSAndroid Build Coastguard Worker }
214*61c4878aSAndroid Build Coastguard Worker
TEST(StringBuilder,Append_PartialCString)215*61c4878aSAndroid Build Coastguard Worker TEST(StringBuilder, Append_PartialCString) {
216*61c4878aSAndroid Build Coastguard Worker StringBuffer<12> sb;
217*61c4878aSAndroid Build Coastguard Worker size_t count = 4;
218*61c4878aSAndroid Build Coastguard Worker EXPECT_TRUE(sb.append("123456", count).ok());
219*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(4u, sb.size());
220*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ("1234", sb.data());
221*61c4878aSAndroid Build Coastguard Worker }
222*61c4878aSAndroid Build Coastguard Worker
TEST(StringBuilder,Append_CString)223*61c4878aSAndroid Build Coastguard Worker TEST(StringBuilder, Append_CString) {
224*61c4878aSAndroid Build Coastguard Worker auto sb = MakeString("hello");
225*61c4878aSAndroid Build Coastguard Worker EXPECT_TRUE(sb.append(" goodbye").ok());
226*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ("hello goodbye", sb.data());
227*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(13u, sb.size());
228*61c4878aSAndroid Build Coastguard Worker }
229*61c4878aSAndroid Build Coastguard Worker
TEST(StringBuilder,Append_CString_Full)230*61c4878aSAndroid Build Coastguard Worker TEST(StringBuilder, Append_CString_Full) {
231*61c4878aSAndroid Build Coastguard Worker auto sb = MakeString<6>("hello");
232*61c4878aSAndroid Build Coastguard Worker size_t count = 1;
233*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(Status::ResourceExhausted(),
234*61c4878aSAndroid Build Coastguard Worker sb.append("890123", count).last_status());
235*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(Status::ResourceExhausted(), sb.status());
236*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(sb.max_size(), sb.size());
237*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ("hello", sb.data());
238*61c4878aSAndroid Build Coastguard Worker }
239*61c4878aSAndroid Build Coastguard Worker
TEST(StringBuilder,Append_StringView)240*61c4878aSAndroid Build Coastguard Worker TEST(StringBuilder, Append_StringView) {
241*61c4878aSAndroid Build Coastguard Worker auto sb = MakeString<32>("hello");
242*61c4878aSAndroid Build Coastguard Worker EXPECT_TRUE(sb.append("???"sv).ok());
243*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ("hello???"sv, sb);
244*61c4878aSAndroid Build Coastguard Worker }
245*61c4878aSAndroid Build Coastguard Worker
TEST(StringBuilder,Append_StringView_Substring)246*61c4878aSAndroid Build Coastguard Worker TEST(StringBuilder, Append_StringView_Substring) {
247*61c4878aSAndroid Build Coastguard Worker auto sb = MakeString<32>("I like ");
248*61c4878aSAndroid Build Coastguard Worker size_t position = 5;
249*61c4878aSAndroid Build Coastguard Worker size_t count = 5;
250*61c4878aSAndroid Build Coastguard Worker EXPECT_TRUE(sb.append("your shoes!!!"sv, position, count).ok());
251*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ("I like shoes"sv, sb);
252*61c4878aSAndroid Build Coastguard Worker }
253*61c4878aSAndroid Build Coastguard Worker
TEST(StringBuilder,Append_StringView_RemainingSubstring)254*61c4878aSAndroid Build Coastguard Worker TEST(StringBuilder, Append_StringView_RemainingSubstring) {
255*61c4878aSAndroid Build Coastguard Worker auto sb = MakeString<32>("I like ");
256*61c4878aSAndroid Build Coastguard Worker size_t count = 5;
257*61c4878aSAndroid Build Coastguard Worker EXPECT_TRUE(sb.append("your shoes!!!"sv, count).ok());
258*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ("I like shoes!!!"sv, sb);
259*61c4878aSAndroid Build Coastguard Worker }
260*61c4878aSAndroid Build Coastguard Worker
TEST(StringBuilder,Resize_Smaller)261*61c4878aSAndroid Build Coastguard Worker TEST(StringBuilder, Resize_Smaller) {
262*61c4878aSAndroid Build Coastguard Worker auto sb = MakeString<12>("Four");
263*61c4878aSAndroid Build Coastguard Worker sb.resize(2);
264*61c4878aSAndroid Build Coastguard Worker EXPECT_TRUE(sb.ok());
265*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(2u, sb.size());
266*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ("Fo", sb.data());
267*61c4878aSAndroid Build Coastguard Worker }
268*61c4878aSAndroid Build Coastguard Worker
TEST(StringBuilder,Resize_Clear)269*61c4878aSAndroid Build Coastguard Worker TEST(StringBuilder, Resize_Clear) {
270*61c4878aSAndroid Build Coastguard Worker auto sb = MakeString<12>("Four");
271*61c4878aSAndroid Build Coastguard Worker sb.resize(0);
272*61c4878aSAndroid Build Coastguard Worker EXPECT_TRUE(sb.ok());
273*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(0u, sb.size());
274*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ("", sb.data());
275*61c4878aSAndroid Build Coastguard Worker }
276*61c4878aSAndroid Build Coastguard Worker
TEST(StringBuilder,Resize_Larger_Fails)277*61c4878aSAndroid Build Coastguard Worker TEST(StringBuilder, Resize_Larger_Fails) {
278*61c4878aSAndroid Build Coastguard Worker auto sb = MakeString<12>("Four");
279*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(4u, sb.size());
280*61c4878aSAndroid Build Coastguard Worker sb.resize(10);
281*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(sb.status(), Status::OutOfRange());
282*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(4u, sb.size());
283*61c4878aSAndroid Build Coastguard Worker }
284*61c4878aSAndroid Build Coastguard Worker
TEST(StringBuilder,Resize_LargerThanCapacity_Fails)285*61c4878aSAndroid Build Coastguard Worker TEST(StringBuilder, Resize_LargerThanCapacity_Fails) {
286*61c4878aSAndroid Build Coastguard Worker auto sb = MakeString<12>("Four");
287*61c4878aSAndroid Build Coastguard Worker sb.resize(1234);
288*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(sb.status(), Status::OutOfRange());
289*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(4u, sb.size());
290*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ("Four", sb.data());
291*61c4878aSAndroid Build Coastguard Worker }
292*61c4878aSAndroid Build Coastguard Worker
TEST(StringBuilder,Format_Normal)293*61c4878aSAndroid Build Coastguard Worker TEST(StringBuilder, Format_Normal) {
294*61c4878aSAndroid Build Coastguard Worker std::byte buffer[64];
295*61c4878aSAndroid Build Coastguard Worker StringBuilder sb(buffer);
296*61c4878aSAndroid Build Coastguard Worker EXPECT_TRUE(sb.Format("0x%x", 0xabc).ok());
297*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ("0xabc", sb.data());
298*61c4878aSAndroid Build Coastguard Worker
299*61c4878aSAndroid Build Coastguard Worker sb << "def";
300*61c4878aSAndroid Build Coastguard Worker
301*61c4878aSAndroid Build Coastguard Worker EXPECT_TRUE(sb.Format("GHI").ok());
302*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ("0xabcdefGHI", sb.data());
303*61c4878aSAndroid Build Coastguard Worker }
304*61c4878aSAndroid Build Coastguard Worker
TEST(StringBuilder,Format_ExhaustBuffer)305*61c4878aSAndroid Build Coastguard Worker TEST(StringBuilder, Format_ExhaustBuffer) {
306*61c4878aSAndroid Build Coastguard Worker StringBuffer<6> sb;
307*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(Status::ResourceExhausted(), sb.Format("012345").status());
308*61c4878aSAndroid Build Coastguard Worker
309*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ("01234", sb.data());
310*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(Status::ResourceExhausted(), sb.status());
311*61c4878aSAndroid Build Coastguard Worker }
312*61c4878aSAndroid Build Coastguard Worker
TEST(StringBuilder,StreamOutput_MultipleTypes)313*61c4878aSAndroid Build Coastguard Worker TEST(StringBuilder, StreamOutput_MultipleTypes) {
314*61c4878aSAndroid Build Coastguard Worker constexpr const char* kExpected = "This is -1true example\n of this";
315*61c4878aSAndroid Build Coastguard Worker constexpr const char* kExample = "example";
316*61c4878aSAndroid Build Coastguard Worker
317*61c4878aSAndroid Build Coastguard Worker StringBuffer<64> sb;
318*61c4878aSAndroid Build Coastguard Worker sb << "This is " << -1 << true << ' ' << kExample << '\n' << " of this";
319*61c4878aSAndroid Build Coastguard Worker
320*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ(kExpected, sb.data());
321*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(std::strlen(kExpected), sb.size());
322*61c4878aSAndroid Build Coastguard Worker }
323*61c4878aSAndroid Build Coastguard Worker
TEST(StringBuilder,StreamOutput_FullBufferIgnoresExtraStrings)324*61c4878aSAndroid Build Coastguard Worker TEST(StringBuilder, StreamOutput_FullBufferIgnoresExtraStrings) {
325*61c4878aSAndroid Build Coastguard Worker StringBuffer<6> sb;
326*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(5u, sb.max_size()); // max_size() excludes the null terminator
327*61c4878aSAndroid Build Coastguard Worker
328*61c4878aSAndroid Build Coastguard Worker sb << 1 - 1;
329*61c4878aSAndroid Build Coastguard Worker EXPECT_TRUE(sb.ok());
330*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ("0", sb.data());
331*61c4878aSAndroid Build Coastguard Worker
332*61c4878aSAndroid Build Coastguard Worker sb << true << "Now it's way " << static_cast<unsigned char>(2) << " long";
333*61c4878aSAndroid Build Coastguard Worker EXPECT_FALSE(sb.ok());
334*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(Status::ResourceExhausted(), sb.status());
335*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ("0true", sb.data());
336*61c4878aSAndroid Build Coastguard Worker }
337*61c4878aSAndroid Build Coastguard Worker
TEST(StringBuilder,StreamOutput_ExhaustBuffer_InOneString)338*61c4878aSAndroid Build Coastguard Worker TEST(StringBuilder, StreamOutput_ExhaustBuffer_InOneString) {
339*61c4878aSAndroid Build Coastguard Worker StringBuffer<9> sb;
340*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(8u, sb.max_size());
341*61c4878aSAndroid Build Coastguard Worker
342*61c4878aSAndroid Build Coastguard Worker sb << "0123456789"; // write 10 chars
343*61c4878aSAndroid Build Coastguard Worker EXPECT_FALSE(sb.ok());
344*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ("01234567", sb.data()); // only can fit 8
345*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(8u, sb.size());
346*61c4878aSAndroid Build Coastguard Worker
347*61c4878aSAndroid Build Coastguard Worker sb << "no"
348*61c4878aSAndroid Build Coastguard Worker << " more "
349*61c4878aSAndroid Build Coastguard Worker << "room" << '?';
350*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ("01234567", sb.data());
351*61c4878aSAndroid Build Coastguard Worker }
352*61c4878aSAndroid Build Coastguard Worker
TEST(StringBuilder,StreamOutput_ExhaustBuffer_InTwoStrings)353*61c4878aSAndroid Build Coastguard Worker TEST(StringBuilder, StreamOutput_ExhaustBuffer_InTwoStrings) {
354*61c4878aSAndroid Build Coastguard Worker StringBuffer<4> sb;
355*61c4878aSAndroid Build Coastguard Worker
356*61c4878aSAndroid Build Coastguard Worker sb << "01"; // fill 3/4 of buffer
357*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(2u, sb.size());
358*61c4878aSAndroid Build Coastguard Worker sb << "234";
359*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ("012", sb.data());
360*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(Status::ResourceExhausted(), sb.status());
361*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(3u, sb.size());
362*61c4878aSAndroid Build Coastguard Worker }
363*61c4878aSAndroid Build Coastguard Worker
TEST(StringBuilder,StreamOutput_NonTerminatedString)364*61c4878aSAndroid Build Coastguard Worker TEST(StringBuilder, StreamOutput_NonTerminatedString) {
365*61c4878aSAndroid Build Coastguard Worker static char bad_string[256];
366*61c4878aSAndroid Build Coastguard Worker std::memset(bad_string, '?', sizeof(bad_string));
367*61c4878aSAndroid Build Coastguard Worker
368*61c4878aSAndroid Build Coastguard Worker StringBuffer<6> sb;
369*61c4878aSAndroid Build Coastguard Worker sb << "hey" << bad_string;
370*61c4878aSAndroid Build Coastguard Worker
371*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(Status::ResourceExhausted(), sb.status());
372*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ("hey??", sb.data());
373*61c4878aSAndroid Build Coastguard Worker }
374*61c4878aSAndroid Build Coastguard Worker
TEST(StringBuilder,SteamOutput_StringView)375*61c4878aSAndroid Build Coastguard Worker TEST(StringBuilder, SteamOutput_StringView) {
376*61c4878aSAndroid Build Coastguard Worker StringBuffer<6> buffer;
377*61c4878aSAndroid Build Coastguard Worker constexpr std::string_view hello("hello");
378*61c4878aSAndroid Build Coastguard Worker
379*61c4878aSAndroid Build Coastguard Worker buffer << hello;
380*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(OkStatus(), buffer.status());
381*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ("hello", buffer.data());
382*61c4878aSAndroid Build Coastguard Worker }
383*61c4878aSAndroid Build Coastguard Worker
TEST(StringBuilder,StreamOutput_EmptyStringView)384*61c4878aSAndroid Build Coastguard Worker TEST(StringBuilder, StreamOutput_EmptyStringView) {
385*61c4878aSAndroid Build Coastguard Worker StringBuffer<4> buffer;
386*61c4878aSAndroid Build Coastguard Worker buffer << "hi" << std::string_view() << "!";
387*61c4878aSAndroid Build Coastguard Worker EXPECT_TRUE(buffer.ok());
388*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ("hi!", buffer.data());
389*61c4878aSAndroid Build Coastguard Worker }
390*61c4878aSAndroid Build Coastguard Worker
TEST(StringBuilder,StreamOutput_ByteArray)391*61c4878aSAndroid Build Coastguard Worker TEST(StringBuilder, StreamOutput_ByteArray) {
392*61c4878aSAndroid Build Coastguard Worker StringBuffer<7> buffer;
393*61c4878aSAndroid Build Coastguard Worker std::array<std::byte, 3> data{
394*61c4878aSAndroid Build Coastguard Worker {std::byte(0xc8), std::byte(0x02), std::byte(0x41)}};
395*61c4878aSAndroid Build Coastguard Worker buffer << data;
396*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(buffer.status(), OkStatus());
397*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ("c80241", buffer.data());
398*61c4878aSAndroid Build Coastguard Worker }
399*61c4878aSAndroid Build Coastguard Worker
TEST(StringBuilder,StreamOutput_ByteSpan)400*61c4878aSAndroid Build Coastguard Worker TEST(StringBuilder, StreamOutput_ByteSpan) {
401*61c4878aSAndroid Build Coastguard Worker StringBuffer<11> buffer;
402*61c4878aSAndroid Build Coastguard Worker std::array<std::byte, 5> data{{std::byte(0),
403*61c4878aSAndroid Build Coastguard Worker std::byte(0xc8),
404*61c4878aSAndroid Build Coastguard Worker std::byte(0x02),
405*61c4878aSAndroid Build Coastguard Worker std::byte(0x41),
406*61c4878aSAndroid Build Coastguard Worker std::byte(0xe0)}};
407*61c4878aSAndroid Build Coastguard Worker buffer << as_bytes(span(data));
408*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(buffer.status(), OkStatus());
409*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ("00c80241e0", buffer.data());
410*61c4878aSAndroid Build Coastguard Worker }
411*61c4878aSAndroid Build Coastguard Worker
TEST(StringBuilder,StreamOutput_ByteSpanOutOfSpace)412*61c4878aSAndroid Build Coastguard Worker TEST(StringBuilder, StreamOutput_ByteSpanOutOfSpace) {
413*61c4878aSAndroid Build Coastguard Worker StringBuffer<4> buffer;
414*61c4878aSAndroid Build Coastguard Worker std::array<uint8_t, 3> data{{0xc8, 0x02, 0x41}};
415*61c4878aSAndroid Build Coastguard Worker buffer << as_bytes(span(data));
416*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(buffer.status(), Status::ResourceExhausted());
417*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ("", buffer.data());
418*61c4878aSAndroid Build Coastguard Worker }
419*61c4878aSAndroid Build Coastguard Worker
TEST(StringBuffer,Assign)420*61c4878aSAndroid Build Coastguard Worker TEST(StringBuffer, Assign) {
421*61c4878aSAndroid Build Coastguard Worker StringBuffer<10> one;
422*61c4878aSAndroid Build Coastguard Worker StringBuffer<10> two;
423*61c4878aSAndroid Build Coastguard Worker
424*61c4878aSAndroid Build Coastguard Worker one << "What";
425*61c4878aSAndroid Build Coastguard Worker ASSERT_STREQ("What", one.data());
426*61c4878aSAndroid Build Coastguard Worker two = one;
427*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ("What", two.data());
428*61c4878aSAndroid Build Coastguard Worker EXPECT_NE(one.data(), two.data());
429*61c4878aSAndroid Build Coastguard Worker one << " the";
430*61c4878aSAndroid Build Coastguard Worker two << " heck";
431*61c4878aSAndroid Build Coastguard Worker
432*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ("What the", one.data());
433*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ("What heck", two.data());
434*61c4878aSAndroid Build Coastguard Worker
435*61c4878aSAndroid Build Coastguard Worker two << "0123456789";
436*61c4878aSAndroid Build Coastguard Worker ASSERT_STREQ("What heck", two.data());
437*61c4878aSAndroid Build Coastguard Worker ASSERT_EQ(Status::ResourceExhausted(), two.status());
438*61c4878aSAndroid Build Coastguard Worker ASSERT_EQ(Status::ResourceExhausted(), two.last_status());
439*61c4878aSAndroid Build Coastguard Worker
440*61c4878aSAndroid Build Coastguard Worker one = two;
441*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ("What heck", one.data());
442*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(Status::ResourceExhausted(), one.status());
443*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(Status::ResourceExhausted(), one.last_status());
444*61c4878aSAndroid Build Coastguard Worker
445*61c4878aSAndroid Build Coastguard Worker StringBuffer<12> three;
446*61c4878aSAndroid Build Coastguard Worker three = two;
447*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ(three.data(), two.data());
448*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(three.size(), two.size());
449*61c4878aSAndroid Build Coastguard Worker }
450*61c4878aSAndroid Build Coastguard Worker
TEST(StringBuffer,CopyConstructFromSameSize)451*61c4878aSAndroid Build Coastguard Worker TEST(StringBuffer, CopyConstructFromSameSize) {
452*61c4878aSAndroid Build Coastguard Worker StringBuffer<10> one;
453*61c4878aSAndroid Build Coastguard Worker
454*61c4878aSAndroid Build Coastguard Worker one << "What";
455*61c4878aSAndroid Build Coastguard Worker ASSERT_STREQ("What", one.data());
456*61c4878aSAndroid Build Coastguard Worker StringBuffer<10> two(one);
457*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ("What", two.data());
458*61c4878aSAndroid Build Coastguard Worker EXPECT_NE(one.data(), two.data());
459*61c4878aSAndroid Build Coastguard Worker one << " the";
460*61c4878aSAndroid Build Coastguard Worker two << " heck";
461*61c4878aSAndroid Build Coastguard Worker
462*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ("What the", one.data());
463*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ("What heck", two.data());
464*61c4878aSAndroid Build Coastguard Worker
465*61c4878aSAndroid Build Coastguard Worker two << "0123456789";
466*61c4878aSAndroid Build Coastguard Worker two << "";
467*61c4878aSAndroid Build Coastguard Worker ASSERT_STREQ("What heck", two.data());
468*61c4878aSAndroid Build Coastguard Worker ASSERT_EQ(Status::ResourceExhausted(), two.status());
469*61c4878aSAndroid Build Coastguard Worker ASSERT_EQ(OkStatus(), two.last_status());
470*61c4878aSAndroid Build Coastguard Worker }
471*61c4878aSAndroid Build Coastguard Worker
TEST(StringBuffer,CopyConstructFromSmaller)472*61c4878aSAndroid Build Coastguard Worker TEST(StringBuffer, CopyConstructFromSmaller) {
473*61c4878aSAndroid Build Coastguard Worker StringBuffer<10> one = MakeString<10>("You are the chosen one.");
474*61c4878aSAndroid Build Coastguard Worker StringBuffer<12> two(one);
475*61c4878aSAndroid Build Coastguard Worker
476*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ("You are t", two.data());
477*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(Status::ResourceExhausted(), two.status());
478*61c4878aSAndroid Build Coastguard Worker }
479*61c4878aSAndroid Build Coastguard Worker
TEST(StringBuilder,Object)480*61c4878aSAndroid Build Coastguard Worker TEST(StringBuilder, Object) {
481*61c4878aSAndroid Build Coastguard Worker StringBuffer<64> sb;
482*61c4878aSAndroid Build Coastguard Worker sb << CustomType();
483*61c4878aSAndroid Build Coastguard Worker
484*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ(CustomType::kToString, sb.data());
485*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(std::strlen(CustomType::kToString), sb.size());
486*61c4878aSAndroid Build Coastguard Worker }
487*61c4878aSAndroid Build Coastguard Worker
TEST(StringBuilder,UseStringAsBuffer)488*61c4878aSAndroid Build Coastguard Worker TEST(StringBuilder, UseStringAsBuffer) {
489*61c4878aSAndroid Build Coastguard Worker InlineString<32> string;
490*61c4878aSAndroid Build Coastguard Worker StringBuilder sb(string);
491*61c4878aSAndroid Build Coastguard Worker
492*61c4878aSAndroid Build Coastguard Worker sb << 123 << "456";
493*61c4878aSAndroid Build Coastguard Worker
494*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(sb.data(), string.data());
495*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(sb.size(), string.size());
496*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(6u, string.size());
497*61c4878aSAndroid Build Coastguard Worker
498*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ(sb.c_str(), "123456");
499*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ(string.c_str(), "123456");
500*61c4878aSAndroid Build Coastguard Worker }
501*61c4878aSAndroid Build Coastguard Worker
TEST(StringBuilder,OverflowStringAsBuffer)502*61c4878aSAndroid Build Coastguard Worker TEST(StringBuilder, OverflowStringAsBuffer) {
503*61c4878aSAndroid Build Coastguard Worker InlineString<5> string;
504*61c4878aSAndroid Build Coastguard Worker StringBuilder sb(string);
505*61c4878aSAndroid Build Coastguard Worker
506*61c4878aSAndroid Build Coastguard Worker sb << 123 << "456";
507*61c4878aSAndroid Build Coastguard Worker
508*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(sb.status(), Status::ResourceExhausted());
509*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(string.size(), 5u);
510*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ(string.c_str(), "12345");
511*61c4878aSAndroid Build Coastguard Worker }
512*61c4878aSAndroid Build Coastguard Worker
TEST(MakeString,Object)513*61c4878aSAndroid Build Coastguard Worker TEST(MakeString, Object) {
514*61c4878aSAndroid Build Coastguard Worker CustomType custom;
515*61c4878aSAndroid Build Coastguard Worker const auto sb = MakeString<64>(custom);
516*61c4878aSAndroid Build Coastguard Worker
517*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ(CustomType::kToString, sb.data());
518*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(std::strlen(CustomType::kToString), sb.size());
519*61c4878aSAndroid Build Coastguard Worker }
520*61c4878aSAndroid Build Coastguard Worker
TEST(MakeString,IntegerTypes)521*61c4878aSAndroid Build Coastguard Worker TEST(MakeString, IntegerTypes) {
522*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ("0123-4567",
523*61c4878aSAndroid Build Coastguard Worker MakeString(0ll,
524*61c4878aSAndroid Build Coastguard Worker 1u,
525*61c4878aSAndroid Build Coastguard Worker 2l,
526*61c4878aSAndroid Build Coastguard Worker 3,
527*61c4878aSAndroid Build Coastguard Worker -4,
528*61c4878aSAndroid Build Coastguard Worker static_cast<unsigned short>(5),
529*61c4878aSAndroid Build Coastguard Worker static_cast<short>(6),
530*61c4878aSAndroid Build Coastguard Worker static_cast<unsigned char>(7))
531*61c4878aSAndroid Build Coastguard Worker .data());
532*61c4878aSAndroid Build Coastguard Worker }
533*61c4878aSAndroid Build Coastguard Worker
TEST(MakeString,Char)534*61c4878aSAndroid Build Coastguard Worker TEST(MakeString, Char) {
535*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ("a b c", MakeString('a', ' ', 'b', ' ', 'c').data());
536*61c4878aSAndroid Build Coastguard Worker }
537*61c4878aSAndroid Build Coastguard Worker
TEST(MakeString,Float)538*61c4878aSAndroid Build Coastguard Worker TEST(MakeString, Float) { EXPECT_STREQ("-inf", MakeString(-INFINITY).data()); }
539*61c4878aSAndroid Build Coastguard Worker
TEST(MakeString,Pointer_Null)540*61c4878aSAndroid Build Coastguard Worker TEST(MakeString, Pointer_Null) {
541*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ("(null)", MakeString(nullptr).data());
542*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ("(null)", MakeString(static_cast<void*>(nullptr)).data());
543*61c4878aSAndroid Build Coastguard Worker }
544*61c4878aSAndroid Build Coastguard Worker
TEST(MakeString,Pointer_NonNull)545*61c4878aSAndroid Build Coastguard Worker TEST(MakeString, Pointer_NonNull) {
546*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ("1", MakeString(reinterpret_cast<void*>(0x1)).data());
547*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ("123", MakeString(reinterpret_cast<int*>(0x123)).data());
548*61c4878aSAndroid Build Coastguard Worker }
549*61c4878aSAndroid Build Coastguard Worker
TEST(MakeString,Pointer_CustomType)550*61c4878aSAndroid Build Coastguard Worker TEST(MakeString, Pointer_CustomType) {
551*61c4878aSAndroid Build Coastguard Worker char expected[32] = {};
552*61c4878aSAndroid Build Coastguard Worker
553*61c4878aSAndroid Build Coastguard Worker CustomType custom;
554*61c4878aSAndroid Build Coastguard Worker std::snprintf(expected,
555*61c4878aSAndroid Build Coastguard Worker sizeof(expected),
556*61c4878aSAndroid Build Coastguard Worker "%" PRIxPTR,
557*61c4878aSAndroid Build Coastguard Worker reinterpret_cast<uintptr_t>(&custom));
558*61c4878aSAndroid Build Coastguard Worker
559*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ(expected, MakeString(&custom).data());
560*61c4878aSAndroid Build Coastguard Worker }
561*61c4878aSAndroid Build Coastguard Worker
TEST(MakeString,Bool)562*61c4878aSAndroid Build Coastguard Worker TEST(MakeString, Bool) {
563*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ("true", MakeString(true).data());
564*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ("false", MakeString(false).data());
565*61c4878aSAndroid Build Coastguard Worker }
566*61c4878aSAndroid Build Coastguard Worker
TEST(MakeString,MutableString)567*61c4878aSAndroid Build Coastguard Worker TEST(MakeString, MutableString) {
568*61c4878aSAndroid Build Coastguard Worker char chars[] = {'C', 'o', 'o', 'l', '\0'};
569*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ("Cool?", MakeString(chars, "?").data());
570*61c4878aSAndroid Build Coastguard Worker }
571*61c4878aSAndroid Build Coastguard Worker
TEST(MakeString,Empty_IsEmpty)572*61c4878aSAndroid Build Coastguard Worker TEST(MakeString, Empty_IsEmpty) { EXPECT_TRUE(MakeString().empty()); }
573*61c4878aSAndroid Build Coastguard Worker
574*61c4878aSAndroid Build Coastguard Worker constexpr char kLongestString[] = "18446744073709551615"; // largest uint64_t
575*61c4878aSAndroid Build Coastguard Worker
TEST(MakeString,DefaultSizeString_FitsWholeString)576*61c4878aSAndroid Build Coastguard Worker TEST(MakeString, DefaultSizeString_FitsWholeString) {
577*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ(
578*61c4878aSAndroid Build Coastguard Worker kLongestString,
579*61c4878aSAndroid Build Coastguard Worker MakeString(184, "467", u'\x04', "40", '7', '3', '7', "0", "", 955ul, 1615)
580*61c4878aSAndroid Build Coastguard Worker .data());
581*61c4878aSAndroid Build Coastguard Worker }
582*61c4878aSAndroid Build Coastguard Worker
TEST(MakeString,LargerThanDefaultSize_Truncates)583*61c4878aSAndroid Build Coastguard Worker TEST(MakeString, LargerThanDefaultSize_Truncates) {
584*61c4878aSAndroid Build Coastguard Worker auto sb = MakeString("1844674407", 3709551615, 123456);
585*61c4878aSAndroid Build Coastguard Worker
586*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(Status::ResourceExhausted(), sb.status());
587*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ(kLongestString, sb.data());
588*61c4878aSAndroid Build Coastguard Worker }
589*61c4878aSAndroid Build Coastguard Worker
TEST(MakeString,StringLiteral_ResizesToFitWholeLiteral)590*61c4878aSAndroid Build Coastguard Worker TEST(MakeString, StringLiteral_ResizesToFitWholeLiteral) {
591*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ("", MakeString().data());
592*61c4878aSAndroid Build Coastguard Worker
593*61c4878aSAndroid Build Coastguard Worker [[maybe_unused]] auto normal = MakeString("");
594*61c4878aSAndroid Build Coastguard Worker static_assert(normal.max_size() == decltype(MakeString(1))::max_size());
595*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(normal.max_size(), decltype(MakeString(1))::max_size());
596*61c4878aSAndroid Build Coastguard Worker
597*61c4878aSAndroid Build Coastguard Worker [[maybe_unused]] auto resized =
598*61c4878aSAndroid Build Coastguard Worker MakeString("This string is reeeeeeeeeaaaaallly long!!!!!");
599*61c4878aSAndroid Build Coastguard Worker static_assert(resized.max_size() > decltype(MakeString(1))::max_size());
600*61c4878aSAndroid Build Coastguard Worker static_assert(resized.max_size() ==
601*61c4878aSAndroid Build Coastguard Worker sizeof("This string is reeeeeeeeeaaaaallly long!!!!!") - 1);
602*61c4878aSAndroid Build Coastguard Worker EXPECT_GT(resized.max_size(), decltype(MakeString(1))::max_size());
603*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(resized.max_size(),
604*61c4878aSAndroid Build Coastguard Worker sizeof("This string is reeeeeeeeeaaaaallly long!!!!!") - 1);
605*61c4878aSAndroid Build Coastguard Worker }
606*61c4878aSAndroid Build Coastguard Worker
TEST(MakeString,StringLiteral_UsesLongerFixedSize)607*61c4878aSAndroid Build Coastguard Worker TEST(MakeString, StringLiteral_UsesLongerFixedSize) {
608*61c4878aSAndroid Build Coastguard Worker auto fixed_size = MakeString<64>("");
609*61c4878aSAndroid Build Coastguard Worker static_assert(fixed_size.max_size() == 63u);
610*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(fixed_size.max_size(), 63u);
611*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ("", fixed_size.data());
612*61c4878aSAndroid Build Coastguard Worker }
613*61c4878aSAndroid Build Coastguard Worker
TEST(MakeString,StringLiteral_TruncatesShorterFixedSize)614*61c4878aSAndroid Build Coastguard Worker TEST(MakeString, StringLiteral_TruncatesShorterFixedSize) {
615*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ("Goo", MakeString<4>("Google").data());
616*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ("Google", MakeString<7>("Google").data());
617*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(MakeString().max_size(), MakeString("Google").max_size());
618*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ("Google", MakeString("Google").data());
619*61c4878aSAndroid Build Coastguard Worker }
620*61c4878aSAndroid Build Coastguard Worker
TEST(MakeString,DefaultSize_FitsMaxAndMinInts)621*61c4878aSAndroid Build Coastguard Worker TEST(MakeString, DefaultSize_FitsMaxAndMinInts) {
622*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ("-9223372036854775808",
623*61c4878aSAndroid Build Coastguard Worker MakeString(std::numeric_limits<int64_t>::min()).data());
624*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ("18446744073709551615",
625*61c4878aSAndroid Build Coastguard Worker MakeString(std::numeric_limits<uint64_t>::max()).data());
626*61c4878aSAndroid Build Coastguard Worker }
627*61c4878aSAndroid Build Coastguard Worker
TEST(MakeString,OutputToTemporaryStringBuffer)628*61c4878aSAndroid Build Coastguard Worker TEST(MakeString, OutputToTemporaryStringBuffer) {
629*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ("hello", (MakeString<6>("hello ") << "world").data());
630*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ("hello world", (MakeString("hello ") << "world").data());
631*61c4878aSAndroid Build Coastguard Worker }
632*61c4878aSAndroid Build Coastguard Worker
633*61c4878aSAndroid Build Coastguard Worker // Test MakeString's default size calculations.
634*61c4878aSAndroid Build Coastguard Worker template <typename... Args>
DefaultStringBufferSize(Args &&...)635*61c4878aSAndroid Build Coastguard Worker constexpr size_t DefaultStringBufferSize(Args&&...) {
636*61c4878aSAndroid Build Coastguard Worker return string_internal::DefaultStringBufferSize<Args...>();
637*61c4878aSAndroid Build Coastguard Worker }
638*61c4878aSAndroid Build Coastguard Worker
639*61c4878aSAndroid Build Coastguard Worker // Default sizes are rounded up to 24 bytes.
640*61c4878aSAndroid Build Coastguard Worker static_assert(DefaultStringBufferSize("") == 24);
641*61c4878aSAndroid Build Coastguard Worker static_assert(DefaultStringBufferSize("123") == 24);
642*61c4878aSAndroid Build Coastguard Worker static_assert(DefaultStringBufferSize("123", "456", "78901234567890") == 24);
643*61c4878aSAndroid Build Coastguard Worker static_assert(DefaultStringBufferSize("1234567890", "1234567890", "123") == 24);
644*61c4878aSAndroid Build Coastguard Worker static_assert(DefaultStringBufferSize(1234, 5678, 9012) == 24);
645*61c4878aSAndroid Build Coastguard Worker
646*61c4878aSAndroid Build Coastguard Worker // The buffer is sized to fix strings needing more than 24 bytes.
647*61c4878aSAndroid Build Coastguard Worker static_assert(DefaultStringBufferSize("1234567890", "1234567890", "1234") ==
648*61c4878aSAndroid Build Coastguard Worker 25);
649*61c4878aSAndroid Build Coastguard Worker static_assert(DefaultStringBufferSize("1234567890", "1234567890", "12345") ==
650*61c4878aSAndroid Build Coastguard Worker 26);
651*61c4878aSAndroid Build Coastguard Worker static_assert(DefaultStringBufferSize("1234567890", "1234567890", "12345678") ==
652*61c4878aSAndroid Build Coastguard Worker 29);
653*61c4878aSAndroid Build Coastguard Worker
654*61c4878aSAndroid Build Coastguard Worker // Four bytes are allocated for each non-string argument.
655*61c4878aSAndroid Build Coastguard Worker static_assert(DefaultStringBufferSize(1234, 5678, 9012, 3456, 7890, 1234) ==
656*61c4878aSAndroid Build Coastguard Worker 25);
657*61c4878aSAndroid Build Coastguard Worker static_assert(DefaultStringBufferSize('a', nullptr, 'b', 4, 5, 6, 7, 8) == 33);
658*61c4878aSAndroid Build Coastguard Worker
659*61c4878aSAndroid Build Coastguard Worker struct SomeCustomType {};
660*61c4878aSAndroid Build Coastguard Worker
operator <<(StringBuilder & sb,const SomeCustomType &)661*61c4878aSAndroid Build Coastguard Worker StringBuilder& operator<<(StringBuilder& sb, const SomeCustomType&) {
662*61c4878aSAndroid Build Coastguard Worker return sb << "SomeCustomType was here!";
663*61c4878aSAndroid Build Coastguard Worker }
664*61c4878aSAndroid Build Coastguard Worker
TEST(StringBuilder,ShiftOperatorOverload_SameNamsepace)665*61c4878aSAndroid Build Coastguard Worker TEST(StringBuilder, ShiftOperatorOverload_SameNamsepace) {
666*61c4878aSAndroid Build Coastguard Worker pw::StringBuffer<48> buffer;
667*61c4878aSAndroid Build Coastguard Worker buffer << SomeCustomType{};
668*61c4878aSAndroid Build Coastguard Worker
669*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ("SomeCustomType was here!", buffer.c_str());
670*61c4878aSAndroid Build Coastguard Worker }
671*61c4878aSAndroid Build Coastguard Worker
672*61c4878aSAndroid Build Coastguard Worker } // namespace
673*61c4878aSAndroid Build Coastguard Worker } // namespace pw
674*61c4878aSAndroid Build Coastguard Worker
675*61c4878aSAndroid Build Coastguard Worker namespace some_other_ns {
676*61c4878aSAndroid Build Coastguard Worker
677*61c4878aSAndroid Build Coastguard Worker struct MyCustomType {
678*61c4878aSAndroid Build Coastguard Worker int item;
679*61c4878aSAndroid Build Coastguard Worker };
680*61c4878aSAndroid Build Coastguard Worker
operator <<(pw::StringBuilder & sb,const MyCustomType & value)681*61c4878aSAndroid Build Coastguard Worker pw::StringBuilder& operator<<(pw::StringBuilder& sb,
682*61c4878aSAndroid Build Coastguard Worker const MyCustomType& value) {
683*61c4878aSAndroid Build Coastguard Worker return sb << "MyCustomType(" << value.item << ')';
684*61c4878aSAndroid Build Coastguard Worker }
685*61c4878aSAndroid Build Coastguard Worker
686*61c4878aSAndroid Build Coastguard Worker } // namespace some_other_ns
687*61c4878aSAndroid Build Coastguard Worker
688*61c4878aSAndroid Build Coastguard Worker namespace pw_test_namespace {
689*61c4878aSAndroid Build Coastguard Worker
TEST(StringBuilder,ShiftOperatorOverload_DifferentNamsepace)690*61c4878aSAndroid Build Coastguard Worker TEST(StringBuilder, ShiftOperatorOverload_DifferentNamsepace) {
691*61c4878aSAndroid Build Coastguard Worker pw::StringBuffer<48> buffer;
692*61c4878aSAndroid Build Coastguard Worker buffer << "This is " << some_other_ns::MyCustomType{1138};
693*61c4878aSAndroid Build Coastguard Worker
694*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ("This is MyCustomType(1138)", buffer.data());
695*61c4878aSAndroid Build Coastguard Worker }
696*61c4878aSAndroid Build Coastguard Worker
697*61c4878aSAndroid Build Coastguard Worker } // namespace pw_test_namespace
698