1 //===-- CompletionRequestTest.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 "gtest/gtest.h"
10 
11 #include "lldb/Utility/CompletionRequest.h"
12 using namespace lldb_private;
13 
14 TEST(CompletionRequest, Constructor) {
15   std::string command = "a bad c";
16   const unsigned cursor_pos = 3;
17   const int arg_index = 1;
18   const int arg_cursor_pos = 1;
19   StringList matches;
20   CompletionResult result;
21 
22   CompletionRequest request(command, cursor_pos, result);
23   result.GetMatches(matches);
24 
25   EXPECT_STREQ(request.GetRawLine().str().c_str(), command.c_str());
26   EXPECT_EQ(request.GetRawCursorPos(), cursor_pos);
27   EXPECT_EQ(request.GetCursorIndex(), arg_index);
28   EXPECT_EQ(request.GetCursorCharPosition(), arg_cursor_pos);
29   EXPECT_EQ(request.GetWordComplete(), false);
30 
31   EXPECT_EQ(request.GetPartialParsedLine().GetArgumentCount(), 2u);
32   EXPECT_STREQ(request.GetPartialParsedLine().GetArgumentAtIndex(1), "b");
33 }
34 
35 TEST(CompletionRequest, DuplicateFiltering) {
36   std::string command = "a bad c";
37   const unsigned cursor_pos = 3;
38   StringList matches;
39 
40   CompletionResult result;
41   CompletionRequest request(command, cursor_pos, result);
42   result.GetMatches(matches);
43 
44   EXPECT_EQ(0U, request.GetNumberOfMatches());
45 
46   // Add foo twice
47   request.AddCompletion("foo");
48   result.GetMatches(matches);
49 
50   EXPECT_EQ(1U, request.GetNumberOfMatches());
51   EXPECT_EQ(1U, matches.GetSize());
52   EXPECT_STREQ("foo", matches.GetStringAtIndex(0));
53 
54   request.AddCompletion("foo");
55   result.GetMatches(matches);
56 
57   EXPECT_EQ(1U, request.GetNumberOfMatches());
58   EXPECT_EQ(1U, matches.GetSize());
59   EXPECT_STREQ("foo", matches.GetStringAtIndex(0));
60 
61   // Add bar twice
62   request.AddCompletion("bar");
63   result.GetMatches(matches);
64 
65   EXPECT_EQ(2U, request.GetNumberOfMatches());
66   EXPECT_EQ(2U, matches.GetSize());
67   EXPECT_STREQ("foo", matches.GetStringAtIndex(0));
68   EXPECT_STREQ("bar", matches.GetStringAtIndex(1));
69 
70   request.AddCompletion("bar");
71   result.GetMatches(matches);
72 
73   EXPECT_EQ(2U, request.GetNumberOfMatches());
74   EXPECT_EQ(2U, matches.GetSize());
75   EXPECT_STREQ("foo", matches.GetStringAtIndex(0));
76   EXPECT_STREQ("bar", matches.GetStringAtIndex(1));
77 
78   // Add foo again.
79   request.AddCompletion("foo");
80   result.GetMatches(matches);
81 
82   EXPECT_EQ(2U, request.GetNumberOfMatches());
83   EXPECT_EQ(2U, matches.GetSize());
84   EXPECT_STREQ("foo", matches.GetStringAtIndex(0));
85   EXPECT_STREQ("bar", matches.GetStringAtIndex(1));
86 
87   // Add something with an existing prefix
88   request.AddCompletion("foobar");
89   result.GetMatches(matches);
90 
91   EXPECT_EQ(3U, request.GetNumberOfMatches());
92   EXPECT_EQ(3U, matches.GetSize());
93   EXPECT_STREQ("foo", matches.GetStringAtIndex(0));
94   EXPECT_STREQ("bar", matches.GetStringAtIndex(1));
95   EXPECT_STREQ("foobar", matches.GetStringAtIndex(2));
96 }
97 
98 TEST(CompletionRequest, DuplicateFilteringWithComments) {
99   std::string command = "a bad c";
100   const unsigned cursor_pos = 3;
101   StringList matches, descriptions;
102 
103   CompletionResult result;
104   CompletionRequest request(command, cursor_pos, result);
105   result.GetMatches(matches);
106   result.GetDescriptions(descriptions);
107 
108   EXPECT_EQ(0U, request.GetNumberOfMatches());
109 
110   // Add foo twice with same comment
111   request.AddCompletion("foo", "comment");
112   result.GetMatches(matches);
113   result.GetDescriptions(descriptions);
114 
115   EXPECT_EQ(1U, request.GetNumberOfMatches());
116   EXPECT_EQ(1U, matches.GetSize());
117   EXPECT_EQ(1U, descriptions.GetSize());
118   EXPECT_STREQ("foo", matches.GetStringAtIndex(0));
119   EXPECT_STREQ("comment", descriptions.GetStringAtIndex(0));
120 
121   request.AddCompletion("foo", "comment");
122   result.GetMatches(matches);
123   result.GetDescriptions(descriptions);
124 
125   EXPECT_EQ(1U, request.GetNumberOfMatches());
126   EXPECT_EQ(1U, matches.GetSize());
127   EXPECT_EQ(1U, descriptions.GetSize());
128   EXPECT_STREQ("foo", matches.GetStringAtIndex(0));
129   EXPECT_STREQ("comment", descriptions.GetStringAtIndex(0));
130 
131   // Add bar twice with different comments
132   request.AddCompletion("bar", "comment");
133   result.GetMatches(matches);
134   result.GetDescriptions(descriptions);
135 
136   EXPECT_EQ(2U, request.GetNumberOfMatches());
137   EXPECT_EQ(2U, matches.GetSize());
138   EXPECT_EQ(2U, descriptions.GetSize());
139   EXPECT_STREQ("foo", matches.GetStringAtIndex(0));
140   EXPECT_STREQ("bar", matches.GetStringAtIndex(1));
141 
142   request.AddCompletion("bar", "another comment");
143   result.GetMatches(matches);
144   result.GetDescriptions(descriptions);
145 
146   EXPECT_EQ(3U, request.GetNumberOfMatches());
147   EXPECT_EQ(3U, matches.GetSize());
148   EXPECT_EQ(3U, descriptions.GetSize());
149   EXPECT_STREQ("foo", matches.GetStringAtIndex(0));
150   EXPECT_STREQ("comment", descriptions.GetStringAtIndex(0));
151   EXPECT_STREQ("bar", matches.GetStringAtIndex(1));
152   EXPECT_STREQ("comment", descriptions.GetStringAtIndex(1));
153   EXPECT_STREQ("bar", matches.GetStringAtIndex(2));
154   EXPECT_STREQ("another comment", descriptions.GetStringAtIndex(2));
155 
156   // Add foo again with no comment
157   request.AddCompletion("foo");
158   result.GetMatches(matches);
159   result.GetDescriptions(descriptions);
160 
161   EXPECT_EQ(4U, request.GetNumberOfMatches());
162   EXPECT_EQ(4U, matches.GetSize());
163   EXPECT_EQ(4U, descriptions.GetSize());
164   EXPECT_STREQ("foo", matches.GetStringAtIndex(0));
165   EXPECT_STREQ("comment", descriptions.GetStringAtIndex(0));
166   EXPECT_STREQ("bar", matches.GetStringAtIndex(1));
167   EXPECT_STREQ("comment", descriptions.GetStringAtIndex(1));
168   EXPECT_STREQ("bar", matches.GetStringAtIndex(2));
169   EXPECT_STREQ("another comment", descriptions.GetStringAtIndex(2));
170   EXPECT_STREQ("foo", matches.GetStringAtIndex(3));
171   EXPECT_STREQ("", descriptions.GetStringAtIndex(3));
172 }
173 
174 TEST(CompletionRequest, TestCompletionOwnership) {
175   std::string command = "a bad c";
176   const unsigned cursor_pos = 3;
177   StringList matches;
178 
179   CompletionResult result;
180   CompletionRequest request(command, cursor_pos, result);
181 
182   std::string Temporary = "bar";
183   request.AddCompletion(Temporary);
184   // Manipulate our completion. The request should have taken a copy, so that
185   // shouldn't influence anything.
186   Temporary[0] = 'f';
187 
188   result.GetMatches(matches);
189   EXPECT_EQ(1U, request.GetNumberOfMatches());
190   EXPECT_STREQ("bar", matches.GetStringAtIndex(0));
191 }
192