summaryrefslogtreecommitdiff
path: root/unittests/Format
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2017-07-13 19:25:38 +0000
committerDimitry Andric <dim@FreeBSD.org>2017-07-13 19:25:38 +0000
commit8746d127c04f5bbaf6c6e88cef8606ca5a6a54e9 (patch)
tree84c9d77f8c764f04bcef0b1da4eedfa233d67a46 /unittests/Format
parentcf1b401909b5e54edfd80656b1a18eaa31f9f6f1 (diff)
Notes
Diffstat (limited to 'unittests/Format')
-rw-r--r--unittests/Format/CMakeLists.txt1
-rw-r--r--unittests/Format/FormatTest.cpp25
-rw-r--r--unittests/Format/FormatTestComments.cpp64
-rw-r--r--unittests/Format/FormatTestJS.cpp9
-rw-r--r--unittests/Format/FormatTestProto.cpp20
-rw-r--r--unittests/Format/FormatTestTextProto.cpp250
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