1 //===-- ConfigCompileTests.cpp --------------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
10 #include "ConfigFragment.h"
11 #include "ConfigTesting.h"
12 #include "Diagnostics.h"
15 #include "clang/Basic/DiagnosticSema.h"
16 #include "llvm/ADT/StringRef.h"
17 #include "llvm/Support/Path.h"
18 #include "llvm/Support/SourceMgr.h"
19 #include "gmock/gmock.h"
20 #include "gtest/gtest.h"
28 using ::testing::AllOf
;
29 using ::testing::Contains
;
30 using ::testing::ElementsAre
;
31 using ::testing::IsEmpty
;
32 using ::testing::SizeIs
;
33 using ::testing::StartsWith
;
34 using ::testing::UnorderedElementsAre
;
36 class ConfigCompileTests
: public ::testing::Test
{
43 bool compileAndApply() {
45 Diags
.Diagnostics
.clear();
46 auto Compiled
= std::move(Frag
).compile(Diags
.callback());
47 return Compiled(Parm
, Conf
);
51 TEST_F(ConfigCompileTests
, Condition
) {
54 Frag
.CompileFlags
.Add
.emplace_back("X");
55 EXPECT_TRUE(compileAndApply()) << "Empty config";
56 EXPECT_THAT(Diags
.Diagnostics
, IsEmpty());
57 EXPECT_THAT(Conf
.CompileFlags
.Edits
, SizeIs(1));
59 // Regex with no file.
61 Frag
.If
.PathMatch
.emplace_back("fo*");
62 EXPECT_FALSE(compileAndApply());
63 EXPECT_THAT(Diags
.Diagnostics
, IsEmpty());
64 EXPECT_THAT(Conf
.CompileFlags
.Edits
, SizeIs(0));
66 // Following tests have a file path set.
69 // Non-matching regex.
71 Frag
.If
.PathMatch
.emplace_back("fo*");
72 EXPECT_FALSE(compileAndApply());
73 EXPECT_THAT(Diags
.Diagnostics
, IsEmpty());
77 Frag
.If
.PathMatch
.emplace_back("fo*");
78 Frag
.If
.PathMatch
.emplace_back("ba*r");
79 EXPECT_TRUE(compileAndApply());
80 EXPECT_THAT(Diags
.Diagnostics
, IsEmpty());
84 Frag
.If
.PathMatch
.emplace_back("b.*");
85 Frag
.If
.PathExclude
.emplace_back(".*r");
86 EXPECT_FALSE(compileAndApply()) << "Included but also excluded";
87 EXPECT_THAT(Diags
.Diagnostics
, IsEmpty());
91 Frag
.If
.PathMatch
.emplace_back("**]@theu");
92 EXPECT_TRUE(compileAndApply());
93 EXPECT_THAT(Diags
.Diagnostics
, SizeIs(1));
94 EXPECT_THAT(Diags
.Diagnostics
.front().Message
, StartsWith("Invalid regex"));
96 // Valid regex and unknown key.
98 Frag
.If
.HasUnrecognizedCondition
= true;
99 Frag
.If
.PathMatch
.emplace_back("ba*r");
100 EXPECT_FALSE(compileAndApply());
101 EXPECT_THAT(Diags
.Diagnostics
, IsEmpty());
103 // Only matches case-insensitively.
105 Frag
.If
.PathMatch
.emplace_back("B.*R");
106 EXPECT_THAT(Diags
.Diagnostics
, IsEmpty());
107 #ifdef CLANGD_PATH_CASE_INSENSITIVE
108 EXPECT_TRUE(compileAndApply());
110 EXPECT_FALSE(compileAndApply());
114 Frag
.If
.PathExclude
.emplace_back("B.*R");
115 EXPECT_THAT(Diags
.Diagnostics
, IsEmpty());
116 #ifdef CLANGD_PATH_CASE_INSENSITIVE
117 EXPECT_FALSE(compileAndApply());
119 EXPECT_TRUE(compileAndApply());
123 TEST_F(ConfigCompileTests
, CompileCommands
) {
124 Frag
.CompileFlags
.Compiler
.emplace("tpc.exe");
125 Frag
.CompileFlags
.Add
.emplace_back("-foo");
126 Frag
.CompileFlags
.Remove
.emplace_back("--include-directory=");
127 std::vector
<std::string
> Argv
= {"clang", "-I", "bar/", "--", "a.cc"};
128 EXPECT_TRUE(compileAndApply());
129 EXPECT_THAT(Conf
.CompileFlags
.Edits
, SizeIs(3));
130 for (auto &Edit
: Conf
.CompileFlags
.Edits
)
132 EXPECT_THAT(Argv
, ElementsAre("tpc.exe", "-foo", "--", "a.cc"));
135 TEST_F(ConfigCompileTests
, CompilationDatabase
) {
136 Frag
.CompileFlags
.CompilationDatabase
.emplace("None");
137 EXPECT_TRUE(compileAndApply());
138 EXPECT_EQ(Conf
.CompileFlags
.CDBSearch
.Policy
,
139 Config::CDBSearchSpec::NoCDBSearch
);
141 Frag
.CompileFlags
.CompilationDatabase
.emplace("Ancestors");
142 EXPECT_TRUE(compileAndApply());
143 EXPECT_EQ(Conf
.CompileFlags
.CDBSearch
.Policy
,
144 Config::CDBSearchSpec::Ancestors
);
146 // Relative path not allowed without directory set.
147 Frag
.CompileFlags
.CompilationDatabase
.emplace("Something");
148 EXPECT_TRUE(compileAndApply());
149 EXPECT_EQ(Conf
.CompileFlags
.CDBSearch
.Policy
,
150 Config::CDBSearchSpec::Ancestors
)
152 EXPECT_THAT(Diags
.Diagnostics
,
153 ElementsAre(diagMessage(
154 "CompilationDatabase must be an absolute path, because this "
155 "fragment is not associated with any directory.")));
157 // Relative path allowed if directory is set.
158 Frag
.Source
.Directory
= testRoot();
159 EXPECT_TRUE(compileAndApply());
160 EXPECT_EQ(Conf
.CompileFlags
.CDBSearch
.Policy
,
161 Config::CDBSearchSpec::FixedDir
);
162 EXPECT_EQ(Conf
.CompileFlags
.CDBSearch
.FixedCDBPath
, testPath("Something"));
163 EXPECT_THAT(Diags
.Diagnostics
, IsEmpty());
165 // Absolute path allowed.
166 Frag
.Source
.Directory
.clear();
167 Frag
.CompileFlags
.CompilationDatabase
.emplace(testPath("Something2"));
168 EXPECT_TRUE(compileAndApply());
169 EXPECT_EQ(Conf
.CompileFlags
.CDBSearch
.Policy
,
170 Config::CDBSearchSpec::FixedDir
);
171 EXPECT_EQ(Conf
.CompileFlags
.CDBSearch
.FixedCDBPath
, testPath("Something2"));
172 EXPECT_THAT(Diags
.Diagnostics
, IsEmpty());
175 TEST_F(ConfigCompileTests
, Index
) {
176 Frag
.Index
.Background
.emplace("Skip");
177 EXPECT_TRUE(compileAndApply());
178 EXPECT_EQ(Conf
.Index
.Background
, Config::BackgroundPolicy::Skip
);
181 Frag
.Index
.Background
.emplace("Foo");
182 EXPECT_TRUE(compileAndApply());
183 EXPECT_EQ(Conf
.Index
.Background
, Config::BackgroundPolicy::Build
)
187 ElementsAre(diagMessage(
188 "Invalid Background value 'Foo'. Valid values are Build, Skip.")));
191 TEST_F(ConfigCompileTests
, PathSpecMatch
) {
192 auto BarPath
= llvm::sys::path::convert_to_slash(testPath("foo/bar.h"));
196 std::string Directory
;
197 std::string PathSpec
;
201 // Absolute path matches.
203 llvm::sys::path::convert_to_slash(testPath("foo/bar.h")),
207 // Absolute path fails.
209 llvm::sys::path::convert_to_slash(testPath("bar/bar.h")),
213 // Relative should fail to match as /foo/bar.h doesn't reside under
220 // Relative should pass with /foo as directory.
228 for (const auto &Case
: Cases
) {
230 Frag
.If
.PathMatch
.emplace_back(Case
.PathSpec
);
231 Frag
.Source
.Directory
= Case
.Directory
;
232 EXPECT_EQ(compileAndApply(), Case
.ShouldMatch
);
233 ASSERT_THAT(Diags
.Diagnostics
, IsEmpty());
237 for (const auto &Case
: Cases
) {
238 SCOPED_TRACE(Case
.Directory
);
239 SCOPED_TRACE(Case
.PathSpec
);
241 Frag
.If
.PathExclude
.emplace_back(Case
.PathSpec
);
242 Frag
.Source
.Directory
= Case
.Directory
;
243 EXPECT_NE(compileAndApply(), Case
.ShouldMatch
);
244 ASSERT_THAT(Diags
.Diagnostics
, IsEmpty());
248 TEST_F(ConfigCompileTests
, DiagnosticsIncludeCleaner
) {
249 // Defaults to Strict.
250 EXPECT_TRUE(compileAndApply());
251 EXPECT_EQ(Conf
.Diagnostics
.UnusedIncludes
, Config::IncludesPolicy::Strict
);
254 Frag
.Diagnostics
.UnusedIncludes
.emplace("None");
255 EXPECT_TRUE(compileAndApply());
256 EXPECT_EQ(Conf
.Diagnostics
.UnusedIncludes
, Config::IncludesPolicy::None
);
259 Frag
.Diagnostics
.UnusedIncludes
.emplace("Strict");
260 EXPECT_TRUE(compileAndApply());
261 EXPECT_EQ(Conf
.Diagnostics
.UnusedIncludes
, Config::IncludesPolicy::Strict
);
264 EXPECT_TRUE(Conf
.Diagnostics
.Includes
.IgnoreHeader
.empty())
265 << Conf
.Diagnostics
.Includes
.IgnoreHeader
.size();
266 Frag
.Diagnostics
.Includes
.IgnoreHeader
.push_back(
267 Located
<std::string
>("foo.h"));
268 Frag
.Diagnostics
.Includes
.IgnoreHeader
.push_back(
269 Located
<std::string
>(".*inc"));
270 EXPECT_TRUE(compileAndApply());
271 auto HeaderFilter
= [this](llvm::StringRef Path
) {
272 for (auto &Filter
: Conf
.Diagnostics
.Includes
.IgnoreHeader
) {
278 EXPECT_TRUE(HeaderFilter("foo.h"));
279 EXPECT_FALSE(HeaderFilter("bar.h"));
282 EXPECT_FALSE(Conf
.Diagnostics
.Includes
.AnalyzeAngledIncludes
);
283 Frag
.Diagnostics
.Includes
.AnalyzeAngledIncludes
= true;
284 EXPECT_TRUE(compileAndApply());
285 EXPECT_TRUE(Conf
.Diagnostics
.Includes
.AnalyzeAngledIncludes
);
288 TEST_F(ConfigCompileTests
, DiagnosticSuppression
) {
289 Frag
.Diagnostics
.Suppress
.emplace_back("bugprone-use-after-move");
290 Frag
.Diagnostics
.Suppress
.emplace_back("unreachable-code");
291 Frag
.Diagnostics
.Suppress
.emplace_back("-Wunused-variable");
292 Frag
.Diagnostics
.Suppress
.emplace_back("typecheck_bool_condition");
293 Frag
.Diagnostics
.Suppress
.emplace_back("err_unexpected_friend");
294 Frag
.Diagnostics
.Suppress
.emplace_back("warn_alloca");
295 EXPECT_TRUE(compileAndApply());
296 EXPECT_THAT(Conf
.Diagnostics
.Suppress
.keys(),
297 UnorderedElementsAre("bugprone-use-after-move",
298 "unreachable-code", "unused-variable",
299 "typecheck_bool_condition",
300 "unexpected_friend", "warn_alloca"));
301 EXPECT_TRUE(isBuiltinDiagnosticSuppressed(
302 diag::warn_unreachable
, Conf
.Diagnostics
.Suppress
, LangOptions()));
303 // Subcategory not respected/suppressed.
304 EXPECT_FALSE(isBuiltinDiagnosticSuppressed(
305 diag::warn_unreachable_break
, Conf
.Diagnostics
.Suppress
, LangOptions()));
306 EXPECT_TRUE(isBuiltinDiagnosticSuppressed(
307 diag::warn_unused_variable
, Conf
.Diagnostics
.Suppress
, LangOptions()));
308 EXPECT_TRUE(isBuiltinDiagnosticSuppressed(diag::err_typecheck_bool_condition
,
309 Conf
.Diagnostics
.Suppress
,
311 EXPECT_TRUE(isBuiltinDiagnosticSuppressed(
312 diag::err_unexpected_friend
, Conf
.Diagnostics
.Suppress
, LangOptions()));
313 EXPECT_TRUE(isBuiltinDiagnosticSuppressed(
314 diag::warn_alloca
, Conf
.Diagnostics
.Suppress
, LangOptions()));
316 Frag
.Diagnostics
.Suppress
.emplace_back("*");
317 EXPECT_TRUE(compileAndApply());
318 EXPECT_TRUE(Conf
.Diagnostics
.SuppressAll
);
319 EXPECT_THAT(Conf
.Diagnostics
.Suppress
, IsEmpty());
322 TEST_F(ConfigCompileTests
, Tidy
) {
323 auto &Tidy
= Frag
.Diagnostics
.ClangTidy
;
324 Tidy
.Add
.emplace_back("bugprone-use-after-move");
325 Tidy
.Add
.emplace_back("llvm-*");
326 Tidy
.Remove
.emplace_back("llvm-include-order");
327 Tidy
.Remove
.emplace_back("readability-*");
328 Tidy
.CheckOptions
.emplace_back(
329 std::make_pair(std::string("StrictMode"), std::string("true")));
330 Tidy
.CheckOptions
.emplace_back(std::make_pair(
331 std::string("example-check.ExampleOption"), std::string("0")));
332 EXPECT_TRUE(compileAndApply());
333 EXPECT_EQ(Conf
.Diagnostics
.ClangTidy
.CheckOptions
.size(), 2U);
334 EXPECT_EQ(Conf
.Diagnostics
.ClangTidy
.CheckOptions
.lookup("StrictMode"),
336 EXPECT_EQ(Conf
.Diagnostics
.ClangTidy
.CheckOptions
.lookup(
337 "example-check.ExampleOption"),
339 #if CLANGD_TIDY_CHECKS
341 Conf
.Diagnostics
.ClangTidy
.Checks
,
342 "bugprone-use-after-move,llvm-*,-llvm-include-order,-readability-*");
343 EXPECT_THAT(Diags
.Diagnostics
, IsEmpty());
344 #else // !CLANGD_TIDY_CHECKS
345 EXPECT_EQ(Conf
.Diagnostics
.ClangTidy
.Checks
, "llvm-*,-readability-*");
350 "clang-tidy check 'bugprone-use-after-move' was not found"),
351 diagMessage("clang-tidy check 'llvm-include-order' was not found")));
355 TEST_F(ConfigCompileTests
, TidyBadChecks
) {
356 auto &Tidy
= Frag
.Diagnostics
.ClangTidy
;
357 Tidy
.Add
.emplace_back("unknown-check");
358 Tidy
.Remove
.emplace_back("*");
359 Tidy
.Remove
.emplace_back("llvm-includeorder");
360 EXPECT_TRUE(compileAndApply());
361 // Ensure bad checks are stripped from the glob.
362 EXPECT_EQ(Conf
.Diagnostics
.ClangTidy
.Checks
, "-*");
366 AllOf(diagMessage("clang-tidy check 'unknown-check' was not found"),
367 diagKind(llvm::SourceMgr::DK_Warning
)),
369 diagMessage("clang-tidy check 'llvm-includeorder' was not found"),
370 diagKind(llvm::SourceMgr::DK_Warning
))));
373 TEST_F(ConfigCompileTests
, ExternalServerNeedsTrusted
) {
374 Fragment::IndexBlock::ExternalBlock External
;
375 External
.Server
.emplace("xxx");
376 Frag
.Index
.External
= std::move(External
);
380 ElementsAre(diagMessage(
381 "Remote index may not be specified by untrusted configuration. "
382 "Copy this into user config to use it.")));
383 EXPECT_EQ(Conf
.Index
.External
.Kind
, Config::ExternalIndexSpec::None
);
386 TEST_F(ConfigCompileTests
, ExternalBlockWarnOnMultipleSource
) {
387 Frag
.Source
.Trusted
= true;
388 Fragment::IndexBlock::ExternalBlock External
;
389 External
.File
.emplace("");
390 External
.Server
.emplace("");
391 Frag
.Index
.External
= std::move(External
);
393 #ifdef CLANGD_ENABLE_REMOTE
397 AllOf(diagMessage("Exactly one of File, Server or None must be set."),
398 diagKind(llvm::SourceMgr::DK_Error
))));
400 ASSERT_TRUE(Conf
.Index
.External
.hasValue());
401 EXPECT_EQ(Conf
.Index
.External
->Kind
, Config::ExternalIndexSpec::File
);
405 TEST_F(ConfigCompileTests
, ExternalBlockDisableWithNone
) {
407 EXPECT_EQ(Conf
.Index
.External
.Kind
, Config::ExternalIndexSpec::None
);
409 Fragment::IndexBlock::ExternalBlock External
;
410 External
.IsNone
= true;
411 Frag
.Index
.External
= std::move(External
);
413 EXPECT_EQ(Conf
.Index
.External
.Kind
, Config::ExternalIndexSpec::None
);
416 TEST_F(ConfigCompileTests
, ExternalBlockErrOnNoSource
) {
417 Frag
.Index
.External
.emplace(Fragment::IndexBlock::ExternalBlock
{});
422 AllOf(diagMessage("Exactly one of File, Server or None must be set."),
423 diagKind(llvm::SourceMgr::DK_Error
))));
426 TEST_F(ConfigCompileTests
, ExternalBlockDisablesBackgroundIndex
) {
427 auto BazPath
= testPath("foo/bar/baz.h", llvm::sys::path::Style::posix
);
429 Frag
.Index
.Background
.emplace("Build");
430 Fragment::IndexBlock::ExternalBlock External
;
431 External
.File
.emplace(testPath("foo"));
432 External
.MountPoint
.emplace(
433 testPath("foo/bar", llvm::sys::path::Style::posix
));
434 Frag
.Index
.External
= std::move(External
);
436 EXPECT_EQ(Conf
.Index
.Background
, Config::BackgroundPolicy::Skip
);
439 TEST_F(ConfigCompileTests
, ExternalBlockMountPoint
) {
440 auto GetFrag
= [](llvm::StringRef Directory
,
441 std::optional
<const char *> MountPoint
) {
443 Frag
.Source
.Directory
= Directory
.str();
444 Fragment::IndexBlock::ExternalBlock External
;
445 External
.File
.emplace(testPath("foo"));
447 External
.MountPoint
.emplace(*MountPoint
);
448 Frag
.Index
.External
= std::move(External
);
452 auto BarPath
= testPath("foo/bar.h", llvm::sys::path::Style::posix
);
453 BarPath
= llvm::sys::path::convert_to_slash(BarPath
);
455 // Non-absolute MountPoint without a directory raises an error.
456 Frag
= GetFrag("", "foo");
461 AllOf(diagMessage("MountPoint must be an absolute path, because this "
462 "fragment is not associated with any directory."),
463 diagKind(llvm::SourceMgr::DK_Error
))));
464 EXPECT_EQ(Conf
.Index
.External
.Kind
, Config::ExternalIndexSpec::None
);
466 auto FooPath
= testPath("foo/", llvm::sys::path::Style::posix
);
467 FooPath
= llvm::sys::path::convert_to_slash(FooPath
);
469 Frag
= GetFrag(testRoot(), "foo/");
471 ASSERT_THAT(Diags
.Diagnostics
, IsEmpty());
472 ASSERT_EQ(Conf
.Index
.External
.Kind
, Config::ExternalIndexSpec::File
);
473 EXPECT_THAT(Conf
.Index
.External
.MountPoint
, FooPath
);
475 // None defaults to ".".
476 Frag
= GetFrag(FooPath
, std::nullopt
);
478 ASSERT_THAT(Diags
.Diagnostics
, IsEmpty());
479 ASSERT_EQ(Conf
.Index
.External
.Kind
, Config::ExternalIndexSpec::File
);
480 EXPECT_THAT(Conf
.Index
.External
.MountPoint
, FooPath
);
482 // Without a file, external index is empty.
484 Frag
= GetFrag("", FooPath
.c_str());
486 ASSERT_THAT(Diags
.Diagnostics
, IsEmpty());
487 ASSERT_EQ(Conf
.Index
.External
.Kind
, Config::ExternalIndexSpec::None
);
489 // File outside MountPoint, no index.
490 auto BazPath
= testPath("bar/baz.h", llvm::sys::path::Style::posix
);
491 BazPath
= llvm::sys::path::convert_to_slash(BazPath
);
493 Frag
= GetFrag("", FooPath
.c_str());
495 ASSERT_THAT(Diags
.Diagnostics
, IsEmpty());
496 ASSERT_EQ(Conf
.Index
.External
.Kind
, Config::ExternalIndexSpec::None
);
498 // File under MountPoint, index should be set.
499 BazPath
= testPath("foo/baz.h", llvm::sys::path::Style::posix
);
500 BazPath
= llvm::sys::path::convert_to_slash(BazPath
);
502 Frag
= GetFrag("", FooPath
.c_str());
504 ASSERT_THAT(Diags
.Diagnostics
, IsEmpty());
505 ASSERT_EQ(Conf
.Index
.External
.Kind
, Config::ExternalIndexSpec::File
);
506 EXPECT_THAT(Conf
.Index
.External
.MountPoint
, FooPath
);
508 // Only matches case-insensitively.
509 BazPath
= testPath("fOo/baz.h", llvm::sys::path::Style::posix
);
510 BazPath
= llvm::sys::path::convert_to_slash(BazPath
);
513 FooPath
= testPath("FOO/", llvm::sys::path::Style::posix
);
514 FooPath
= llvm::sys::path::convert_to_slash(FooPath
);
515 Frag
= GetFrag("", FooPath
.c_str());
517 ASSERT_THAT(Diags
.Diagnostics
, IsEmpty());
518 #ifdef CLANGD_PATH_CASE_INSENSITIVE
519 ASSERT_EQ(Conf
.Index
.External
.Kind
, Config::ExternalIndexSpec::File
);
520 EXPECT_THAT(Conf
.Index
.External
.MountPoint
, FooPath
);
522 ASSERT_EQ(Conf
.Index
.External
.Kind
, Config::ExternalIndexSpec::None
);
526 TEST_F(ConfigCompileTests
, AllScopes
) {
528 EXPECT_TRUE(compileAndApply());
529 EXPECT_TRUE(Conf
.Completion
.AllScopes
);
532 Frag
.Completion
.AllScopes
= false;
533 EXPECT_TRUE(compileAndApply());
534 EXPECT_FALSE(Conf
.Completion
.AllScopes
);
537 Frag
.Completion
.AllScopes
= true;
538 EXPECT_TRUE(compileAndApply());
539 EXPECT_TRUE(Conf
.Completion
.AllScopes
);
542 TEST_F(ConfigCompileTests
, Style
) {
544 Frag
.Style
.FullyQualifiedNamespaces
.push_back(std::string("foo"));
545 Frag
.Style
.FullyQualifiedNamespaces
.push_back(std::string("bar"));
546 EXPECT_TRUE(compileAndApply());
547 EXPECT_THAT(Conf
.Style
.FullyQualifiedNamespaces
, ElementsAre("foo", "bar"));
551 EXPECT_TRUE(Conf
.Style
.QuotedHeaders
.empty())
552 << Conf
.Style
.QuotedHeaders
.size();
553 Frag
.Style
.QuotedHeaders
.push_back(Located
<std::string
>("foo.h"));
554 Frag
.Style
.QuotedHeaders
.push_back(Located
<std::string
>(".*inc"));
555 EXPECT_TRUE(compileAndApply());
556 auto HeaderFilter
= [this](llvm::StringRef Path
) {
557 for (auto &Filter
: Conf
.Style
.QuotedHeaders
) {
563 EXPECT_TRUE(HeaderFilter("foo.h"));
564 EXPECT_TRUE(HeaderFilter("prefix/foo.h"));
565 EXPECT_FALSE(HeaderFilter("bar.h"));
566 EXPECT_FALSE(HeaderFilter("foo.h/bar.h"));
571 EXPECT_TRUE(Conf
.Style
.AngledHeaders
.empty())
572 << Conf
.Style
.AngledHeaders
.size();
573 Frag
.Style
.AngledHeaders
.push_back(Located
<std::string
>("foo.h"));
574 Frag
.Style
.AngledHeaders
.push_back(Located
<std::string
>(".*inc"));
575 EXPECT_TRUE(compileAndApply());
576 auto HeaderFilter
= [this](llvm::StringRef Path
) {
577 for (auto &Filter
: Conf
.Style
.AngledHeaders
) {
583 EXPECT_TRUE(HeaderFilter("foo.h"));
584 EXPECT_FALSE(HeaderFilter("bar.h"));
588 } // namespace config
589 } // namespace clangd