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