1//===--- IncludeSpellerTest.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 "clang-include-cleaner/IncludeSpeller.h"
10#include "clang-include-cleaner/Analysis.h"
11#include "clang-include-cleaner/Types.h"
12#include "clang/Lex/Preprocessor.h"
13#include "clang/Testing/TestAST.h"
14#include "clang/Tooling/Inclusions/StandardLibrary.h"
15#include "llvm/ADT/SmallString.h"
16#include "llvm/ADT/StringRef.h"
17#include "llvm/Support/Path.h"
18#include "gtest/gtest.h"
19#include <assert.h>
20#include <string>
21namespace clang::include_cleaner {
22namespace {
23
24const char *testRoot() {
25#ifdef _WIN32
26 return "C:\\include-cleaner-test";
27#else
28 return "/include-cleaner-test";
29#endif
30}
31
32std::string testPath(llvm::StringRef File) {
33 assert(llvm::sys::path::is_relative(File) && "FileName should be relative");
34
35 llvm::SmallString<32> NativeFile = File;
36 llvm::sys::path::native(path&: NativeFile, style: llvm::sys::path::Style::native);
37 llvm::SmallString<32> Path;
38 llvm::sys::path::append(path&: Path, style: llvm::sys::path::Style::native, a: testRoot(),
39 b: NativeFile);
40 return std::string(Path.str());
41}
42
43class DummyIncludeSpeller : public IncludeSpeller {
44public:
45 std::string operator()(const IncludeSpeller::Input &Input) const override {
46 if (Input.H.kind() == Header::Standard)
47 return "<bits/stdc++.h>";
48 if (Input.H.kind() != Header::Physical)
49 return "";
50 llvm::StringRef AbsolutePath = Input.H.resolvedPath();
51 std::string RootWithSeparator{testRoot()};
52 RootWithSeparator += llvm::sys::path::get_separator();
53 if (!AbsolutePath.consume_front(Prefix: llvm::StringRef{RootWithSeparator}))
54 return "";
55 return "\"" + AbsolutePath.str() + "\"";
56 }
57};
58
59TEST(IncludeSpeller, IsRelativeToTestRoot) {
60 TestInputs Inputs;
61
62 Inputs.ExtraArgs.push_back(x: "-isystemdir");
63
64 Inputs.ExtraFiles[testPath(File: "foo.h")] = "";
65 Inputs.ExtraFiles["dir/header.h"] = "";
66 TestAST AST{Inputs};
67
68 auto &FM = AST.fileManager();
69 auto &HS = AST.preprocessor().getHeaderSearchInfo();
70 const auto *MainFile = AST.sourceManager().getFileEntryForID(
71 FID: AST.sourceManager().getMainFileID());
72
73 EXPECT_EQ("\"foo.h\"",
74 spellHeader({Header{*FM.getOptionalFileRef(testPath("foo.h"))}, HS,
75 MainFile}));
76 EXPECT_EQ("<header.h>",
77 spellHeader({Header{*FM.getOptionalFileRef("dir/header.h")}, HS,
78 MainFile}));
79}
80
81TEST(IncludeSpeller, CanOverrideSystemHeaders) {
82 TestAST AST("");
83 auto &HS = AST.preprocessor().getHeaderSearchInfo();
84 const auto *MainFile = AST.sourceManager().getFileEntryForID(
85 FID: AST.sourceManager().getMainFileID());
86 EXPECT_EQ("<bits/stdc++.h>",
87 spellHeader({Header{*tooling::stdlib::Header::named("<vector>")},
88 HS, MainFile}));
89}
90
91TEST(IncludeSpeller, RelativeIncludeSearchPath) {
92 TestInputs Inputs;
93
94 Inputs.WorkingDir = "/root/inner";
95 Inputs.ExtraArgs.push_back(x: "-I..");
96 Inputs.ExtraFiles["/root/foo.h"] = "";
97 TestAST AST{Inputs};
98
99 auto &FM = AST.fileManager();
100 auto &HS = AST.preprocessor().getHeaderSearchInfo();
101 const auto *MainFile = AST.sourceManager().getFileEntryForID(
102 FID: AST.sourceManager().getMainFileID());
103
104 EXPECT_EQ("\"foo.h\"",
105 spellHeader(
106 {Header{*FM.getOptionalFileRef("/root/foo.h")}, HS, MainFile}));
107}
108
109IncludeSpellingStrategy::Add<DummyIncludeSpeller>
110 Speller("dummy", "Dummy Include Speller");
111
112} // namespace
113} // namespace clang::include_cleaner
114

Provided by KDAB

Privacy Policy
Update your C++ knowledge – Modern C++11/14/17 Training
Find out more

source code of clang-tools-extra/include-cleaner/unittests/IncludeSpellerTest.cpp