blob: 5a1d0de8b4221ed7e73a24c7e0286dd50e00d23f [file] [log] [blame]
#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