clang-tools  11.0.0
ConfigYAMLTests.cpp
Go to the documentation of this file.
1 //===-- ConfigYAMLTests.cpp -----------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "Annotations.h"
10 #include "ConfigFragment.h"
11 #include "ConfigTesting.h"
12 #include "Protocol.h"
13 #include "llvm/Support/SMLoc.h"
14 #include "llvm/Support/ScopedPrinter.h"
15 #include "llvm/Support/SourceMgr.h"
16 #include "gmock/gmock.h"
17 #include "gtest/gtest.h"
18 
19 namespace clang {
20 namespace clangd {
21 namespace config {
22 template <typename T> void PrintTo(const Located<T> &V, std::ostream *OS) {
23  *OS << ::testing::PrintToString(*V);
24 }
25 
26 namespace {
27 using ::testing::AllOf;
28 using ::testing::ElementsAre;
29 using ::testing::IsEmpty;
30 
31 MATCHER_P(Val, Value, "") {
32  if (*arg == Value)
33  return true;
34  *result_listener << "value is " << *arg;
35  return false;
36 }
37 
38 TEST(ParseYAML, SyntacticForms) {
39  CapturedDiags Diags;
40  const char *YAML = R"yaml(
41 If:
42  PathMatch:
43  - 'abc'
44 CompileFlags: { Add: [foo, bar] }
45 ---
46 CompileFlags:
47  Add: |
48  b
49  az
50  )yaml";
51  auto Results = Fragment::parseYAML(YAML, "config.yaml", Diags.callback());
52  EXPECT_THAT(Diags.Diagnostics, IsEmpty());
53  ASSERT_EQ(Results.size(), 2u);
54  EXPECT_FALSE(Results.front().If.HasUnrecognizedCondition);
55  EXPECT_THAT(Results.front().If.PathMatch, ElementsAre(Val("abc")));
56  EXPECT_THAT(Results.front().CompileFlags.Add,
57  ElementsAre(Val("foo"), Val("bar")));
58 
59  EXPECT_THAT(Results.back().CompileFlags.Add, ElementsAre(Val("b\naz\n")));
60 }
61 
62 TEST(ParseYAML, Locations) {
63  CapturedDiags Diags;
64  Annotations YAML(R"yaml(
65 If:
66  PathMatch: [['???bad***regex(((']]
67  )yaml");
68  auto Results =
69  Fragment::parseYAML(YAML.code(), "config.yaml", Diags.callback());
70  EXPECT_THAT(Diags.Diagnostics, IsEmpty());
71  ASSERT_EQ(Results.size(), 1u);
72  ASSERT_NE(Results.front().Source.Manager, nullptr);
73  EXPECT_EQ(toRange(Results.front().If.PathMatch.front().Range,
74  *Results.front().Source.Manager),
75  YAML.range());
76 }
77 
78 TEST(ParseYAML, Diagnostics) {
79  CapturedDiags Diags;
80  Annotations YAML(R"yaml(
81 If:
82  [[UnknownCondition]]: "foo"
83 CompileFlags:
84  Add: 'first'
85 ---
86 CompileFlags: {^
87 )yaml");
88  auto Results =
89  Fragment::parseYAML(YAML.code(), "config.yaml", Diags.callback());
90 
91  ASSERT_THAT(
93  ElementsAre(AllOf(DiagMessage("Unknown If key UnknownCondition"),
94  DiagKind(llvm::SourceMgr::DK_Warning),
95  DiagPos(YAML.range().start), DiagRange(YAML.range())),
96  AllOf(DiagMessage("Unexpected token. Expected Key, Flow "
97  "Entry, or Flow Mapping End."),
98  DiagKind(llvm::SourceMgr::DK_Error),
99  DiagPos(YAML.point()), DiagRange(llvm::None))));
100 
101  ASSERT_EQ(Results.size(), 1u); // invalid fragment discarded.
102  EXPECT_THAT(Results.front().CompileFlags.Add, ElementsAre(Val("first")));
103  EXPECT_TRUE(Results.front().If.HasUnrecognizedCondition);
104 }
105 
106 TEST(ParseYAML, Invalid) {
107  CapturedDiags Diags;
108  const char *YAML = R"yaml(
109 If:
110 
111 horrible
112 ---
113 - 1
114  )yaml";
115  auto Results = Fragment::parseYAML(YAML, "config.yaml", Diags.callback());
116  EXPECT_THAT(Diags.Diagnostics,
117  ElementsAre(DiagMessage("If should be a dictionary"),
118  DiagMessage("Config should be a dictionary")));
119  ASSERT_THAT(Results, IsEmpty());
120 }
121 
122 } // namespace
123 } // namespace config
124 } // namespace clangd
125 } // namespace clang
clang::clangd::IndexFileFormat::YAML
clang::clangd::TEST
TEST(BackgroundQueueTest, Priority)
Definition: BackgroundIndexTests.cpp:704
clang::clangd::config::Fragment::parseYAML
static std::vector< Fragment > parseYAML(llvm::StringRef YAML, llvm::StringRef BufferName, DiagnosticCallback)
Parses fragments from a YAML file (one from each — delimited document).
Definition: ConfigYAML.cpp:198
clang::clangd::config::CapturedDiags::callback
std::function< void(const llvm::SMDiagnostic &)> callback()
Definition: ConfigTesting.h:25
clang::clangd::TextDocumentSyncKind::None
Documents should not be synced at all.
clang::clangd::config::Located
An entity written in config along, with its optional location in the file.
Definition: ConfigFragment.h:49
Protocol.h
clang::clangd::config::MATCHER_P
MATCHER_P(DiagMessage, M, "")
Definition: ConfigTesting.h:56
ConfigTesting.h
Results
std::vector< CodeCompletionResult > Results
Definition: CodeComplete.cpp:712
Annotations.h
clang
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
Definition: ApplyReplacements.h:27
OS
llvm::raw_string_ostream OS
Definition: TraceTests.cpp:162
Diags
CapturedDiags Diags
Definition: ConfigCompileTests.cpp:26
clang::clangd::config::PrintTo
void PrintTo(const Located< T > &V, std::ostream *OS)
Definition: ConfigYAMLTests.cpp:22
clang::clangd::config::CapturedDiags::Diagnostics
std::vector< Diag > Diagnostics
Definition: ConfigTesting.h:53
clang::clangd::config::toRange
Range toRange(llvm::SMRange R, const llvm::SourceMgr &SM)
Definition: ConfigTesting.h:69
ConfigFragment.h