//===- unittest/Format/FormatTestSelective.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 "FormatTestUtils.h" #include "clang/Format/Format.h" #include "llvm/Support/Debug.h" #include "gtest/gtest.h" #define DEBUG_TYPE "format-test" namespace clang { namespace format { namespace { class FormatTestSelective : public ::testing::Test { protected: std::string format(llvm::StringRef Code, unsigned Offset, unsigned Length) { LLVM_DEBUG(llvm::errs() << "---\n"); LLVM_DEBUG(llvm::errs() << Code << "\n\n"); std::vector Ranges(1, tooling::Range(Offset, Length)); FormattingAttemptStatus Status; tooling::Replacements Replaces = reformat(Style, Code, Ranges, "", &Status); EXPECT_TRUE(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; } FormatStyle Style = getLLVMStyle(); }; TEST_F(FormatTestSelective, RemovesTrailingWhitespaceOfFormattedLine) { EXPECT_EQ("int a;\nint b;", format("int a; \nint b;", 0, 0)); EXPECT_EQ("int a;", format("int a; ", 0, 0)); EXPECT_EQ("int a;\n", format("int a; \n \n \n ", 0, 0)); EXPECT_EQ("int a;\nint b; ", format("int a; \nint b; ", 0, 0)); } TEST_F(FormatTestSelective, FormatsCorrectRegionForLeadingWhitespace) { EXPECT_EQ("{int b;\n" " int a;\n" "}", format("{int b;\n int a;}", 8, 0)); EXPECT_EQ("{\n" " int b;\n" " int a;}", format("{int b;\n int a;}", 7, 0)); Style.ColumnLimit = 12; EXPECT_EQ("#define A \\\n" " int a; \\\n" " int b;", format("#define A \\\n" " int a; \\\n" " int b;", 26, 0)); EXPECT_EQ("#define A \\\n" " int a; \\\n" " int b;", format("#define A \\\n" " int a; \\\n" " int b;", 25, 0)); } TEST_F(FormatTestSelective, FormatLineWhenInvokedOnTrailingNewline) { EXPECT_EQ("int b;\n\nint a;", format("int b;\n\nint a;", 8, 0)); EXPECT_EQ("int b;\n\nint a;", format("int b;\n\nint a;", 7, 0)); // This might not strictly be correct, but is likely good in all practical // cases. EXPECT_EQ("int b;\nint a;", format("int b;int a;", 7, 0)); } TEST_F(FormatTestSelective, RemovesWhitespaceWhenTriggeredOnEmptyLine) { EXPECT_EQ("int a;\n\n int b;", format("int a;\n \n\n int b;", 8, 0)); EXPECT_EQ("int a;\n\n int b;", format("int a;\n \n\n int b;", 9, 0)); } TEST_F(FormatTestSelective, ReformatsMovedLines) { EXPECT_EQ( "template T *getFETokenInfo() const {\n" " return static_cast(FETokenInfo);\n" "}\n" "int a; // <- Should not be formatted", format( "template\n" "T *getFETokenInfo() const { return static_cast(FETokenInfo); }\n" "int a; // <- Should not be formatted", 9, 5)); } TEST_F(FormatTestSelective, FormatsIfWithoutCompoundStatement) { Style.AllowShortIfStatementsOnASingleLine = FormatStyle::SIS_WithoutElse; EXPECT_EQ("if (a) return;", format("if(a)\nreturn;", 7, 1)); EXPECT_EQ("if (a) return; // comment", format("if(a)\nreturn; // comment", 20, 1)); } TEST_F(FormatTestSelective, FormatsCommentsLocally) { EXPECT_EQ("int a; // comment\n" "int b; // comment", format("int a; // comment\n" "int b; // comment", 0, 0)); EXPECT_EQ("int a; // comment\n" " // line 2\n" "int b;", format("int a; // comment\n" " // line 2\n" "int b;", 28, 0)); EXPECT_EQ("int a; // comment\n" "// comment 2\n" "int b;", format("int a; // comment\n" "// comment 2\n" "int b;", 28, 0)); EXPECT_EQ("int aaaaaa; // comment\n" "int b;\n" "int c; // unrelated comment", format("int aaaaaa; // comment\n" "int b;\n" "int c; // unrelated comment", 31, 0)); EXPECT_EQ("int a; // This\n" " // is\n" " // a", format("int a; // This\n" " // is\n" " // a", 0, 0)); EXPECT_EQ("int a; // This\n" " // is\n" " // a\n" "// This is b\n" "int b;", format("int a; // This\n" " // is\n" " // a\n" "// This is b\n" "int b;", 0, 0)); EXPECT_EQ("int a; // This\n" " // is\n" " // a\n" "\n" "//This is unrelated", format("int a; // This\n" " // is\n" " // a\n" "\n" "//This is unrelated", 0, 0)); EXPECT_EQ("int a;\n" "// This is\n" "// not formatted. ", format("int a;\n" "// This is\n" "// not formatted. ", 0, 0)); EXPECT_EQ("int x; // Format this line.\n" "int xx; //\n" "int xxxxx; //", format("int x; // Format this line.\n" "int xx; //\n" "int xxxxx; //", 0, 0)); } TEST_F(FormatTestSelective, ContinueReindenting) { // When we change an indent, we continue formatting as long as following // lines are not indented correctly. EXPECT_EQ("int i;\n" "int b;\n" "int c;\n" "int d;\n" "int e;\n" " int f;\n", format("int i;\n" " int b;\n" " int c;\n" " int d;\n" "int e;\n" " int f;\n", 11, 0)); } TEST_F(FormatTestSelective, ReindentClosingBrace) { EXPECT_EQ("int i;\n" "int f() {\n" " int a;\n" " int b;\n" "}\n" " int c;\n", format("int i;\n" " int f(){\n" "int a;\n" "int b;\n" " }\n" " int c;\n", 11, 0)); EXPECT_EQ("void f() {\n" " if (foo) {\n" " b();\n" " } else {\n" " c();\n" " }\n" "int d;\n" "}\n", format("void f() {\n" " if (foo) {\n" "b();\n" "}else{\n" "c();\n" "}\n" "int d;\n" "}\n", 13, 0)); EXPECT_EQ("int i = []() {\n" " class C {\n" " int a;\n" " int b;\n" " };\n" " int c;\n" "};\n", format("int i = []() {\n" " class C{\n" "int a;\n" "int b;\n" "};\n" "int c;\n" " };\n", 17, 0)); } TEST_F(FormatTestSelective, IndividualStatementsOfNestedBlocks) { EXPECT_EQ("DEBUG({\n" " int i;\n" " int j;\n" "});", format("DEBUG( {\n" " int i;\n" " int j;\n" "} ) ;", 20, 1)); EXPECT_EQ("DEBUG( {\n" " int i;\n" " int j;\n" "} ) ;", format("DEBUG( {\n" " int i;\n" " int j;\n" "} ) ;", 41, 1)); EXPECT_EQ("DEBUG( {\n" " int i;\n" " int j;\n" "} ) ;", format("DEBUG( {\n" " int i;\n" " int j;\n" "} ) ;", 41, 1)); EXPECT_EQ("DEBUG({\n" " int i;\n" " int j;\n" "});", format("DEBUG( {\n" " int i;\n" " int j;\n" "} ) ;", 20, 1)); EXPECT_EQ("Debug({\n" " if (aaaaaaaaaaaaaaaaaaaaaaaa)\n" " return;\n" " },\n" " a);", format("Debug({\n" " if (aaaaaaaaaaaaaaaaaaaaaaaa)\n" " return;\n" " },\n" " a);", 50, 1)); EXPECT_EQ("DEBUG({\n" " DEBUG({\n" " int a;\n" " int b;\n" " }) ;\n" "});", format("DEBUG({\n" " DEBUG({\n" " int a;\n" " int b;\n" // Format this line only. " }) ;\n" // Don't touch this line. "});", 35, 0)); EXPECT_EQ("DEBUG({\n" " int a; //\n" "});", format("DEBUG({\n" " int a; //\n" "});", 0, 0)); EXPECT_EQ("someFunction(\n" " [] {\n" " // Only with this comment.\n" " int i; // invoke formatting here.\n" " }, // force line break\n" " aaa);", format("someFunction(\n" " [] {\n" " // Only with this comment.\n" " int i; // invoke formatting here.\n" " }, // force line break\n" " aaa);", 63, 1)); EXPECT_EQ("int longlongname; // comment\n" "int x = f({\n" " int x; // comment\n" " int y; // comment\n" "});", format("int longlongname; // comment\n" "int x = f({\n" " int x; // comment\n" " int y; // comment\n" "});", 65, 0)); EXPECT_EQ("int s = f({\n" " class X {\n" " public:\n" " void f();\n" " };\n" "});", format("int s = f({\n" " class X {\n" " public:\n" " void f();\n" " };\n" "});", 0, 0)); EXPECT_EQ("SomeFunction(\n" " [] {\n" " int i;\n" " return i;\n" // Format this line. " },\n" " [] {\n" " return 2;\n" // Don't fix this. " });", format("SomeFunction(\n" " [] {\n" " int i;\n" " return i;\n" // Format this line. " },\n" " [] {\n" " return 2;\n" // Don't fix this. " });", 40, 0)); } TEST_F(FormatTestSelective, WrongIndent) { EXPECT_EQ("namespace {\n" "int i;\n" "int j;\n" "}", format("namespace {\n" " int i;\n" // Format here. " int j;\n" "}", 15, 0)); EXPECT_EQ("namespace {\n" " int i;\n" " int j;\n" "}", format("namespace {\n" " int i;\n" " int j;\n" // Format here. "}", 24, 0)); } TEST_F(FormatTestSelective, AlwaysFormatsEntireMacroDefinitions) { Style.AlignEscapedNewlines = FormatStyle::ENAS_Left; EXPECT_EQ("int i;\n" "#define A \\\n" " int i; \\\n" " int j\n" "int k;", format("int i;\n" "#define A \\\n" " int i ; \\\n" " int j\n" "int k;", 8, 0)); // 8: position of "#define". EXPECT_EQ("int i;\n" "#define A \\\n" " int i; \\\n" " int j\n" "int k;", format("int i;\n" "#define A \\\n" " int i ; \\\n" " int j\n" "int k;", 45, 0)); // 45: position of "j". } TEST_F(FormatTestSelective, ReformatRegionAdjustsIndent) { EXPECT_EQ("{\n" "{\n" "a;\n" "b;\n" "}\n" "}", format("{\n" "{\n" "a;\n" " b;\n" "}\n" "}", 13, 2)); EXPECT_EQ("{\n" "{\n" " a;\n" " b;\n" " c;\n" " d;\n" "}\n" "}", format("{\n" "{\n" " a;\n" " b;\n" " c;\n" " d;\n" "}\n" "}", 9, 2)); EXPECT_EQ("{\n" "{\n" "public:\n" " b;\n" "}\n" "}", format("{\n" "{\n" "public:\n" " b;\n" "}\n" "}", 17, 2)); EXPECT_EQ("{\n" "{\n" "a;\n" "}\n" "{\n" " b; //\n" "}\n" "}", format("{\n" "{\n" "a;\n" "}\n" "{\n" " b; //\n" "}\n" "}", 22, 2)); EXPECT_EQ(" {\n" " a; //\n" " }", format(" {\n" "a; //\n" " }", 4, 2)); EXPECT_EQ("void f() {}\n" "void g() {}", format("void f() {}\n" "void g() {}", 13, 0)); EXPECT_EQ("int a; // comment\n" " // line 2\n" "int b;", format("int a; // comment\n" " // line 2\n" " int b;", 35, 0)); EXPECT_EQ(" void f() {\n" "#define A 1\n" " }", format(" void f() {\n" " #define A 1\n" // Format this line. " }", 20, 0)); EXPECT_EQ(" void f() {\n" " int i;\n" "#define A \\\n" " int i; \\\n" " int j;\n" " int k;\n" " }", format(" void f() {\n" " int i;\n" "#define A \\\n" " int i; \\\n" " int j;\n" " int k;\n" // Format this line. " }", 67, 0)); Style.ColumnLimit = 11; EXPECT_EQ(" int a;\n" " void\n" " ffffff() {\n" " }", format(" int a;\n" "void ffffff() {}", 11, 0)); } TEST_F(FormatTestSelective, UnderstandsTabs) { Style.IndentWidth = 8; Style.UseTab = FormatStyle::UT_Always; Style.AlignEscapedNewlines = FormatStyle::ENAS_Left; EXPECT_EQ("void f() {\n" "\tf();\n" "\tg();\n" "}", format("void f() {\n" "\tf();\n" "\tg();\n" "}", 0, 0)); EXPECT_EQ("void f() {\n" "\tf();\n" "\tg();\n" "}", format("void f() {\n" "\tf();\n" "\tg();\n" "}", 16, 0)); EXPECT_EQ("void f() {\n" " \tf();\n" "\tg();\n" "}", format("void f() {\n" " \tf();\n" " \tg();\n" "}", 21, 0)); } TEST_F(FormatTestSelective, StopFormattingWhenLeavingScope) { EXPECT_EQ( "void f() {\n" " if (a) {\n" " g();\n" " h();\n" " }\n" "\n" "void g() {\n" "}", format("void f() {\n" " if (a) {\n" // Assume this was added without the closing brace. " g();\n" " h();\n" "}\n" "\n" "void g() {\n" // Make sure not to format this. "}", 15, 0)); } TEST_F(FormatTestSelective, SelectivelyRequoteJavaScript) { Style = getGoogleStyle(FormatStyle::LK_JavaScript); EXPECT_EQ( "var x = \"a\";\n" "var x = 'a';\n" "var x = \"a\";", format("var x = \"a\";\n" "var x = \"a\";\n" "var x = \"a\";", 20, 0)); } TEST_F(FormatTestSelective, KeepsIndentAfterCommentSectionImport) { std::string Code = "#include // line 1\n" // 23 chars long " // line 2\n" // 23 chars long "\n" // this newline is char 47 "int i;"; // this line is not indented EXPECT_EQ(Code, format(Code, 47, 1)); } } // end namespace } // end namespace format } // end namespace clang