clang-tools 10.0.0

TweakTesting.h
Go to the documentation of this file.
1 //===--- TweakTesting.h - Test helpers for refactoring actions ---*- C++-*-===//
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 #ifndef LLVM_CLANG_TOOLS_EXTRA_UNITTESTS_CLANGD_TWEAKTESTING_H
10 #define LLVM_CLANG_TOOLS_EXTRA_UNITTESTS_CLANGD_TWEAKTESTING_H
11
12 #include "TestTU.h"
13 #include "index/Index.h"
14 #include "llvm/ADT/StringMap.h"
15 #include "llvm/ADT/StringRef.h"
16 #include "gmock/gmock.h"
17 #include "gtest/gtest.h"
18 #include <memory>
19 #include <string>
20
21 namespace clang {
22 namespace clangd {
23
24 // Fixture base for testing tweaks. Intended to be subclassed for each tweak.
25 //
26 // Usage:
27 // TWEAK_TEST(ExpandAutoType);
28 //
29 // TEST_F(ExpandAutoTypeTest, ShortensTypes) {
30 // Header = R"cpp(
31 // namespace foo { template<typename> class X{}; }
32 // using namespace foo;
33 // )cpp";
34 // Context = Function;
35 // EXPECT_THAT(apply("[[auto]] X = foo<int>();"),
36 // "foo<int> X = foo<int();");
37 // EXPECT_AVAILABLE("^a^u^t^o^ X = foo<int>();");
38 // EXPECT_UNAVAILABLE("auto ^X^ = ^foo<int>();");
39 // }
40 class TweakTest : public ::testing::Test {
41 const char *TweakID;
42
43 public:
44 // Inputs are wrapped in file boilerplate before attempting to apply a tweak.
45 // Context describes the type of boilerplate.
46 enum CodeContext {
47 // Code snippet is placed directly into the source file. e.g. a declaration.
48 File,
49 // Snippet will appear within a function body. e.g. a statement.
50 Function,
51 // Snippet is an expression.
52 Expression,
53 };
54
55 // Mapping from file name to contents.
56 llvm::StringMap<std::string> ExtraFiles;
57
58 protected:
59 TweakTest(const char *TweakID) : TweakID(TweakID) {}
60
61 // Contents of a header file to be implicitly included.
62 // This typically contains declarations that will be used for a set of related
63 // testcases.
64 std::string Header;
65
66 llvm::StringRef FileName = "TestTU.cpp";
67
68 // Extra flags passed to the compilation in apply().
69 std::vector<const char *> ExtraArgs;
70
71 // Context in which snippets of code should be placed to run tweaks.
72 CodeContext Context = File;
73
74 // Index to be passed into Tweak::Selection.
75 std::unique_ptr<const SymbolIndex> Index = nullptr;
76
77 // Apply the current tweak to the range (or point) in MarkedCode.
78 // MarkedCode will be wrapped according to the Context.
79 // - if the tweak produces edits, returns the edited code (without markings)
80 // for the main file.
81 // Populates \p EditedFiles if there were changes to other files whenever
82 // it is non-null. It is a mapping from absolute path of the edited file to
83 // its new contents. Passing a nullptr to \p EditedFiles when there are
84 // changes, will result in a failure.
85 // The context added to MarkedCode will be stripped away before returning,
86 // unless the tweak edited it.
87 // - if the tweak produces a message, returns "message:\n<message>"
88 // - if prepare() returns false, returns "unavailable"
89 // - if apply() returns an error, returns "fail: <message>"
90 std::string apply(llvm::StringRef MarkedCode,
91 llvm::StringMap<std::string> *EditedFiles = nullptr) const;
92
93 // Accepts a code snippet with many ranges (or points) marked, and returns a
94 // list of snippets with one range marked each.
95 // Primarily used from EXPECT_AVAILABLE/EXPECT_UNAVAILABLE macro.
96 static std::vector<std::string> expandCases(llvm::StringRef MarkedCode);
97
98 // Returns a matcher that accepts marked code snippets where the tweak is
99 // available at the marked range.
100 ::testing::Matcher<llvm::StringRef> isAvailable() const;
101 };
102
103 #define TWEAK_TEST(TweakID) \
104 class TweakID##Test : public ::clang::clangd::TweakTest { \
105 protected: \
106 TweakID##Test() : TweakTest(#TweakID) {} \
107 }
108
109 #define EXPECT_AVAILABLE(MarkedCode) \
110 do { \
111 for (const auto &Case : expandCases(MarkedCode)) \
112 EXPECT_THAT(Case, ::clang::clangd::TweakTest::isAvailable()); \
113 } while (0)
114
115 #define EXPECT_UNAVAILABLE(MarkedCode) \
116 do { \
117 for (const auto &Case : expandCases(MarkedCode)) \
118 EXPECT_THAT(Case, \
119 ::testing::Not(::clang::clangd::TweakTest::isAvailable())); \
120 } while (0)
121
122 } // namespace clangd
123 } // namespace clang
124
125 #endif
clang::clangd::TweakTest::ExtraArgs
std::vector< const char * > ExtraArgs
Definition: TweakTesting.h:69
Index.h
clang::clangd::TweakTest::isAvailable
::testing::Matcher< llvm::StringRef > isAvailable() const
Definition: TweakTesting.cpp:136
clang::clangd::TweakTest::expandCases
static std::vector< std::string > expandCases(llvm::StringRef MarkedCode)
Definition: TweakTesting.cpp:141
clang::clangd::TweakTest::apply
std::string apply(llvm::StringRef MarkedCode, llvm::StringMap< std::string > *EditedFiles=nullptr) const
Definition: TweakTesting.cpp:89
TestTU.h
clang::clangd::TweakTest::CodeContext
CodeContext
Definition: TweakTesting.h:46
clang::clangd::TweakTest::Index
std::unique_ptr< const SymbolIndex > Index
Definition: TweakTesting.h:75
clang::clangd::TweakTest::ExtraFiles
llvm::StringMap< std::string > ExtraFiles
Definition: TweakTesting.h:56
clang::clangd::TweakTest::TweakTest
TweakTest(const char *TweakID)
Definition: TweakTesting.h:59
clang::clangd::TweakTest::Expression
Definition: TweakTesting.h:52
clang::clangd::Context
A context is an immutable container for per-request data that must be propagated through layers that ...
Definition: Context.h:69
clang::clangd::TweakTest::Header
std::string Header
Definition: TweakTesting.h:64
clang::clangd::TweakTest::File
Definition: TweakTesting.h:48
clang
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
Definition: ApplyReplacements.h:27
clang::clangd::TweakTest::Function
Definition: TweakTesting.h:50
clang::clangd::TweakTest
Definition: TweakTesting.h:40
clang::clangd::TweakTest::FileName
llvm::StringRef FileName
Definition: TweakTesting.h:66