• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 2025 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include <gtest/gtest.h>
17 #include "lsp_api_test.h"
18 #include "lsp/include/navigate_to.h"
19 
20 namespace {
21 
22 using ark::es2panda::SourceFile;
23 using ark::es2panda::lsp::GetNavigateToItems;
24 using ark::es2panda::lsp::Initializer;
25 using std::string;
26 using std::vector;
27 
28 class NavigateToTest : public LSPAPITests {};
29 
TEST_F(NavigateToTest,MatchLimitRespected)30 TEST_F(NavigateToTest, MatchLimitRespected)
31 {
32     std::vector<SourceFile> files = {{"matchLimitRespected1.sts", R"(
33          function foo() {
34              let a = 1;
35              return a;
36          }
37          )"},
38                                      {"matchLimitRespected2.sts", R"(
39          function foobar() {
40              let b = 2;
41              return b;
42          }
43          )"},
44                                      {"matchLimitRespected3.sts", R"(
45          function my_foo() {
46              let c = 3;
47              return c;
48          }
49          )"}};
50     const int maxResultCountTwo = 2;
51     const int expectedResultSize = 2;
52     std::string searchTerm = "foo";
53 
54     Initializer initializer;
55     std::vector<ark::es2panda::lsp::NavigateToItem> allResults;
56 
57     for (const auto &file : files) {
58         std::string sourceStr(file.source);
59         es2panda_Context *ctx =
60             initializer.CreateContext(file.filePath.data(), ES2PANDA_STATE_CHECKED, sourceStr.c_str());
61         ASSERT_NE(ctx, nullptr);
62 
63         std::vector<SourceFile> singleFile = {{file.filePath, sourceStr}};
64         auto matches = GetNavigateToItems(ctx, singleFile, maxResultCountTwo, searchTerm, false);
65         allResults.insert(allResults.end(), matches.begin(), matches.end());
66 
67         initializer.DestroyContext(ctx);
68     }
69 
70     ASSERT_LE(allResults.size(), expectedResultSize);
71 }
72 
TEST_F(NavigateToTest,MultiFileSubstringMatch)73 TEST_F(NavigateToTest, MultiFileSubstringMatch)
74 {
75     std::vector<SourceFile> files = {{"multiFileSubstringMatch1.sts", R"(
76          function foo() {
77              let a = 1;
78              return a;
79          }
80          )"},
81                                      {"multiFileSubstringMatch2.sts", R"(
82          function foobar() {
83              let b = 2;
84              return b;
85          }
86          )"},
87                                      {"multiFileSubstringMatch3.sts", R"(
88          function my_foo() {
89              let c = 3;
90              return c;
91          }
92          )"}};
93     Initializer initializer;
94     const int maxResultCount = 10;
95     size_t totalMatches = 0;
96     std::string searchTerm = "_foo";
97     const int expectedResultSize = 1;
98 
99     for (const auto &file : files) {
100         std::string sourceStr(file.source);
101         es2panda_Context *ctx =
102             initializer.CreateContext(file.filePath.data(), ES2PANDA_STATE_CHECKED, sourceStr.c_str());
103         ASSERT_NE(ctx, nullptr);
104 
105         std::vector<SourceFile> singleFile = {{file.filePath, sourceStr}};
106         auto matches = GetNavigateToItems(ctx, singleFile, maxResultCount, searchTerm, false);
107         totalMatches += matches.size();
108 
109         initializer.DestroyContext(ctx);
110     }
111 
112     ASSERT_EQ(totalMatches, expectedResultSize);
113 }
114 
TEST_F(NavigateToTest,PrefixMatchOnly)115 TEST_F(NavigateToTest, PrefixMatchOnly)
116 {
117     std::vector<SourceFile> files = {{"prefixMatchOnly1.sts", R"(
118          function foo() {
119              let a = 1;
120              return a;
121          }
122          )"},
123                                      {"prefixMatchOnly2.sts", R"(
124          function foobar() {
125              let b = 2;
126              return b;
127          }
128          )"},
129                                      {"prefixMatchOnly3.sts", R"(
130          function my_foo() {
131              let c = 3;
132              return c;
133          }
134          )"}};
135     Initializer initializer;
136     const int maxResultCount = 10;
137     size_t prefixCount = 0;
138     const int expectedResultSize = 1;
139     std::string searchTerm = "foo";
140 
141     for (const auto &file : files) {
142         std::string sourceStr(file.source);
143         es2panda_Context *ctx =
144             initializer.CreateContext(file.filePath.data(), ES2PANDA_STATE_CHECKED, sourceStr.c_str());
145         ASSERT_NE(ctx, nullptr);
146 
147         std::vector<SourceFile> singleFile = {{file.filePath, sourceStr}};
148         auto matches = GetNavigateToItems(ctx, singleFile, maxResultCount, searchTerm, false);
149         for (const auto &match : matches) {
150             if (match.matchKind == ark::es2panda::lsp::MatchKind::PREFIX) {
151                 ++prefixCount;
152             }
153         }
154 
155         initializer.DestroyContext(ctx);
156     }
157 
158     ASSERT_EQ(prefixCount, expectedResultSize);  // Only "foobar" is a PREFIX of "foo"
159 }
160 
TEST_F(NavigateToTest,MatchFromSecondFile)161 TEST_F(NavigateToTest, MatchFromSecondFile)
162 {
163     std::vector<SourceFile> files = {{"matchFromSecondFile1.sts", R"(
164          function foo() {
165              let a = 1;
166              return a;
167          }
168          )"},
169                                      {"matchFromSecondFile2.sts", R"(
170          function foobar() {
171              let b = 2;
172              return b;
173          }
174          )"},
175                                      {"matchFromSecondFile3.sts", R"(
176          function my_foo() {
177              let c = 3;
178              return c;
179          }
180          )"}};
181     Initializer initializer;
182     const int maxResultCount = 10;
183     const int expectedResultSize = 1;
184     std::string searchTerm = "foobar";
185     std::vector<ark::es2panda::lsp::NavigateToItem> matches;
186 
187     for (const auto &file : files) {
188         std::string sourceStr(file.source);
189         es2panda_Context *ctx =
190             initializer.CreateContext(file.filePath.data(), ES2PANDA_STATE_CHECKED, sourceStr.c_str());
191         ASSERT_NE(ctx, nullptr);
192 
193         std::vector<SourceFile> singleFile = {{file.filePath, sourceStr}};
194         auto results = GetNavigateToItems(ctx, singleFile, maxResultCount, searchTerm, false);
195         matches.insert(matches.end(), results.begin(), results.end());
196 
197         initializer.DestroyContext(ctx);
198     }
199     ASSERT_EQ(matches.size(), expectedResultSize);
200     ASSERT_EQ(matches[0].name, searchTerm);
201 }
202 
TEST_F(NavigateToTest,MatchOnClassMember)203 TEST_F(NavigateToTest, MatchOnClassMember)
204 {
205     std::vector<SourceFile> files = {{"matchOnClassMember1.sts", R"(
206          class Test {
207              yeke: number = 2;
208              method() {
209                  let b = 3;
210                  return b;
211              }
212          }
213          )"},
214                                      {"matchOnClassMember2.sts", R"(
215          function foobar() {
216              let b = 2;
217              return b;
218          }
219          )"},
220                                      {"matchOnClassMember3.sts", R"(
221          function my_foo() {
222              let c = 3;
223              return c;
224          }
225          )"}};
226     Initializer initializer;
227     const int maxResultCount = 10;
228     const int expectedResultSize = 1;
229     std::string searchTerm = "yeke";
230     std::string containerName = "Test";
231     std::vector<ark::es2panda::lsp::NavigateToItem> results;
232 
233     for (const auto &file : files) {
234         std::string sourceStr(file.source);
235         es2panda_Context *ctx =
236             initializer.CreateContext(file.filePath.data(), ES2PANDA_STATE_CHECKED, sourceStr.c_str());
237         ASSERT_NE(ctx, nullptr);
238 
239         std::vector<SourceFile> singleFile = {{file.filePath, sourceStr}};
240         auto items = GetNavigateToItems(ctx, singleFile, maxResultCount, searchTerm, false);
241         results.insert(results.end(), items.begin(), items.end());
242 
243         initializer.DestroyContext(ctx);
244     }
245 
246     ASSERT_EQ(results.size(), expectedResultSize);
247     ASSERT_EQ(results[0].name, searchTerm);
248     ASSERT_EQ(results[0].containerName, containerName);
249 }
250 
251 }  // namespace