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 <cstddef>
18 #include <string>
19 #include "lsp_api_test.h"
20 #include "lsp/include/applicable_refactors.h"
21
22 namespace {
23 using ark::es2panda::lsp::Initializer;
24
25 class LspConvFuncTests : public LSPAPITests {
26 public:
27 static constexpr std::string_view TO_NAMED_FUNCTION_KIND = "refactor.rewrite.function.named";
28 static constexpr std::string_view INVALID_KIND = "aaabbbccc";
29 static constexpr std::string_view TO_NAMED_FUNCTION_NAME = "Convert to named function";
30 };
31
TEST_F(LspConvFuncTests,ConvertFunctionRefactor1)32 TEST_F(LspConvFuncTests, ConvertFunctionRefactor1)
33 {
34 std::vector<std::string> files = {"convertFunctionRefactor1.ets"};
35 std::vector<std::string> texts = {R"(const add = (x: number, y: number): number => {
36 return x + y;
37 };)"};
38 auto filePaths = CreateTempFile(files, texts);
39 size_t const expectedFileCount = 1;
40 ASSERT_EQ(filePaths.size(), expectedFileCount);
41
42 size_t const position = 8;
43 Initializer initializer = Initializer();
44 auto ctx = initializer.CreateContext(filePaths[0].c_str(), ES2PANDA_STATE_CHECKED);
45 ark::es2panda::lsp::RefactorContext refactorContext;
46 refactorContext.context = ctx;
47 refactorContext.kind = std::string(TO_NAMED_FUNCTION_KIND);
48 refactorContext.span.pos = position;
49 auto result = GetApplicableRefactorsImpl(&refactorContext);
50 initializer.DestroyContext(ctx);
51 ASSERT_EQ(1, result.size());
52 ASSERT_EQ(std::string(TO_NAMED_FUNCTION_NAME), result[0].action.name);
53 }
54
TEST_F(LspConvFuncTests,ConvertFunctionRefactor2)55 TEST_F(LspConvFuncTests, ConvertFunctionRefactor2)
56 {
57 std::vector<std::string> files = {"convertFunctionRefactor2.ets"};
58 std::vector<std::string> texts = {R"(function sub(a: number, b: number): number{
59 return a - b;
60 };)"};
61 auto filePaths = CreateTempFile(files, texts);
62 size_t const expectedFileCount = 1;
63 ASSERT_EQ(filePaths.size(), expectedFileCount);
64
65 size_t const position = 11;
66 Initializer initializer = Initializer();
67 auto ctx = initializer.CreateContext(filePaths[0].c_str(), ES2PANDA_STATE_CHECKED);
68 ark::es2panda::lsp::RefactorContext refactorContext;
69 refactorContext.context = ctx;
70 refactorContext.kind = std::string(TO_NAMED_FUNCTION_KIND);
71 refactorContext.span.pos = position;
72 auto result = GetApplicableRefactorsImpl(&refactorContext);
73 initializer.DestroyContext(ctx);
74 ASSERT_EQ(0, result.size());
75 }
76
TEST_F(LspConvFuncTests,ConvertFunctionRefactor3)77 TEST_F(LspConvFuncTests, ConvertFunctionRefactor3)
78 {
79 std::vector<std::string> files = {"convertFunctionRefactor3.ets"};
80 std::vector<std::string> texts = {R"(const add = (x: number, y: number): number => {
81 return x + y;
82 };)"};
83 auto filePaths = CreateTempFile(files, texts);
84 size_t const expectedFileCount = 1;
85 ASSERT_EQ(filePaths.size(), expectedFileCount);
86
87 size_t const position = 8;
88 Initializer initializer = Initializer();
89 auto ctx = initializer.CreateContext(filePaths[0].c_str(), ES2PANDA_STATE_CHECKED);
90 ark::es2panda::lsp::RefactorContext refactorContext;
91 refactorContext.context = ctx;
92 refactorContext.kind = std::string(INVALID_KIND);
93 refactorContext.span.pos = position;
94 auto result = GetApplicableRefactorsImpl(&refactorContext);
95 initializer.DestroyContext(ctx);
96 ASSERT_EQ(0, result.size());
97 }
98
TEST_F(LspConvFuncTests,ConvertFunctionRefactor4)99 TEST_F(LspConvFuncTests, ConvertFunctionRefactor4)
100 {
101 std::vector<std::string> files = {"convertFunctionRefactor4.ets"};
102 std::vector<std::string> texts = {R"(const foo = a => {
103 let b = 1;
104 return a + b;
105 };)"};
106 auto filePaths = CreateTempFile(files, texts);
107 size_t const expectedFileCount = 1;
108 ASSERT_EQ(filePaths.size(), expectedFileCount);
109 size_t const position = 13;
110 Initializer initializer = Initializer();
111 auto ctx = initializer.CreateContext(filePaths[0].c_str(), ES2PANDA_STATE_CHECKED);
112 ark::es2panda::lsp::RefactorContext refactorContext;
113 refactorContext.context = ctx;
114 refactorContext.kind = std::string(TO_NAMED_FUNCTION_KIND);
115 refactorContext.span.pos = position;
116 auto result = GetApplicableRefactorsImpl(&refactorContext);
117 initializer.DestroyContext(ctx);
118 ASSERT_EQ(1, result.size());
119 ASSERT_EQ(std::string(TO_NAMED_FUNCTION_NAME), result[0].action.name);
120 }
121
TEST_F(LspConvFuncTests,ConvertFunctionRefactor5)122 TEST_F(LspConvFuncTests, ConvertFunctionRefactor5)
123 {
124 std::vector<std::string> files = {"convertFunctionRefactor5.ets"};
125 std::vector<std::string> texts = {R"(function doSomething(a){}
126 doSomething(() => 1 + 1);)"};
127 auto filePaths = CreateTempFile(files, texts);
128 size_t const expectedFileCount = 1;
129 ASSERT_EQ(filePaths.size(), expectedFileCount);
130
131 size_t const position = 41;
132 Initializer initializer = Initializer();
133 auto ctx = initializer.CreateContext(filePaths[0].c_str(), ES2PANDA_STATE_CHECKED);
134 ark::es2panda::lsp::RefactorContext refactorContext;
135 refactorContext.context = ctx;
136 refactorContext.kind = std::string(TO_NAMED_FUNCTION_KIND);
137 refactorContext.span.pos = position;
138 auto result = GetApplicableRefactorsImpl(&refactorContext);
139 initializer.DestroyContext(ctx);
140 ASSERT_EQ(0, result.size());
141 }
142
TEST_F(LspConvFuncTests,ConvertFunctionRefactor6)143 TEST_F(LspConvFuncTests, ConvertFunctionRefactor6)
144 {
145 std::vector<std::string> files = {"convertFunctionRefactor6.ets"};
146 std::vector<std::string> texts = {R"(const foo = (a,b,c) => a + 1;)"};
147 auto filePaths = CreateTempFile(files, texts);
148 size_t const expectedFileCount = 1;
149 ASSERT_EQ(filePaths.size(), expectedFileCount);
150
151 size_t const position = 14;
152 Initializer initializer = Initializer();
153 auto ctx = initializer.CreateContext(filePaths[0].c_str(), ES2PANDA_STATE_CHECKED);
154 ark::es2panda::lsp::RefactorContext refactorContext;
155 refactorContext.context = ctx;
156 refactorContext.kind = std::string(TO_NAMED_FUNCTION_KIND);
157 refactorContext.span.pos = position;
158 auto result = GetApplicableRefactorsImpl(&refactorContext);
159 initializer.DestroyContext(ctx);
160 ASSERT_EQ(1, result.size());
161 ASSERT_EQ(std::string(TO_NAMED_FUNCTION_NAME), result[0].action.name);
162 }
163
TEST_F(LspConvFuncTests,ConvertFunctionRefactor7)164 TEST_F(LspConvFuncTests, ConvertFunctionRefactor7)
165 {
166 std::vector<std::string> files = {"convertFunctionRefactor7.ets"};
167 std::vector<std::string> texts = {R"(const foo = () => //comment
168 1)"};
169 auto filePaths = CreateTempFile(files, texts);
170 size_t const expectedFileCount = 1;
171 ASSERT_EQ(filePaths.size(), expectedFileCount);
172
173 size_t const position = 14;
174 Initializer initializer = Initializer();
175 auto ctx = initializer.CreateContext(filePaths[0].c_str(), ES2PANDA_STATE_CHECKED);
176 ark::es2panda::lsp::RefactorContext refactorContext;
177 refactorContext.context = ctx;
178 refactorContext.kind = std::string(TO_NAMED_FUNCTION_KIND);
179 refactorContext.span.pos = position;
180 auto result = GetApplicableRefactorsImpl(&refactorContext);
181 initializer.DestroyContext(ctx);
182 ASSERT_EQ(1, result.size());
183 ASSERT_EQ(std::string(TO_NAMED_FUNCTION_NAME), result[0].action.name);
184 }
185
TEST_F(LspConvFuncTests,ConvertFunctionRefactor8)186 TEST_F(LspConvFuncTests, ConvertFunctionRefactor8)
187 {
188 std::vector<std::string> files = {"convertFunctionRefactor8.ets"};
189 std::vector<std::string> texts = {R"(function func() {
190 const test = () => {
191 }
192 })"};
193 auto filePaths = CreateTempFile(files, texts);
194 size_t const expectedFileCount = 1;
195 ASSERT_EQ(filePaths.size(), expectedFileCount);
196
197 size_t const position = 28;
198 Initializer initializer = Initializer();
199 auto ctx = initializer.CreateContext(filePaths[0].c_str(), ES2PANDA_STATE_CHECKED);
200 ark::es2panda::lsp::RefactorContext refactorContext;
201 refactorContext.context = ctx;
202 refactorContext.kind = std::string(TO_NAMED_FUNCTION_KIND);
203 refactorContext.span.pos = position;
204 auto result = GetApplicableRefactorsImpl(&refactorContext);
205 initializer.DestroyContext(ctx);
206 ASSERT_EQ(0, result.size());
207 }
208
TEST_F(LspConvFuncTests,ConvertFunctionRefactor9)209 TEST_F(LspConvFuncTests, ConvertFunctionRefactor9)
210 {
211 std::vector<std::string> files = {"convertFunctionRefactor9.ets"};
212 std::vector<std::string> texts = {R"(class AA {
213 func() {
214 const test = () => {}
215 }
216 })"};
217 auto filePaths = CreateTempFile(files, texts);
218 size_t const expectedFileCount = 1;
219 ASSERT_EQ(filePaths.size(), expectedFileCount);
220
221 size_t const position = 31;
222 Initializer initializer = Initializer();
223 auto ctx = initializer.CreateContext(filePaths[0].c_str(), ES2PANDA_STATE_CHECKED);
224 ark::es2panda::lsp::RefactorContext refactorContext;
225 refactorContext.context = ctx;
226 refactorContext.kind = std::string(TO_NAMED_FUNCTION_KIND);
227 refactorContext.span.pos = position;
228 auto result = GetApplicableRefactorsImpl(&refactorContext);
229 initializer.DestroyContext(ctx);
230 ASSERT_EQ(0, result.size());
231 }
232
TEST_F(LspConvFuncTests,ConvertFunctionRefactor10)233 TEST_F(LspConvFuncTests, ConvertFunctionRefactor10)
234 {
235 std::vector<std::string> files = {"convertFunctionRefactor10.ets"};
236 std::vector<std::string> texts = {R"(const func = () => {
237 const test = () => {}
238 })"};
239 auto filePaths = CreateTempFile(files, texts);
240 size_t const expectedFileCount = 1;
241 ASSERT_EQ(filePaths.size(), expectedFileCount);
242
243 size_t const position = 31;
244 Initializer initializer = Initializer();
245 auto ctx = initializer.CreateContext(filePaths[0].c_str(), ES2PANDA_STATE_CHECKED);
246 ark::es2panda::lsp::RefactorContext refactorContext;
247 refactorContext.context = ctx;
248 refactorContext.kind = std::string(TO_NAMED_FUNCTION_KIND);
249 refactorContext.span.pos = position;
250 auto result = GetApplicableRefactorsImpl(&refactorContext);
251 initializer.DestroyContext(ctx);
252 ASSERT_EQ(0, result.size());
253 }
254
TEST_F(LspConvFuncTests,ConvertFunctionRefactor11)255 TEST_F(LspConvFuncTests, ConvertFunctionRefactor11)
256 {
257 std::vector<std::string> files = {"convertFunctionRefactor11.ets"};
258 std::vector<std::string> texts = {R"(@Component
259 struct Index {
260 build() {
261 Text().onClick(()=>{
262 const test = () =>{}
263 })
264 }
265 })"};
266 auto filePaths = CreateTempFile(files, texts);
267 size_t const expectedFileCount = 1;
268 ASSERT_EQ(filePaths.size(), expectedFileCount);
269
270 size_t const position = 70;
271 Initializer initializer = Initializer();
272 auto ctx = initializer.CreateContext(filePaths[0].c_str(), ES2PANDA_STATE_CHECKED);
273 ark::es2panda::lsp::RefactorContext refactorContext;
274 refactorContext.context = ctx;
275 refactorContext.kind = std::string(TO_NAMED_FUNCTION_KIND);
276 refactorContext.span.pos = position;
277 auto result = GetApplicableRefactorsImpl(&refactorContext);
278 initializer.DestroyContext(ctx);
279 ASSERT_EQ(0, result.size());
280 }
281 } // namespace