1// Copyright 2017 The Fuchsia Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include <fbl/string_buffer.h> 6 7#include <unittest/unittest.h> 8 9#define EXPECT_DATA_AND_LENGTH(expected, actual) \ 10 do { \ 11 EXPECT_STR_EQ(expected, actual.data()); \ 12 EXPECT_EQ(strlen(expected), actual.length()); \ 13 } while (false) 14 15namespace { 16 17// Note: |runnable| can't be a reference since that'd make the behavior of 18// |va_start()| undefined. 19template <typename Runnable> 20void VAListHelper(Runnable runnable, ...) { 21 va_list ap; 22 va_start(ap, runnable); 23 runnable(ap); 24 va_end(ap); 25} 26 27bool capacity_test() { 28 BEGIN_TEST; 29 30 { 31 fbl::StringBuffer<0u> buf; 32 EXPECT_EQ(0u, buf.capacity()); 33 } 34 35 { 36 fbl::StringBuffer<100u> buf; 37 EXPECT_EQ(100u, buf.capacity()); 38 } 39 40 END_TEST; 41} 42 43bool empty_string_test() { 44 BEGIN_TEST; 45 46 { 47 fbl::StringBuffer<0u> empty; 48 49 EXPECT_STR_EQ("", empty.data()); 50 EXPECT_STR_EQ("", empty.c_str()); 51 52 EXPECT_EQ(0u, empty.length()); 53 EXPECT_EQ(0u, empty.size()); 54 EXPECT_TRUE(empty.empty()); 55 EXPECT_EQ(0u, empty.capacity()); 56 57 EXPECT_STR_EQ("", empty.begin()); 58 EXPECT_EQ(0u, empty.end() - empty.begin()); 59 EXPECT_STR_EQ("", empty.cbegin()); 60 EXPECT_EQ(0u, empty.cend() - empty.cbegin()); 61 62 EXPECT_EQ(0, empty[0u]); 63 } 64 65 { 66 fbl::StringBuffer<16u> empty; 67 68 EXPECT_STR_EQ("", empty.data()); 69 EXPECT_STR_EQ("", empty.c_str()); 70 71 EXPECT_EQ(0u, empty.length()); 72 EXPECT_EQ(0u, empty.size()); 73 EXPECT_TRUE(empty.empty()); 74 EXPECT_EQ(16u, empty.capacity()); 75 76 EXPECT_STR_EQ("", empty.begin()); 77 EXPECT_EQ(0u, empty.end() - empty.begin()); 78 EXPECT_STR_EQ("", empty.cbegin()); 79 EXPECT_EQ(0u, empty.cend() - empty.cbegin()); 80 81 EXPECT_EQ(0, empty[0u]); 82 } 83 84 END_TEST; 85} 86 87bool append_test() { 88 BEGIN_TEST; 89 90 { 91 fbl::StringBuffer<16u> str; 92 str.Append('a') 93 .Append('b') 94 .Append("cd") 95 .Append("efghi", 3u) 96 .Append(fbl::StringPiece("hijkl", 3u)) 97 .Append(fbl::String("klmnopqrstuvwxyz")) 98 .Append('z') // these will be truncated away 99 .Append("zz") 100 .Append("zzzzzz", 3u) 101 .Append(fbl::StringPiece("zzzzz", 3u)) 102 .Append(fbl::String("zzzzz")); 103 104 EXPECT_STR_EQ("abcdefghijklmnop", str.data()); 105 EXPECT_STR_EQ("abcdefghijklmnop", str.c_str()); 106 107 EXPECT_EQ(16u, str.length()); 108 EXPECT_EQ(16u, str.size()); 109 EXPECT_FALSE(str.empty()); 110 EXPECT_EQ(16u, str.capacity()); 111 112 EXPECT_STR_EQ("abcdefghijklmnop", str.begin()); 113 EXPECT_EQ(16u, str.end() - str.begin()); 114 EXPECT_STR_EQ("abcdefghijklmnop", str.cbegin()); 115 EXPECT_EQ(16u, str.cend() - str.cbegin()); 116 117 EXPECT_EQ('b', str[1u]); 118 } 119 120 { 121 fbl::StringBuffer<3u> str; 122 str.Append('a'); 123 EXPECT_DATA_AND_LENGTH("a", str); 124 str.Append('b'); 125 EXPECT_DATA_AND_LENGTH("ab", str); 126 str.Append('c'); 127 EXPECT_DATA_AND_LENGTH("abc", str); 128 str.Append('d'); 129 EXPECT_DATA_AND_LENGTH("abc", str); 130 } 131 132 { 133 fbl::StringBuffer<3u> str; 134 str.Append("ab"); 135 EXPECT_DATA_AND_LENGTH("ab", str); 136 str.Append(""); 137 EXPECT_DATA_AND_LENGTH("ab", str); 138 str.Append("cdefg"); 139 EXPECT_DATA_AND_LENGTH("abc", str); 140 } 141 142 { 143 fbl::StringBuffer<3u> str; 144 str.Append("abcdef", 2u); 145 EXPECT_DATA_AND_LENGTH("ab", str); 146 str.Append("zzzz", 0u); 147 EXPECT_DATA_AND_LENGTH("ab", str); 148 str.Append("cdefghijk", 5u); 149 EXPECT_DATA_AND_LENGTH("abc", str); 150 } 151 152 { 153 fbl::StringBuffer<3u> str; 154 str.Append(fbl::StringPiece("abcdef", 2u)); 155 EXPECT_DATA_AND_LENGTH("ab", str); 156 str.Append(fbl::StringPiece("zzzz", 0u)); 157 EXPECT_DATA_AND_LENGTH("ab", str); 158 str.Append(fbl::StringPiece("cdefghijk", 5u)); 159 EXPECT_DATA_AND_LENGTH("abc", str); 160 } 161 162 { 163 fbl::StringBuffer<3u> str; 164 str.Append(fbl::String("ab")); 165 EXPECT_DATA_AND_LENGTH("ab", str); 166 str.Append(fbl::String()); 167 EXPECT_DATA_AND_LENGTH("ab", str); 168 str.Append(fbl::String("cdefg")); 169 EXPECT_DATA_AND_LENGTH("abc", str); 170 } 171 172 END_TEST; 173} 174 175bool append_printf_test() { 176 BEGIN_TEST; 177 178 { 179 fbl::StringBuffer<12u> str; 180 str.AppendPrintf("abc"); 181 EXPECT_DATA_AND_LENGTH("abc", str); 182 str.AppendPrintf("%d,%s", 20, "de").Append('f'); 183 EXPECT_DATA_AND_LENGTH("abc20,def", str); 184 str.AppendPrintf("%d", 123456789); 185 EXPECT_DATA_AND_LENGTH("abc20,def123", str); 186 } 187 188 { 189 fbl::StringBuffer<12u> str; 190 VAListHelper([&str](va_list ap) { str.AppendVPrintf("abc", ap); }); 191 EXPECT_DATA_AND_LENGTH("abc", str); 192 VAListHelper([&str](va_list ap) { str.AppendVPrintf("%d,%s", ap).Append('f'); }, 193 20, "de"); 194 EXPECT_DATA_AND_LENGTH("abc20,def", str); 195 VAListHelper([&str](va_list ap) { str.AppendVPrintf("%d", ap); }, 123456789); 196 EXPECT_DATA_AND_LENGTH("abc20,def123", str); 197 } 198 199 END_TEST; 200} 201 202bool modify_test() { 203 BEGIN_TEST; 204 205 { 206 fbl::StringBuffer<16u> str; 207 str.Append("abcdef"); 208 209 EXPECT_EQ('c', str[2u]); 210 str[2u] = 'x'; 211 EXPECT_EQ('x', str[2u]); 212 EXPECT_DATA_AND_LENGTH("abxdef", str); 213 214 memcpy(str.data(), "yyyy", 4u); 215 EXPECT_DATA_AND_LENGTH("yyyyef", str); 216 } 217 218 END_TEST; 219} 220 221bool resize_test() { 222 BEGIN_TEST; 223 224 { 225 fbl::StringBuffer<16u> str; 226 227 str.Resize(4u, 'x'); 228 EXPECT_STR_EQ("xxxx", str.data()); 229 EXPECT_EQ(4u, str.length()); 230 231 str.Resize(8u, 'y'); 232 EXPECT_STR_EQ("xxxxyyyy", str.data()); 233 EXPECT_EQ(8u, str.length()); 234 235 str.Resize(16u); 236 EXPECT_STR_EQ("xxxxyyyy", str.data()); 237 EXPECT_EQ(0, memcmp("xxxxyyyy\0\0\0\0\0\0\0\0\0", str.data(), str.length() + 1)); 238 EXPECT_EQ(16u, str.length()); 239 240 str.Resize(0u); 241 EXPECT_STR_EQ("", str.data()); 242 EXPECT_EQ(0u, str.length()); 243 } 244 245 END_TEST; 246} 247 248bool clear_test() { 249 BEGIN_TEST; 250 251 { 252 fbl::StringBuffer<16u> str; 253 str.Append("abcdef"); 254 255 str.Clear(); 256 EXPECT_STR_EQ("", str.data()); 257 EXPECT_EQ(0u, str.length()); 258 } 259 260 END_TEST; 261} 262 263bool to_string_test() { 264 BEGIN_TEST; 265 266 { 267 fbl::StringBuffer<16u> buf; 268 buf.Append("abcdef"); 269 270 fbl::String str = buf.ToString(); 271 EXPECT_TRUE(str == "abcdef"); 272 } 273 274 END_TEST; 275} 276 277bool to_string_piece_test() { 278 BEGIN_TEST; 279 280 { 281 fbl::StringBuffer<16u> buf; 282 buf.Append("abcdef"); 283 284 fbl::StringPiece piece = buf.ToStringPiece(); 285 EXPECT_EQ(buf.data(), piece.data()); 286 EXPECT_EQ(buf.length(), piece.length()); 287 } 288 289 END_TEST; 290} 291 292} // namespace 293 294BEGIN_TEST_CASE(string_buffer_tests) 295RUN_TEST(capacity_test) 296RUN_TEST(empty_string_test) 297RUN_TEST(append_test) 298RUN_TEST(append_printf_test) 299RUN_TEST(modify_test) 300RUN_TEST(resize_test) 301RUN_TEST(clear_test) 302RUN_TEST(to_string_test) 303RUN_TEST(to_string_piece_test) 304END_TEST_CASE(string_buffer_tests) 305