• 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 <cstddef>
18 #include <string>
19 #include "lsp_api_test.h"
20 #include "lsp/include/applicable_refactors.h"
21 
22 const size_t REFACTOR_TEMPLATE_POSITION_OFFSET = 8;
23 
24 namespace {
25 using ark::es2panda::lsp::Initializer;
26 
27 class LspTemplateRefTests : public LSPAPITests {
28 public:
29     static constexpr std::string_view TO_NAMED_TEMPLATE_KIND = "refactor.rewrite.string";
30     static constexpr std::string_view TO_NAMED_TEMPLATE_NAME = "Convert to template string";
31 };
32 
TEST_F(LspTemplateRefTests,ConvertTemplateRefactor1)33 TEST_F(LspTemplateRefTests, ConvertTemplateRefactor1)
34 {
35     std::vector<std::string> files = {"ConvertTemplateRefactor1.ets"};
36     std::vector<std::string> texts = {R"(let a = /*1*/"\\0\\b\\f\\t\\r\\n" +text + "\\n"/*2*/;)"};
37     auto filePaths = CreateTempFile(files, texts);
38     size_t const expectedFileCount = 1;
39     ASSERT_EQ(filePaths.size(), expectedFileCount);
40 
41     auto pos = texts[0].find("/*1*/");
42     ASSERT_NE(pos, std::string::npos);
43     Initializer initializer = Initializer();
44 
45     auto ctx = initializer.CreateContext(filePaths[0].c_str(), ES2PANDA_STATE_CHECKED);
46     ark::es2panda::lsp::RefactorContext refactorContext;
47     refactorContext.context = ctx;
48     refactorContext.kind = std::string(TO_NAMED_TEMPLATE_KIND);
49     refactorContext.span.pos = pos + REFACTOR_TEMPLATE_POSITION_OFFSET;
50     auto result = GetApplicableRefactorsImpl(&refactorContext);
51     initializer.DestroyContext(ctx);
52 
53     ASSERT_EQ(1, result.size());
54     ASSERT_EQ(std::string(TO_NAMED_TEMPLATE_NAME), result[0].action.name);
55 }
56 
TEST_F(LspTemplateRefTests,ConvertTemplateRefactor2)57 TEST_F(LspTemplateRefTests, ConvertTemplateRefactor2)
58 {
59     std::vector<std::string> files = {"ConvertTemplateRefactor2.ets"};
60     std::vector<std::string> texts = {R"(let b = /*3*/"" + text + ""/*4*/;)"};
61     auto filePaths = CreateTempFile(files, texts);
62     size_t const expectedFileCount = 1;
63     ASSERT_EQ(filePaths.size(), expectedFileCount);
64 
65     auto pos = texts[0].find("/*3*/");
66     ASSERT_NE(pos, std::string::npos);
67     Initializer initializer = Initializer();
68     auto ctx = initializer.CreateContext(filePaths[0].c_str(), ES2PANDA_STATE_CHECKED);
69     ark::es2panda::lsp::RefactorContext refactorContext;
70     refactorContext.context = ctx;
71     refactorContext.kind = std::string(TO_NAMED_TEMPLATE_KIND);
72     refactorContext.span.pos = pos + REFACTOR_TEMPLATE_POSITION_OFFSET;
73     auto result = GetApplicableRefactorsImpl(&refactorContext);
74     initializer.DestroyContext(ctx);
75     ASSERT_EQ(1, result.size());
76     ASSERT_EQ(std::string(TO_NAMED_TEMPLATE_NAME), result[0].action.name);
77 }
78 
TEST_F(LspTemplateRefTests,ConvertTemplateRefactor3)79 TEST_F(LspTemplateRefTests, ConvertTemplateRefactor3)
80 {
81     std::vector<std::string> files = {"ConvertTemplateRefactor3.ets"};
82     std::vector<std::string> texts = {R"(let c = /*5*/'\$' + text + "\\\\/*6*/";)"};
83     auto filePaths = CreateTempFile(files, texts);
84     size_t const expectedFileCount = 1;
85     ASSERT_EQ(filePaths.size(), expectedFileCount);
86 
87     auto pos = texts[0].find("/*5*/");
88     ASSERT_NE(pos, std::string::npos);
89     Initializer initializer = Initializer();
90     auto ctx = initializer.CreateContext(filePaths[0].c_str(), ES2PANDA_STATE_CHECKED);
91     ark::es2panda::lsp::RefactorContext refactorContext;
92     refactorContext.context = ctx;
93     refactorContext.kind = std::string(TO_NAMED_TEMPLATE_KIND);
94     refactorContext.span.pos = pos + REFACTOR_TEMPLATE_POSITION_OFFSET;
95     auto result = GetApplicableRefactorsImpl(&refactorContext);
96 
97     initializer.DestroyContext(ctx);
98     ASSERT_EQ(1, result.size());
99     ASSERT_EQ(std::string(TO_NAMED_TEMPLATE_NAME), result[0].action.name);
100 }
101 
TEST_F(LspTemplateRefTests,ConvertTemplateRefactor4)102 TEST_F(LspTemplateRefTests, ConvertTemplateRefactor4)
103 {
104     std::vector<std::string> files = {"ConvertTemplateRefactor4.ets"};
105     std::vector<std::string> texts = {R"(let d = /*7*/\'\$\' + text + \'\\\\\'/*8*/;)"};
106     auto filePaths = CreateTempFile(files, texts);
107     size_t const expectedFileCount = 1;
108     ASSERT_EQ(filePaths.size(), expectedFileCount);
109 
110     auto pos = texts[0].find("/*7*/");
111     ASSERT_NE(pos, std::string::npos);
112     Initializer initializer = Initializer();
113     auto ctx = initializer.CreateContext(filePaths[0].c_str(), ES2PANDA_STATE_CHECKED);
114     ark::es2panda::lsp::RefactorContext refactorContext;
115     refactorContext.context = ctx;
116     refactorContext.kind = std::string(TO_NAMED_TEMPLATE_KIND);
117     refactorContext.span.pos = pos + REFACTOR_TEMPLATE_POSITION_OFFSET;
118     auto result = GetApplicableRefactorsImpl(&refactorContext);
119 
120     initializer.DestroyContext(ctx);
121     ASSERT_EQ(0, result.size());
122 }
123 
TEST_F(LspTemplateRefTests,ConvertTemplateRefactor5)124 TEST_F(LspTemplateRefTests, ConvertTemplateRefactor5)
125 {
126     std::vector<std::string> files = {"ConvertTemplateRefactor5.ets"};
127     std::vector<std::string> texts = {R"(let e = /*9*/'\$\{' + text + "\}"/*10*/;)"};
128     auto filePaths = CreateTempFile(files, texts);
129     size_t const expectedFileCount = 1;
130     ASSERT_EQ(filePaths.size(), expectedFileCount);
131 
132     auto pos = texts[0].find("/*9*/");
133     ASSERT_NE(pos, std::string::npos);
134     Initializer initializer = Initializer();
135     auto ctx = initializer.CreateContext(filePaths[0].c_str(), ES2PANDA_STATE_CHECKED);
136     ark::es2panda::lsp::RefactorContext refactorContext;
137     refactorContext.context = ctx;
138     refactorContext.kind = std::string(TO_NAMED_TEMPLATE_KIND);
139     refactorContext.span.pos = pos + REFACTOR_TEMPLATE_POSITION_OFFSET;
140     auto result = GetApplicableRefactorsImpl(&refactorContext);
141 
142     initializer.DestroyContext(ctx);
143     ASSERT_EQ(1, result.size());
144     ASSERT_EQ(std::string(TO_NAMED_TEMPLATE_NAME), result[0].action.name);
145 }
146 
TEST_F(LspTemplateRefTests,ConvertTemplateRefactor6)147 TEST_F(LspTemplateRefTests, ConvertTemplateRefactor6)
148 {
149     std::vector<std::string> files = {"ConvertTemplateRefactor6.ets"};
150     std::vector<std::string> texts = {R"(let f = /*11*/ \'\\\$\{\' + text + \'\}\'/*12*/;)"};
151     auto filePaths = CreateTempFile(files, texts);
152     size_t const expectedFileCount = 1;
153     ASSERT_EQ(filePaths.size(), expectedFileCount);
154 
155     auto pos = texts[0].find("/*11*/");
156     ASSERT_NE(pos, std::string::npos);
157     Initializer initializer = Initializer();
158     auto ctx = initializer.CreateContext(filePaths[0].c_str(), ES2PANDA_STATE_CHECKED);
159     ark::es2panda::lsp::RefactorContext refactorContext;
160     refactorContext.context = ctx;
161     refactorContext.kind = std::string(TO_NAMED_TEMPLATE_KIND);
162     refactorContext.span.pos = pos + REFACTOR_TEMPLATE_POSITION_OFFSET;
163     auto result = GetApplicableRefactorsImpl(&refactorContext);
164     initializer.DestroyContext(ctx);
165     ASSERT_EQ(0, result.size());
166 }
167 
TEST_F(LspTemplateRefTests,ConvertTemplateRefactor7)168 TEST_F(LspTemplateRefTests, ConvertTemplateRefactor7)
169 {
170     std::vector<std::string> files = {"ConvertTemplateRefactor7.ets"};
171     std::vector<std::string> texts = {R"(let g = /*13*/'\\\\$ + text + "\\\\"/*14*/;)"};
172     auto filePaths = CreateTempFile(files, texts);
173     size_t const expectedFileCount = 1;
174     ASSERT_EQ(filePaths.size(), expectedFileCount);
175 
176     auto pos = texts[0].find("/*13*/");
177     ASSERT_NE(pos, std::string::npos);
178     Initializer initializer = Initializer();
179     auto ctx = initializer.CreateContext(filePaths[0].c_str(), ES2PANDA_STATE_CHECKED);
180     ark::es2panda::lsp::RefactorContext refactorContext;
181     refactorContext.context = ctx;
182     refactorContext.kind = std::string(TO_NAMED_TEMPLATE_KIND);
183     refactorContext.span.pos = pos + REFACTOR_TEMPLATE_POSITION_OFFSET;
184     auto result = GetApplicableRefactorsImpl(&refactorContext);
185 
186     initializer.DestroyContext(ctx);
187     ASSERT_EQ(0, result.size());
188 }
189 
TEST_F(LspTemplateRefTests,ConvertTemplateRefactor8)190 TEST_F(LspTemplateRefTests, ConvertTemplateRefactor8)
191 {
192     std::vector<std::string> files = {"ConvertTemplateRefactor8.ets"};
193     std::vector<std::string> texts = {R"(let h = /*15*/"\\u0041\\u0061" + text + "\\0\\u0000"/*16*/;)"};
194     auto filePaths = CreateTempFile(files, texts);
195     size_t const expectedFileCount = 1;
196     ASSERT_EQ(filePaths.size(), expectedFileCount);
197 
198     auto pos = texts[0].find("/*15*/");
199     ASSERT_NE(pos, std::string::npos);
200     Initializer initializer = Initializer();
201     auto ctx = initializer.CreateContext(filePaths[0].c_str(), ES2PANDA_STATE_CHECKED);
202     ark::es2panda::lsp::RefactorContext refactorContext;
203     refactorContext.context = ctx;
204     refactorContext.kind = std::string(TO_NAMED_TEMPLATE_KIND);
205     refactorContext.span.pos = pos + REFACTOR_TEMPLATE_POSITION_OFFSET;
206     auto result = GetApplicableRefactorsImpl(&refactorContext);
207     initializer.DestroyContext(ctx);
208     ASSERT_EQ(1, result.size());
209     ASSERT_EQ(std::string(TO_NAMED_TEMPLATE_NAME), result[0].action.name);
210 }
211 
TEST_F(LspTemplateRefTests,ConvertTemplateRefactor9)212 TEST_F(LspTemplateRefTests, ConvertTemplateRefactor9)
213 {
214     std::vector<std::string> files = {"ConvertTemplateRefactor9.ets"};
215     std::vector<std::string> texts = {R"(let i = /*17*/'\$\`' + text + "\`\\\\"/*18*/;)"};
216     auto filePaths = CreateTempFile(files, texts);
217     size_t const expectedFileCount = 1;
218     ASSERT_EQ(filePaths.size(), expectedFileCount);
219 
220     auto pos = texts[0].find("/*17*/");
221     ASSERT_NE(pos, std::string::npos);
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_TEMPLATE_KIND);
227     refactorContext.span.pos = pos + REFACTOR_TEMPLATE_POSITION_OFFSET;
228     auto result = GetApplicableRefactorsImpl(&refactorContext);
229     initializer.DestroyContext(ctx);
230     ASSERT_EQ(1, result.size());
231     ASSERT_EQ(std::string(TO_NAMED_TEMPLATE_NAME), result[0].action.name);
232 }
233 
234 }  // namespace