1 /*
2 * Copyright 2018 The WebRTC Project Authors. All rights reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11 #include "rtc_base/strings/string_builder.h"
12
13 #include <string.h>
14
15 #include "rtc_base/checks.h"
16 #include "test/gmock.h"
17 #include "test/gtest.h"
18
19 namespace rtc {
20
TEST(SimpleStringBuilder,Limit)21 TEST(SimpleStringBuilder, Limit) {
22 char sb_buf[10];
23 SimpleStringBuilder sb(sb_buf);
24 EXPECT_EQ(0u, strlen(sb.str()));
25
26 // Test that for a SSB with a buffer size of 10, that we can write 9 chars
27 // into it.
28 sb << "012345678"; // 9 characters + '\0'.
29 EXPECT_EQ(0, strcmp(sb.str(), "012345678"));
30 }
31
TEST(SimpleStringBuilder,NumbersAndChars)32 TEST(SimpleStringBuilder, NumbersAndChars) {
33 char sb_buf[100];
34 SimpleStringBuilder sb(sb_buf);
35 sb << 1 << ':' << 2.1 << ":" << 2.2f << ':' << 78187493520ll << ':'
36 << 78187493520ul;
37 EXPECT_EQ(0, strcmp(sb.str(), "1:2.1:2.2:78187493520:78187493520"));
38 }
39
TEST(SimpleStringBuilder,Format)40 TEST(SimpleStringBuilder, Format) {
41 char sb_buf[100];
42 SimpleStringBuilder sb(sb_buf);
43 sb << "Here we go - ";
44 sb.AppendFormat("This is a hex formatted value: 0x%08llx", 3735928559ULL);
45 EXPECT_EQ(0,
46 strcmp(sb.str(),
47 "Here we go - This is a hex formatted value: 0xdeadbeef"));
48 }
49
TEST(SimpleStringBuilder,StdString)50 TEST(SimpleStringBuilder, StdString) {
51 char sb_buf[100];
52 SimpleStringBuilder sb(sb_buf);
53 std::string str = "does this work?";
54 sb << str;
55 EXPECT_EQ(str, sb.str());
56 }
57
58 // These tests are safe to run if we have death test support or if DCHECKs are
59 // off.
60 #if (GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)) || !RTC_DCHECK_IS_ON
61
TEST(SimpleStringBuilderDeathTest,BufferOverrunConstCharP)62 TEST(SimpleStringBuilderDeathTest, BufferOverrunConstCharP) {
63 char sb_buf[4];
64 SimpleStringBuilder sb(sb_buf);
65 const char* const msg = "This is just too much";
66 #if RTC_DCHECK_IS_ON
67 EXPECT_DEATH(sb << msg, "");
68 #else
69 sb << msg;
70 EXPECT_THAT(sb.str(), ::testing::StrEq("Thi"));
71 #endif
72 }
73
TEST(SimpleStringBuilderDeathTest,BufferOverrunStdString)74 TEST(SimpleStringBuilderDeathTest, BufferOverrunStdString) {
75 char sb_buf[4];
76 SimpleStringBuilder sb(sb_buf);
77 sb << 12;
78 const std::string msg = "Aw, come on!";
79 #if RTC_DCHECK_IS_ON
80 EXPECT_DEATH(sb << msg, "");
81 #else
82 sb << msg;
83 EXPECT_THAT(sb.str(), ::testing::StrEq("12A"));
84 #endif
85 }
86
TEST(SimpleStringBuilderDeathTest,BufferOverrunInt)87 TEST(SimpleStringBuilderDeathTest, BufferOverrunInt) {
88 char sb_buf[4];
89 SimpleStringBuilder sb(sb_buf);
90 constexpr int num = -12345;
91 #if RTC_DCHECK_IS_ON
92 EXPECT_DEATH(sb << num, "");
93 #else
94 sb << num;
95 // If we run into the end of the buffer, resonable results are either that
96 // the append has no effect or that it's truncated at the point where the
97 // buffer ends.
98 EXPECT_THAT(sb.str(),
99 ::testing::AnyOf(::testing::StrEq(""), ::testing::StrEq("-12")));
100 #endif
101 }
102
TEST(SimpleStringBuilderDeathTest,BufferOverrunDouble)103 TEST(SimpleStringBuilderDeathTest, BufferOverrunDouble) {
104 char sb_buf[5];
105 SimpleStringBuilder sb(sb_buf);
106 constexpr double num = 123.456;
107 #if RTC_DCHECK_IS_ON
108 EXPECT_DEATH(sb << num, "");
109 #else
110 sb << num;
111 EXPECT_THAT(sb.str(),
112 ::testing::AnyOf(::testing::StrEq(""), ::testing::StrEq("123.")));
113 #endif
114 }
115
TEST(SimpleStringBuilderDeathTest,BufferOverrunConstCharPAlreadyFull)116 TEST(SimpleStringBuilderDeathTest, BufferOverrunConstCharPAlreadyFull) {
117 char sb_buf[4];
118 SimpleStringBuilder sb(sb_buf);
119 sb << 123;
120 const char* const msg = "This is just too much";
121 #if RTC_DCHECK_IS_ON
122 EXPECT_DEATH(sb << msg, "");
123 #else
124 sb << msg;
125 EXPECT_THAT(sb.str(), ::testing::StrEq("123"));
126 #endif
127 }
128
TEST(SimpleStringBuilderDeathTest,BufferOverrunIntAlreadyFull)129 TEST(SimpleStringBuilderDeathTest, BufferOverrunIntAlreadyFull) {
130 char sb_buf[4];
131 SimpleStringBuilder sb(sb_buf);
132 sb << "xyz";
133 constexpr int num = -12345;
134 #if RTC_DCHECK_IS_ON
135 EXPECT_DEATH(sb << num, "");
136 #else
137 sb << num;
138 EXPECT_THAT(sb.str(), ::testing::StrEq("xyz"));
139 #endif
140 }
141
142 #endif
143
144 ////////////////////////////////////////////////////////////////////////////////
145 // StringBuilder.
146
TEST(StringBuilder,Limit)147 TEST(StringBuilder, Limit) {
148 StringBuilder sb;
149 EXPECT_EQ(0u, sb.str().size());
150
151 sb << "012345678";
152 EXPECT_EQ(sb.str(), "012345678");
153 }
154
TEST(StringBuilder,NumbersAndChars)155 TEST(StringBuilder, NumbersAndChars) {
156 StringBuilder sb;
157 sb << 1 << ":" << 2.1 << ":" << 2.2f << ":" << 78187493520ll << ":"
158 << 78187493520ul;
159 EXPECT_THAT(sb.str(),
160 ::testing::MatchesRegex("1:2.10*:2.20*:78187493520:78187493520"));
161 }
162
TEST(StringBuilder,Format)163 TEST(StringBuilder, Format) {
164 StringBuilder sb;
165 sb << "Here we go - ";
166 sb.AppendFormat("This is a hex formatted value: 0x%08llx", 3735928559ULL);
167 EXPECT_EQ(sb.str(), "Here we go - This is a hex formatted value: 0xdeadbeef");
168 }
169
TEST(StringBuilder,StdString)170 TEST(StringBuilder, StdString) {
171 StringBuilder sb;
172 std::string str = "does this work?";
173 sb << str;
174 EXPECT_EQ(str, sb.str());
175 }
176
TEST(StringBuilder,Release)177 TEST(StringBuilder, Release) {
178 StringBuilder sb;
179 std::string str =
180 "This string has to be of a moderate length, or we might "
181 "run into problems with small object optimizations.";
182 EXPECT_LT(sizeof(str), str.size());
183 sb << str;
184 EXPECT_EQ(str, sb.str());
185 const char* original_buffer = sb.str().c_str();
186 std::string moved = sb.Release();
187 EXPECT_TRUE(sb.str().empty());
188 EXPECT_EQ(str, moved);
189 EXPECT_EQ(original_buffer, moved.c_str());
190 }
191
TEST(StringBuilder,Reset)192 TEST(StringBuilder, Reset) {
193 StringBuilder sb("abc");
194 sb << "def";
195 EXPECT_EQ("abcdef", sb.str());
196 sb.Clear();
197 EXPECT_TRUE(sb.str().empty());
198 sb << 123 << "!";
199 EXPECT_EQ("123!", sb.str());
200 }
201
202 } // namespace rtc
203