Home | History | Annotate | Download | only in Format
      1 //===- unittest/Format/SortIncludesTest.cpp - Include sort unit tests -----===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 
     10 #include "FormatTestUtils.h"
     11 #include "clang/Format/Format.h"
     12 #include "llvm/Support/Debug.h"
     13 #include "gtest/gtest.h"
     14 
     15 #define DEBUG_TYPE "format-test"
     16 
     17 namespace clang {
     18 namespace format {
     19 namespace {
     20 
     21 class SortIncludesTest : public ::testing::Test {
     22 protected:
     23   std::vector<tooling::Range> GetCodeRange(StringRef Code) {
     24     return std::vector<tooling::Range>(1, tooling::Range(0, Code.size()));
     25   }
     26 
     27   std::string sort(StringRef Code, StringRef FileName = "input.cpp") {
     28     auto Ranges = GetCodeRange(Code);
     29     auto Sorted =
     30         applyAllReplacements(Code, sortIncludes(Style, Code, Ranges, FileName));
     31     EXPECT_TRUE(static_cast<bool>(Sorted));
     32     auto Result = applyAllReplacements(
     33         *Sorted, reformat(Style, *Sorted, Ranges, FileName));
     34     EXPECT_TRUE(static_cast<bool>(Result));
     35     return *Result;
     36   }
     37 
     38   unsigned newCursor(llvm::StringRef Code, unsigned Cursor) {
     39     sortIncludes(Style, Code, GetCodeRange(Code), "input.cpp", &Cursor);
     40     return Cursor;
     41   }
     42 
     43   FormatStyle Style = getLLVMStyle();
     44 
     45 };
     46 
     47 TEST_F(SortIncludesTest, BasicSorting) {
     48   EXPECT_EQ("#include \"a.h\"\n"
     49             "#include \"b.h\"\n"
     50             "#include \"c.h\"\n",
     51             sort("#include \"a.h\"\n"
     52                  "#include \"c.h\"\n"
     53                  "#include \"b.h\"\n"));
     54 }
     55 
     56 TEST_F(SortIncludesTest, NoReplacementsForValidIncludes) {
     57   // Identical #includes have led to a failure with an unstable sort.
     58   std::string Code = "#include <a>\n"
     59                      "#include <b>\n"
     60                      "#include <b>\n"
     61                      "#include <b>\n"
     62                      "#include <b>\n"
     63                      "#include <c>\n";
     64   EXPECT_TRUE(sortIncludes(Style, Code, GetCodeRange(Code), "a.cc").empty());
     65 }
     66 
     67 TEST_F(SortIncludesTest, SupportClangFormatOff) {
     68   EXPECT_EQ("#include <a>\n"
     69             "#include <b>\n"
     70             "#include <c>\n"
     71             "// clang-format off\n"
     72             "#include <b>\n"
     73             "#include <a>\n"
     74             "#include <c>\n"
     75             "// clang-format on\n",
     76             sort("#include <b>\n"
     77                  "#include <a>\n"
     78                  "#include <c>\n"
     79                  "// clang-format off\n"
     80                  "#include <b>\n"
     81                  "#include <a>\n"
     82                  "#include <c>\n"
     83                  "// clang-format on\n"));
     84 }
     85 
     86 TEST_F(SortIncludesTest, IncludeSortingCanBeDisabled) {
     87   Style.SortIncludes = false;
     88   EXPECT_EQ("#include \"a.h\"\n"
     89             "#include \"c.h\"\n"
     90             "#include \"b.h\"\n",
     91             sort("#include \"a.h\"\n"
     92                  "#include \"c.h\"\n"
     93                  "#include \"b.h\"\n"));
     94 }
     95 
     96 TEST_F(SortIncludesTest, MixIncludeAndImport) {
     97   EXPECT_EQ("#include \"a.h\"\n"
     98             "#import \"b.h\"\n"
     99             "#include \"c.h\"\n",
    100             sort("#include \"a.h\"\n"
    101                  "#include \"c.h\"\n"
    102                  "#import \"b.h\"\n"));
    103 }
    104 
    105 TEST_F(SortIncludesTest, FixTrailingComments) {
    106   EXPECT_EQ("#include \"a.h\"  // comment\n"
    107             "#include \"bb.h\" // comment\n"
    108             "#include \"ccc.h\"\n",
    109             sort("#include \"a.h\" // comment\n"
    110                  "#include \"ccc.h\"\n"
    111                  "#include \"bb.h\" // comment\n"));
    112 }
    113 
    114 TEST_F(SortIncludesTest, LeadingWhitespace) {
    115   EXPECT_EQ("#include \"a.h\"\n"
    116             "#include \"b.h\"\n"
    117             "#include \"c.h\"\n",
    118             sort(" #include \"a.h\"\n"
    119                  "  #include \"c.h\"\n"
    120                  "   #include \"b.h\"\n"));
    121   EXPECT_EQ("#include \"a.h\"\n"
    122             "#include \"b.h\"\n"
    123             "#include \"c.h\"\n",
    124             sort("# include \"a.h\"\n"
    125                  "#  include \"c.h\"\n"
    126                  "#   include \"b.h\"\n"));
    127 }
    128 
    129 TEST_F(SortIncludesTest, GreaterInComment) {
    130   EXPECT_EQ("#include \"a.h\"\n"
    131             "#include \"b.h\" // >\n"
    132             "#include \"c.h\"\n",
    133             sort("#include \"a.h\"\n"
    134                  "#include \"c.h\"\n"
    135                  "#include \"b.h\" // >\n"));
    136 }
    137 
    138 TEST_F(SortIncludesTest, SortsLocallyInEachBlock) {
    139   EXPECT_EQ("#include \"a.h\"\n"
    140             "#include \"c.h\"\n"
    141             "\n"
    142             "#include \"b.h\"\n",
    143             sort("#include \"a.h\"\n"
    144                  "#include \"c.h\"\n"
    145                  "\n"
    146                  "#include \"b.h\"\n"));
    147 }
    148 
    149 TEST_F(SortIncludesTest, HandlesAngledIncludesAsSeparateBlocks) {
    150   EXPECT_EQ("#include \"a.h\"\n"
    151             "#include \"c.h\"\n"
    152             "#include <b.h>\n"
    153             "#include <d.h>\n",
    154             sort("#include <d.h>\n"
    155                  "#include <b.h>\n"
    156                  "#include \"c.h\"\n"
    157                  "#include \"a.h\"\n"));
    158 
    159   Style = getGoogleStyle(FormatStyle::LK_Cpp);
    160   EXPECT_EQ("#include <b.h>\n"
    161             "#include <d.h>\n"
    162             "#include \"a.h\"\n"
    163             "#include \"c.h\"\n",
    164             sort("#include <d.h>\n"
    165                  "#include <b.h>\n"
    166                  "#include \"c.h\"\n"
    167                  "#include \"a.h\"\n"));
    168 }
    169 
    170 TEST_F(SortIncludesTest, HandlesMultilineIncludes) {
    171   EXPECT_EQ("#include \"a.h\"\n"
    172             "#include \"b.h\"\n"
    173             "#include \"c.h\"\n",
    174             sort("#include \"a.h\"\n"
    175                  "#include \\\n"
    176                  "\"c.h\"\n"
    177                  "#include \"b.h\"\n"));
    178 }
    179 
    180 TEST_F(SortIncludesTest, LeavesMainHeaderFirst) {
    181   Style.IncludeIsMainRegex = "([-_](test|unittest))?$";
    182   EXPECT_EQ("#include \"llvm/a.h\"\n"
    183             "#include \"b.h\"\n"
    184             "#include \"c.h\"\n",
    185             sort("#include \"llvm/a.h\"\n"
    186                  "#include \"c.h\"\n"
    187                  "#include \"b.h\"\n",
    188                  "a.cc"));
    189   EXPECT_EQ("#include \"llvm/a.h\"\n"
    190             "#include \"b.h\"\n"
    191             "#include \"c.h\"\n",
    192             sort("#include \"llvm/a.h\"\n"
    193                  "#include \"c.h\"\n"
    194                  "#include \"b.h\"\n",
    195                  "a_test.cc"));
    196   EXPECT_EQ("#include \"llvm/input.h\"\n"
    197             "#include \"b.h\"\n"
    198             "#include \"c.h\"\n",
    199             sort("#include \"llvm/input.h\"\n"
    200                  "#include \"c.h\"\n"
    201                  "#include \"b.h\"\n",
    202                  "input.mm"));
    203 
    204   // Don't allow prefixes.
    205   EXPECT_EQ("#include \"b.h\"\n"
    206             "#include \"c.h\"\n"
    207             "#include \"llvm/not_a.h\"\n",
    208             sort("#include \"llvm/not_a.h\"\n"
    209                  "#include \"c.h\"\n"
    210                  "#include \"b.h\"\n",
    211                  "a.cc"));
    212 
    213   // Don't do this for _main and other suffixes.
    214   EXPECT_EQ("#include \"b.h\"\n"
    215             "#include \"c.h\"\n"
    216             "#include \"llvm/a.h\"\n",
    217             sort("#include \"llvm/a.h\"\n"
    218                  "#include \"c.h\"\n"
    219                  "#include \"b.h\"\n",
    220                  "a_main.cc"));
    221 
    222   // Don't do this in headers.
    223   EXPECT_EQ("#include \"b.h\"\n"
    224             "#include \"c.h\"\n"
    225             "#include \"llvm/a.h\"\n",
    226             sort("#include \"llvm/a.h\"\n"
    227                  "#include \"c.h\"\n"
    228                  "#include \"b.h\"\n",
    229                  "a.h"));
    230 
    231   // Only do this in the first #include block.
    232   EXPECT_EQ("#include <a>\n"
    233             "\n"
    234             "#include \"b.h\"\n"
    235             "#include \"c.h\"\n"
    236             "#include \"llvm/a.h\"\n",
    237             sort("#include <a>\n"
    238                  "\n"
    239                  "#include \"llvm/a.h\"\n"
    240                  "#include \"c.h\"\n"
    241                  "#include \"b.h\"\n",
    242                  "a.cc"));
    243 
    244   // Only recognize the first #include with a matching basename as main include.
    245   EXPECT_EQ("#include \"a.h\"\n"
    246             "#include \"b.h\"\n"
    247             "#include \"c.h\"\n"
    248             "#include \"llvm/a.h\"\n",
    249             sort("#include \"b.h\"\n"
    250                  "#include \"a.h\"\n"
    251                  "#include \"c.h\"\n"
    252                  "#include \"llvm/a.h\"\n",
    253                  "a.cc"));
    254 }
    255 
    256 TEST_F(SortIncludesTest, NegativePriorities) {
    257   Style.IncludeCategories = {{".*important_os_header.*", -1}, {".*", 1}};
    258   EXPECT_EQ("#include \"important_os_header.h\"\n"
    259             "#include \"c_main.h\"\n"
    260             "#include \"a_other.h\"\n",
    261             sort("#include \"c_main.h\"\n"
    262                  "#include \"a_other.h\"\n"
    263                  "#include \"important_os_header.h\"\n",
    264                  "c_main.cc"));
    265 
    266   // check stable when re-run
    267   EXPECT_EQ("#include \"important_os_header.h\"\n"
    268             "#include \"c_main.h\"\n"
    269             "#include \"a_other.h\"\n",
    270             sort("#include \"important_os_header.h\"\n"
    271                  "#include \"c_main.h\"\n"
    272                  "#include \"a_other.h\"\n",
    273                  "c_main.cc"));
    274 }
    275 
    276 TEST_F(SortIncludesTest, CalculatesCorrectCursorPosition) {
    277   std::string Code = "#include <ccc>\n"    // Start of line: 0
    278                      "#include <bbbbbb>\n" // Start of line: 15
    279                      "#include <a>\n";     // Start of line: 33
    280   EXPECT_EQ(31u, newCursor(Code, 0));
    281   EXPECT_EQ(13u, newCursor(Code, 15));
    282   EXPECT_EQ(0u, newCursor(Code, 33));
    283 
    284   EXPECT_EQ(41u, newCursor(Code, 10));
    285   EXPECT_EQ(23u, newCursor(Code, 25));
    286   EXPECT_EQ(10u, newCursor(Code, 43));
    287 }
    288 
    289 } // end namespace
    290 } // end namespace format
    291 } // end namespace clang
    292