diff --git a/clang/unittests/Format/BracesInserterTest.cpp b/clang/unittests/Format/BracesInserterTest.cpp index c6859074518356..e0c447d671f458 100644 --- a/clang/unittests/Format/BracesInserterTest.cpp +++ b/clang/unittests/Format/BracesInserterTest.cpp @@ -6,64 +6,16 @@ // //===----------------------------------------------------------------------===// -#include "clang/Format/Format.h" - -#include "../Tooling/ReplacementTest.h" -#include "FormatTestUtils.h" +#include "FormatTestBase.h" #define DEBUG_TYPE "braces-inserter-test" namespace clang { namespace format { +namespace test { namespace { -class BracesInserterTest : public ::testing::Test { -protected: - std::string format(llvm::StringRef Code, const FormatStyle &Style, - const std::vector &Ranges) { - LLVM_DEBUG(llvm::errs() << "---\n"); - LLVM_DEBUG(llvm::errs() << Code << "\n\n"); - auto NonEmptyRanges = Ranges; - if (Ranges.empty()) - NonEmptyRanges = {1, tooling::Range(0, Code.size())}; - FormattingAttemptStatus Status; - tooling::Replacements Replaces = - reformat(Style, Code, NonEmptyRanges, "", &Status); - EXPECT_EQ(true, Status.FormatComplete) << Code << "\n\n"; - ReplacementCount = Replaces.size(); - auto Result = applyAllReplacements(Code, Replaces); - EXPECT_TRUE(static_cast(Result)); - LLVM_DEBUG(llvm::errs() << "\n" << *Result << "\n\n"); - return *Result; - } - - void _verifyFormat(const char *File, int Line, llvm::StringRef Expected, - llvm::StringRef Code, - const FormatStyle &Style = getLLVMStyle(), - const std::vector &Ranges = {}) { - testing::ScopedTrace t(File, Line, ::testing::Message() << Code.str()); - EXPECT_EQ(Expected.str(), format(Expected, Style, Ranges)) - << "Expected code is not stable"; - EXPECT_EQ(Expected.str(), format(Code, Style, Ranges)); - if (Style.Language == FormatStyle::LK_Cpp && Ranges.empty()) { - // Objective-C++ is a superset of C++, so everything checked for C++ - // needs to be checked for Objective-C++ as well. - FormatStyle ObjCStyle = Style; - ObjCStyle.Language = FormatStyle::LK_ObjC; - EXPECT_EQ(Expected.str(), format(test::messUp(Code), ObjCStyle, Ranges)); - } - } - - void _verifyFormat(const char *File, int Line, llvm::StringRef Code, - const FormatStyle &Style = getLLVMStyle(), - const std::vector &Ranges = {}) { - _verifyFormat(File, Line, Code, Code, Style, Ranges); - } - - int ReplacementCount; -}; - -#define verifyFormat(...) _verifyFormat(__FILE__, __LINE__, __VA_ARGS__) +class BracesInserterTest : public FormatTestBase {}; TEST_F(BracesInserterTest, InsertBraces) { FormatStyle Style = getLLVMStyle(); @@ -328,9 +280,10 @@ TEST_F(BracesInserterTest, InsertBracesRange) { " }", Code, Style, {tooling::Range(10, 8)}); // line 2 - verifyFormat(Code, Style, {tooling::Range(19, 11)}); // line 3 + verifyFormat(Code, Code, Style, {tooling::Range(19, 11)}); // line 3 } } // namespace +} // namespace test } // namespace format } // namespace clang diff --git a/clang/unittests/Format/BracesRemoverTest.cpp b/clang/unittests/Format/BracesRemoverTest.cpp index ba0b3eb53d155a..5155eefb9e08c9 100644 --- a/clang/unittests/Format/BracesRemoverTest.cpp +++ b/clang/unittests/Format/BracesRemoverTest.cpp @@ -6,66 +6,16 @@ // //===----------------------------------------------------------------------===// -#include "clang/Format/Format.h" - -#include "../Tooling/ReplacementTest.h" -#include "FormatTestUtils.h" +#include "FormatTestBase.h" #define DEBUG_TYPE "braces-remover-test" namespace clang { namespace format { +namespace test { namespace { -// TODO: -// Refactor the class declaration, which is copied from BracesInserterTest.cpp. -class BracesRemoverTest : public ::testing::Test { -protected: - std::string format(llvm::StringRef Code, const FormatStyle &Style, - const std::vector &Ranges) { - LLVM_DEBUG(llvm::errs() << "---\n"); - LLVM_DEBUG(llvm::errs() << Code << "\n\n"); - auto NonEmptyRanges = Ranges; - if (Ranges.empty()) - NonEmptyRanges = {1, tooling::Range(0, Code.size())}; - FormattingAttemptStatus Status; - tooling::Replacements Replaces = - reformat(Style, Code, NonEmptyRanges, "", &Status); - EXPECT_EQ(true, Status.FormatComplete) << Code << "\n\n"; - ReplacementCount = Replaces.size(); - auto Result = applyAllReplacements(Code, Replaces); - EXPECT_TRUE(static_cast(Result)); - LLVM_DEBUG(llvm::errs() << "\n" << *Result << "\n\n"); - return *Result; - } - - void _verifyFormat(const char *File, int Line, llvm::StringRef Expected, - llvm::StringRef Code, - const FormatStyle &Style = getLLVMStyle(), - const std::vector &Ranges = {}) { - testing::ScopedTrace t(File, Line, ::testing::Message() << Code.str()); - EXPECT_EQ(Expected.str(), format(Expected, Style, Ranges)) - << "Expected code is not stable"; - EXPECT_EQ(Expected.str(), format(Code, Style, Ranges)); - if (Style.Language == FormatStyle::LK_Cpp && Ranges.empty()) { - // Objective-C++ is a superset of C++, so everything checked for C++ - // needs to be checked for Objective-C++ as well. - FormatStyle ObjCStyle = Style; - ObjCStyle.Language = FormatStyle::LK_ObjC; - EXPECT_EQ(Expected.str(), format(test::messUp(Code), ObjCStyle, Ranges)); - } - } - - void _verifyFormat(const char *File, int Line, llvm::StringRef Code, - const FormatStyle &Style = getLLVMStyle(), - const std::vector &Ranges = {}) { - _verifyFormat(File, Line, Code, Code, Style, Ranges); - } - - int ReplacementCount; -}; - -#define verifyFormat(...) _verifyFormat(__FILE__, __LINE__, __VA_ARGS__) +class BracesRemoverTest : public FormatTestBase {}; TEST_F(BracesRemoverTest, RemoveBraces) { FormatStyle Style = getLLVMStyle(); @@ -982,5 +932,6 @@ TEST_F(BracesRemoverTest, RemoveBraces) { } } // namespace +} // namespace test } // namespace format } // namespace clang diff --git a/clang/unittests/Format/CMakeLists.txt b/clang/unittests/Format/CMakeLists.txt index 1db1f602415bb5..a4f8f7af3d3a7b 100644 --- a/clang/unittests/Format/CMakeLists.txt +++ b/clang/unittests/Format/CMakeLists.txt @@ -14,6 +14,7 @@ add_clang_unittest(FormatTests FormatTestJS.cpp FormatTestJava.cpp FormatTestJson.cpp + FormatTestMacroExpansion.cpp FormatTestObjC.cpp FormatTestProto.cpp FormatTestRawStrings.cpp @@ -22,6 +23,7 @@ add_clang_unittest(FormatTests FormatTestTextProto.cpp FormatTestVerilog.cpp FormatTokenSourceTest.cpp + FormatReplacementTest.cpp IntegerLiteralSeparatorTest.cpp MacroCallReconstructorTest.cpp MacroExpanderTest.cpp diff --git a/clang/unittests/Format/FormatReplacementTest.cpp b/clang/unittests/Format/FormatReplacementTest.cpp new file mode 100644 index 00000000000000..e81c7e0371003c --- /dev/null +++ b/clang/unittests/Format/FormatReplacementTest.cpp @@ -0,0 +1,84 @@ +//===- unittest/Format/FormatReplacementTest.cpp - Formatting unit test ---===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "../Tooling/ReplacementTest.h" +#include "clang/Format/Format.h" + +namespace clang { +namespace tooling { +namespace { + +using format::FormatStyle; +using format::getLLVMStyle; + +TEST_F(ReplacementTest, FormatCodeAfterReplacements) { + // Column limit is 20. + std::string Code = "Type *a =\n" + " new Type();\n" + "g(iiiii, 0, jjjjj,\n" + " 0, kkkkk, 0, mm);\n" + "int bad = format ;"; + std::string Expected = "auto a = new Type();\n" + "g(iiiii, nullptr,\n" + " jjjjj, nullptr,\n" + " kkkkk, nullptr,\n" + " mm);\n" + "int bad = format ;"; + FileID ID = Context.createInMemoryFile("format.cpp", Code); + tooling::Replacements Replaces = toReplacements( + {tooling::Replacement(Context.Sources, Context.getLocation(ID, 1, 1), 6, + "auto "), + tooling::Replacement(Context.Sources, Context.getLocation(ID, 3, 10), 1, + "nullptr"), + tooling::Replacement(Context.Sources, Context.getLocation(ID, 4, 3), 1, + "nullptr"), + tooling::Replacement(Context.Sources, Context.getLocation(ID, 4, 13), 1, + "nullptr")}); + + FormatStyle Style = getLLVMStyle(); + Style.ColumnLimit = 20; // Set column limit to 20 to increase readibility. + auto FormattedReplaces = formatReplacements(Code, Replaces, Style); + EXPECT_TRUE(static_cast(FormattedReplaces)) + << llvm::toString(FormattedReplaces.takeError()) << "\n"; + auto Result = applyAllReplacements(Code, *FormattedReplaces); + EXPECT_TRUE(static_cast(Result)); + EXPECT_EQ(Expected, *Result); +} + +TEST_F(ReplacementTest, SortIncludesAfterReplacement) { + std::string Code = "#include \"a.h\"\n" + "#include \"c.h\"\n" + "\n" + "int main() {\n" + " return 0;\n" + "}"; + std::string Expected = "#include \"a.h\"\n" + "#include \"b.h\"\n" + "#include \"c.h\"\n" + "\n" + "int main() {\n" + " return 0;\n" + "}"; + FileID ID = Context.createInMemoryFile("fix.cpp", Code); + tooling::Replacements Replaces = toReplacements( + {tooling::Replacement(Context.Sources, Context.getLocation(ID, 1, 1), 0, + "#include \"b.h\"\n")}); + + FormatStyle Style = getLLVMStyle(); + Style.SortIncludes = FormatStyle::SI_CaseSensitive; + auto FormattedReplaces = formatReplacements(Code, Replaces, Style); + EXPECT_TRUE(static_cast(FormattedReplaces)) + << llvm::toString(FormattedReplaces.takeError()) << "\n"; + auto Result = applyAllReplacements(Code, *FormattedReplaces); + EXPECT_TRUE(static_cast(Result)); + EXPECT_EQ(Expected, *Result); +} + +} // namespace +} // namespace tooling +} // namespace clang diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index 1180d3dbbdbc35..f200c498956e49 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -6,122 +6,23 @@ // //===----------------------------------------------------------------------===// -#include "clang/Format/Format.h" - -#include "../Tooling/ReplacementTest.h" -#include "FormatTestUtils.h" - -#include "llvm/Support/Debug.h" -#include "gtest/gtest.h" +#include "FormatTestBase.h" #define DEBUG_TYPE "format-test" -using clang::tooling::ReplacementTest; -using clang::tooling::toReplacements; -using testing::ScopedTrace; - namespace clang { namespace format { +namespace test { namespace { -FormatStyle getGoogleStyle() { return getGoogleStyle(FormatStyle::LK_Cpp); } - -class FormatTest : public ::testing::Test { -protected: - enum StatusCheck { SC_ExpectComplete, SC_ExpectIncomplete, SC_DoNotCheck }; - - std::string format(llvm::StringRef Code, - const FormatStyle &Style = getLLVMStyle(), - StatusCheck CheckComplete = SC_ExpectComplete) { - LLVM_DEBUG(llvm::errs() << "---\n"); - LLVM_DEBUG(llvm::errs() << Code << "\n\n"); - std::vector Ranges(1, tooling::Range(0, Code.size())); - FormattingAttemptStatus Status; - tooling::Replacements Replaces = - reformat(Style, Code, Ranges, "", &Status); - if (CheckComplete != SC_DoNotCheck) { - bool ExpectedCompleteFormat = CheckComplete == SC_ExpectComplete; - EXPECT_EQ(ExpectedCompleteFormat, Status.FormatComplete) - << Code << "\n\n"; - } - ReplacementCount = Replaces.size(); - auto Result = applyAllReplacements(Code, Replaces); - EXPECT_TRUE(static_cast(Result)); - LLVM_DEBUG(llvm::errs() << "\n" << *Result << "\n\n"); - return *Result; - } - - FormatStyle getStyleWithColumns(FormatStyle Style, unsigned ColumnLimit) { - Style.ColumnLimit = ColumnLimit; - return Style; - } - - FormatStyle getLLVMStyleWithColumns(unsigned ColumnLimit) { - return getStyleWithColumns(getLLVMStyle(), ColumnLimit); - } - - FormatStyle getGoogleStyleWithColumns(unsigned ColumnLimit) { - return getStyleWithColumns(getGoogleStyle(), ColumnLimit); - } - - void _verifyFormat(const char *File, int Line, llvm::StringRef Expected, - llvm::StringRef Code, - const FormatStyle &Style = getLLVMStyle()) { - ScopedTrace t(File, Line, ::testing::Message() << Code.str()); - EXPECT_EQ(Expected.str(), format(Expected, Style)) - << "Expected code is not stable"; - EXPECT_EQ(Expected.str(), format(Code, Style)); - if (Style.Language == FormatStyle::LK_Cpp) { - // Objective-C++ is a superset of C++, so everything checked for C++ - // needs to be checked for Objective-C++ as well. - FormatStyle ObjCStyle = Style; - ObjCStyle.Language = FormatStyle::LK_ObjC; - EXPECT_EQ(Expected.str(), format(test::messUp(Code), ObjCStyle)); - } - } - - void _verifyFormat(const char *File, int Line, llvm::StringRef Code, - const FormatStyle &Style = getLLVMStyle()) { - _verifyFormat(File, Line, Code, test::messUp(Code), Style); - } - - void _verifyIncompleteFormat(const char *File, int Line, llvm::StringRef Code, - const FormatStyle &Style = getLLVMStyle()) { - ScopedTrace t(File, Line, ::testing::Message() << Code.str()); - EXPECT_EQ(Code.str(), - format(test::messUp(Code), Style, SC_ExpectIncomplete)); - } - - void _verifyIndependentOfContext(const char *File, int Line, - llvm::StringRef Text, - const FormatStyle &Style = getLLVMStyle()) { - _verifyFormat(File, Line, Text, Style); - _verifyFormat(File, Line, llvm::Twine("void f() { " + Text + " }").str(), - Style); - } - - /// \brief Verify that clang-format does not crash on the given input. - void verifyNoCrash(llvm::StringRef Code, - const FormatStyle &Style = getLLVMStyle()) { - format(Code, Style, SC_DoNotCheck); - } - - int ReplacementCount; -}; - -#define verifyIndependentOfContext(...) \ - _verifyIndependentOfContext(__FILE__, __LINE__, __VA_ARGS__) -#define verifyIncompleteFormat(...) \ - _verifyIncompleteFormat(__FILE__, __LINE__, __VA_ARGS__) -#define verifyFormat(...) _verifyFormat(__FILE__, __LINE__, __VA_ARGS__) -#define verifyGoogleFormat(Code) verifyFormat(Code, getGoogleStyle()) +class FormatTest : public test::FormatTestBase {}; TEST_F(FormatTest, MessUp) { - EXPECT_EQ("1 2 3", test::messUp("1 2 3")); - EXPECT_EQ("1 2 3\n", test::messUp("1\n2\n3\n")); - EXPECT_EQ("a\n//b\nc", test::messUp("a\n//b\nc")); - EXPECT_EQ("a\n#b\nc", test::messUp("a\n#b\nc")); - EXPECT_EQ("a\n#b c d\ne", test::messUp("a\n#b\\\nc\\\nd\ne")); + EXPECT_EQ("1 2 3", messUp("1 2 3")); + EXPECT_EQ("1 2 3\n", messUp("1\n2\n3\n")); + EXPECT_EQ("a\n//b\nc", messUp("a\n//b\nc")); + EXPECT_EQ("a\n#b\nc", messUp("a\n#b\nc")); + EXPECT_EQ("a\n#b c d\ne", messUp("a\n#b\\\nc\\\nd\ne")); } TEST_F(FormatTest, DefaultLLVMStyleIsCpp) { @@ -22631,244 +22532,6 @@ TEST_F(FormatTest, MergeLessLessAtEnd) { "aaaallvm::outs()\n <<"); } -TEST_F(FormatTest, UnexpandConfiguredMacros) { - FormatStyle Style = getLLVMStyle(); - Style.Macros.push_back("CLASS=class C {"); - Style.Macros.push_back("SEMI=;"); - Style.Macros.push_back("STMT=f();"); - Style.Macros.push_back("ID(x)=x"); - Style.Macros.push_back("ID3(x, y, z)=x y z"); - Style.Macros.push_back("CALL(x)=f([] { x })"); - Style.Macros.push_back("ASSIGN_OR_RETURN(a, b)=a = (b)"); - Style.Macros.push_back("ASSIGN_OR_RETURN(a, b, c)=a = (b); if (x) return c"); - Style.Macros.push_back("MOCK_METHOD(r, n, a, s)=r n a s"); - - verifyFormat("ID(nested(a(b, c), d))", Style); - verifyFormat("CLASS\n" - " a *b;\n" - "};", - Style); - verifyFormat("SEMI\n" - "SEMI\n" - "SEMI", - Style); - verifyFormat("STMT\n" - "STMT\n" - "STMT", - Style); - verifyFormat("void f() { ID(a *b); }", Style); - verifyFormat(R"(ID( - { ID(a *b); }); -)", - Style); - verifyIncompleteFormat(R"(ID3({, ID(a *b), - ; - }); -)", - Style); - - verifyFormat("ID(CALL(CALL(return a * b;)));", Style); - - verifyFormat("ASSIGN_OR_RETURN(MySomewhatLongType *variable,\n" - " MySomewhatLongFunction(SomethingElse()));\n", - Style); - verifyFormat("ASSIGN_OR_RETURN(MySomewhatLongType *variable,\n" - " MySomewhatLongFunction(SomethingElse()), " - "ReturnMe());\n", - Style); - - verifyFormat(R"( -#define MACRO(a, b) ID(a + b) -)", - Style); - EXPECT_EQ(R"( -int a; -int b; -int c; -int d; -int e; -int f; -ID( - namespace foo { - int a; - } -) // namespace k -)", - format(R"( -int a; -int b; -int c; -int d; -int e; -int f; -ID(namespace foo { int a; }) // namespace k -)", - Style)); - verifyFormat(R"(ID( - // - ({ ; })) -)", - Style); - - Style.ColumnLimit = 35; - // FIXME: Arbitrary formatting of macros where the end of the logical - // line is in the middle of a macro call are not working yet. - verifyFormat(R"(ID( - void f(); - void) -ID(g) ID(()) ID( - ; - void g();) -)", - Style); - - Style.ColumnLimit = 10; - verifyFormat("STMT\n" - "STMT\n" - "STMT", - Style); - - EXPECT_EQ(R"( -ID(CALL(CALL( - a *b))); -)", - format(R"( -ID(CALL(CALL(a * b))); -)", - Style)); - - // FIXME: If we want to support unbalanced braces or parens from macro - // expansions we need to re-think how we propagate errors in - // TokenAnnotator::parseLine; for investigation, switching the inner loop of - // TokenAnnotator::parseLine to return LT_Other instead of LT_Invalid in case - // of !consumeToken() changes the formatting of the test below and makes it - // believe it has a fully correct formatting. - EXPECT_EQ(R"( -ID3( - { - CLASS - a *b; - }; - }, - ID(x *y); - , - STMT - STMT - STMT) -void f(); -)", - format(R"( -ID3({CLASS a*b; };}, ID(x*y);, STMT STMT STMT) -void f(); -)", - Style)); - - verifyFormat("ID(a(\n" - "#ifdef A\n" - " b, c\n" - "#else\n" - " d(e)\n" - "#endif\n" - " ))", - Style); - Style.ColumnLimit = 80; - verifyFormat(R"(ASSIGN_OR_RETURN( - // Comment - a b, c); -)", - Style); - Style.ColumnLimit = 30; - verifyFormat(R"(ASSIGN_OR_RETURN( - // Comment - // - a b, - xxxxxxxxxxxx( - yyyyyyyyyyyyyyyyy, - zzzzzzzzzzzzzzzzzz), - f([]() { - a(); - b(); - })); -)", - Style); - verifyFormat(R"(int a = []() { - ID( - x; - y; - z;) - ; -}(); -)", - Style); - EXPECT_EQ( - R"(ASSIGN_OR_RETURN(( -==== -#)) -})", - format(R"(ASSIGN_OR_RETURN(( -==== -#)) -})", - Style, SC_ExpectIncomplete)); - EXPECT_EQ(R"(ASSIGN_OR_RETURN( -} -( -==== -#), - a))", - format(R"(ASSIGN_OR_RETURN( -} -( -==== -#), -a))", - Style, SC_ExpectIncomplete)); - EXPECT_EQ(R"(ASSIGN_OR_RETURN(a -// -==== -# - <))", - format(R"(ASSIGN_OR_RETURN(a -// -==== -# - <))", - Style)); - verifyFormat("class C {\n" - " MOCK_METHOD(R, f,\n" - " (a *b, c *d),\n" - " (override));\n" - "};", - Style); -} - -TEST_F(FormatTest, KeepParensWhenExpandingObjectLikeMacros) { - FormatStyle Style = getLLVMStyle(); - Style.Macros.push_back("FN=class C { int f"); - verifyFormat("void f() {\n" - " FN(a *b);\n" - " };\n" - "}", - Style); -} - -TEST_F(FormatTest, DoesNotExpandFunctionLikeMacrosWithoutParens) { - FormatStyle Style = getLLVMStyle(); - Style.Macros.push_back("CLASS()=class C {"); - verifyFormat("CLASS void f();\n" - "}\n" - ";", - Style); -} - -TEST_F(FormatTest, ContinueFormattingAfterUnclosedParensAfterObjectLikeMacro) { - FormatStyle Style = getLLVMStyle(); - Style.Macros.push_back("O=class {"); - verifyIncompleteFormat("O(auto x = [](){\n" - " f();}", - Style); -} - TEST_F(FormatTest, HandleUnbalancedImplicitBracesAcrossPPBranches) { std::string code = "#if A\n" "#if B\n" @@ -23080,69 +22743,6 @@ TEST_F(FormatTest, ArrayAsTemplateType) { TEST_F(FormatTest, NoSpaceAfterSuper) { verifyFormat("__super::FooBar();"); } -TEST_F(ReplacementTest, FormatCodeAfterReplacements) { - // Column limit is 20. - std::string Code = "Type *a =\n" - " new Type();\n" - "g(iiiii, 0, jjjjj,\n" - " 0, kkkkk, 0, mm);\n" - "int bad = format ;"; - std::string Expected = "auto a = new Type();\n" - "g(iiiii, nullptr,\n" - " jjjjj, nullptr,\n" - " kkkkk, nullptr,\n" - " mm);\n" - "int bad = format ;"; - FileID ID = Context.createInMemoryFile("format.cpp", Code); - tooling::Replacements Replaces = toReplacements( - {tooling::Replacement(Context.Sources, Context.getLocation(ID, 1, 1), 6, - "auto "), - tooling::Replacement(Context.Sources, Context.getLocation(ID, 3, 10), 1, - "nullptr"), - tooling::Replacement(Context.Sources, Context.getLocation(ID, 4, 3), 1, - "nullptr"), - tooling::Replacement(Context.Sources, Context.getLocation(ID, 4, 13), 1, - "nullptr")}); - - FormatStyle Style = getLLVMStyle(); - Style.ColumnLimit = 20; // Set column limit to 20 to increase readibility. - auto FormattedReplaces = formatReplacements(Code, Replaces, Style); - EXPECT_TRUE(static_cast(FormattedReplaces)) - << llvm::toString(FormattedReplaces.takeError()) << "\n"; - auto Result = applyAllReplacements(Code, *FormattedReplaces); - EXPECT_TRUE(static_cast(Result)); - EXPECT_EQ(Expected, *Result); -} - -TEST_F(ReplacementTest, SortIncludesAfterReplacement) { - std::string Code = "#include \"a.h\"\n" - "#include \"c.h\"\n" - "\n" - "int main() {\n" - " return 0;\n" - "}"; - std::string Expected = "#include \"a.h\"\n" - "#include \"b.h\"\n" - "#include \"c.h\"\n" - "\n" - "int main() {\n" - " return 0;\n" - "}"; - FileID ID = Context.createInMemoryFile("fix.cpp", Code); - tooling::Replacements Replaces = toReplacements( - {tooling::Replacement(Context.Sources, Context.getLocation(ID, 1, 1), 0, - "#include \"b.h\"\n")}); - - FormatStyle Style = getLLVMStyle(); - Style.SortIncludes = FormatStyle::SI_CaseSensitive; - auto FormattedReplaces = formatReplacements(Code, Replaces, Style); - EXPECT_TRUE(static_cast(FormattedReplaces)) - << llvm::toString(FormattedReplaces.takeError()) << "\n"; - auto Result = applyAllReplacements(Code, *FormattedReplaces); - EXPECT_TRUE(static_cast(Result)); - EXPECT_EQ(Expected, *Result); -} - TEST_F(FormatTest, FormatSortsUsingDeclarations) { EXPECT_EQ("using std::cin;\n" "using std::cout;", @@ -25714,5 +25314,6 @@ TEST_F(FormatTest, SpaceAfterUDL) { } } // namespace +} // namespace test } // namespace format } // namespace clang diff --git a/clang/unittests/Format/FormatTestBase.h b/clang/unittests/Format/FormatTestBase.h new file mode 100644 index 00000000000000..ea214468965a5e --- /dev/null +++ b/clang/unittests/Format/FormatTestBase.h @@ -0,0 +1,142 @@ +//===- unittest/Format/FormatTestBase.h - Formatting test base classs -----===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file defines the base class for format tests. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_UNITTESTS_FORMAT_FORMATTESTBASE_H +#define LLVM_CLANG_UNITTESTS_FORMAT_FORMATTESTBASE_H + +#include "FormatTestUtils.h" + +#include "clang/Format/Format.h" +#include "llvm/Support/Debug.h" +#include "gtest/gtest.h" + +namespace clang { +namespace format { +namespace test { + +#define DEBUG_TYPE "format-test-base" + +class FormatTestBase : public ::testing::Test { +protected: + enum StatusCheck { SC_ExpectComplete, SC_ExpectIncomplete, SC_DoNotCheck }; + + virtual FormatStyle getDefaultStyle() const { return getLLVMStyle(); } + + std::string format(llvm::StringRef Code, + const std::optional &Style = {}, + StatusCheck CheckComplete = SC_ExpectComplete, + const std::vector &Ranges = {}) { + LLVM_DEBUG(llvm::errs() << "---\n"); + LLVM_DEBUG(llvm::errs() << Code << "\n\n"); + auto NonEmptyRanges = + !Ranges.empty() + ? Ranges + : std::vector{1, tooling::Range(0, Code.size())}; + auto UsedStyle = Style ? Style.value() : getDefaultStyle(); + FormattingAttemptStatus Status; + tooling::Replacements Replaces = + reformat(UsedStyle, Code, NonEmptyRanges, "", &Status); + if (CheckComplete != SC_DoNotCheck) { + bool ExpectedCompleteFormat = CheckComplete == SC_ExpectComplete; + EXPECT_EQ(ExpectedCompleteFormat, Status.FormatComplete) + << Code << "\n\n"; + } + ReplacementCount = Replaces.size(); + auto Result = applyAllReplacements(Code, Replaces); + EXPECT_TRUE(static_cast(Result)); + LLVM_DEBUG(llvm::errs() << "\n" << *Result << "\n\n"); + return *Result; + } + + FormatStyle getStyleWithColumns(FormatStyle Style, unsigned ColumnLimit) { + Style.ColumnLimit = ColumnLimit; + return Style; + } + + FormatStyle getLLVMStyleWithColumns(unsigned ColumnLimit) { + return getStyleWithColumns(getLLVMStyle(), ColumnLimit); + } + + FormatStyle getGoogleStyleWithColumns(unsigned ColumnLimit) { + return getStyleWithColumns(getGoogleStyle(), ColumnLimit); + } + + FormatStyle getTextProtoStyleWithColumns(unsigned ColumnLimit) { + FormatStyle Style = getGoogleStyle(FormatStyle::FormatStyle::LK_TextProto); + Style.ColumnLimit = ColumnLimit; + return Style; + } + + void _verifyFormat(const char *File, int Line, llvm::StringRef Expected, + llvm::StringRef Code, + const std::optional &Style = {}, + const std::vector &Ranges = {}) { + testing::ScopedTrace t(File, Line, ::testing::Message() << Code.str()); + EXPECT_EQ(Expected.str(), + format(Expected, Style, SC_ExpectComplete, Ranges)) + << "Expected code is not stable"; + EXPECT_EQ(Expected.str(), format(Code, Style, SC_ExpectComplete, Ranges)); + auto UsedStyle = Style ? Style.value() : getDefaultStyle(); + if (UsedStyle.Language == FormatStyle::LK_Cpp) { + // Objective-C++ is a superset of C++, so everything checked for C++ + // needs to be checked for Objective-C++ as well. + FormatStyle ObjCStyle = UsedStyle; + ObjCStyle.Language = FormatStyle::LK_ObjC; + // FIXME: Additional messUp is superfluous. + EXPECT_EQ(Expected.str(), + format(Code, ObjCStyle, SC_ExpectComplete, Ranges)); + } + } + + void _verifyFormat(const char *File, int Line, llvm::StringRef Code, + const std::optional &Style = {}) { + _verifyFormat(File, Line, Code, test::messUp(Code), Style); + } + + void _verifyIncompleteFormat(const char *File, int Line, llvm::StringRef Code, + const std::optional &Style = {}) { + testing::ScopedTrace t(File, Line, ::testing::Message() << Code.str()); + EXPECT_EQ(Code.str(), + format(test::messUp(Code), Style, SC_ExpectIncomplete)); + } + + void + _verifyIndependentOfContext(const char *File, int Line, llvm::StringRef Text, + const std::optional &Style = {}) { + _verifyFormat(File, Line, Text, Style); + _verifyFormat(File, Line, llvm::Twine("void f() { " + Text + " }").str(), + Style); + } + + /// \brief Verify that clang-format does not crash on the given input. + void verifyNoCrash(llvm::StringRef Code, + const std::optional &Style = {}) { + format(Code, Style, SC_DoNotCheck); + } + + int ReplacementCount; +}; + +#undef DEBUG_TYPE + +#define verifyIndependentOfContext(...) \ + _verifyIndependentOfContext(__FILE__, __LINE__, __VA_ARGS__) +#define verifyIncompleteFormat(...) \ + _verifyIncompleteFormat(__FILE__, __LINE__, __VA_ARGS__) +#define verifyFormat(...) _verifyFormat(__FILE__, __LINE__, __VA_ARGS__) +#define verifyGoogleFormat(Code) verifyFormat(Code, getGoogleStyle()) + +} // namespace test +} // namespace format +} // namespace clang + +#endif \ No newline at end of file diff --git a/clang/unittests/Format/FormatTestComments.cpp b/clang/unittests/Format/FormatTestComments.cpp index 3336ee4f39efc5..03d093bd589132 100644 --- a/clang/unittests/Format/FormatTestComments.cpp +++ b/clang/unittests/Format/FormatTestComments.cpp @@ -6,79 +6,18 @@ // //===----------------------------------------------------------------------===// -#include "clang/Format/Format.h" +#include "FormatTestBase.h" -#include "../Tooling/ReplacementTest.h" -#include "FormatTestUtils.h" - -#include "llvm/Support/Debug.h" -#include "gtest/gtest.h" - -#define DEBUG_TYPE "format-test" - -using clang::tooling::ReplacementTest; +#define DEBUG_TYPE "format-test-comments" namespace clang { namespace format { +namespace test { namespace { FormatStyle getGoogleStyle() { return getGoogleStyle(FormatStyle::LK_Cpp); } -class FormatTestComments : public ::testing::Test { -protected: - enum StatusCheck { SC_ExpectComplete, SC_ExpectIncomplete, SC_DoNotCheck }; - - std::string format(llvm::StringRef Code, - const FormatStyle &Style = getLLVMStyle(), - StatusCheck CheckComplete = SC_ExpectComplete) { - LLVM_DEBUG(llvm::errs() << "---\n"); - LLVM_DEBUG(llvm::errs() << Code << "\n\n"); - std::vector Ranges(1, tooling::Range(0, Code.size())); - FormattingAttemptStatus Status; - tooling::Replacements Replaces = - reformat(Style, Code, Ranges, "", &Status); - if (CheckComplete != SC_DoNotCheck) { - bool ExpectedCompleteFormat = CheckComplete == SC_ExpectComplete; - EXPECT_EQ(ExpectedCompleteFormat, Status.FormatComplete) - << Code << "\n\n"; - } - ReplacementCount = Replaces.size(); - auto Result = applyAllReplacements(Code, Replaces); - EXPECT_TRUE(static_cast(Result)); - LLVM_DEBUG(llvm::errs() << "\n" << *Result << "\n\n"); - return *Result; - } - - FormatStyle getLLVMStyleWithColumns(unsigned ColumnLimit) { - FormatStyle Style = getLLVMStyle(); - Style.ColumnLimit = ColumnLimit; - return Style; - } - - FormatStyle getTextProtoStyleWithColumns(unsigned ColumnLimit) { - FormatStyle Style = getGoogleStyle(FormatStyle::FormatStyle::LK_TextProto); - Style.ColumnLimit = ColumnLimit; - return Style; - } - - void verifyFormat(llvm::StringRef Code, - const FormatStyle &Style = getLLVMStyle()) { - EXPECT_EQ(Code.str(), format(Code, Style)) << "Expected code is not stable"; - EXPECT_EQ(Code.str(), format(test::messUp(Code), Style)); - } - - void verifyGoogleFormat(llvm::StringRef Code) { - verifyFormat(Code, getGoogleStyle()); - } - - /// \brief Verify that clang-format does not crash on the given input. - void verifyNoCrash(llvm::StringRef Code, - const FormatStyle &Style = getLLVMStyle()) { - format(Code, Style, SC_DoNotCheck); - } - - int ReplacementCount; -}; +class FormatTestComments : public FormatTestBase {}; //===----------------------------------------------------------------------===// // Tests for comments. @@ -4376,5 +4315,6 @@ TEST_F(FormatTestComments, SplitCommentIntroducers) { } } // end namespace +} // namespace test } // end namespace format } // end namespace clang diff --git a/clang/unittests/Format/FormatTestMacroExpansion.cpp b/clang/unittests/Format/FormatTestMacroExpansion.cpp new file mode 100644 index 00000000000000..feafadb1593e29 --- /dev/null +++ b/clang/unittests/Format/FormatTestMacroExpansion.cpp @@ -0,0 +1,262 @@ +//===- unittest/Format/FormatMacroExpansion.cpp - Formatting unit tests ---===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "FormatTestBase.h" + +#define DEBUG_TYPE "format-test-macro-expansion" + +namespace clang { +namespace format { +namespace test { +namespace { + +class FormatTestMacroExpansion : public FormatTestBase {}; + +TEST_F(FormatTestMacroExpansion, UnexpandConfiguredMacros) { + FormatStyle Style = getLLVMStyle(); + Style.Macros.push_back("CLASS=class C {"); + Style.Macros.push_back("SEMI=;"); + Style.Macros.push_back("STMT=f();"); + Style.Macros.push_back("ID(x)=x"); + Style.Macros.push_back("ID3(x, y, z)=x y z"); + Style.Macros.push_back("CALL(x)=f([] { x })"); + Style.Macros.push_back("ASSIGN_OR_RETURN(a, b)=a = (b)"); + Style.Macros.push_back("ASSIGN_OR_RETURN(a, b, c)=a = (b); if (x) return c"); + Style.Macros.push_back("MOCK_METHOD(r, n, a, s)=r n a s"); + + verifyFormat("ID(nested(a(b, c), d))", Style); + verifyFormat("CLASS\n" + " a *b;\n" + "};", + Style); + verifyFormat("SEMI\n" + "SEMI\n" + "SEMI", + Style); + verifyFormat("STMT\n" + "STMT\n" + "STMT", + Style); + verifyFormat("void f() { ID(a *b); }", Style); + verifyFormat(R"(ID( + { ID(a *b); }); +)", + Style); + verifyIncompleteFormat(R"(ID3({, ID(a *b), + ; + }); +)", + Style); + + verifyFormat("ID(CALL(CALL(return a * b;)));", Style); + + verifyFormat("ASSIGN_OR_RETURN(MySomewhatLongType *variable,\n" + " MySomewhatLongFunction(SomethingElse()));\n", + Style); + verifyFormat("ASSIGN_OR_RETURN(MySomewhatLongType *variable,\n" + " MySomewhatLongFunction(SomethingElse()), " + "ReturnMe());\n", + Style); + + verifyFormat(R"( +#define MACRO(a, b) ID(a + b) +)", + Style); + EXPECT_EQ(R"( +int a; +int b; +int c; +int d; +int e; +int f; +ID( + namespace foo { + int a; + } +) // namespace k +)", + format(R"( +int a; +int b; +int c; +int d; +int e; +int f; +ID(namespace foo { int a; }) // namespace k +)", + Style)); + verifyFormat(R"(ID( + // + ({ ; })) +)", + Style); + + Style.ColumnLimit = 35; + // FIXME: Arbitrary formatting of macros where the end of the logical + // line is in the middle of a macro call are not working yet. + verifyFormat(R"(ID( + void f(); + void) +ID(g) ID(()) ID( + ; + void g();) +)", + Style); + + Style.ColumnLimit = 10; + verifyFormat("STMT\n" + "STMT\n" + "STMT", + Style); + + EXPECT_EQ(R"( +ID(CALL(CALL( + a *b))); +)", + format(R"( +ID(CALL(CALL(a * b))); +)", + Style)); + + // FIXME: If we want to support unbalanced braces or parens from macro + // expansions we need to re-think how we propagate errors in + // TokenAnnotator::parseLine; for investigation, switching the inner loop of + // TokenAnnotator::parseLine to return LT_Other instead of LT_Invalid in case + // of !consumeToken() changes the formatting of the test below and makes it + // believe it has a fully correct formatting. + EXPECT_EQ(R"( +ID3( + { + CLASS + a *b; + }; + }, + ID(x *y); + , + STMT + STMT + STMT) +void f(); +)", + format(R"( +ID3({CLASS a*b; };}, ID(x*y);, STMT STMT STMT) +void f(); +)", + Style)); + + verifyFormat("ID(a(\n" + "#ifdef A\n" + " b, c\n" + "#else\n" + " d(e)\n" + "#endif\n" + " ))", + Style); + Style.ColumnLimit = 80; + verifyFormat(R"(ASSIGN_OR_RETURN( + // Comment + a b, c); +)", + Style); + Style.ColumnLimit = 30; + verifyFormat(R"(ASSIGN_OR_RETURN( + // Comment + // + a b, + xxxxxxxxxxxx( + yyyyyyyyyyyyyyyyy, + zzzzzzzzzzzzzzzzzz), + f([]() { + a(); + b(); + })); +)", + Style); + verifyFormat(R"(int a = []() { + ID( + x; + y; + z;) + ; +}(); +)", + Style); + EXPECT_EQ( + R"(ASSIGN_OR_RETURN(( +==== +#)) +})", + format(R"(ASSIGN_OR_RETURN(( +==== +#)) +})", + Style, SC_ExpectIncomplete)); + EXPECT_EQ(R"(ASSIGN_OR_RETURN( +} +( +==== +#), + a))", + format(R"(ASSIGN_OR_RETURN( +} +( +==== +#), +a))", + Style, SC_ExpectIncomplete)); + EXPECT_EQ(R"(ASSIGN_OR_RETURN(a +// +==== +# + <))", + format(R"(ASSIGN_OR_RETURN(a +// +==== +# + <))", + Style)); + verifyFormat("class C {\n" + " MOCK_METHOD(R, f,\n" + " (a *b, c *d),\n" + " (override));\n" + "};", + Style); +} + +TEST_F(FormatTestMacroExpansion, KeepParensWhenExpandingObjectLikeMacros) { + FormatStyle Style = getLLVMStyle(); + Style.Macros.push_back("FN=class C { int f"); + verifyFormat("void f() {\n" + " FN(a *b);\n" + " };\n" + "}", + Style); +} + +TEST_F(FormatTestMacroExpansion, DoesNotExpandFunctionLikeMacrosWithoutParens) { + FormatStyle Style = getLLVMStyle(); + Style.Macros.push_back("CLASS()=class C {"); + verifyFormat("CLASS void f();\n" + "}\n" + ";", + Style); +} + +TEST_F(FormatTestMacroExpansion, + ContinueFormattingAfterUnclosedParensAfterObjectLikeMacro) { + FormatStyle Style = getLLVMStyle(); + Style.Macros.push_back("O=class {"); + verifyIncompleteFormat("O(auto x = [](){\n" + " f();}", + Style); +} + +} // namespace +} // namespace test +} // namespace format +} // namespace clang \ No newline at end of file diff --git a/clang/unittests/Format/FormatTestObjC.cpp b/clang/unittests/Format/FormatTestObjC.cpp index e421082796c506..e32b09239ae454 100644 --- a/clang/unittests/Format/FormatTestObjC.cpp +++ b/clang/unittests/Format/FormatTestObjC.cpp @@ -6,61 +6,23 @@ // //===----------------------------------------------------------------------===// -#include "clang/Format/Format.h" +#include "FormatTestBase.h" -#include "../Tooling/ReplacementTest.h" -#include "FormatTestUtils.h" - -#include "llvm/Support/Debug.h" -#include "llvm/Support/MemoryBuffer.h" -#include "gtest/gtest.h" - -#define DEBUG_TYPE "format-test" - -using testing::ScopedTrace; +#define DEBUG_TYPE "format-test-objc" namespace clang { namespace format { +namespace test { namespace { -class FormatTestObjC : public ::testing::Test { +class FormatTestObjC : public FormatTestBase { protected: FormatTestObjC() { Style = getLLVMStyle(); Style.Language = FormatStyle::LK_ObjC; } - enum StatusCheck { SC_ExpectComplete, SC_ExpectIncomplete, SC_DoNotCheck }; - - std::string format(llvm::StringRef Code, - StatusCheck CheckComplete = SC_ExpectComplete) { - LLVM_DEBUG(llvm::errs() << "---\n"); - LLVM_DEBUG(llvm::errs() << Code << "\n\n"); - std::vector Ranges(1, tooling::Range(0, Code.size())); - FormattingAttemptStatus Status; - tooling::Replacements Replaces = - reformat(Style, Code, Ranges, "", &Status); - if (CheckComplete != SC_DoNotCheck) { - bool ExpectedCompleteFormat = CheckComplete == SC_ExpectComplete; - EXPECT_EQ(ExpectedCompleteFormat, Status.FormatComplete) - << Code << "\n\n"; - } - auto Result = applyAllReplacements(Code, Replaces); - EXPECT_TRUE(static_cast(Result)); - LLVM_DEBUG(llvm::errs() << "\n" << *Result << "\n\n"); - return *Result; - } - - void _verifyFormat(const char *File, int Line, StringRef Code) { - ScopedTrace t(File, Line, ::testing::Message() << Code.str()); - EXPECT_EQ(Code.str(), format(Code)) << "Expected code is not stable"; - EXPECT_EQ(Code.str(), format(test::messUp(Code))); - } - - void _verifyIncompleteFormat(const char *File, int Line, StringRef Code) { - ScopedTrace t(File, Line, ::testing::Message() << Code.str()); - EXPECT_EQ(Code.str(), format(test::messUp(Code), SC_ExpectIncomplete)); - } + FormatStyle getDefaultStyle() const override { return Style; } FormatStyle Style; }; @@ -1539,5 +1501,6 @@ TEST_F(FormatTestObjC, Attributes) { } } // end namespace +} // namespace test } // end namespace format } // end namespace clang diff --git a/clang/unittests/Format/FormatTestTextProto.cpp b/clang/unittests/Format/FormatTestTextProto.cpp index 10a43c1519d6dc..6df8d451279227 100644 --- a/clang/unittests/Format/FormatTestTextProto.cpp +++ b/clang/unittests/Format/FormatTestTextProto.cpp @@ -6,50 +6,24 @@ // //===----------------------------------------------------------------------===// -#include "FormatTestUtils.h" -#include "clang/Format/Format.h" -#include "llvm/Support/Debug.h" -#include "gtest/gtest.h" +#include "FormatTestBase.h" -#define DEBUG_TYPE "format-test" +#define DEBUG_TYPE "format-test-text-proto" namespace clang { namespace format { +namespace test { +namespace { -class FormatTestTextProto : public ::testing::Test { +class FormatTestTextProto : public FormatTestBase { protected: - static std::string format(llvm::StringRef Code, unsigned Offset, - unsigned Length, const FormatStyle &Style) { - LLVM_DEBUG(llvm::errs() << "---\n"); - LLVM_DEBUG(llvm::errs() << Code << "\n\n"); - std::vector Ranges(1, tooling::Range(Offset, Length)); - tooling::Replacements Replaces = reformat(Style, Code, Ranges); - auto Result = applyAllReplacements(Code, Replaces); - EXPECT_TRUE(static_cast(Result)); - LLVM_DEBUG(llvm::errs() << "\n" << *Result << "\n\n"); - return *Result; - } - - static std::string format(llvm::StringRef Code, const FormatStyle &Style) { - return format(Code, 0, Code.size(), Style); - } - - static void _verifyFormat(const char *File, int Line, llvm::StringRef Code, - const FormatStyle &Style) { - ::testing::ScopedTrace t(File, Line, ::testing::Message() << Code.str()); - EXPECT_EQ(Code.str(), format(Code, Style)) << "Expected code is not stable"; - EXPECT_EQ(Code.str(), format(test::messUp(Code), Style)); - } - - static void _verifyFormat(const char *File, int Line, llvm::StringRef Code) { + virtual FormatStyle getDefaultStyle() const override { FormatStyle Style = getGoogleStyle(FormatStyle::LK_TextProto); Style.ColumnLimit = 60; // To make writing tests easier. - _verifyFormat(File, Line, Code, Style); + return Style; } }; -#define verifyFormat(...) _verifyFormat(__FILE__, __LINE__, __VA_ARGS__) - TEST_F(FormatTestTextProto, KeepsTopLevelEntriesFittingALine) { verifyFormat("field_a: OK field_b: OK field_c: OK field_d: OK field_e: OK"); } @@ -761,5 +735,7 @@ TEST_F(FormatTestTextProto, KeepsAmpersandsNextToKeys) { "}"); } +} // namespace +} // namespace test } // namespace format } // end namespace clang diff --git a/clang/unittests/Format/FormatTestUtils.h b/clang/unittests/Format/FormatTestUtils.h index defe0738c28ced..fa42b61c547d58 100644 --- a/clang/unittests/Format/FormatTestUtils.h +++ b/clang/unittests/Format/FormatTestUtils.h @@ -13,12 +13,17 @@ #ifndef LLVM_CLANG_UNITTESTS_FORMAT_FORMATTESTUTILS_H #define LLVM_CLANG_UNITTESTS_FORMAT_FORMATTESTUTILS_H +#include "clang/Format/Format.h" #include "llvm/ADT/StringRef.h" namespace clang { namespace format { namespace test { +inline FormatStyle getGoogleStyle() { + return getGoogleStyle(FormatStyle::LK_Cpp); +} + // When HandleHash is false, preprocessor directives starting with hash will not // be on separate lines. This is needed because Verilog uses hash for other // purposes. diff --git a/clang/unittests/Format/IntegerLiteralSeparatorTest.cpp b/clang/unittests/Format/IntegerLiteralSeparatorTest.cpp index 8698947818e5e8..1c9ccebf44e99b 100644 --- a/clang/unittests/Format/IntegerLiteralSeparatorTest.cpp +++ b/clang/unittests/Format/IntegerLiteralSeparatorTest.cpp @@ -6,66 +6,16 @@ // //===----------------------------------------------------------------------===// -#include "clang/Format/Format.h" - -#include "../Tooling/ReplacementTest.h" -#include "FormatTestUtils.h" +#include "FormatTestBase.h" #define DEBUG_TYPE "integer-literal-separator-test" namespace clang { namespace format { +namespace test { namespace { -// TODO: -// Refactor the class declaration, which is copied from BracesInserterTest.cpp. -class IntegerLiteralSeparatorTest : public ::testing::Test { -protected: - std::string format(llvm::StringRef Code, const FormatStyle &Style, - const std::vector &Ranges) { - LLVM_DEBUG(llvm::errs() << "---\n"); - LLVM_DEBUG(llvm::errs() << Code << "\n\n"); - auto NonEmptyRanges = Ranges; - if (Ranges.empty()) - NonEmptyRanges = {1, tooling::Range(0, Code.size())}; - FormattingAttemptStatus Status; - tooling::Replacements Replaces = - reformat(Style, Code, NonEmptyRanges, "", &Status); - EXPECT_EQ(true, Status.FormatComplete) << Code << "\n\n"; - ReplacementCount = Replaces.size(); - auto Result = applyAllReplacements(Code, Replaces); - EXPECT_TRUE(static_cast(Result)); - LLVM_DEBUG(llvm::errs() << "\n" << *Result << "\n\n"); - return *Result; - } - - void _verifyFormat(const char *File, int Line, llvm::StringRef Expected, - llvm::StringRef Code, - const FormatStyle &Style = getLLVMStyle(), - const std::vector &Ranges = {}) { - testing::ScopedTrace t(File, Line, ::testing::Message() << Code.str()); - EXPECT_EQ(Expected.str(), format(Expected, Style, Ranges)) - << "Expected code is not stable"; - EXPECT_EQ(Expected.str(), format(Code, Style, Ranges)); - if (Style.Language == FormatStyle::LK_Cpp && Ranges.empty()) { - // Objective-C++ is a superset of C++, so everything checked for C++ - // needs to be checked for Objective-C++ as well. - FormatStyle ObjCStyle = Style; - ObjCStyle.Language = FormatStyle::LK_ObjC; - EXPECT_EQ(Expected.str(), format(test::messUp(Code), ObjCStyle, Ranges)); - } - } - - void _verifyFormat(const char *File, int Line, llvm::StringRef Code, - const FormatStyle &Style = getLLVMStyle(), - const std::vector &Ranges = {}) { - _verifyFormat(File, Line, Code, Code, Style, Ranges); - } - - int ReplacementCount; -}; - -#define verifyFormat(...) _verifyFormat(__FILE__, __LINE__, __VA_ARGS__) +class IntegerLiteralSeparatorTest : public FormatTestBase {}; TEST_F(IntegerLiteralSeparatorTest, SingleQuoteAsSeparator) { FormatStyle Style = getLLVMStyle(); @@ -176,7 +126,7 @@ TEST_F(IntegerLiteralSeparatorTest, FixRanges) { "k = +1'23'4;", Code, Style, {tooling::Range(0, 11)}); // line 1 - verifyFormat(Code, Style, {tooling::Range(32, 10)}); // line 3 + verifyFormat(Code, Code, Style, {tooling::Range(32, 10)}); // line 3 verifyFormat("i = -12'34;\n" "// clang-format off\n" @@ -224,5 +174,6 @@ TEST_F(IntegerLiteralSeparatorTest, FloatingPoint) { } } // namespace +} // namespace test } // namespace format } // namespace clang diff --git a/clang/unittests/Format/QualifierFixerTest.cpp b/clang/unittests/Format/QualifierFixerTest.cpp index d320eacc52c8d5..b2447339a7d681 100755 --- a/clang/unittests/Format/QualifierFixerTest.cpp +++ b/clang/unittests/Format/QualifierFixerTest.cpp @@ -6,20 +6,15 @@ // //===----------------------------------------------------------------------===// -#include "clang/Format/Format.h" - -#include "FormatTestUtils.h" +#include "../lib/Format/QualifierAlignmentFixer.h" +#include "FormatTestBase.h" #include "TestLexer.h" -#include "gtest/gtest.h" - -#include "../../lib/Format/QualifierAlignmentFixer.h" #define DEBUG_TYPE "format-qualifier-fixer-test" -using testing::ScopedTrace; - namespace clang { namespace format { +namespace test { namespace { #define CHECK_PARSE(TEXT, FIELD, VALUE) \ @@ -31,96 +26,16 @@ namespace { EXPECT_NE(0, parseConfiguration(TEXT, &Style).value()); \ EXPECT_EQ(VALUE, Style.FIELD) << "Unexpected value after parsing!" -class QualifierFixerTest : public ::testing::Test { +class QualifierFixerTest : public FormatTestBase { protected: - enum StatusCheck { SC_ExpectComplete, SC_ExpectIncomplete, SC_DoNotCheck }; - TokenList annotate(llvm::StringRef Code, const FormatStyle &Style = getLLVMStyle()) { return TestLexer(Allocator, Buffers, Style).annotate(Code); } llvm::SpecificBumpPtrAllocator Allocator; std::vector> Buffers; - - std::string format(llvm::StringRef Code, - const FormatStyle &Style = getLLVMStyle(), - StatusCheck CheckComplete = SC_ExpectComplete) { - LLVM_DEBUG(llvm::errs() << "---\n"); - LLVM_DEBUG(llvm::errs() << Code << "\n\n"); - std::vector Ranges(1, tooling::Range(0, Code.size())); - FormattingAttemptStatus Status; - tooling::Replacements Replaces = - reformat(Style, Code, Ranges, "", &Status); - if (CheckComplete != SC_DoNotCheck) { - bool ExpectedCompleteFormat = CheckComplete == SC_ExpectComplete; - EXPECT_EQ(ExpectedCompleteFormat, Status.FormatComplete) - << Code << "\n\n"; - } - ReplacementCount = Replaces.size(); - auto Result = applyAllReplacements(Code, Replaces); - EXPECT_TRUE(static_cast(Result)); - LLVM_DEBUG(llvm::errs() << "\n" << *Result << "\n\n"); - return *Result; - } - - FormatStyle getStyleWithColumns(FormatStyle Style, unsigned ColumnLimit) { - Style.ColumnLimit = ColumnLimit; - return Style; - } - - FormatStyle getLLVMStyleWithColumns(unsigned ColumnLimit) { - return getStyleWithColumns(getLLVMStyle(), ColumnLimit); - } - - void _verifyFormat(const char *File, int Line, llvm::StringRef Expected, - llvm::StringRef Code, - const FormatStyle &Style = getLLVMStyle()) { - ScopedTrace t(File, Line, ::testing::Message() << Code.str()); - EXPECT_EQ(Expected.str(), format(Expected, Style)) - << "Expected code is not stable"; - EXPECT_EQ(Expected.str(), format(Code, Style)); - if (Style.Language == FormatStyle::LK_Cpp) { - // Objective-C++ is a superset of C++, so everything checked for C++ - // needs to be checked for Objective-C++ as well. - FormatStyle ObjCStyle = Style; - ObjCStyle.Language = FormatStyle::LK_ObjC; - EXPECT_EQ(Expected.str(), format(test::messUp(Code), ObjCStyle)); - } - } - - void _verifyFormat(const char *File, int Line, llvm::StringRef Code, - const FormatStyle &Style = getLLVMStyle()) { - _verifyFormat(File, Line, Code, test::messUp(Code), Style); - } - - void _verifyIncompleteFormat(const char *File, int Line, llvm::StringRef Code, - const FormatStyle &Style = getLLVMStyle()) { - ScopedTrace t(File, Line, ::testing::Message() << Code.str()); - EXPECT_EQ(Code.str(), - format(test::messUp(Code), Style, SC_ExpectIncomplete)); - } - - void _verifyIndependentOfContext(const char *File, int Line, - llvm::StringRef Text, - const FormatStyle &Style = getLLVMStyle()) { - _verifyFormat(File, Line, Text, Style); - _verifyFormat(File, Line, llvm::Twine("void f() { " + Text + " }").str(), - Style); - } - - /// \brief Verify that clang-format does not crash on the given input. - void verifyNoCrash(llvm::StringRef Code, - const FormatStyle &Style = getLLVMStyle()) { - format(Code, Style, SC_DoNotCheck); - } - - int ReplacementCount; }; -#define verifyFormat(...) _verifyFormat(__FILE__, __LINE__, __VA_ARGS__) - -} // namespace - TEST_F(QualifierFixerTest, RotateTokens) { // TODO add test EXPECT_EQ(LeftRightQualifierAlignmentFixer::getTokenFromQualifier("const"), @@ -974,5 +889,7 @@ TEST_F(QualifierFixerTest, TemplatesLeft) { "TemplateType t;", Style); } +} // namespace +} // namespace test } // namespace format } // namespace clang