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/internal_api.h"
22 #include "public/es2panda_lib.h"
23 #include "public/public.h"
24
25 namespace {
26
27 using ark::es2panda::lsp::Initializer;
28
TEST_F(LSPAPITests,DiagnosticConstructorAndField)29 TEST_F(LSPAPITests, DiagnosticConstructorAndField)
30 {
31 int const errorCode = 404;
32 int const defaultCharacter = 10;
33 std::vector<DiagnosticTag> tags {};
34 std::vector<DiagnosticRelatedInformation> relatedInfoList {};
35 Diagnostic diagnostic(range_, tags, relatedInfoList, DiagnosticSeverity::Error, errorCode, message_);
36
37 EXPECT_EQ(diagnostic.range_.start.line_, 1);
38 EXPECT_EQ(diagnostic.range_.end.character_, defaultCharacter);
39 EXPECT_EQ(diagnostic.message_, message_);
40 EXPECT_EQ(diagnostic.severity_, DiagnosticSeverity::Error);
41 EXPECT_EQ(std::get<int>(diagnostic.code_), errorCode);
42 }
43
TEST_F(LSPAPITests,DiagnosticCodeDescriptionOptional)44 TEST_F(LSPAPITests, DiagnosticCodeDescriptionOptional)
45 {
46 CodeDescription codeDesc;
47 codeDesc.href_ = "http://example.com/error/404";
48 int const errorCode = 404;
49 std::vector<DiagnosticTag> tags {};
50 std::vector<DiagnosticRelatedInformation> relatedInfoList {};
51
52 Diagnostic diagnostic(range_, tags, relatedInfoList, DiagnosticSeverity::Error, errorCode, message_, codeDesc);
53
54 const auto &codeDescription = diagnostic.codeDescription_;
55 EXPECT_EQ(codeDescription.href_, "http://example.com/error/404");
56 }
57
TEST_F(LSPAPITests,DiagnosticTagsAndRelatedInformation)58 TEST_F(LSPAPITests, DiagnosticTagsAndRelatedInformation)
59 {
60 std::vector<DiagnosticTag> tags {};
61 tags.push_back(DiagnosticTag::Unnecessary);
62 std::vector<DiagnosticRelatedInformation> relatedInfoList {};
63 DiagnosticRelatedInformation relatedInfo;
64 relatedInfo.location_ = Location {"www.test.uri", range_};
65 relatedInfo.message_ = "Related information message";
66 relatedInfoList.push_back(relatedInfo);
67 int const errorCode = 200;
68 CodeDescription des = {};
69
70 Diagnostic diagnostic(range_, tags, relatedInfoList, DiagnosticSeverity::Information, errorCode, message_, des,
71 "default");
72
73 const auto &diagnosticTags = diagnostic.tags_;
74 EXPECT_EQ(diagnosticTags.size(), 1);
75 EXPECT_EQ(diagnosticTags[0], DiagnosticTag::Unnecessary);
76
77 const auto &relatedInformation = diagnostic.relatedInformation_;
78 EXPECT_EQ(relatedInformation.size(), 1);
79 EXPECT_EQ(relatedInformation[0].message_, "Related information message");
80 }
81
TEST_F(LSPAPITests,DiagnosticDataField)82 TEST_F(LSPAPITests, DiagnosticDataField)
83 {
84 int const dataValue = 42;
85 std::variant<int, std::string> data = dataValue;
86 int const errorCode = 400;
87 int const dataResult = 42;
88 std::vector<DiagnosticTag> tags {};
89 std::vector<DiagnosticRelatedInformation> relatedInfoList {};
90
91 Diagnostic diagnostic(range_, tags, relatedInfoList, DiagnosticSeverity::Error, errorCode, message_, {}, {}, data);
92
93 const auto &diagnosticData = diagnostic.data_;
94 EXPECT_EQ(std::get<int>(diagnosticData), dataResult);
95 }
96
TEST_F(LSPAPITests,CreateDiagnosticForNode1)97 TEST_F(LSPAPITests, CreateDiagnosticForNode1)
98 {
99 using ark::es2panda::ir::AstNode;
100 using ark::es2panda::public_lib::Context;
101 Initializer initializer = Initializer();
102 es2panda_Context *ctx = initializer.CreateContext("file1.ets", ES2PANDA_STATE_CHECKED, "function main() {}");
103 auto astNode = GetAstFromContext<es2panda_AstNode>(ctx);
104 int const dataValue = 42;
105 std::variant<int, std::string> data = dataValue;
106 int const errorCode = 400;
107 std::string message = "Diagnostic";
108 std::vector<DiagnosticTag> tags {};
109 std::vector<DiagnosticRelatedInformation> relatedInfoList {};
110
111 Diagnostic diagnostic(range_, tags, relatedInfoList, DiagnosticSeverity::Error, errorCode, message, {}, {}, data);
112 FileDiagnostic result = ark::es2panda::lsp::CreateDiagnosticForNode(astNode, diagnostic);
113
114 int const startLine = 0;
115 int const endLine = 0;
116 int const startChar = 0;
117 int const endChar = 18;
118 ASSERT_EQ(result.diagnostic.message_, "Diagnostic");
119 ASSERT_EQ(result.diagnostic.range_.start.line_, startLine);
120 ASSERT_EQ(result.diagnostic.range_.end.line_, endLine);
121 ASSERT_EQ(result.diagnostic.range_.start.character_, startChar);
122 ASSERT_EQ(result.diagnostic.range_.end.character_, endChar);
123 initializer.DestroyContext(ctx);
124 }
125
TEST_F(LSPAPITests,CreateDiagnosticForNode2)126 TEST_F(LSPAPITests, CreateDiagnosticForNode2)
127 {
128 using ark::es2panda::ir::AstNode;
129 using ark::es2panda::public_lib::Context;
130 Initializer initializer = Initializer();
131 es2panda_Context *ctx = initializer.CreateContext("file1.ets", ES2PANDA_STATE_CHECKED, "function main() {}");
132 auto astNode = GetAstFromContext<es2panda_AstNode>(ctx);
133 int const dataValue = 42;
134 std::variant<int, std::string> data = dataValue;
135 int const errorCode = 400;
136 std::string message = "Diagnostic {0}, for the {1}, and {2}";
137 std::vector<std::string> args = {"Error1", "Error2", "Error3"};
138 std::vector<DiagnosticTag> tags {};
139 std::vector<DiagnosticRelatedInformation> relatedInfoList {};
140
141 Diagnostic diagnostic(range_, tags, relatedInfoList, DiagnosticSeverity::Error, errorCode, message, {}, {}, data);
142 FileDiagnostic result = ark::es2panda::lsp::CreateDiagnosticForNode(astNode, diagnostic, args);
143
144 int const startLine = 0;
145 int const endLine = 0;
146 int const startChar = 0;
147 int const endChar = 18;
148 ASSERT_EQ(result.diagnostic.message_, "Diagnostic Error1, for the Error2, and Error3");
149 ASSERT_EQ(result.diagnostic.range_.start.line_, startLine);
150 ASSERT_EQ(result.diagnostic.range_.end.line_, endLine);
151 ASSERT_EQ(result.diagnostic.range_.start.character_, startChar);
152 ASSERT_EQ(result.diagnostic.range_.end.character_, endChar);
153 initializer.DestroyContext(ctx);
154 }
155
TEST_F(LSPAPITests,CreateDiagnosticForNode3)156 TEST_F(LSPAPITests, CreateDiagnosticForNode3)
157 {
158 using ark::es2panda::ir::AstNode;
159 using ark::es2panda::public_lib::Context;
160 Initializer initializer = Initializer();
161 es2panda_Context *ctx =
162 initializer.CreateContext("file1.ets", ES2PANDA_STATE_CHECKED, "let a = () => {\n return 1;\n}");
163 auto astNode = reinterpret_cast<AstNode *>(GetAstFromContext<ark::es2panda::ir::AstNode>(ctx));
164 astNode = astNode->FindChild([](ark::es2panda::ir::AstNode *child) { return child->IsArrowFunctionExpression(); });
165 int const dataValue = 42;
166 std::variant<int, std::string> data = dataValue;
167 int const errorCode = 400;
168 std::string message = "Diagnostic {0}, for the {1}, and {2}";
169 std::vector<std::string> args = {"Error1", "Error2", "Error3"};
170 std::vector<DiagnosticTag> tags {};
171 std::vector<DiagnosticRelatedInformation> relatedInfoList {};
172
173 Diagnostic diagnostic(range_, tags, relatedInfoList, DiagnosticSeverity::Error, errorCode, message, {}, {}, data);
174 FileDiagnostic result =
175 ark::es2panda::lsp::CreateDiagnosticForNode(reinterpret_cast<es2panda_AstNode *>(astNode), diagnostic, args);
176
177 int const startLine = 0;
178 int const endLine = 2;
179 int const startChar = 12;
180 int const endChar = 33;
181 ASSERT_EQ(result.diagnostic.message_, "Diagnostic Error1, for the Error2, and Error3");
182 ASSERT_EQ(result.diagnostic.range_.start.line_, startLine);
183 ASSERT_EQ(result.diagnostic.range_.end.line_, endLine);
184 ASSERT_EQ(result.diagnostic.range_.start.character_, startChar);
185 ASSERT_EQ(result.diagnostic.range_.end.character_, endChar);
186 initializer.DestroyContext(ctx);
187 }
188
189 } // namespace
190