| #include "clang/Format/Format.h" |
| #include "gtest/gtest.h" |
| |
| #define DEBUG_TYPE "format-test" |
| |
| namespace clang { |
| namespace format { |
| namespace { |
| |
| class SortImportsTestJava : public ::testing::Test { |
| protected: |
| std::vector<tooling::Range> GetCodeRange(StringRef Code) { |
| return std::vector<tooling::Range>(1, tooling::Range(0, Code.size())); |
| } |
| |
| std::string sort(StringRef Code, std::vector<tooling::Range> Ranges) { |
| auto Replaces = sortIncludes(FmtStyle, Code, Ranges, "input.java"); |
| Ranges = tooling::calculateRangesAfterReplacements(Replaces, Ranges); |
| auto Sorted = applyAllReplacements(Code, Replaces); |
| EXPECT_TRUE(static_cast<bool>(Sorted)); |
| auto Result = applyAllReplacements( |
| *Sorted, reformat(FmtStyle, *Sorted, Ranges, "input.java")); |
| EXPECT_TRUE(static_cast<bool>(Result)); |
| return *Result; |
| } |
| |
| std::string sort(StringRef Code) { return sort(Code, GetCodeRange(Code)); } |
| |
| FormatStyle FmtStyle; |
| |
| public: |
| SortImportsTestJava() { |
| FmtStyle = getGoogleStyle(FormatStyle::LK_Java); |
| FmtStyle.JavaImportGroups = {"com.test", "org", "com"}; |
| FmtStyle.SortIncludes = FormatStyle::SI_CaseInsensitive; |
| } |
| }; |
| |
| TEST_F(SortImportsTestJava, StaticSplitFromNormal) { |
| EXPECT_EQ("import static org.b;\n" |
| "\n" |
| "import org.a;\n", |
| sort("import org.a;\n" |
| "import static org.b;\n")); |
| } |
| |
| TEST_F(SortImportsTestJava, CapitalBeforeLowercase) { |
| EXPECT_EQ("import org.Test;\n" |
| "import org.a.Test;\n" |
| "import org.b;\n", |
| sort("import org.a.Test;\n" |
| "import org.Test;\n" |
| "import org.b;\n")); |
| } |
| |
| TEST_F(SortImportsTestJava, KeepSplitGroupsWithOneNewImport) { |
| EXPECT_EQ("import static com.test.a;\n" |
| "\n" |
| "import static org.a;\n" |
| "\n" |
| "import static com.a;\n" |
| "\n" |
| "import com.test.b;\n" |
| "import com.test.c;\n" |
| "\n" |
| "import org.b;\n" |
| "\n" |
| "import com.b;\n", |
| sort("import static com.test.a;\n" |
| "\n" |
| "import static org.a;\n" |
| "\n" |
| "import static com.a;\n" |
| "\n" |
| "import com.test.b;\n" |
| "\n" |
| "import org.b;\n" |
| "\n" |
| "import com.b;\n" |
| "import com.test.c;\n")); |
| } |
| |
| TEST_F(SortImportsTestJava, SplitGroupsWithNewline) { |
| EXPECT_EQ("import static com.test.a;\n" |
| "\n" |
| "import static org.a;\n" |
| "\n" |
| "import static com.a;\n" |
| "\n" |
| "import com.test.b;\n" |
| "\n" |
| "import org.b;\n" |
| "\n" |
| "import com.b;\n", |
| sort("import static com.test.a;\n" |
| "import static org.a;\n" |
| "import static com.a;\n" |
| "import com.test.b;\n" |
| "import org.b;\n" |
| "import com.b;\n")); |
| } |
| |
| TEST_F(SortImportsTestJava, UnspecifiedGroupAfterAllGroups) { |
| EXPECT_EQ("import com.test.a;\n" |
| "\n" |
| "import org.a;\n" |
| "\n" |
| "import com.a;\n" |
| "\n" |
| "import abc.a;\n" |
| "import xyz.b;\n", |
| sort("import com.test.a;\n" |
| "import com.a;\n" |
| "import xyz.b;\n" |
| "import abc.a;\n" |
| "import org.a;\n")); |
| } |
| |
| TEST_F(SortImportsTestJava, NoSortOutsideRange) { |
| std::vector<tooling::Range> Ranges = {tooling::Range(27, 15)}; |
| EXPECT_EQ("import org.b;\n" |
| "import org.a;\n" |
| "// comments\n" |
| "// that do\n" |
| "// nothing\n", |
| sort("import org.b;\n" |
| "import org.a;\n" |
| "// comments\n" |
| "// that do\n" |
| "// nothing\n", |
| Ranges)); |
| } |
| |
| TEST_F(SortImportsTestJava, SortWhenRangeContainsOneLine) { |
| std::vector<tooling::Range> Ranges = {tooling::Range(27, 20)}; |
| EXPECT_EQ("import org.a;\n" |
| "import org.b;\n" |
| "\n" |
| "import com.a;\n" |
| "// comments\n" |
| "// that do\n" |
| "// nothing\n", |
| sort("import org.b;\n" |
| "import org.a;\n" |
| "import com.a;\n" |
| "// comments\n" |
| "// that do\n" |
| "// nothing\n", |
| Ranges)); |
| } |
| |
| TEST_F(SortImportsTestJava, SortLexicographically) { |
| EXPECT_EQ("import org.a.*;\n" |
| "import org.a.a;\n" |
| "import org.aA;\n" |
| "import org.aa;\n", |
| sort("import org.aa;\n" |
| "import org.a.a;\n" |
| "import org.a.*;\n" |
| "import org.aA;\n")); |
| } |
| |
| TEST_F(SortImportsTestJava, StaticInCommentHasNoEffect) { |
| EXPECT_EQ("import org.a; // static\n" |
| "import org.b;\n" |
| "import org.c; // static\n", |
| sort("import org.a; // static\n" |
| "import org.c; // static\n" |
| "import org.b;\n")); |
| } |
| |
| TEST_F(SortImportsTestJava, CommentsWithAffectedImports) { |
| EXPECT_EQ("import org.a;\n" |
| "// commentB\n" |
| "/* commentB\n" |
| " commentB*/\n" |
| "import org.b;\n" |
| "// commentC\n" |
| "import org.c;\n", |
| sort("import org.a;\n" |
| "// commentC\n" |
| "import org.c;\n" |
| "// commentB\n" |
| "/* commentB\n" |
| " commentB*/\n" |
| "import org.b;\n")); |
| } |
| |
| TEST_F(SortImportsTestJava, CommentWithUnaffectedImports) { |
| EXPECT_EQ("import org.a;\n" |
| "// comment\n" |
| "import org.b;\n", |
| sort("import org.a;\n" |
| "// comment\n" |
| "import org.b;\n")); |
| } |
| |
| TEST_F(SortImportsTestJava, CommentAfterAffectedImports) { |
| EXPECT_EQ("import org.a;\n" |
| "import org.b;\n" |
| "// comment\n", |
| sort("import org.b;\n" |
| "import org.a;\n" |
| "// comment\n")); |
| } |
| |
| TEST_F(SortImportsTestJava, CommentBeforeAffectedImports) { |
| EXPECT_EQ("// comment\n" |
| "import org.a;\n" |
| "import org.b;\n", |
| sort("// comment\n" |
| "import org.b;\n" |
| "import org.a;\n")); |
| } |
| |
| TEST_F(SortImportsTestJava, FormatTotallyOff) { |
| EXPECT_EQ("// clang-format off\n" |
| "import org.b;\n" |
| "import org.a;\n" |
| "// clang-format on\n", |
| sort("// clang-format off\n" |
| "import org.b;\n" |
| "import org.a;\n" |
| "// clang-format on\n")); |
| } |
| |
| TEST_F(SortImportsTestJava, FormatTotallyOn) { |
| EXPECT_EQ("// clang-format off\n" |
| "// clang-format on\n" |
| "import org.a;\n" |
| "import org.b;\n", |
| sort("// clang-format off\n" |
| "// clang-format on\n" |
| "import org.b;\n" |
| "import org.a;\n")); |
| } |
| |
| TEST_F(SortImportsTestJava, FormatPariallyOnShouldNotReorder) { |
| EXPECT_EQ("// clang-format off\n" |
| "import org.b;\n" |
| "import org.a;\n" |
| "// clang-format on\n" |
| "import org.d;\n" |
| "import org.c;\n", |
| sort("// clang-format off\n" |
| "import org.b;\n" |
| "import org.a;\n" |
| "// clang-format on\n" |
| "import org.d;\n" |
| "import org.c;\n")); |
| } |
| |
| TEST_F(SortImportsTestJava, SortJavaStaticImport) { |
| FmtStyle.SortJavaStaticImport = FormatStyle::SJSIO_Before; |
| EXPECT_EQ("import static com.test.a;\n" |
| "\n" |
| "import static org.a;\n" |
| "\n" |
| "import static com.a;\n" |
| "\n" |
| "import com.test.b;\n" |
| "\n" |
| "import org.b;\n" |
| "\n" |
| "import com.b;\n", |
| sort("import static com.test.a;\n" |
| "import static org.a;\n" |
| "import static com.a;\n" |
| "import com.test.b;\n" |
| "import org.b;\n" |
| "import com.b;\n")); |
| |
| FmtStyle.SortJavaStaticImport = FormatStyle::SJSIO_After; |
| EXPECT_EQ("import com.test.b;\n" |
| "import com.test.c;\n" |
| "\n" |
| "import org.b;\n" |
| "\n" |
| "import com.b;\n" |
| "\n" |
| "import static com.test.a;\n" |
| "\n" |
| "import static org.a;\n" |
| "\n" |
| "import static com.a;\n", |
| sort("import static com.test.a;\n" |
| "import static org.a;\n" |
| "import static com.a;\n" |
| "import com.test.b;\n" |
| "import org.b;\n" |
| "import com.b;\n" |
| "import com.test.c;\n")); |
| } |
| |
| TEST_F(SortImportsTestJava, SortJavaStaticImportAsGroup) { |
| FmtStyle.SortJavaStaticImport = FormatStyle::SJSIO_After; |
| |
| EXPECT_EQ("import com.test.a;\n" |
| "import com.test.b;\n" |
| "\n" |
| "import static org.a;\n" |
| "import static org.b;\n", |
| sort("import com.test.a;\n" |
| "import static org.a;\n" |
| "import com.test.b;\n" |
| "import static org.b;\n")); |
| } |
| |
| TEST_F(SortImportsTestJava, DeduplicateImports) { |
| EXPECT_EQ("import org.a;\n", sort("import org.a;\n" |
| "import org.a;\n")); |
| } |
| |
| TEST_F(SortImportsTestJava, NoNewlineAtEnd) { |
| EXPECT_EQ("import org.a;\n" |
| "import org.b;", |
| sort("import org.b;\n" |
| "import org.a;")); |
| } |
| |
| TEST_F(SortImportsTestJava, ImportNamedFunction) { |
| EXPECT_EQ("import X;\n" |
| "class C {\n" |
| " void m() {\n" |
| " importFile();\n" |
| " }\n" |
| "}\n", |
| sort("import X;\n" |
| "class C {\n" |
| " void m() {\n" |
| " importFile();\n" |
| " }\n" |
| "}\n")); |
| } |
| |
| TEST_F(SortImportsTestJava, NoReplacementsForValidImports) { |
| // Identical #includes have led to a failure with an unstable sort. |
| std::string Code = "import org.a;\n" |
| "import org.b;\n"; |
| EXPECT_TRUE( |
| sortIncludes(FmtStyle, Code, GetCodeRange(Code), "input.java").empty()); |
| } |
| |
| TEST_F(SortImportsTestJava, NoReplacementsForValidImportsWindows) { |
| std::string Code = "import org.a;\r\n" |
| "import org.b;\r\n"; |
| EXPECT_TRUE( |
| sortIncludes(FmtStyle, Code, GetCodeRange(Code), "input.java").empty()); |
| } |
| |
| } // end namespace |
| } // end namespace format |
| } // end namespace clang |