blob: 4bb9d53cd00bdd4b703c42118da4993ca4fd631b [file] [log] [blame]
// Copyright 2024 The Dawn & Tint Authors
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <string>
#include <string_view>
#include "gmock/gmock.h"
#include "langsvr/lsp/lsp.h"
#include "langsvr/lsp/primitives.h"
#include "langsvr/lsp/printer.h"
#include "src/tint/lang/wgsl/ls/helpers_test.h"
namespace tint::wgsl::ls {
namespace {
namespace lsp = langsvr::lsp;
struct Case {
const std::string_view wgsl;
const std::vector<lsp::Diagnostic> diagnostics;
};
struct Diagnostic : lsp::Diagnostic {
explicit Diagnostic(std::string_view msg) { message = msg; }
Diagnostic& Range(lsp::Uinteger start_line,
lsp::Uinteger start_column,
lsp::Uinteger end_line,
lsp::Uinteger end_column) {
range = lsp::Range{{start_line, start_column}, {end_line, end_column}};
return *this;
}
Diagnostic& Severity(lsp::DiagnosticSeverity s) {
severity = s;
return *this;
}
};
std::ostream& operator<<(std::ostream& stream, const Case& c) {
return stream << "wgsl: '" << c.wgsl << "'";
}
using LsDiagnosticsTest = LsTestWithParam<Case>;
TEST_P(LsDiagnosticsTest, Diagnostics) {
lsp::TextDocumentDocumentSymbolRequest req{};
req.text_document.uri = OpenDocument(GetParam().wgsl);
ASSERT_EQ(diagnostics_.Length(), 1u);
auto& notification = diagnostics_[0];
EXPECT_EQ(notification.uri, req.text_document.uri);
EXPECT_THAT(notification.diagnostics, testing::ContainerEq(GetParam().diagnostics));
}
INSTANTIATE_TEST_SUITE_P(,
LsDiagnosticsTest,
::testing::ValuesIn(std::vector<Case>{
{
"",
{},
},
{
"unknown_symbol",
{
Diagnostic{"unexpected token"}
.Range(0, 0, 0, 14)
.Severity(lsp::DiagnosticSeverity::kError),
},
},
{
"fn f() { return; return; }",
{
Diagnostic{"code is unreachable"}
.Range(0, 17, 0, 23)
.Severity(lsp::DiagnosticSeverity::kWarning),
},
},
{
"const A = B; const B = A;",
{
Diagnostic{"cyclic dependency found: 'A' -> 'B' -> 'A'"}
.Range(0, 0, 0, 11)
.Severity(lsp::DiagnosticSeverity::kError),
Diagnostic{"const 'A' references const 'B' here"}
.Range(0, 10, 0, 11)
.Severity(lsp::DiagnosticSeverity::kInformation),
Diagnostic{"const 'B' references const 'A' here"}
.Range(0, 23, 0, 24)
.Severity(lsp::DiagnosticSeverity::kInformation),
},
},
}));
} // namespace
} // namespace tint::wgsl::ls