1 //===-- CompletionRequestTest.cpp -----------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 #include "gtest/gtest.h"
11 #include "lldb/Utility/CompletionRequest.h"
12 using namespace lldb_private
;
14 TEST(CompletionRequest
, Constructor
) {
15 std::string command
= "a bad c";
16 const unsigned cursor_pos
= 3;
17 const size_t arg_index
= 1;
19 CompletionResult result
;
21 CompletionRequest
request(command
, cursor_pos
, result
);
22 result
.GetMatches(matches
);
24 EXPECT_EQ(request
.GetRawLine(), "a b");
25 EXPECT_EQ(request
.GetRawLineWithUnusedSuffix(), command
);
26 EXPECT_EQ(request
.GetRawCursorPos(), cursor_pos
);
27 EXPECT_EQ(request
.GetCursorIndex(), arg_index
);
29 EXPECT_EQ(request
.GetParsedLine().GetArgumentCount(), 2u);
30 EXPECT_EQ(request
.GetCursorArgumentPrefix().str(), "b");
33 TEST(CompletionRequest
, FakeLastArg
) {
34 // We insert an empty fake argument into the argument list when the
35 // cursor is after a space.
36 std::string command
= "a bad c ";
37 const unsigned cursor_pos
= command
.size();
38 CompletionResult result
;
40 CompletionRequest
request(command
, cursor_pos
, result
);
42 EXPECT_EQ(request
.GetRawLine(), command
);
43 EXPECT_EQ(request
.GetRawLineWithUnusedSuffix(), command
);
44 EXPECT_EQ(request
.GetRawCursorPos(), cursor_pos
);
45 EXPECT_EQ(request
.GetCursorIndex(), 3U);
47 EXPECT_EQ(request
.GetParsedLine().GetArgumentCount(), 4U);
48 EXPECT_EQ(request
.GetCursorArgumentPrefix().str(), "");
51 TEST(CompletionRequest
, TryCompleteCurrentArgGood
) {
52 std::string command
= "a bad c";
53 StringList matches
, descriptions
;
54 CompletionResult result
;
56 CompletionRequest
request(command
, 3, result
);
57 request
.TryCompleteCurrentArg("boo", "car");
58 result
.GetMatches(matches
);
59 result
.GetDescriptions(descriptions
);
61 EXPECT_EQ(1U, result
.GetResults().size());
62 EXPECT_STREQ("boo", matches
.GetStringAtIndex(0U));
63 EXPECT_EQ(1U, descriptions
.GetSize());
64 EXPECT_STREQ("car", descriptions
.GetStringAtIndex(0U));
67 TEST(CompletionRequest
, TryCompleteCurrentArgBad
) {
68 std::string command
= "a bad c";
69 CompletionResult result
;
71 CompletionRequest
request(command
, 3, result
);
72 request
.TryCompleteCurrentArg("car", "card");
74 EXPECT_EQ(0U, result
.GetResults().size());
77 TEST(CompletionRequest
, TryCompleteCurrentArgMode
) {
78 std::string command
= "a bad c";
79 CompletionResult result
;
81 CompletionRequest
request(command
, 3, result
);
82 request
.TryCompleteCurrentArg
<CompletionMode::Partial
>("bar", "bard");
84 EXPECT_EQ(1U, result
.GetResults().size());
85 EXPECT_EQ(CompletionMode::Partial
, result
.GetResults()[0].GetMode());
88 TEST(CompletionRequest
, ShiftArguments
) {
89 std::string command
= "a bad c";
90 const unsigned cursor_pos
= 3;
91 const size_t arg_index
= 1;
93 CompletionResult result
;
95 CompletionRequest
request(command
, cursor_pos
, result
);
96 result
.GetMatches(matches
);
98 EXPECT_EQ(request
.GetRawLine(), "a b");
99 EXPECT_EQ(request
.GetRawLineWithUnusedSuffix(), command
);
100 EXPECT_EQ(request
.GetRawCursorPos(), cursor_pos
);
101 EXPECT_EQ(request
.GetCursorIndex(), arg_index
);
103 EXPECT_EQ(request
.GetParsedLine().GetArgumentCount(), 2u);
104 EXPECT_STREQ(request
.GetParsedLine().GetArgumentAtIndex(1), "b");
106 // Shift away the 'a' argument.
107 request
.ShiftArguments();
109 // The raw line/cursor stays identical.
110 EXPECT_EQ(request
.GetRawLine(), "a b");
111 EXPECT_EQ(request
.GetRawLineWithUnusedSuffix(), command
);
112 EXPECT_EQ(request
.GetRawCursorPos(), cursor_pos
);
114 // Partially parsed line and cursor should be updated.
115 EXPECT_EQ(request
.GetCursorIndex(), arg_index
- 1U);
116 EXPECT_EQ(request
.GetParsedLine().GetArgumentCount(), 1u);
117 EXPECT_EQ(request
.GetCursorArgumentPrefix().str(), "b");
120 TEST(CompletionRequest
, DuplicateFiltering
) {
121 std::string command
= "a bad c";
122 const unsigned cursor_pos
= 3;
125 CompletionResult result
;
126 CompletionRequest
request(command
, cursor_pos
, result
);
127 result
.GetMatches(matches
);
129 EXPECT_EQ(0U, result
.GetNumberOfResults());
132 request
.AddCompletion("foo");
133 result
.GetMatches(matches
);
135 EXPECT_EQ(1U, result
.GetNumberOfResults());
136 EXPECT_EQ(1U, matches
.GetSize());
137 EXPECT_STREQ("foo", matches
.GetStringAtIndex(0));
139 request
.AddCompletion("foo");
140 result
.GetMatches(matches
);
142 EXPECT_EQ(1U, result
.GetNumberOfResults());
143 EXPECT_EQ(1U, matches
.GetSize());
144 EXPECT_STREQ("foo", matches
.GetStringAtIndex(0));
147 request
.AddCompletion("bar");
148 result
.GetMatches(matches
);
150 EXPECT_EQ(2U, result
.GetNumberOfResults());
151 EXPECT_EQ(2U, matches
.GetSize());
152 EXPECT_STREQ("foo", matches
.GetStringAtIndex(0));
153 EXPECT_STREQ("bar", matches
.GetStringAtIndex(1));
155 request
.AddCompletion("bar");
156 result
.GetMatches(matches
);
158 EXPECT_EQ(2U, result
.GetNumberOfResults());
159 EXPECT_EQ(2U, matches
.GetSize());
160 EXPECT_STREQ("foo", matches
.GetStringAtIndex(0));
161 EXPECT_STREQ("bar", matches
.GetStringAtIndex(1));
164 request
.AddCompletion("foo");
165 result
.GetMatches(matches
);
167 EXPECT_EQ(2U, result
.GetNumberOfResults());
168 EXPECT_EQ(2U, matches
.GetSize());
169 EXPECT_STREQ("foo", matches
.GetStringAtIndex(0));
170 EXPECT_STREQ("bar", matches
.GetStringAtIndex(1));
172 // Add something with an existing prefix
173 request
.AddCompletion("foobar");
174 result
.GetMatches(matches
);
176 EXPECT_EQ(3U, result
.GetNumberOfResults());
177 EXPECT_EQ(3U, matches
.GetSize());
178 EXPECT_STREQ("foo", matches
.GetStringAtIndex(0));
179 EXPECT_STREQ("bar", matches
.GetStringAtIndex(1));
180 EXPECT_STREQ("foobar", matches
.GetStringAtIndex(2));
183 TEST(CompletionRequest
, DuplicateFilteringWithComments
) {
184 std::string command
= "a bad c";
185 const unsigned cursor_pos
= 3;
186 StringList matches
, descriptions
;
188 CompletionResult result
;
189 CompletionRequest
request(command
, cursor_pos
, result
);
190 result
.GetMatches(matches
);
191 result
.GetDescriptions(descriptions
);
193 EXPECT_EQ(0U, result
.GetNumberOfResults());
195 // Add foo twice with same comment
196 request
.AddCompletion("foo", "comment");
197 result
.GetMatches(matches
);
198 result
.GetDescriptions(descriptions
);
200 EXPECT_EQ(1U, result
.GetNumberOfResults());
201 EXPECT_EQ(1U, matches
.GetSize());
202 EXPECT_EQ(1U, descriptions
.GetSize());
203 EXPECT_STREQ("foo", matches
.GetStringAtIndex(0));
204 EXPECT_STREQ("comment", descriptions
.GetStringAtIndex(0));
206 request
.AddCompletion("foo", "comment");
207 result
.GetMatches(matches
);
208 result
.GetDescriptions(descriptions
);
210 EXPECT_EQ(1U, result
.GetNumberOfResults());
211 EXPECT_EQ(1U, matches
.GetSize());
212 EXPECT_EQ(1U, descriptions
.GetSize());
213 EXPECT_STREQ("foo", matches
.GetStringAtIndex(0));
214 EXPECT_STREQ("comment", descriptions
.GetStringAtIndex(0));
216 // Add bar twice with different comments
217 request
.AddCompletion("bar", "comment");
218 result
.GetMatches(matches
);
219 result
.GetDescriptions(descriptions
);
221 EXPECT_EQ(2U, result
.GetNumberOfResults());
222 EXPECT_EQ(2U, matches
.GetSize());
223 EXPECT_EQ(2U, descriptions
.GetSize());
224 EXPECT_STREQ("foo", matches
.GetStringAtIndex(0));
225 EXPECT_STREQ("bar", matches
.GetStringAtIndex(1));
227 request
.AddCompletion("bar", "another comment");
228 result
.GetMatches(matches
);
229 result
.GetDescriptions(descriptions
);
231 EXPECT_EQ(3U, result
.GetNumberOfResults());
232 EXPECT_EQ(3U, matches
.GetSize());
233 EXPECT_EQ(3U, descriptions
.GetSize());
234 EXPECT_STREQ("foo", matches
.GetStringAtIndex(0));
235 EXPECT_STREQ("comment", descriptions
.GetStringAtIndex(0));
236 EXPECT_STREQ("bar", matches
.GetStringAtIndex(1));
237 EXPECT_STREQ("comment", descriptions
.GetStringAtIndex(1));
238 EXPECT_STREQ("bar", matches
.GetStringAtIndex(2));
239 EXPECT_STREQ("another comment", descriptions
.GetStringAtIndex(2));
241 // Add foo again with no comment
242 request
.AddCompletion("foo");
243 result
.GetMatches(matches
);
244 result
.GetDescriptions(descriptions
);
246 EXPECT_EQ(4U, result
.GetNumberOfResults());
247 EXPECT_EQ(4U, matches
.GetSize());
248 EXPECT_EQ(4U, descriptions
.GetSize());
249 EXPECT_STREQ("foo", matches
.GetStringAtIndex(0));
250 EXPECT_STREQ("comment", descriptions
.GetStringAtIndex(0));
251 EXPECT_STREQ("bar", matches
.GetStringAtIndex(1));
252 EXPECT_STREQ("comment", descriptions
.GetStringAtIndex(1));
253 EXPECT_STREQ("bar", matches
.GetStringAtIndex(2));
254 EXPECT_STREQ("another comment", descriptions
.GetStringAtIndex(2));
255 EXPECT_STREQ("foo", matches
.GetStringAtIndex(3));
256 EXPECT_STREQ("", descriptions
.GetStringAtIndex(3));
259 TEST(CompletionRequest
, TestCompletionOwnership
) {
260 std::string command
= "a bad c";
261 const unsigned cursor_pos
= 3;
264 CompletionResult result
;
265 CompletionRequest
request(command
, cursor_pos
, result
);
267 std::string Temporary
= "bar";
268 request
.AddCompletion(Temporary
);
269 // Manipulate our completion. The request should have taken a copy, so that
270 // shouldn't influence anything.
273 result
.GetMatches(matches
);
274 EXPECT_EQ(1U, result
.GetNumberOfResults());
275 EXPECT_STREQ("bar", matches
.GetStringAtIndex(0));