• 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 
18 #include "lsp_api_test.h"
19 #include "lsp/include/internal_api.h"
20 #include "lsp/include/todo_comments.h"
21 
22 namespace {
23 // NOLINTBEGIN
24 using ark::es2panda::lsp::Initializer;
25 
26 class TodoCommentsTest : public LSPAPITests {};
27 
TEST_F(TodoCommentsTest,GetTodoCommentsSimpleTodo)28 TEST_F(TodoCommentsTest, GetTodoCommentsSimpleTodo)
29 {
30     const time_t kDesignatedThrottleTime = 123;
31     const int kDescriptorPriority = 1;
32     const int kExpectedSize = 1;
33     const char *const kTodoTag = "TODO";
34     const char *const kFileName = "simple-todo.sts";
35     const char *const kFileContent = "// TODO: Fix this";
36     const char *const kExpectedMessage = "TODO: Fix this";
37 
38     using ark::es2panda::ir::AstNode;
39     using ark::es2panda::public_lib::Context;
40     auto cancellationToken = ark::es2panda::lsp::CancellationToken(kDesignatedThrottleTime, nullptr);
41 
42     Initializer initializer = Initializer();
43     es2panda_Context *ctx = initializer.CreateContext(kFileName, ES2PANDA_STATE_CHECKED, kFileContent);
44 
45     std::vector<ark::es2panda::lsp::TodoCommentDescriptor> descriptors = {
46         ark::es2panda::lsp::TodoCommentDescriptor(kTodoTag, kDescriptorPriority)};
47 
48     auto comments = ark::es2panda::lsp::GetTodoCommentsImpl(ctx, descriptors, &cancellationToken);
49 
50     ASSERT_EQ(comments.size(), kExpectedSize);
51     EXPECT_EQ(comments[0].GetCommentDescriptor().GetText(), kTodoTag);
52     EXPECT_EQ(comments[0].GetMessage(), kExpectedMessage);
53 
54     initializer.DestroyContext(ctx);
55 }
56 
TEST_F(TodoCommentsTest,GetTodoCommentsSimpleTodoWithName)57 TEST_F(TodoCommentsTest, GetTodoCommentsSimpleTodoWithName)
58 {
59     const time_t kDesignatedThrottleTime = 123;
60     const int kDescriptorPriority = 1;
61     const int kExpectedSize = 1;
62     const char *const kTodoTag = "TODO";
63     const char *const kFileName = "simple-todo-name.sts";
64     const char *const kFileContent = "// TODO(name): Fix this";
65     const char *const kExpectedMessage = "TODO(name): Fix this";
66 
67     using ark::es2panda::ir::AstNode;
68     using ark::es2panda::public_lib::Context;
69     auto cancellationToken = ark::es2panda::lsp::CancellationToken(kDesignatedThrottleTime, nullptr);
70 
71     Initializer initializer = Initializer();
72     es2panda_Context *ctx = initializer.CreateContext(kFileName, ES2PANDA_STATE_CHECKED, kFileContent);
73 
74     std::vector<ark::es2panda::lsp::TodoCommentDescriptor> descriptors = {
75         ark::es2panda::lsp::TodoCommentDescriptor(kTodoTag, kDescriptorPriority)};
76 
77     auto comments = ark::es2panda::lsp::GetTodoCommentsImpl(ctx, descriptors, &cancellationToken);
78 
79     ASSERT_EQ(comments.size(), kExpectedSize);
80     EXPECT_EQ(comments[0].GetCommentDescriptor().GetText(), kTodoTag);
81     EXPECT_EQ(comments[0].GetMessage(), kExpectedMessage);
82 
83     initializer.DestroyContext(ctx);
84 }
85 
TEST_F(TodoCommentsTest,GetTodoCommentsSimpleHack)86 TEST_F(TodoCommentsTest, GetTodoCommentsSimpleHack)
87 {
88     const time_t kDesignatedThrottleTime = 123;
89     const int kDescriptorPriority = 1;
90     const int kExpectedSize = 1;
91     const char *const kHackTag = "HACK";
92     const char *const kFileName = "simple-hack.sts";
93     const char *const kFileContent = "// HACK: Needs work";
94     const char *const kExpectedMessage = "HACK: Needs work";
95 
96     using ark::es2panda::ir::AstNode;
97     using ark::es2panda::public_lib::Context;
98     auto cancellationToken = ark::es2panda::lsp::CancellationToken(kDesignatedThrottleTime, nullptr);
99 
100     Initializer initializer = Initializer();
101     es2panda_Context *ctx = initializer.CreateContext(kFileName, ES2PANDA_STATE_CHECKED, kFileContent);
102 
103     std::vector<ark::es2panda::lsp::TodoCommentDescriptor> descriptors = {
104         ark::es2panda::lsp::TodoCommentDescriptor(kHackTag, kDescriptorPriority)};
105 
106     auto comments = ark::es2panda::lsp::GetTodoCommentsImpl(ctx, descriptors, &cancellationToken);
107 
108     ASSERT_EQ(comments.size(), kExpectedSize);
109     EXPECT_EQ(comments[0].GetCommentDescriptor().GetText(), kHackTag);
110     EXPECT_EQ(comments[0].GetMessage(), kExpectedMessage);
111 
112     initializer.DestroyContext(ctx);
113 }
114 
TEST_F(TodoCommentsTest,GetTodoCommentsBlockCommentTodo)115 TEST_F(TodoCommentsTest, GetTodoCommentsBlockCommentTodo)
116 {
117     const time_t kDesignatedThrottleTime = 123;
118     const int kDescriptorPriority = 1;
119     const int kExpectedSize = 1;
120     const char *const kTodoTag = "TODO";
121     const char *const kFileName = "block-comment.sts";
122     const char *const kFileContent = "/* TODO: Fix this */";
123     const char *const kExpectedMessage = "TODO: Fix this ";
124 
125     using ark::es2panda::ir::AstNode;
126     using ark::es2panda::public_lib::Context;
127     auto cancellationToken = ark::es2panda::lsp::CancellationToken(kDesignatedThrottleTime, nullptr);
128 
129     Initializer initializer = Initializer();
130     es2panda_Context *ctx = initializer.CreateContext(kFileName, ES2PANDA_STATE_CHECKED, kFileContent);
131 
132     std::vector<ark::es2panda::lsp::TodoCommentDescriptor> descriptors = {
133         ark::es2panda::lsp::TodoCommentDescriptor(kTodoTag, kDescriptorPriority)};
134 
135     auto comments = ark::es2panda::lsp::GetTodoCommentsImpl(ctx, descriptors, &cancellationToken);
136 
137     ASSERT_EQ(comments.size(), kExpectedSize);
138     EXPECT_EQ(comments[0].GetCommentDescriptor().GetText(), kTodoTag);
139     EXPECT_EQ(comments[0].GetMessage(), kExpectedMessage);
140 
141     initializer.DestroyContext(ctx);
142 }
143 
TEST_F(TodoCommentsTest,GetTodoCommentsMultiLineBlockComment)144 TEST_F(TodoCommentsTest, GetTodoCommentsMultiLineBlockComment)
145 {
146     const time_t kDesignatedThrottleTime = 123;
147     const int kDescriptorPriority = 1;
148     const int kExpectedSize = 1;
149     const char *const kTodoTag = "TODO";
150     const char *const kFileName = "multiline-block-comment.sts";
151     const char *const kFileContent = "/*\n * TODO: Multi-line fix\n */";
152     const char *const kExpectedMessage = "TODO: Multi-line fix";
153 
154     using ark::es2panda::ir::AstNode;
155     using ark::es2panda::public_lib::Context;
156     auto cancellationToken = ark::es2panda::lsp::CancellationToken(kDesignatedThrottleTime, nullptr);
157 
158     Initializer initializer = Initializer();
159     es2panda_Context *ctx = initializer.CreateContext(kFileName, ES2PANDA_STATE_CHECKED, kFileContent);
160 
161     std::vector<ark::es2panda::lsp::TodoCommentDescriptor> descriptors = {
162         ark::es2panda::lsp::TodoCommentDescriptor(kTodoTag, kDescriptorPriority)};
163 
164     auto comments = ark::es2panda::lsp::GetTodoCommentsImpl(ctx, descriptors, &cancellationToken);
165 
166     ASSERT_EQ(comments.size(), kExpectedSize);
167     EXPECT_EQ(comments[0].GetCommentDescriptor().GetText(), kTodoTag);
168     EXPECT_EQ(comments[0].GetMessage(), kExpectedMessage);
169 
170     initializer.DestroyContext(ctx);
171 }
172 
TEST_F(TodoCommentsTest,GetTodoCommentsIgnoresNonComments)173 TEST_F(TodoCommentsTest, GetTodoCommentsIgnoresNonComments)
174 {
175     const time_t kDesignatedThrottleTime = 123;
176     const int kDescriptorPriority = 1;
177     const char *const kTodoTag = "TODO";
178     const char *const kFileName = "non-comment.sts";
179     const char *const kFileContent = "let s = \"TODO: not a comment\"";
180 
181     using ark::es2panda::ir::AstNode;
182     using ark::es2panda::public_lib::Context;
183 
184     auto cancellationToken = ark::es2panda::lsp::CancellationToken(kDesignatedThrottleTime, nullptr);
185 
186     Initializer initializer = Initializer();
187     es2panda_Context *ctx = initializer.CreateContext(kFileName, ES2PANDA_STATE_CHECKED, kFileContent);
188 
189     std::vector<ark::es2panda::lsp::TodoCommentDescriptor> descriptors = {
190         ark::es2panda::lsp::TodoCommentDescriptor(kTodoTag, kDescriptorPriority)};
191 
192     auto comments = ark::es2panda::lsp::GetTodoCommentsImpl(ctx, descriptors, &cancellationToken);
193 
194     ASSERT_TRUE(comments.empty());
195 
196     initializer.DestroyContext(ctx);
197 }
198 
TEST_F(TodoCommentsTest,GetTodoCommentsMultiLineCodeMultiComments)199 TEST_F(TodoCommentsTest, GetTodoCommentsMultiLineCodeMultiComments)
200 {
201     const time_t kDesignatedThrottleTime = 123;
202     const int kDescriptorPriority = 1;
203     const int kExpectedSize = 2;
204     const char *const kTodoTag = "TODO";
205     const char *const kHackTag = "HACK";
206     const char *const kFileName = "multiline-multicomment.sts";
207     const char *const kFileContent =
208         R"(export function A(a:number): number {return a;}
209  // TODO: this is a todo comment
210 
211  // HACK: fix me
212  export function B(a:number, b:number): number {return a + b;})";
213     const char *const kExpectedTodoMessage = "TODO: this is a todo comment";
214     const char *const kExpectedHackMessage = "HACK: fix me";
215     const int kExpectedTodoPosition = 52;
216     const int kExpectedHackPosition = 87;
217 
218     using ark::es2panda::ir::AstNode;
219     using ark::es2panda::public_lib::Context;
220 
221     auto cancellationToken = ark::es2panda::lsp::CancellationToken(kDesignatedThrottleTime, nullptr);
222 
223     Initializer initializer = Initializer();
224     es2panda_Context *ctx = initializer.CreateContext(kFileName, ES2PANDA_STATE_CHECKED, kFileContent);
225 
226     std::vector<ark::es2panda::lsp::TodoCommentDescriptor> descriptors = {
227         ark::es2panda::lsp::TodoCommentDescriptor(kTodoTag, kDescriptorPriority),
228         ark::es2panda::lsp::TodoCommentDescriptor(kHackTag, kDescriptorPriority)};
229 
230     auto comments = ark::es2panda::lsp::GetTodoCommentsImpl(ctx, descriptors, &cancellationToken);
231 
232     ASSERT_EQ(comments.size(), kExpectedSize);
233     EXPECT_EQ(comments[0].GetCommentDescriptor().GetText(), kTodoTag);
234     EXPECT_EQ(comments[0].GetMessage(), kExpectedTodoMessage);
235     EXPECT_EQ(comments[0].GetPosition(), kExpectedTodoPosition);
236     EXPECT_EQ(comments[1].GetCommentDescriptor().GetText(), kHackTag);
237     EXPECT_EQ(comments[1].GetMessage(), kExpectedHackMessage);
238     EXPECT_EQ(comments[1].GetPosition(), kExpectedHackPosition);
239 
240     initializer.DestroyContext(ctx);
241 }
242 
TEST_F(TodoCommentsTest,GetTodoCommentsMultiLineCodeSameComments)243 TEST_F(TodoCommentsTest, GetTodoCommentsMultiLineCodeSameComments)
244 {
245     const time_t kDesignatedThrottleTime = 123;
246     const int kDescriptorPriority = 1;
247     const int kExpectedSize = 2;
248     const char *const kTodoTag = "TODO";
249     const char *const kFileName = "multiline-duplicate.sts";
250     const char *const kFileContent =
251         R"(export function A(a:number): number {return a;}
252  // TODO: this is a duplicate todo comment
253 
254  // TODO: this is a duplicate todo comment
255  export function B(a:number, b:number): number {return a + b;})";
256     const char *const kExpectedMessage = "TODO: this is a duplicate todo comment";
257     const int kExpectedFirstPosition = 52;
258     const int kExpectedSecondPosition = 97;
259 
260     using ark::es2panda::ir::AstNode;
261     using ark::es2panda::public_lib::Context;
262 
263     auto cancellationToken = ark::es2panda::lsp::CancellationToken(kDesignatedThrottleTime, nullptr);
264 
265     Initializer initializer = Initializer();
266     es2panda_Context *ctx = initializer.CreateContext(kFileName, ES2PANDA_STATE_CHECKED, kFileContent);
267 
268     std::vector<ark::es2panda::lsp::TodoCommentDescriptor> descriptors = {
269         ark::es2panda::lsp::TodoCommentDescriptor(kTodoTag, kDescriptorPriority)};
270 
271     auto comments = ark::es2panda::lsp::GetTodoCommentsImpl(ctx, descriptors, &cancellationToken);
272 
273     ASSERT_EQ(comments.size(), kExpectedSize);
274     EXPECT_EQ(comments[0].GetCommentDescriptor().GetText(), kTodoTag);
275     EXPECT_EQ(comments[1].GetCommentDescriptor().GetText(), kTodoTag);
276     EXPECT_EQ(comments[0].GetMessage(), kExpectedMessage);
277     EXPECT_EQ(comments[1].GetMessage(), kExpectedMessage);
278     EXPECT_EQ(comments[0].GetPosition(), kExpectedFirstPosition);
279     EXPECT_EQ(comments[1].GetPosition(), kExpectedSecondPosition);
280 
281     initializer.DestroyContext(ctx);
282 }
283 
TEST_F(TodoCommentsTest,GetTodoCommentsNotTodoComment)284 TEST_F(TodoCommentsTest, GetTodoCommentsNotTodoComment)
285 {
286     const time_t kDesignatedThrottleTime = 123;
287     const int kDescriptorPriority = 1;
288     const char *const kTodoTag = "TODO";
289     const char *const kFileName = "non-comment.sts";
290     const char *const kFileContent = "// TODOX not a todo comment";
291 
292     using ark::es2panda::ir::AstNode;
293     using ark::es2panda::public_lib::Context;
294 
295     auto cancellationToken = ark::es2panda::lsp::CancellationToken(kDesignatedThrottleTime, nullptr);
296 
297     Initializer initializer = Initializer();
298     es2panda_Context *ctx = initializer.CreateContext(kFileName, ES2PANDA_STATE_CHECKED, kFileContent);
299 
300     std::vector<ark::es2panda::lsp::TodoCommentDescriptor> descriptors = {
301         ark::es2panda::lsp::TodoCommentDescriptor(kTodoTag, kDescriptorPriority)};
302 
303     auto comments = ark::es2panda::lsp::GetTodoCommentsImpl(ctx, descriptors, &cancellationToken);
304 
305     ASSERT_TRUE(comments.empty());
306 
307     initializer.DestroyContext(ctx);
308 }
309 
TEST_F(TodoCommentsTest,GetTodoCommentsBlockCommentFixMe)310 TEST_F(TodoCommentsTest, GetTodoCommentsBlockCommentFixMe)
311 {
312     const time_t kDesignatedThrottleTime = 123;
313     const int kDescriptorPriority = 1;
314     const int kExpectedSize = 1;
315     const char *const kTodoTag = "FIXME";
316     const char *const kFileName = "block-comment-fixme.sts";
317     const char *const kFileContent = "/* FIXME: Fix this */";
318     const char *const kExpectedMessage = "FIXME: Fix this ";
319 
320     using ark::es2panda::ir::AstNode;
321     using ark::es2panda::public_lib::Context;
322     auto cancellationToken = ark::es2panda::lsp::CancellationToken(kDesignatedThrottleTime, nullptr);
323 
324     Initializer initializer = Initializer();
325     es2panda_Context *ctx = initializer.CreateContext(kFileName, ES2PANDA_STATE_CHECKED, kFileContent);
326 
327     std::vector<ark::es2panda::lsp::TodoCommentDescriptor> descriptors = {
328         ark::es2panda::lsp::TodoCommentDescriptor(kTodoTag, kDescriptorPriority)};
329 
330     auto comments = ark::es2panda::lsp::GetTodoCommentsImpl(ctx, descriptors, &cancellationToken);
331 
332     ASSERT_EQ(comments.size(), kExpectedSize);
333     EXPECT_EQ(comments[0].GetCommentDescriptor().GetText(), kTodoTag);
334     EXPECT_EQ(comments[0].GetMessage(), kExpectedMessage);
335 
336     initializer.DestroyContext(ctx);
337 }
338 
TEST_F(TodoCommentsTest,GetTodoCommentsSimpleFix)339 TEST_F(TodoCommentsTest, GetTodoCommentsSimpleFix)
340 {
341     const time_t kDesignatedThrottleTime = 123;
342     const int kDescriptorPriority = 1;
343     const int kExpectedSize = 1;
344     const char *const kHackTag = "FIX";
345     const char *const kFileName = "simple-comment-fix.sts";
346     const char *const kFileContent = "// FIX: Needs to be fixed";
347     const char *const kExpectedMessage = "FIX: Needs to be fixed";
348 
349     using ark::es2panda::ir::AstNode;
350     using ark::es2panda::public_lib::Context;
351     auto cancellationToken = ark::es2panda::lsp::CancellationToken(kDesignatedThrottleTime, nullptr);
352 
353     Initializer initializer = Initializer();
354     es2panda_Context *ctx = initializer.CreateContext(kFileName, ES2PANDA_STATE_CHECKED, kFileContent);
355 
356     std::vector<ark::es2panda::lsp::TodoCommentDescriptor> descriptors = {
357         ark::es2panda::lsp::TodoCommentDescriptor(kHackTag, kDescriptorPriority)};
358 
359     auto comments = ark::es2panda::lsp::GetTodoCommentsImpl(ctx, descriptors, &cancellationToken);
360 
361     ASSERT_EQ(comments.size(), kExpectedSize);
362     EXPECT_EQ(comments[0].GetCommentDescriptor().GetText(), kHackTag);
363     EXPECT_EQ(comments[0].GetMessage(), kExpectedMessage);
364 
365     initializer.DestroyContext(ctx);
366 }
367 
TEST_F(TodoCommentsTest,GetTodoCommentsNoteMultiLineCodeSameComments)368 TEST_F(TodoCommentsTest, GetTodoCommentsNoteMultiLineCodeSameComments)
369 {
370     const time_t kDesignatedThrottleTime = 123;
371     const int kDescriptorPriority = 1;
372     const int kExpectedSize = 2;
373     const char *const kTodoTag = "NOTE";
374     const char *const kFileName = "multiline-duplicate-note.sts";
375     const char *const kFileContent =
376         R"(export function A(b:number): number {return c;}
377  // NOTE: this is a duplicate note comment
378 
379  // Comment line
380 
381  // NOTE: this is a duplicate note comment
382  export function B(a:number, b:number): number {return a + b;})";
383     const char *const kExpectedMessage = "NOTE: this is a duplicate note comment";
384     const int kExpectedFirstPosition = 52;
385     const int kExpectedSecondPosition = 115;
386 
387     using ark::es2panda::ir::AstNode;
388     using ark::es2panda::public_lib::Context;
389 
390     auto cancellationToken = ark::es2panda::lsp::CancellationToken(kDesignatedThrottleTime, nullptr);
391 
392     Initializer initializer = Initializer();
393     es2panda_Context *ctx = initializer.CreateContext(kFileName, ES2PANDA_STATE_CHECKED, kFileContent);
394 
395     std::vector<ark::es2panda::lsp::TodoCommentDescriptor> descriptors = {
396         ark::es2panda::lsp::TodoCommentDescriptor(kTodoTag, kDescriptorPriority)};
397 
398     auto comments = ark::es2panda::lsp::GetTodoCommentsImpl(ctx, descriptors, &cancellationToken);
399 
400     ASSERT_EQ(comments.size(), kExpectedSize);
401     EXPECT_EQ(comments[0].GetCommentDescriptor().GetText(), kTodoTag);
402     EXPECT_EQ(comments[1].GetCommentDescriptor().GetText(), kTodoTag);
403     EXPECT_EQ(comments[0].GetMessage(), kExpectedMessage);
404     EXPECT_EQ(comments[1].GetMessage(), kExpectedMessage);
405     EXPECT_EQ(comments[0].GetPosition(), kExpectedFirstPosition);
406     EXPECT_EQ(comments[1].GetPosition(), kExpectedSecondPosition);
407 
408     initializer.DestroyContext(ctx);
409 }
410 // NOLINTEND
411 }  // namespace