277 lines · cpp
1//===-- CompletionRequestTest.cpp -----------------------------------------===//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-exception6//7//===----------------------------------------------------------------------===//8 9#include "gtest/gtest.h"10 11#include "lldb/Utility/CompletionRequest.h"12using namespace lldb_private;13 14TEST(CompletionRequest, Constructor) {15 std::string command = "a bad c";16 const unsigned cursor_pos = 3;17 const size_t arg_index = 1;18 StringList matches;19 CompletionResult result;20 21 CompletionRequest request(command, cursor_pos, result);22 result.GetMatches(matches);23 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);28 29 EXPECT_EQ(request.GetParsedLine().GetArgumentCount(), 2u);30 EXPECT_EQ(request.GetCursorArgumentPrefix().str(), "b");31}32 33TEST(CompletionRequest, FakeLastArg) {34 // We insert an empty fake argument into the argument list when the35 // cursor is after a space.36 std::string command = "a bad c ";37 const unsigned cursor_pos = command.size();38 CompletionResult result;39 40 CompletionRequest request(command, cursor_pos, result);41 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);46 47 EXPECT_EQ(request.GetParsedLine().GetArgumentCount(), 4U);48 EXPECT_EQ(request.GetCursorArgumentPrefix().str(), "");49}50 51TEST(CompletionRequest, TryCompleteCurrentArgGood) {52 std::string command = "a bad c";53 StringList matches, descriptions;54 CompletionResult result;55 56 CompletionRequest request(command, 3, result);57 request.TryCompleteCurrentArg("boo", "car");58 result.GetMatches(matches);59 result.GetDescriptions(descriptions);60 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));65}66 67TEST(CompletionRequest, TryCompleteCurrentArgBad) {68 std::string command = "a bad c";69 CompletionResult result;70 71 CompletionRequest request(command, 3, result);72 request.TryCompleteCurrentArg("car", "card");73 74 EXPECT_EQ(0U, result.GetResults().size());75}76 77TEST(CompletionRequest, TryCompleteCurrentArgMode) {78 std::string command = "a bad c";79 CompletionResult result;80 81 CompletionRequest request(command, 3, result);82 request.TryCompleteCurrentArg<CompletionMode::Partial>("bar", "bard");83 84 EXPECT_EQ(1U, result.GetResults().size());85 EXPECT_EQ(CompletionMode::Partial, result.GetResults()[0].GetMode());86}87 88TEST(CompletionRequest, ShiftArguments) {89 std::string command = "a bad c";90 const unsigned cursor_pos = 3;91 const size_t arg_index = 1;92 StringList matches;93 CompletionResult result;94 95 CompletionRequest request(command, cursor_pos, result);96 result.GetMatches(matches);97 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);102 103 EXPECT_EQ(request.GetParsedLine().GetArgumentCount(), 2u);104 EXPECT_STREQ(request.GetParsedLine().GetArgumentAtIndex(1), "b");105 106 // Shift away the 'a' argument.107 request.ShiftArguments();108 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);113 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");118}119 120TEST(CompletionRequest, DuplicateFiltering) {121 std::string command = "a bad c";122 const unsigned cursor_pos = 3;123 StringList matches;124 125 CompletionResult result;126 CompletionRequest request(command, cursor_pos, result);127 result.GetMatches(matches);128 129 EXPECT_EQ(0U, result.GetNumberOfResults());130 131 // Add foo twice132 request.AddCompletion("foo");133 result.GetMatches(matches);134 135 EXPECT_EQ(1U, result.GetNumberOfResults());136 EXPECT_EQ(1U, matches.GetSize());137 EXPECT_STREQ("foo", matches.GetStringAtIndex(0));138 139 request.AddCompletion("foo");140 result.GetMatches(matches);141 142 EXPECT_EQ(1U, result.GetNumberOfResults());143 EXPECT_EQ(1U, matches.GetSize());144 EXPECT_STREQ("foo", matches.GetStringAtIndex(0));145 146 // Add bar twice147 request.AddCompletion("bar");148 result.GetMatches(matches);149 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));154 155 request.AddCompletion("bar");156 result.GetMatches(matches);157 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));162 163 // Add foo again.164 request.AddCompletion("foo");165 result.GetMatches(matches);166 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));171 172 // Add something with an existing prefix173 request.AddCompletion("foobar");174 result.GetMatches(matches);175 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));181}182 183TEST(CompletionRequest, DuplicateFilteringWithComments) {184 std::string command = "a bad c";185 const unsigned cursor_pos = 3;186 StringList matches, descriptions;187 188 CompletionResult result;189 CompletionRequest request(command, cursor_pos, result);190 result.GetMatches(matches);191 result.GetDescriptions(descriptions);192 193 EXPECT_EQ(0U, result.GetNumberOfResults());194 195 // Add foo twice with same comment196 request.AddCompletion("foo", "comment");197 result.GetMatches(matches);198 result.GetDescriptions(descriptions);199 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));205 206 request.AddCompletion("foo", "comment");207 result.GetMatches(matches);208 result.GetDescriptions(descriptions);209 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));215 216 // Add bar twice with different comments217 request.AddCompletion("bar", "comment");218 result.GetMatches(matches);219 result.GetDescriptions(descriptions);220 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));226 227 request.AddCompletion("bar", "another comment");228 result.GetMatches(matches);229 result.GetDescriptions(descriptions);230 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));240 241 // Add foo again with no comment242 request.AddCompletion("foo");243 result.GetMatches(matches);244 result.GetDescriptions(descriptions);245 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));257}258 259TEST(CompletionRequest, TestCompletionOwnership) {260 std::string command = "a bad c";261 const unsigned cursor_pos = 3;262 StringList matches;263 264 CompletionResult result;265 CompletionRequest request(command, cursor_pos, result);266 267 std::string Temporary = "bar";268 request.AddCompletion(Temporary);269 // Manipulate our completion. The request should have taken a copy, so that270 // shouldn't influence anything.271 Temporary[0] = 'f';272 273 result.GetMatches(matches);274 EXPECT_EQ(1U, result.GetNumberOfResults());275 EXPECT_STREQ("bar", matches.GetStringAtIndex(0));276}277