• 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 "../lsp_api_test.h"
17 
18 #include <gtest/gtest.h>
19 
20 #include "ir/astNode.h"
21 #include "lsp/include/register_code_fix/ui_plugin_suggest.h"
22 #include "lsp/include/internal_api.h"
23 #include "public/es2panda_lib.h"
24 #include "public/public.h"
25 
26 namespace {
27 
28 class LspUISuggestionTests : public LSPAPITests {};
29 
30 using ark::es2panda::lsp::Initializer;
31 
AssertDiagnosticContainsCodeAndMessage(const DiagnosticReferences & suggest,const int code,const char * dmessage)32 void AssertDiagnosticContainsCodeAndMessage(const DiagnosticReferences &suggest, const int code, const char *dmessage)
33 {
34     bool found = false;
35     for (auto diag : suggest.diagnostic) {
36         if (std::get<int>(diag.code_) == code) {
37             if (diag.message_ == dmessage) {
38                 found = true;
39             }
40         }
41     }
42     ASSERT_TRUE(found) << "Expected code: " << code << " not found";
43 }
44 
TEST_F(LspUISuggestionTests,UIPluginsErrorTest1)45 TEST_F(LspUISuggestionTests, UIPluginsErrorTest1)
46 {
47     using ark::es2panda::ir::AstNode;
48     using ark::es2panda::public_lib::Context;
49     Initializer initializer = Initializer();
50     std::vector<std::string> files = {"ui_error1.ets"};
51     std::vector<std::string> texts = {R"delimiter(function main() {})delimiter"};
52     auto filePaths = CreateTempFile(files, texts);
53     auto ctx = initializer.CreateContext(filePaths[0].c_str(), ES2PANDA_STATE_CHECKED);
54     LSPAPI const *lspApi = GetImpl();
55     int const offset = 11;
56     // NOLINTNEXTLINE
57     const char *params[] = {
58         "a",
59     };
60     const char *dmessage1 = "origin {}";
61     const size_t argc1 = 1;
62     const char *substitutionCode = "replace b";
63     const char *dmessage2 = "error";
64     const size_t argc0 = 0;
65     const size_t index1 = 1;
66     const size_t line1 = 0;
67     const size_t index2 = 15;
68     const size_t line2 = 0;
69     const int code = 4000;
70     auto suggestionkind = initializer.CreateDiagnosticKind(ctx, dmessage1, ES2PANDA_PLUGIN_SUGGESTION);
71     auto suggestionInfo = initializer.CreateSuggestionInfo(ctx, suggestionkind, params, argc1, substitutionCode);
72     auto diagnostikind = initializer.CreateDiagnosticKind(ctx, dmessage2, ES2PANDA_PLUGIN_ERROR);
73     auto diagnosticInfo = initializer.CreateDiagnosticInfo(ctx, diagnostikind, nullptr, argc0);
74     es2panda_SourcePosition *left = initializer.CreateSourcePosition(ctx, index1, line1);
75     es2panda_SourcePosition *right = initializer.CreateSourcePosition(ctx, index2, line2);
76     es2panda_SourceRange *range = initializer.CreateSourceRange(ctx, left, right);
77     initializer.LogDiagnosticWithSuggestion(ctx, diagnosticInfo, suggestionInfo, range);
78     auto suggest = lspApi->getSyntacticDiagnostics(ctx);
79     AssertDiagnosticContainsCodeAndMessage(suggest, code, dmessage2);
80     auto result = ark::es2panda::lsp::UIPluginSuggest::GetUIPluginCodeFixes(ctx, offset, false);
81     ASSERT_EQ(result.at(0).textChanges.at(0).newText, substitutionCode);
82     std::vector<int> codes;
83     codes.emplace_back(code);
84     CodeFixOptions emptyOptions;
85     auto fix = ark::es2panda::lsp::GetCodeFixesAtPositionImpl(ctx, index1, index2, codes, emptyOptions);
86     ASSERT_EQ(fix.at(0).changes_.at(0).textChanges.at(0).newText, substitutionCode);
87     ASSERT_EQ(fix.at(0).changes_.at(0).textChanges.at(0).span.length, index2 - index1);
88 
89     initializer.DestroyContext(ctx);
90 }
91 
TEST_F(LspUISuggestionTests,UIPluginsErrorTest2)92 TEST_F(LspUISuggestionTests, UIPluginsErrorTest2)
93 {
94     using ark::es2panda::ir::AstNode;
95     using ark::es2panda::public_lib::Context;
96     Initializer initializer = Initializer();
97     std::vector<std::string> files = {"ui_error2.ets"};
98     std::vector<std::string> texts = {R"delimiter(function main() {})delimiter"};
99     auto filePaths = CreateTempFile(files, texts);
100     auto ctx = initializer.CreateContext(filePaths[0].c_str(), ES2PANDA_STATE_CHECKED);
101     LSPAPI const *lspApi = GetImpl();
102     // NOLINTNEXTLINE
103     const char *params[] = {
104         "a",
105     };
106     const size_t argc1 = 1;
107     const char *dmessage2 = "origin {}";
108     const char *dmessage1 = "origin a";
109     const size_t index1 = 0;
110     const size_t line1 = 0;
111     const int code = 4000;
112     auto diagnostikind = initializer.CreateDiagnosticKind(ctx, dmessage2, ES2PANDA_PLUGIN_ERROR);
113     es2panda_SourcePosition *left = initializer.CreateSourcePosition(ctx, index1, line1);
114 
115     initializer.LogDiagnostic(ctx, diagnostikind, params, argc1, left);
116     auto suggest = lspApi->getSyntacticDiagnostics(ctx);
117     AssertDiagnosticContainsCodeAndMessage(suggest, code, dmessage1);
118     std::vector<int> codes;
119     codes.emplace_back(code);
120     CodeFixOptions emptyOptions;
121     auto fix = ark::es2panda::lsp::GetCodeFixesAtPositionImpl(ctx, index1, index1, codes, emptyOptions);
122     ASSERT_TRUE(fix.at(0).changes_.at(0).textChanges.empty());
123 
124     initializer.DestroyContext(ctx);
125 }
126 
TEST_F(LspUISuggestionTests,UIPluginsErrorTest3)127 TEST_F(LspUISuggestionTests, UIPluginsErrorTest3)
128 {
129     using ark::es2panda::ir::AstNode;
130     using ark::es2panda::public_lib::Context;
131     Initializer initializer = Initializer();
132     std::vector<std::string> files = {"ui_error3.ets"};
133     std::vector<std::string> texts = {R"delimiter(function main() {})delimiter"};
134     auto filePaths = CreateTempFile(files, texts);
135     auto ctx = initializer.CreateContext(filePaths[0].c_str(), ES2PANDA_STATE_CHECKED);
136     LSPAPI const *lspApi = GetImpl();
137     const char *dmessage1 = "origin a";
138     const char *substitutionCode = "replace b";
139     const char *dmessage2 = "error";
140     const size_t argc0 = 0;
141     const size_t index1 = 0;
142     const size_t line1 = 0;
143     const size_t index2 = 15;
144     const size_t line2 = 0;
145     const int code = 4000;
146     auto suggestionkind = initializer.CreateDiagnosticKind(ctx, dmessage1, ES2PANDA_PLUGIN_SUGGESTION);
147     auto suggestionInfo = initializer.CreateSuggestionInfo(ctx, suggestionkind, nullptr, argc0, substitutionCode);
148     auto diagnostikind = initializer.CreateDiagnosticKind(ctx, dmessage2, ES2PANDA_PLUGIN_ERROR);
149     auto diagnosticInfo = initializer.CreateDiagnosticInfo(ctx, diagnostikind, nullptr, argc0);
150     es2panda_SourcePosition *left = initializer.CreateSourcePosition(ctx, index1, line1);
151     es2panda_SourcePosition *right = initializer.CreateSourcePosition(ctx, index2, line2);
152     es2panda_SourceRange *range = initializer.CreateSourceRange(ctx, left, right);
153     initializer.LogDiagnosticWithSuggestion(ctx, diagnosticInfo, suggestionInfo, range);
154 
155     const char *substitutionCode2 = "replace c";
156     auto suggestionkind2 = initializer.CreateDiagnosticKind(ctx, dmessage1, ES2PANDA_PLUGIN_SUGGESTION);
157     auto suggestionInfo2 = initializer.CreateSuggestionInfo(ctx, suggestionkind2, nullptr, argc0, substitutionCode2);
158     auto diagnostikind2 = initializer.CreateDiagnosticKind(ctx, dmessage2, ES2PANDA_PLUGIN_ERROR);
159     auto diagnosticInfo2 = initializer.CreateDiagnosticInfo(ctx, diagnostikind2, nullptr, argc0);
160     es2panda_SourcePosition *left2 = initializer.CreateSourcePosition(ctx, index1, line1);
161     es2panda_SourcePosition *right2 = initializer.CreateSourcePosition(ctx, index2, line2);
162     es2panda_SourceRange *range2 = initializer.CreateSourceRange(ctx, left2, right2);
163     initializer.LogDiagnosticWithSuggestion(ctx, diagnosticInfo2, suggestionInfo2, range2);
164 
165     auto suggest = lspApi->getSyntacticDiagnostics(ctx);
166     AssertDiagnosticContainsCodeAndMessage(suggest, code, dmessage2);
167     AssertDiagnosticContainsCodeAndMessage(suggest, code, dmessage2);
168     std::vector<int> codes;
169     codes.emplace_back(code);
170     CodeFixOptions emptyOptions;
171     const std::string fixId = "UIPluginSuggest";
172     auto fix = ark::es2panda::lsp::GetCodeFixesAtPositionImpl(ctx, index1, index1, codes, emptyOptions);
173     ASSERT_FALSE(fix.at(0).changes_.at(0).textChanges.empty());
174     auto fixAll = ark::es2panda::lsp::GetCombinedCodeFixImpl(ctx, fixId, emptyOptions);
175     const size_t expectedCount = 2;
176     ASSERT_EQ(fixAll.changes_.size(), expectedCount);
177 
178     initializer.DestroyContext(ctx);
179 }
180 
181 }  // namespace
182