1//===-- StringListTest.cpp ------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include "lldb/Utility/StringList.h"
10#include "lldb/Utility/StreamString.h"
11#include "gmock/gmock.h"
12#include "gtest/gtest.h"
13
14using namespace lldb_private;
15
16TEST(StringListTest, DefaultConstructor) {
17 StringList s;
18 EXPECT_EQ(0U, s.GetSize());
19}
20
21TEST(StringListTest, Assignment) {
22 StringList orig;
23 orig.AppendString(str: "foo");
24 orig.AppendString(str: "bar");
25
26 StringList s = orig;
27
28 ASSERT_EQ(2U, s.GetSize());
29 EXPECT_STREQ("foo", s.GetStringAtIndex(0));
30 EXPECT_STREQ("bar", s.GetStringAtIndex(1));
31
32 ASSERT_EQ(2U, orig.GetSize());
33 EXPECT_STREQ("foo", orig.GetStringAtIndex(0));
34 EXPECT_STREQ("bar", orig.GetStringAtIndex(1));
35}
36
37TEST(StringListTest, AppendStringStdString) {
38 StringList s;
39 s.AppendString(str: "foo");
40 ASSERT_EQ(1U, s.GetSize());
41 EXPECT_STREQ("foo", s.GetStringAtIndex(0));
42
43 s.AppendString(str: "bar");
44 ASSERT_EQ(2U, s.GetSize());
45 EXPECT_STREQ("foo", s.GetStringAtIndex(0));
46 EXPECT_STREQ("bar", s.GetStringAtIndex(1));
47}
48
49TEST(StringListTest, AppendStringCString) {
50 StringList s;
51 s.AppendString(str: "foo", str_len: strlen(s: "foo"));
52 ASSERT_EQ(1U, s.GetSize());
53 EXPECT_STREQ("foo", s.GetStringAtIndex(0));
54
55 s.AppendString(str: "bar", str_len: strlen(s: "bar"));
56 ASSERT_EQ(2U, s.GetSize());
57 EXPECT_STREQ("foo", s.GetStringAtIndex(0));
58 EXPECT_STREQ("bar", s.GetStringAtIndex(1));
59}
60
61TEST(StringListTest, AppendStringMove) {
62 StringList s;
63 std::string foo = "foo";
64 std::string bar = "bar";
65
66 s.AppendString(s: std::move(foo));
67 ASSERT_EQ(1U, s.GetSize());
68 EXPECT_STREQ("foo", s.GetStringAtIndex(0));
69
70 s.AppendString(s: std::move(bar));
71 ASSERT_EQ(2U, s.GetSize());
72 EXPECT_STREQ("foo", s.GetStringAtIndex(0));
73 EXPECT_STREQ("bar", s.GetStringAtIndex(1));
74}
75
76TEST(StringListTest, ShiftStdString) {
77 StringList s;
78 std::string foo = "foo";
79 std::string bar = "bar";
80
81 s << foo;
82 ASSERT_EQ(1U, s.GetSize());
83 EXPECT_STREQ("foo", s.GetStringAtIndex(0));
84
85 s << bar;
86 ASSERT_EQ(2U, s.GetSize());
87 EXPECT_STREQ("foo", s.GetStringAtIndex(0));
88 EXPECT_STREQ("bar", s.GetStringAtIndex(1));
89}
90
91TEST(StringListTest, ShiftCString) {
92 StringList s;
93 s << "foo";
94 ASSERT_EQ(1U, s.GetSize());
95 EXPECT_STREQ("foo", s.GetStringAtIndex(0));
96
97 s << "bar";
98 ASSERT_EQ(2U, s.GetSize());
99 EXPECT_STREQ("foo", s.GetStringAtIndex(0));
100 EXPECT_STREQ("bar", s.GetStringAtIndex(1));
101}
102
103TEST(StringListTest, ShiftMove) {
104 StringList s;
105 std::string foo = "foo";
106 std::string bar = "bar";
107
108 s << std::move(foo);
109 ASSERT_EQ(1U, s.GetSize());
110 EXPECT_STREQ("foo", s.GetStringAtIndex(0));
111
112 s << std::move(bar);
113 ASSERT_EQ(2U, s.GetSize());
114 EXPECT_STREQ("foo", s.GetStringAtIndex(0));
115 EXPECT_STREQ("bar", s.GetStringAtIndex(1));
116}
117
118TEST(StringListTest, AppendListCStringArrayEmpty) {
119 StringList s;
120 s.AppendList(strv: nullptr, strc: 0);
121 EXPECT_EQ(0U, s.GetSize());
122}
123
124TEST(StringListTest, AppendListCStringArray) {
125 StringList s;
126 const char *items[3] = {"foo", "", "bar"};
127 s.AppendList(strv: items, strc: 3);
128
129 EXPECT_EQ(3U, s.GetSize());
130 EXPECT_STREQ("foo", s.GetStringAtIndex(0));
131 EXPECT_STREQ("", s.GetStringAtIndex(1));
132 EXPECT_STREQ("bar", s.GetStringAtIndex(2));
133}
134
135TEST(StringListTest, AppendList) {
136 StringList other;
137 other.AppendString(str: "foo");
138 other.AppendString(str: "");
139 other.AppendString(str: "bar");
140
141 StringList empty;
142
143 StringList s;
144 s.AppendList(strings: other);
145
146 EXPECT_EQ(3U, s.GetSize());
147 EXPECT_STREQ("foo", s.GetStringAtIndex(0));
148 EXPECT_STREQ("", s.GetStringAtIndex(1));
149 EXPECT_STREQ("bar", s.GetStringAtIndex(2));
150
151 EXPECT_EQ(3U, other.GetSize());
152 EXPECT_STREQ("foo", other.GetStringAtIndex(0));
153 EXPECT_STREQ("", other.GetStringAtIndex(1));
154 EXPECT_STREQ("bar", other.GetStringAtIndex(2));
155
156 s.AppendList(strings: empty);
157 s.AppendList(strings: other);
158 EXPECT_EQ(6U, s.GetSize());
159 EXPECT_STREQ("foo", s.GetStringAtIndex(0));
160 EXPECT_STREQ("", s.GetStringAtIndex(1));
161 EXPECT_STREQ("bar", s.GetStringAtIndex(2));
162 EXPECT_STREQ("foo", s.GetStringAtIndex(3));
163 EXPECT_STREQ("", s.GetStringAtIndex(4));
164 EXPECT_STREQ("bar", s.GetStringAtIndex(5));
165
166 EXPECT_EQ(3U, other.GetSize());
167 EXPECT_STREQ("foo", other.GetStringAtIndex(0));
168 EXPECT_STREQ("", other.GetStringAtIndex(1));
169 EXPECT_STREQ("bar", other.GetStringAtIndex(2));
170}
171
172TEST(StringListTest, GetSize) {
173 StringList s;
174 s.AppendString(str: "foo");
175 EXPECT_EQ(1U, s.GetSize());
176
177 s.AppendString(str: "foo");
178 EXPECT_EQ(2U, s.GetSize());
179
180 s.AppendString(str: "foobar");
181 EXPECT_EQ(3U, s.GetSize());
182}
183
184TEST(StringListTest, SetSize) {
185 StringList s;
186 s.SetSize(3);
187 EXPECT_EQ(3U, s.GetSize());
188 EXPECT_STREQ("", s.GetStringAtIndex(0));
189 EXPECT_STREQ("", s.GetStringAtIndex(1));
190 EXPECT_STREQ("", s.GetStringAtIndex(2));
191}
192
193TEST(StringListTest, SplitIntoLines) {
194 StringList s;
195 s.SplitIntoLines(lines: "\nfoo\nbar\n\n");
196 EXPECT_EQ(4U, s.GetSize());
197 EXPECT_STREQ("", s.GetStringAtIndex(0));
198 EXPECT_STREQ("foo", s.GetStringAtIndex(1));
199 EXPECT_STREQ("bar", s.GetStringAtIndex(2));
200 EXPECT_STREQ("", s.GetStringAtIndex(3));
201}
202
203TEST(StringListTest, SplitIntoLinesSingleTrailingCR) {
204 StringList s;
205 s.SplitIntoLines(lines: "\r");
206 EXPECT_EQ(1U, s.GetSize());
207 EXPECT_STREQ("", s.GetStringAtIndex(0));
208}
209
210TEST(StringListTest, SplitIntoLinesEmpty) {
211 StringList s;
212 s.SplitIntoLines(lines: "");
213 EXPECT_EQ(0U, s.GetSize());
214}
215
216TEST(StringListTest, LongestCommonPrefixEmpty) {
217 StringList s;
218 std::string prefix = s.LongestCommonPrefix();
219 EXPECT_EQ("", prefix);
220}
221
222TEST(StringListTest, LongestCommonPrefix) {
223 StringList s;
224 s.AppendString(str: "foo");
225 s.AppendString(str: "foobar");
226 s.AppendString(str: "foo");
227 s.AppendString(str: "foozar");
228
229 std::string prefix = s.LongestCommonPrefix();
230 EXPECT_EQ("foo", prefix);
231}
232
233TEST(StringListTest, LongestCommonPrefixSingleElement) {
234 StringList s;
235 s.AppendString(str: "foo");
236
237 std::string prefix = s.LongestCommonPrefix();
238 EXPECT_EQ("foo", prefix);
239}
240
241TEST(StringListTest, LongestCommonPrefixDuplicateElement) {
242 StringList s;
243 s.AppendString(str: "foo");
244 s.AppendString(str: "foo");
245
246 std::string prefix = s.LongestCommonPrefix();
247 EXPECT_EQ("foo", prefix);
248}
249
250TEST(StringListTest, LongestCommonPrefixNoPrefix) {
251 StringList s;
252 s.AppendString(str: "foo");
253 s.AppendString(str: "1foobar");
254 s.AppendString(str: "2foo");
255 s.AppendString(str: "3foozar");
256
257 std::string prefix = s.LongestCommonPrefix();
258 EXPECT_EQ("", prefix);
259}
260
261TEST(StringListTest, Clear) {
262 StringList s;
263 s.Clear();
264 EXPECT_EQ(0U, s.GetSize());
265
266 s.AppendString(str: "foo");
267 s.Clear();
268 EXPECT_EQ(0U, s.GetSize());
269
270 s.AppendString(str: "foo");
271 s.AppendString(str: "foo");
272 s.Clear();
273 EXPECT_EQ(0U, s.GetSize());
274}
275
276TEST(StringListTest, PopBack) {
277 StringList s;
278 s.AppendString(str: "foo");
279 s.AppendString(str: "bar");
280 s.AppendString(str: "boo");
281
282 s.PopBack();
283 EXPECT_EQ(2U, s.GetSize());
284 EXPECT_STREQ("foo", s.GetStringAtIndex(0));
285 EXPECT_STREQ("bar", s.GetStringAtIndex(1));
286
287 s.PopBack();
288 EXPECT_EQ(1U, s.GetSize());
289 EXPECT_STREQ("foo", s.GetStringAtIndex(0));
290
291 s.PopBack();
292 EXPECT_EQ(0U, s.GetSize());
293}
294
295TEST(StringListTest, RemoveBlankLines) {
296 StringList s;
297
298 // Nothing to remove yet.
299 s.RemoveBlankLines();
300 EXPECT_EQ(0U, s.GetSize());
301
302 // Add some lines.
303 s.AppendString(str: "");
304 s.AppendString(str: "");
305 s.AppendString(str: "\t");
306 s.AppendString(str: "");
307 s.AppendString(str: " ");
308 s.AppendString(str: "");
309 s.AppendString(str: "");
310 s.AppendString(str: "f");
311 s.AppendString(str: "");
312 s.AppendString(str: "");
313
314 // And remove all the empty ones again.
315 s.RemoveBlankLines();
316
317 EXPECT_EQ(3U, s.GetSize());
318 EXPECT_STREQ("\t", s.GetStringAtIndex(0));
319 EXPECT_STREQ(" ", s.GetStringAtIndex(1));
320 EXPECT_STREQ("f", s.GetStringAtIndex(2));
321}
322
323TEST(StringListTest, InsertStringAtIndexStart) {
324 StringList s;
325
326 s.InsertStringAtIndex(id: 0, str: "bar");
327 EXPECT_EQ(1U, s.GetSize());
328 EXPECT_STREQ("bar", s.GetStringAtIndex(0));
329
330 s.InsertStringAtIndex(id: 0, str: "foo");
331 EXPECT_EQ(2U, s.GetSize());
332 EXPECT_STREQ("foo", s.GetStringAtIndex(0));
333 EXPECT_STREQ("bar", s.GetStringAtIndex(1));
334}
335
336TEST(StringListTest, InsertStringAtIndexEnd) {
337 StringList s;
338
339 s.InsertStringAtIndex(id: 0, str: "foo");
340 EXPECT_EQ(1U, s.GetSize());
341 EXPECT_STREQ("foo", s.GetStringAtIndex(0));
342
343 s.InsertStringAtIndex(id: 1, str: "bar");
344 EXPECT_EQ(2U, s.GetSize());
345 EXPECT_STREQ("foo", s.GetStringAtIndex(0));
346 EXPECT_STREQ("bar", s.GetStringAtIndex(1));
347}
348
349TEST(StringListTest, InsertStringAtIndexOutOfBounds) {
350 StringList s;
351
352 s.InsertStringAtIndex(id: 1, str: "foo");
353 EXPECT_EQ(1U, s.GetSize());
354 EXPECT_STREQ("foo", s.GetStringAtIndex(0));
355
356 // FIXME: Inserting at an OOB index will always just append to the list. This
357 // seems not very intuitive.
358 s.InsertStringAtIndex(id: 3, str: "bar");
359 EXPECT_EQ(2U, s.GetSize());
360 EXPECT_STREQ("foo", s.GetStringAtIndex(0));
361 EXPECT_STREQ("bar", s.GetStringAtIndex(1));
362}
363
364TEST(StringListTest, InsertStringAtIndexStdString) {
365 StringList s;
366
367 std::string foo = "foo";
368 s.InsertStringAtIndex(idx: 0, str: foo);
369 EXPECT_EQ(1U, s.GetSize());
370 EXPECT_STREQ("foo", s.GetStringAtIndex(0));
371}
372
373TEST(StringListTest, InsertStringAtIndexMove) {
374 StringList s;
375
376 std::string foo = "foo";
377 s.InsertStringAtIndex(idx: 0, str: std::move(foo));
378 EXPECT_EQ(1U, s.GetSize());
379 EXPECT_STREQ("foo", s.GetStringAtIndex(0));
380}
381
382TEST(StringListTest, CopyListEmpty) {
383 StringList s;
384
385 EXPECT_EQ("", s.CopyList());
386 EXPECT_EQ("", s.CopyList("+"));
387}
388
389TEST(StringListTest, CopyListSingle) {
390 StringList s;
391 s.AppendString(str: "ab");
392
393 EXPECT_EQ("ab", s.CopyList());
394 EXPECT_EQ("-ab", s.CopyList("-"));
395}
396
397TEST(StringListTest, CopyList) {
398 StringList s;
399 s.AppendString(str: "ab");
400 s.AppendString(str: "cd");
401
402 EXPECT_EQ("ab\ncd", s.CopyList());
403 EXPECT_EQ("-ab\n-cd", s.CopyList("-"));
404}
405
406TEST(StringListTest, Join) {
407 StringList s;
408 s.AppendString(str: "ab");
409 s.AppendString(str: "cd");
410
411 StreamString ss;
412 s.Join(separator: " ", strm&: ss);
413
414 EXPECT_EQ("ab cd", ss.GetString());
415}
416
417TEST(StringListTest, JoinEmpty) {
418 StringList s;
419
420 StreamString ss;
421 s.Join(separator: " ", strm&: ss);
422
423 EXPECT_EQ("", ss.GetString());
424}
425
426TEST(StringListTest, JoinSingle) {
427 StringList s;
428 s.AppendString(str: "foo");
429
430 StreamString ss;
431 s.Join(separator: " ", strm&: ss);
432
433 EXPECT_EQ("foo", ss.GetString());
434}
435
436TEST(StringListTest, JoinThree) {
437 StringList s;
438 s.AppendString(str: "1");
439 s.AppendString(str: "2");
440 s.AppendString(str: "3");
441
442 StreamString ss;
443 s.Join(separator: " ", strm&: ss);
444
445 EXPECT_EQ("1 2 3", ss.GetString());
446}
447
448TEST(StringListTest, JoinNonSpace) {
449 StringList s;
450 s.AppendString(str: "1");
451 s.AppendString(str: "2");
452 s.AppendString(str: "3");
453
454 StreamString ss;
455 s.Join(separator: ".", strm&: ss);
456
457 EXPECT_EQ("1.2.3", ss.GetString());
458}
459
460TEST(StringListTest, JoinMultiCharSeparator) {
461 StringList s;
462 s.AppendString(str: "1");
463 s.AppendString(str: "2");
464 s.AppendString(str: "3");
465
466 StreamString ss;
467 s.Join(separator: "--", strm&: ss);
468
469 EXPECT_EQ("1--2--3", ss.GetString());
470}
471
472TEST(StringListTest, GetMaxStringLengthEqualSize) {
473 StringList s;
474 s.AppendString(str: "123");
475 s.AppendString(str: "123");
476 EXPECT_EQ(3U, s.GetMaxStringLength());
477}
478
479TEST(StringListTest, GetMaxStringLengthIncreasingSize) {
480 StringList s;
481 s.AppendString(str: "123");
482 s.AppendString(str: "1234");
483 EXPECT_EQ(4U, s.GetMaxStringLength());
484}
485
486TEST(StringListTest, GetMaxStringLengthDecreasingSize) {
487 StringList s;
488 s.AppendString(str: "1234");
489 s.AppendString(str: "123");
490 EXPECT_EQ(4U, s.GetMaxStringLength());
491}
492
493TEST(StringListTest, GetMaxStringLengthMixed) {
494 StringList s;
495 s.AppendString(str: "123");
496 s.AppendString(str: "1");
497 s.AppendString(str: "123");
498 s.AppendString(str: "1234");
499 s.AppendString(str: "123");
500 s.AppendString(str: "1");
501 EXPECT_EQ(4U, s.GetMaxStringLength());
502}
503
504TEST(StringListTest, GetMaxStringLengthEmpty) {
505 StringList s;
506 EXPECT_EQ(0U, s.GetMaxStringLength());
507}
508
509TEST(StringListTest, ForRangeEmpty) {
510 StringList s;
511 for (const std::string &e : s)
512 FAIL() << "Shouldn't have hit an element in for range" << e;
513}
514
515TEST(StringListTest, ForRange) {
516 StringList s;
517 s.AppendString(str: "a");
518 s.AppendString(str: "b");
519 s.AppendString(str: "c");
520 std::vector<std::string> recorded;
521 for (const std::string &e : s)
522 recorded.push_back(x: e);
523 EXPECT_THAT(recorded, testing::ElementsAre("a", "b", "c"));
524}
525

source code of lldb/unittests/Utility/StringListTest.cpp