2 #include "ClangTidyTest.h"
3 #include "gtest/gtest.h"
10 class TestCheck
: public ClangTidyCheck
{
12 TestCheck(StringRef Name
, ClangTidyContext
*Context
)
13 : ClangTidyCheck(Name
, Context
) {
14 diag("DiagWithNoLoc");
16 void registerMatchers(ast_matchers::MatchFinder
*Finder
) override
{
17 Finder
->addMatcher(ast_matchers::varDecl().bind("var"), this);
19 void check(const ast_matchers::MatchFinder::MatchResult
&Result
) override
{
20 const auto *Var
= Result
.Nodes
.getNodeAs
<VarDecl
>("var");
21 // Add diagnostics in the wrong order.
22 diag(Var
->getLocation(), "variable");
23 diag(Var
->getTypeSpecStartLoc(), "type specifier");
27 class HighlightTestCheck
: public ClangTidyCheck
{
29 HighlightTestCheck(StringRef Name
, ClangTidyContext
*Context
)
30 : ClangTidyCheck(Name
, Context
) {}
31 void registerMatchers(ast_matchers::MatchFinder
*Finder
) override
{
32 Finder
->addMatcher(ast_matchers::varDecl().bind("var"), this);
34 void check(const ast_matchers::MatchFinder::MatchResult
&Result
) override
{
35 const auto *Var
= Result
.Nodes
.getNodeAs
<VarDecl
>("var");
36 diag(Var
->getLocation(), "highlight range") << Var
->getSourceRange();
40 class InvalidRangeTestCheck
: public ClangTidyCheck
{
42 InvalidRangeTestCheck(StringRef Name
, ClangTidyContext
*Context
)
43 : ClangTidyCheck(Name
, Context
) {}
44 void registerMatchers(ast_matchers::MatchFinder
*Finder
) override
{
45 Finder
->addMatcher(ast_matchers::varDecl().bind("var"), this);
47 void check(const ast_matchers::MatchFinder::MatchResult
&Result
) override
{
48 const auto *Var
= Result
.Nodes
.getNodeAs
<VarDecl
>("var");
49 SourceLocation ValidBeginLoc
= Var
->getBeginLoc();
50 SourceLocation ValidEndLoc
= Var
->getEndLoc();
51 SourceLocation InvalidLoc
;
52 ASSERT_TRUE(ValidBeginLoc
.isValid());
53 ASSERT_TRUE(ValidEndLoc
.isValid());
54 ASSERT_TRUE(InvalidLoc
.isInvalid());
56 diag(ValidBeginLoc
, "valid->valid")
57 << SourceRange(ValidBeginLoc
, ValidEndLoc
);
58 diag(ValidBeginLoc
, "valid->invalid")
59 << SourceRange(ValidBeginLoc
, InvalidLoc
);
60 diag(ValidBeginLoc
, "invalid->valid")
61 << SourceRange(InvalidLoc
, ValidEndLoc
);
62 diag(ValidBeginLoc
, "invalid->invalid")
63 << SourceRange(InvalidLoc
, InvalidLoc
);
69 TEST(ClangTidyDiagnosticConsumer
, SortsErrors
) {
70 std::vector
<ClangTidyError
> Errors
;
71 runCheckOnCode
<TestCheck
>("int a;", &Errors
);
72 EXPECT_EQ(3ul, Errors
.size());
73 EXPECT_EQ("DiagWithNoLoc", Errors
[0].Message
.Message
);
74 EXPECT_EQ("type specifier", Errors
[1].Message
.Message
);
75 EXPECT_EQ("variable", Errors
[2].Message
.Message
);
78 TEST(ClangTidyDiagnosticConsumer
, HandlesSourceRangeHighlight
) {
79 std::vector
<ClangTidyError
> Errors
;
80 runCheckOnCode
<HighlightTestCheck
>("int abc;", &Errors
);
81 EXPECT_EQ(1ul, Errors
.size());
82 EXPECT_EQ("highlight range", Errors
[0].Message
.Message
);
87 EXPECT_EQ(4ul, Errors
[0].Message
.FileOffset
);
90 // ~~~~~~~ -> Length 7. (0-length highlights are nonsensical.)
91 EXPECT_EQ(1ul, Errors
[0].Message
.Ranges
.size());
92 EXPECT_EQ(0ul, Errors
[0].Message
.Ranges
[0].FileOffset
);
93 EXPECT_EQ(7ul, Errors
[0].Message
.Ranges
[0].Length
);
96 TEST(ClangTidyDiagnosticConsumer
, InvalidSourceLocationRangesIgnored
) {
97 std::vector
<ClangTidyError
> Errors
;
98 runCheckOnCode
<InvalidRangeTestCheck
>("int x;", &Errors
);
99 EXPECT_EQ(4ul, Errors
.size());
101 EXPECT_EQ("invalid->invalid", Errors
[0].Message
.Message
);
102 EXPECT_TRUE(Errors
[0].Message
.Ranges
.empty());
104 EXPECT_EQ("invalid->valid", Errors
[1].Message
.Message
);
105 EXPECT_TRUE(Errors
[1].Message
.Ranges
.empty());
107 EXPECT_EQ("valid->invalid", Errors
[2].Message
.Message
);
108 EXPECT_TRUE(Errors
[2].Message
.Ranges
.empty());
110 EXPECT_EQ("valid->valid", Errors
[3].Message
.Message
);
111 EXPECT_EQ(1ul, Errors
[3].Message
.Ranges
.size());