diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2017-07-13 19:25:38 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2017-07-13 19:25:38 +0000 |
commit | 8746d127c04f5bbaf6c6e88cef8606ca5a6a54e9 (patch) | |
tree | 84c9d77f8c764f04bcef0b1da4eedfa233d67a46 /unittests/Format | |
parent | cf1b401909b5e54edfd80656b1a18eaa31f9f6f1 (diff) |
Notes
Diffstat (limited to 'unittests/Format')
-rw-r--r-- | unittests/Format/CMakeLists.txt | 1 | ||||
-rw-r--r-- | unittests/Format/FormatTest.cpp | 25 | ||||
-rw-r--r-- | unittests/Format/FormatTestComments.cpp | 64 | ||||
-rw-r--r-- | unittests/Format/FormatTestJS.cpp | 9 | ||||
-rw-r--r-- | unittests/Format/FormatTestProto.cpp | 20 | ||||
-rw-r--r-- | unittests/Format/FormatTestTextProto.cpp | 250 |
6 files changed, 358 insertions, 11 deletions
diff --git a/unittests/Format/CMakeLists.txt b/unittests/Format/CMakeLists.txt index 5c04ba1143c6f..fa7e32c33d9ff 100644 --- a/unittests/Format/CMakeLists.txt +++ b/unittests/Format/CMakeLists.txt @@ -11,6 +11,7 @@ add_clang_unittest(FormatTests FormatTestObjC.cpp FormatTestProto.cpp FormatTestSelective.cpp + FormatTestTextProto.cpp NamespaceEndCommentsFixerTest.cpp SortImportsTestJS.cpp SortIncludesTest.cpp diff --git a/unittests/Format/FormatTest.cpp b/unittests/Format/FormatTest.cpp index b5f959f9c1f7d..937362f5c9d79 100644 --- a/unittests/Format/FormatTest.cpp +++ b/unittests/Format/FormatTest.cpp @@ -825,12 +825,35 @@ TEST_F(FormatTest, FormatsSwitchStatement) { " case A:\n" " f();\n" " break;\n" - " // On B:\n" + " // fallthrough\n" " case B:\n" " g();\n" " break;\n" " }\n" "});"); + EXPECT_EQ("DEBUG({\n" + " switch (x) {\n" + " case A:\n" + " f();\n" + " break;\n" + " // On B:\n" + " case B:\n" + " g();\n" + " break;\n" + " }\n" + "});", + format("DEBUG({\n" + " switch (x) {\n" + " case A:\n" + " f();\n" + " break;\n" + " // On B:\n" + " case B:\n" + " g();\n" + " break;\n" + " }\n" + "});", + getLLVMStyle())); verifyFormat("switch (a) {\n" "case (b):\n" " return;\n" diff --git a/unittests/Format/FormatTestComments.cpp b/unittests/Format/FormatTestComments.cpp index fdb5a08e7a219..7916e65e51149 100644 --- a/unittests/Format/FormatTestComments.cpp +++ b/unittests/Format/FormatTestComments.cpp @@ -805,6 +805,70 @@ TEST_F(FormatTestComments, ParsesCommentsAdjacentToPPDirectives) { format("namespace {}\n /* Test */ #define A")); } +TEST_F(FormatTestComments, KeepsLevelOfCommentBeforePPDirective) { + // Keep the current level if the comment was originally not aligned with + // the preprocessor directive. + EXPECT_EQ("void f() {\n" + " int i;\n" + " /* comment */\n" + "#ifdef A\n" + " int j;\n" + "}", + format("void f() {\n" + " int i;\n" + " /* comment */\n" + "#ifdef A\n" + " int j;\n" + "}")); + + EXPECT_EQ("void f() {\n" + " int i;\n" + " /* comment */\n" + "\n" + "#ifdef A\n" + " int j;\n" + "}", + format("void f() {\n" + " int i;\n" + " /* comment */\n" + "\n" + "#ifdef A\n" + " int j;\n" + "}")); + + // Keep the current level if there is an empty line between the comment and + // the preprocessor directive. + EXPECT_EQ("void f() {\n" + " int i;\n" + " /* comment */\n" + "\n" + "#ifdef A\n" + " int j;\n" + "}", + format("void f() {\n" + " int i;\n" + "/* comment */\n" + "\n" + "#ifdef A\n" + " int j;\n" + "}")); + + // Align with the preprocessor directive if the comment was originally aligned + // with the preprocessor directive. + EXPECT_EQ("void f() {\n" + " int i;\n" + "/* comment */\n" + "#ifdef A\n" + " int j;\n" + "}", + format("void f() {\n" + " int i;\n" + "/* comment */\n" + "#ifdef A\n" + " int j;\n" + "}")); +} + TEST_F(FormatTestComments, SplitsLongLinesInComments) { EXPECT_EQ("/* This is a long\n" " * comment that\n" diff --git a/unittests/Format/FormatTestJS.cpp b/unittests/Format/FormatTestJS.cpp index e84f470687ec6..11e386a1c7c7d 100644 --- a/unittests/Format/FormatTestJS.cpp +++ b/unittests/Format/FormatTestJS.cpp @@ -930,6 +930,14 @@ TEST_F(FormatTestJS, WrapRespectsAutomaticSemicolonInsertion) { " aaa\n" "];", getGoogleJSStyleWithColumns(12)); + verifyFormat("class X {\n" + " readonly ratherLongField =\n" + " 1;\n" + "}", + "class X {\n" + " readonly ratherLongField = 1;\n" + "}", + getGoogleJSStyleWithColumns(20)); } TEST_F(FormatTestJS, AutomaticSemicolonInsertionHeuristic) { @@ -1622,6 +1630,7 @@ TEST_F(FormatTestJS, NestedTemplateStrings) { TEST_F(FormatTestJS, TaggedTemplateStrings) { verifyFormat("var x = html`<ul>`;"); + verifyFormat("yield `hello`;"); } TEST_F(FormatTestJS, CastSyntax) { diff --git a/unittests/Format/FormatTestProto.cpp b/unittests/Format/FormatTestProto.cpp index 2e3b9311d12c6..639da87c6ea99 100644 --- a/unittests/Format/FormatTestProto.cpp +++ b/unittests/Format/FormatTestProto.cpp @@ -199,11 +199,11 @@ TEST_F(FormatTestProto, FormatsOptions) { "};"); verifyFormat("option (MyProto.options) = {\n" " field_c: \"OK\"\n" - " msg_field{field_d: 123}\n" + " msg_field {field_d: 123}\n" "};"); verifyFormat("option (MyProto.options) = {\n" " field_a: OK\n" - " field_b{field_c: OK}\n" + " field_b {field_c: OK}\n" " field_d: OKOKOK\n" " field_e: OK\n" "}"); @@ -216,7 +216,7 @@ TEST_F(FormatTestProto, FormatsOptions) { verifyFormat("option (MyProto.options) = {\n" " field_a: OK\n" - " field_b<field_c: OK>\n" + " field_b <field_c: OK>\n" " field_d: OKOKOK\n" " field_e: OK\n" "}"); @@ -255,7 +255,7 @@ TEST_F(FormatTestProto, FormatsOptions) { verifyFormat("option (MyProto.options) = <\n" " field_a: \"OK\"\n" - " msg_field<\n" + " msg_field <\n" " field_b: OK\n" " field_c: OK\n" " field_d: OK\n" @@ -267,7 +267,7 @@ TEST_F(FormatTestProto, FormatsOptions) { verifyFormat("option (MyProto.options) = <\n" " field_a: \"OK\"\n" - " msg_field<\n" + " msg_field <\n" " field_b: OK,\n" " field_c: OK,\n" " field_d: OK,\n" @@ -303,7 +303,7 @@ TEST_F(FormatTestProto, FormatsOptions) { verifyFormat("option (MyProto.options) = <\n" " field_a: \"OK\"\n" - " msg_field{\n" + " msg_field {\n" " field_b: OK\n" " field_c: OK\n" " field_d: OK\n" @@ -315,7 +315,7 @@ TEST_F(FormatTestProto, FormatsOptions) { verifyFormat("option (MyProto.options) = {\n" " field_a: \"OK\"\n" - " msg_field<\n" + " msg_field <\n" " field_b: OK\n" " field_c: OK\n" " field_d: OK\n" @@ -339,18 +339,18 @@ TEST_F(FormatTestProto, FormatsOptions) { verifyFormat("option (MyProto.options) = <\n" " field_a: \"OK\"\n" - " msg_field{\n" + " msg_field {\n" " field_b: OK\n" " field_c: OK\n" " field_d: OK\n" - " msg_field<\n" + " msg_field <\n" " field_A: 1\n" " field_B: 2\n" " field_C: 3\n" " field_D: 4\n" " field_E: 5\n" " >\n" - " msg_field<field_A: 1 field_B: 2 field_C: 3 field_D: 4>\n" + " msg_field <field_A: 1 field_B: 2 field_C: 3 field_D: 4>\n" " field_e: OK\n" " field_f: OK\n" " }\n" diff --git a/unittests/Format/FormatTestTextProto.cpp b/unittests/Format/FormatTestTextProto.cpp new file mode 100644 index 0000000000000..2de7e181f2cb8 --- /dev/null +++ b/unittests/Format/FormatTestTextProto.cpp @@ -0,0 +1,250 @@ +//===- unittest/Format/FormatTestProto.cpp --------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#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 { + +class FormatTestTextProto : public ::testing::Test { +protected: + static std::string format(llvm::StringRef Code, unsigned Offset, + unsigned Length, const FormatStyle &Style) { + DEBUG(llvm::errs() << "---\n"); + DEBUG(llvm::errs() << Code << "\n\n"); + std::vector<tooling::Range> Ranges(1, tooling::Range(Offset, Length)); + tooling::Replacements Replaces = reformat(Style, Code, Ranges); + auto Result = applyAllReplacements(Code, Replaces); + EXPECT_TRUE(static_cast<bool>(Result)); + DEBUG(llvm::errs() << "\n" << *Result << "\n\n"); + return *Result; + } + + static std::string format(llvm::StringRef Code) { + FormatStyle Style = getGoogleStyle(FormatStyle::LK_TextProto); + Style.ColumnLimit = 60; // To make writing tests easier. + return format(Code, 0, Code.size(), Style); + } + + static void verifyFormat(llvm::StringRef Code) { + EXPECT_EQ(Code.str(), format(test::messUp(Code))); + } +}; + +TEST_F(FormatTestTextProto, KeepsTopLevelEntriesFittingALine) { + verifyFormat("field_a: OK field_b: OK field_c: OK field_d: OK field_e: OK"); +} + +TEST_F(FormatTestTextProto, SupportsMessageFields) { + verifyFormat("msg_field: {}"); + + verifyFormat("msg_field: {field_a: A}"); + + verifyFormat("msg_field: {field_a: \"OK\" field_b: 123}"); + + verifyFormat("msg_field: {\n" + " field_a: 1\n" + " field_b: OK\n" + " field_c: \"OK\"\n" + " field_d: 123\n" + " field_e: 23\n" + "}"); + + verifyFormat("msg_field {}"); + + verifyFormat("msg_field {field_a: A}"); + + verifyFormat("msg_field {field_a: \"OK\" field_b: 123}"); + + verifyFormat("msg_field {\n" + " field_a: 1\n" + " field_b: OK\n" + " field_c: \"OK\"\n" + " field_d: 123\n" + " field_e: 23.0\n" + " field_f: false\n" + " field_g: 'lala'\n" + " field_h: 1234.567e-89\n" + "}"); + + verifyFormat("msg_field: {msg_field {field_a: 1}}"); + + verifyFormat("id: \"ala.bala\"\n" + "item {type: ITEM_A rank: 1 score: 90.0}\n" + "item {type: ITEM_B rank: 2 score: 70.5}\n" + "item {\n" + " type: ITEM_A\n" + " rank: 3\n" + " score: 20.0\n" + " description: \"the third item has a description\"\n" + "}"); +} + +TEST_F(FormatTestTextProto, AvoidsTopLevelBinPacking) { + verifyFormat("field_a: OK\n" + "field_b: OK\n" + "field_c: OK\n" + "field_d: OK\n" + "field_e: OK\n" + "field_f: OK"); + + verifyFormat("field_a: OK\n" + "field_b: \"OK\"\n" + "field_c: \"OK\"\n" + "msg_field: {field_d: 123}\n" + "field_e: OK\n" + "field_f: OK"); + + verifyFormat("field_a: OK\n" + "field_b: \"OK\"\n" + "field_c: \"OK\"\n" + "msg_field: {field_d: 123 field_e: OK}"); + + verifyFormat("a: {\n" + " field_a: OK\n" + " field_b {field_c: OK}\n" + " field_d: OKOKOK\n" + " field_e: OK\n" + "}"); + + verifyFormat("field_a: OK,\n" + "field_b {field_c: OK},\n" + "field_d: OKOKOK,\n" + "field_e: OK"); +} + +TEST_F(FormatTestTextProto, AddsNewlinesAfterTrailingComments) { + verifyFormat("field_a: OK // Comment\n" + "field_b: 1"); + + verifyFormat("field_a: OK\n" + "msg_field: {\n" + " field_b: OK // Comment\n" + "}"); + + verifyFormat("field_a: OK\n" + "msg_field {\n" + " field_b: OK // Comment\n" + "}"); +} + +TEST_F(FormatTestTextProto, SupportsAngleBracketMessageFields) { + // Single-line tests + verifyFormat("msg_field <>"); + verifyFormat("msg_field: <>"); + verifyFormat("msg_field <field_a: OK>"); + verifyFormat("msg_field: <field_a: 123>"); + verifyFormat("msg_field <field_a <>>"); + verifyFormat("msg_field <field_a <field_b <>>>"); + verifyFormat("msg_field: <field_a <field_b: <>>>"); + verifyFormat("msg_field <field_a: OK, field_b: \"OK\">"); + verifyFormat("msg_field <field_a: OK field_b: <>, field_c: OK>"); + verifyFormat("msg_field <field_a {field_b: 1}, field_c: <field_d: 2>>"); + verifyFormat("msg_field: <field_a: OK, field_b: \"OK\">"); + verifyFormat("msg_field: <field_a: OK field_b: <>, field_c: OK>"); + verifyFormat("msg_field: <field_a {field_b: 1}, field_c: <field_d: 2>>"); + verifyFormat("field_a: \"OK\", msg_field: <field_b: 123>, field_c: {}"); + verifyFormat("field_a <field_b: 1>, msg_field: <field_b: 123>, field_c <>"); + verifyFormat("field_a <field_b: 1> msg_field: <field_b: 123> field_c <>"); + verifyFormat("field <field <field: <>>, field <>> field: <field: 1>"); + + // Multiple lines tests + verifyFormat("msg_field <\n" + " field_a: OK\n" + " field_b: \"OK\"\n" + " field_c: 1\n" + " field_d: 12.5\n" + " field_e: OK\n" + ">"); + + verifyFormat("msg_field: <>\n" + "field_c: \"OK\",\n" + "msg_field: <field_d: 123>\n" + "field_e: OK\n" + "msg_field: <field_d: 12>"); + + verifyFormat("field_a: OK,\n" + "field_b <field_c: OK>,\n" + "field_d: <12.5>,\n" + "field_e: OK"); + + verifyFormat("field_a: OK\n" + "field_b <field_c: OK>\n" + "field_d: <12.5>\n" + "field_e: OKOKOK"); + + verifyFormat("msg_field <\n" + " field_a: OK,\n" + " field_b <field_c: OK>,\n" + " field_d: <12.5>,\n" + " field_e: OK\n" + ">"); + + verifyFormat("msg_field <\n" + " field_a: <field: OK>,\n" + " field_b <field_c: OK>,\n" + " field_d: <12.5>,\n" + " field_e: OK,\n" + ">"); + + verifyFormat("msg_field: <\n" + " field_a: \"OK\"\n" + " msg_field: {field_b: OK}\n" + " field_g: OK\n" + " field_g: OK\n" + " field_g: OK\n" + ">"); + + verifyFormat("field_a {\n" + " field_d: ok\n" + " field_b: <field_c: 1>\n" + " field_d: ok\n" + " field_d: ok\n" + "}"); + + verifyFormat("field_a: {\n" + " field_d: ok\n" + " field_b: <field_c: 1>\n" + " field_d: ok\n" + " field_d: ok\n" + "}"); + + verifyFormat("field_a: <f1: 1, f2: <>>\n" + "field_b <\n" + " field_b1: <>\n" + " field_b2: ok,\n" + " field_b3: <\n" + " field_x {} // Comment\n" + " field_y: {field_z: 1}\n" + " field_w: ok\n" + " >\n" + " field {\n" + " field_x <> // Comment\n" + " field_y: <field_z: 1>\n" + " field_w: ok\n" + " msg_field: <\n" + " field: <>\n" + " field: <field: 1>\n" + " field: <field: 2>\n" + " field: <field: 3>\n" + " field: <field: 4>\n" + " field: ok\n" + " >\n" + " }\n" + ">\n" + "field: OK,\n" + "field_c <field <field <>>>"); +} +} // end namespace tooling +} // end namespace clang |