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 = s.LongestCommonPrefix();
218   EXPECT_EQ("", prefix);
219 }
220 
221 TEST(StringListTest, LongestCommonPrefix) {
222   StringList s;
223   s.AppendString("foo");
224   s.AppendString("foobar");
225   s.AppendString("foo");
226   s.AppendString("foozar");
227 
228   std::string prefix = s.LongestCommonPrefix();
229   EXPECT_EQ("foo", prefix);
230 }
231 
232 TEST(StringListTest, LongestCommonPrefixSingleElement) {
233   StringList s;
234   s.AppendString("foo");
235 
236   std::string prefix = s.LongestCommonPrefix();
237   EXPECT_EQ("foo", prefix);
238 }
239 
240 TEST(StringListTest, LongestCommonPrefixDuplicateElement) {
241   StringList s;
242   s.AppendString("foo");
243   s.AppendString("foo");
244 
245   std::string prefix = s.LongestCommonPrefix();
246   EXPECT_EQ("foo", prefix);
247 }
248 
249 TEST(StringListTest, LongestCommonPrefixNoPrefix) {
250   StringList s;
251   s.AppendString("foo");
252   s.AppendString("1foobar");
253   s.AppendString("2foo");
254   s.AppendString("3foozar");
255 
256   std::string prefix = s.LongestCommonPrefix();
257   EXPECT_EQ("", prefix);
258 }
259 
260 TEST(StringListTest, Clear) {
261   StringList s;
262   s.Clear();
263   EXPECT_EQ(0U, s.GetSize());
264 
265   s.AppendString("foo");
266   s.Clear();
267   EXPECT_EQ(0U, s.GetSize());
268 
269   s.AppendString("foo");
270   s.AppendString("foo");
271   s.Clear();
272   EXPECT_EQ(0U, s.GetSize());
273 }
274 
275 TEST(StringListTest, PopBack) {
276   StringList s;
277   s.AppendString("foo");
278   s.AppendString("bar");
279   s.AppendString("boo");
280 
281   s.PopBack();
282   EXPECT_EQ(2U, s.GetSize());
283   EXPECT_STREQ("foo", s.GetStringAtIndex(0));
284   EXPECT_STREQ("bar", s.GetStringAtIndex(1));
285 
286   s.PopBack();
287   EXPECT_EQ(1U, s.GetSize());
288   EXPECT_STREQ("foo", s.GetStringAtIndex(0));
289 
290   s.PopBack();
291   EXPECT_EQ(0U, s.GetSize());
292 }
293 
294 TEST(StringListTest, RemoveBlankLines) {
295   StringList s;
296 
297   // Nothing to remove yet.
298   s.RemoveBlankLines();
299   EXPECT_EQ(0U, s.GetSize());
300 
301   // Add some lines.
302   s.AppendString("");
303   s.AppendString("");
304   s.AppendString("\t");
305   s.AppendString("");
306   s.AppendString(" ");
307   s.AppendString("");
308   s.AppendString("");
309   s.AppendString("f");
310   s.AppendString("");
311   s.AppendString("");
312 
313   // And remove all the empty ones again.
314   s.RemoveBlankLines();
315 
316   EXPECT_EQ(3U, s.GetSize());
317   EXPECT_STREQ("\t", s.GetStringAtIndex(0));
318   EXPECT_STREQ(" ", s.GetStringAtIndex(1));
319   EXPECT_STREQ("f", s.GetStringAtIndex(2));
320 }
321 
322 TEST(StringListTest, InsertStringAtIndexStart) {
323   StringList s;
324 
325   s.InsertStringAtIndex(0, "bar");
326   EXPECT_EQ(1U, s.GetSize());
327   EXPECT_STREQ("bar", s.GetStringAtIndex(0));
328 
329   s.InsertStringAtIndex(0, "foo");
330   EXPECT_EQ(2U, s.GetSize());
331   EXPECT_STREQ("foo", s.GetStringAtIndex(0));
332   EXPECT_STREQ("bar", s.GetStringAtIndex(1));
333 }
334 
335 TEST(StringListTest, InsertStringAtIndexEnd) {
336   StringList s;
337 
338   s.InsertStringAtIndex(0, "foo");
339   EXPECT_EQ(1U, s.GetSize());
340   EXPECT_STREQ("foo", s.GetStringAtIndex(0));
341 
342   s.InsertStringAtIndex(1, "bar");
343   EXPECT_EQ(2U, s.GetSize());
344   EXPECT_STREQ("foo", s.GetStringAtIndex(0));
345   EXPECT_STREQ("bar", s.GetStringAtIndex(1));
346 }
347 
348 TEST(StringListTest, InsertStringAtIndexOutOfBounds) {
349   StringList s;
350 
351   s.InsertStringAtIndex(1, "foo");
352   EXPECT_EQ(1U, s.GetSize());
353   EXPECT_STREQ("foo", s.GetStringAtIndex(0));
354 
355   // FIXME: Inserting at an OOB index will always just append to the list. This
356   // seems not very intuitive.
357   s.InsertStringAtIndex(3, "bar");
358   EXPECT_EQ(2U, s.GetSize());
359   EXPECT_STREQ("foo", s.GetStringAtIndex(0));
360   EXPECT_STREQ("bar", s.GetStringAtIndex(1));
361 }
362 
363 TEST(StringListTest, InsertStringAtIndexStdString) {
364   StringList s;
365 
366   std::string foo = "foo";
367   s.InsertStringAtIndex(0, foo);
368   EXPECT_EQ(1U, s.GetSize());
369   EXPECT_STREQ("foo", s.GetStringAtIndex(0));
370 }
371 
372 TEST(StringListTest, InsertStringAtIndexMove) {
373   StringList s;
374 
375   std::string foo = "foo";
376   s.InsertStringAtIndex(0, std::move(foo));
377   EXPECT_EQ(1U, s.GetSize());
378   EXPECT_STREQ("foo", s.GetStringAtIndex(0));
379 }
380 
381 TEST(StringListTest, CopyListEmpty) {
382   StringList s;
383 
384   EXPECT_EQ("", s.CopyList());
385   EXPECT_EQ("", s.CopyList("+"));
386 }
387 
388 TEST(StringListTest, CopyListSingle) {
389   StringList s;
390   s.AppendString("ab");
391 
392   EXPECT_EQ("ab", s.CopyList());
393   EXPECT_EQ("-ab", s.CopyList("-"));
394 }
395 
396 TEST(StringListTest, CopyList) {
397   StringList s;
398   s.AppendString("ab");
399   s.AppendString("cd");
400 
401   EXPECT_EQ("ab\ncd", s.CopyList());
402   EXPECT_EQ("-ab\n-cd", s.CopyList("-"));
403 }
404 
405 TEST(StringListTest, Join) {
406   StringList s;
407   s.AppendString("ab");
408   s.AppendString("cd");
409 
410   StreamString ss;
411   s.Join(" ", ss);
412 
413   EXPECT_EQ("ab cd", ss.GetString());
414 }
415 
416 TEST(StringListTest, JoinEmpty) {
417   StringList s;
418 
419   StreamString ss;
420   s.Join(" ", ss);
421 
422   EXPECT_EQ("", ss.GetString());
423 }
424 
425 TEST(StringListTest, JoinSingle) {
426   StringList s;
427   s.AppendString("foo");
428 
429   StreamString ss;
430   s.Join(" ", ss);
431 
432   EXPECT_EQ("foo", ss.GetString());
433 }
434 
435 TEST(StringListTest, JoinThree) {
436   StringList s;
437   s.AppendString("1");
438   s.AppendString("2");
439   s.AppendString("3");
440 
441   StreamString ss;
442   s.Join(" ", ss);
443 
444   EXPECT_EQ("1 2 3", ss.GetString());
445 }
446 
447 TEST(StringListTest, JoinNonSpace) {
448   StringList s;
449   s.AppendString("1");
450   s.AppendString("2");
451   s.AppendString("3");
452 
453   StreamString ss;
454   s.Join(".", ss);
455 
456   EXPECT_EQ("1.2.3", ss.GetString());
457 }
458 
459 TEST(StringListTest, JoinMultiCharSeparator) {
460   StringList s;
461   s.AppendString("1");
462   s.AppendString("2");
463   s.AppendString("3");
464 
465   StreamString ss;
466   s.Join("--", ss);
467 
468   EXPECT_EQ("1--2--3", ss.GetString());
469 }
470 
471 TEST(StringListTest, GetMaxStringLengthEqualSize) {
472   StringList s;
473   s.AppendString("123");
474   s.AppendString("123");
475   EXPECT_EQ(3U, s.GetMaxStringLength());
476 }
477 
478 TEST(StringListTest, GetMaxStringLengthIncreasingSize) {
479   StringList s;
480   s.AppendString("123");
481   s.AppendString("1234");
482   EXPECT_EQ(4U, s.GetMaxStringLength());
483 }
484 
485 TEST(StringListTest, GetMaxStringLengthDecreasingSize) {
486   StringList s;
487   s.AppendString("1234");
488   s.AppendString("123");
489   EXPECT_EQ(4U, s.GetMaxStringLength());
490 }
491 
492 TEST(StringListTest, GetMaxStringLengthMixed) {
493   StringList s;
494   s.AppendString("123");
495   s.AppendString("1");
496   s.AppendString("123");
497   s.AppendString("1234");
498   s.AppendString("123");
499   s.AppendString("1");
500   EXPECT_EQ(4U, s.GetMaxStringLength());
501 }
502 
503 TEST(StringListTest, GetMaxStringLengthEmpty) {
504   StringList s;
505   EXPECT_EQ(0U, s.GetMaxStringLength());
506 }
507