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