//===--- IncludeSpellerTest.cpp--------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #include "clang-include-cleaner/IncludeSpeller.h" #include "clang-include-cleaner/Analysis.h" #include "clang-include-cleaner/Types.h" #include "clang/Lex/Preprocessor.h" #include "clang/Testing/TestAST.h" #include "clang/Tooling/Inclusions/StandardLibrary.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/Path.h" #include "gtest/gtest.h" #include #include namespace clang::include_cleaner { namespace { const char *testRoot() { #ifdef _WIN32 return "C:\\include-cleaner-test"; #else return "/include-cleaner-test"; #endif } std::string testPath(llvm::StringRef File) { assert(llvm::sys::path::is_relative(File) && "FileName should be relative"); llvm::SmallString<32> NativeFile = File; llvm::sys::path::native(NativeFile, llvm::sys::path::Style::native); llvm::SmallString<32> Path; llvm::sys::path::append(Path, llvm::sys::path::Style::native, testRoot(), NativeFile); return std::string(Path.str()); } class DummyIncludeSpeller : public IncludeSpeller { public: std::string operator()(const IncludeSpeller::Input &Input) const override { if (Input.H.kind() == Header::Standard) return ""; if (Input.H.kind() != Header::Physical) return ""; llvm::StringRef AbsolutePath = Input.H.physical().getFileEntry().tryGetRealPathName(); std::string RootWithSeparator{testRoot()}; RootWithSeparator += llvm::sys::path::get_separator(); if (!AbsolutePath.consume_front(llvm::StringRef{RootWithSeparator})) return ""; return "\"" + AbsolutePath.str() + "\""; } }; TEST(IncludeSpeller, IsRelativeToTestRoot) { TestInputs Inputs; Inputs.ExtraArgs.push_back("-isystemdir"); Inputs.ExtraFiles[testPath("foo.h")] = ""; Inputs.ExtraFiles["dir/header.h"] = ""; TestAST AST{Inputs}; auto &FM = AST.fileManager(); auto &HS = AST.preprocessor().getHeaderSearchInfo(); const auto *MainFile = AST.sourceManager().getFileEntryForID( AST.sourceManager().getMainFileID()); EXPECT_EQ("\"foo.h\"", spellHeader({Header{*FM.getOptionalFileRef(testPath("foo.h"))}, HS, MainFile})); EXPECT_EQ("", spellHeader({Header{*FM.getOptionalFileRef("dir/header.h")}, HS, MainFile})); } TEST(IncludeSpeller, CanOverrideSystemHeaders) { TestAST AST(""); auto &HS = AST.preprocessor().getHeaderSearchInfo(); const auto *MainFile = AST.sourceManager().getFileEntryForID( AST.sourceManager().getMainFileID()); EXPECT_EQ("", spellHeader({Header{*tooling::stdlib::Header::named("")}, HS, MainFile})); } IncludeSpellingStrategy::Add Speller("dummy", "Dummy Include Speller"); } // namespace } // namespace clang::include_cleaner