1 //===- unittest/AST/CommentTextTest.cpp - Comment text extraction test ----===//
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 // Tests for user-friendly output formatting of comments, i.e.
10 // RawComment::getFormattedText().
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "clang/AST/RawCommentList.h"
15 #include "clang/Basic/CommentOptions.h"
16 #include "clang/Basic/Diagnostic.h"
17 #include "clang/Basic/DiagnosticIDs.h"
18 #include "clang/Basic/FileManager.h"
19 #include "clang/Basic/FileSystemOptions.h"
20 #include "clang/Basic/SourceLocation.h"
21 #include "clang/Basic/SourceManager.h"
22 #include "llvm/Support/MemoryBuffer.h"
23 #include "llvm/Support/VirtualFileSystem.h"
24 #include <gtest/gtest.h>
25 
26 namespace clang {
27 
28 class CommentTextTest : public ::testing::Test {
29 protected:
formatComment(llvm::StringRef CommentText)30   std::string formatComment(llvm::StringRef CommentText) {
31     SourceManagerForFile FileSourceMgr("comment-test.cpp", CommentText);
32     SourceManager& SourceMgr = FileSourceMgr.get();
33 
34     auto CommentStartOffset = CommentText.find("/");
35     assert(CommentStartOffset != llvm::StringRef::npos);
36     FileID File = SourceMgr.getMainFileID();
37 
38     SourceRange CommentRange(
39         SourceMgr.getLocForStartOfFile(File).getLocWithOffset(
40             CommentStartOffset),
41         SourceMgr.getLocForEndOfFile(File));
42     CommentOptions EmptyOpts;
43     // FIXME: technically, merged that we set here is incorrect, but that
44     // shouldn't matter.
45     RawComment Comment(SourceMgr, CommentRange, EmptyOpts, /*Merged=*/true);
46     DiagnosticsEngine Diags(new DiagnosticIDs, new DiagnosticOptions);
47     return Comment.getFormattedText(SourceMgr, Diags);
48   }
49 };
50 
TEST_F(CommentTextTest,FormattedText)51 TEST_F(CommentTextTest, FormattedText) {
52   // clang-format off
53   auto ExpectedOutput =
54 R"(This function does this and that.
55 For example,
56    Runnning it in that case will give you
57    this result.
58 That's about it.)";
59   // Two-slash comments.
60   auto Formatted = formatComment(
61 R"cpp(
62 // This function does this and that.
63 // For example,
64 //    Runnning it in that case will give you
65 //    this result.
66 // That's about it.)cpp");
67   EXPECT_EQ(ExpectedOutput, Formatted);
68 
69   // Three-slash comments.
70   Formatted = formatComment(
71 R"cpp(
72 /// This function does this and that.
73 /// For example,
74 ///    Runnning it in that case will give you
75 ///    this result.
76 /// That's about it.)cpp");
77   EXPECT_EQ(ExpectedOutput, Formatted);
78 
79   // Block comments.
80   Formatted = formatComment(
81 R"cpp(
82 /* This function does this and that.
83  * For example,
84  *    Runnning it in that case will give you
85  *    this result.
86  * That's about it.*/)cpp");
87   EXPECT_EQ(ExpectedOutput, Formatted);
88 
89   // Doxygen-style block comments.
90   Formatted = formatComment(
91 R"cpp(
92 /** This function does this and that.
93   * For example,
94   *    Runnning it in that case will give you
95   *    this result.
96   * That's about it.*/)cpp");
97   EXPECT_EQ(ExpectedOutput, Formatted);
98 
99   // Weird indentation.
100   Formatted = formatComment(
101 R"cpp(
102        // This function does this and that.
103   //      For example,
104   //         Runnning it in that case will give you
105         //   this result.
106        // That's about it.)cpp");
107   EXPECT_EQ(ExpectedOutput, Formatted);
108   // clang-format on
109 }
110 
TEST_F(CommentTextTest,KeepsDoxygenControlSeqs)111 TEST_F(CommentTextTest, KeepsDoxygenControlSeqs) {
112   // clang-format off
113   auto ExpectedOutput =
114 R"(\brief This is the brief part of the comment.
115 \param a something about a.
116 @param b something about b.)";
117 
118   auto Formatted = formatComment(
119 R"cpp(
120 /// \brief This is the brief part of the comment.
121 /// \param a something about a.
122 /// @param b something about b.)cpp");
123   EXPECT_EQ(ExpectedOutput, Formatted);
124   // clang-format on
125 }
126 
TEST_F(CommentTextTest,EmptyFormattedText)127 TEST_F(CommentTextTest, EmptyFormattedText) {
128   // Test that empty formatted text doesn't cause crash.
129   const char *ExpectedOutput = "";
130   auto Formatted = formatComment("//!<");
131   EXPECT_EQ(ExpectedOutput, Formatted);
132 }
133 
134 } // namespace clang
135