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