summaryrefslogtreecommitdiffstats
path: root/unittests
diff options
context:
space:
mode:
authorKrasimir Georgiev <krasimir@google.com>2017-10-30 14:01:50 +0000
committerKrasimir Georgiev <krasimir@google.com>2017-10-30 14:01:50 +0000
commitbd3b05d2cc22423f7eb44ff6bf948b44cc605309 (patch)
tree9ad996068e7388a2cdb3db0bb9a17beb559813ef /unittests
parent1157fbd7d668f9579b5a633dd245657bb940076b (diff)
[clang-format] Format raw string literals
Summary: This patch adds raw string literal formatting. Reviewers: djasper, klimek Reviewed By: klimek Subscribers: klimek, mgorny Differential Revision: https://reviews.llvm.org/D35943 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@316903 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'unittests')
-rw-r--r--unittests/Format/CMakeLists.txt1
-rw-r--r--unittests/Format/FormatTest.cpp14
-rw-r--r--unittests/Format/FormatTestRawStrings.cpp733
3 files changed, 748 insertions, 0 deletions
diff --git a/unittests/Format/CMakeLists.txt b/unittests/Format/CMakeLists.txt
index fa7e32c33d..992db0e508 100644
--- a/unittests/Format/CMakeLists.txt
+++ b/unittests/Format/CMakeLists.txt
@@ -10,6 +10,7 @@ add_clang_unittest(FormatTests
FormatTestJava.cpp
FormatTestObjC.cpp
FormatTestProto.cpp
+ FormatTestRawStrings.cpp
FormatTestSelective.cpp
FormatTestTextProto.cpp
NamespaceEndCommentsFixerTest.cpp
diff --git a/unittests/Format/FormatTest.cpp b/unittests/Format/FormatTest.cpp
index dadc0254c6..3651fa539d 100644
--- a/unittests/Format/FormatTest.cpp
+++ b/unittests/Format/FormatTest.cpp
@@ -10254,6 +10254,20 @@ TEST_F(FormatTest, ParsesConfiguration) {
" Priority: 1",
IncludeCategories, ExpectedCategories);
CHECK_PARSE("IncludeIsMainRegex: 'abc$'", IncludeIsMainRegex, "abc$");
+
+ Style.RawStringFormats.clear();
+ std::vector<FormatStyle::RawStringFormat> ExpectedRawStringFormats = {
+ {"pb", FormatStyle::LK_TextProto, "llvm"},
+ {"cpp", FormatStyle::LK_Cpp, "google"}};
+
+ CHECK_PARSE("RawStringFormats:\n"
+ " - Delimiter: 'pb'\n"
+ " Language: TextProto\n"
+ " BasedOnStyle: llvm\n"
+ " - Delimiter: 'cpp'\n"
+ " Language: Cpp\n"
+ " BasedOnStyle: google",
+ RawStringFormats, ExpectedRawStringFormats);
}
TEST_F(FormatTest, ParsesConfigurationWithLanguages) {
diff --git a/unittests/Format/FormatTestRawStrings.cpp b/unittests/Format/FormatTestRawStrings.cpp
new file mode 100644
index 0000000000..6e7b706587
--- /dev/null
+++ b/unittests/Format/FormatTestRawStrings.cpp
@@ -0,0 +1,733 @@
+//===- unittest/Format/FormatTestRawStrings.cpp - Formatting unit tests ---===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Format/Format.h"
+
+#include "../Tooling/ReplacementTest.h"
+#include "FormatTestUtils.h"
+
+#include "clang/Frontend/TextDiagnosticPrinter.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "gtest/gtest.h"
+
+#define DEBUG_TYPE "format-test"
+
+using clang::tooling::ReplacementTest;
+using clang::tooling::toReplacements;
+
+namespace clang {
+namespace format {
+namespace {
+
+class FormatTestRawStrings : 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) {
+ DEBUG(llvm::errs() << "---\n");
+ DEBUG(llvm::errs() << Code << "\n\n");
+ std::vector<tooling::Range> Ranges(1, tooling::Range(0, Code.size()));
+ FormattingAttemptStatus Status;
+ tooling::Replacements Replaces =
+ reformat(Style, Code, Ranges, "<stdin>", &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<bool>(Result));
+ 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);
+ }
+
+ int ReplacementCount;
+
+ FormatStyle getRawStringPbStyleWithColumns(unsigned ColumnLimit) {
+ FormatStyle Style = getLLVMStyle();
+ Style.ColumnLimit = ColumnLimit;
+ Style.RawStringFormats = {{/*Delimiter=*/"pb",
+ /*Kind=*/FormatStyle::LK_TextProto,
+ /*BasedOnStyle=*/"google"}};
+ return Style;
+ }
+
+ FormatStyle getRawStringLLVMCppStyleBasedOn(std::string BasedOnStyle) {
+ FormatStyle Style = getLLVMStyle();
+ Style.RawStringFormats = {{/*Delimiter=*/"cpp",
+ /*Kind=*/FormatStyle::LK_Cpp, BasedOnStyle}};
+ return Style;
+ }
+
+ FormatStyle getRawStringGoogleCppStyleBasedOn(std::string BasedOnStyle) {
+ FormatStyle Style = getGoogleStyle(FormatStyle::LK_Cpp);
+ Style.RawStringFormats = {{/*Delimiter=*/"cpp",
+ /*Kind=*/FormatStyle::LK_Cpp, BasedOnStyle}};
+ return Style;
+ }
+
+ // Gcc 4.8 doesn't support raw string literals in macros, which breaks some
+ // build bots. We use this function instead.
+ void expect_eq(const std::string Expected, const std::string Actual) {
+ EXPECT_EQ(Expected, Actual);
+ }
+};
+
+TEST_F(FormatTestRawStrings, ReformatsAccordingToBaseStyle) {
+ // llvm style puts '*' on the right.
+ // google style puts '*' on the left.
+
+ // Use the llvm style if the raw string style has no BasedOnStyle.
+ expect_eq(R"test(int *i = R"cpp(int *p = nullptr;)cpp")test",
+ format(R"test(int * i = R"cpp(int * p = nullptr;)cpp")test",
+ getRawStringLLVMCppStyleBasedOn("")));
+
+ // Use the google style if the raw string style has BasedOnStyle=google.
+ expect_eq(R"test(int *i = R"cpp(int* p = nullptr;)cpp")test",
+ format(R"test(int * i = R"cpp(int * p = nullptr;)cpp")test",
+ getRawStringLLVMCppStyleBasedOn("google")));
+
+ // Use the llvm style if the raw string style has no BasedOnStyle=llvm.
+ expect_eq(R"test(int* i = R"cpp(int *p = nullptr;)cpp")test",
+ format(R"test(int * i = R"cpp(int * p = nullptr;)cpp")test",
+ getRawStringGoogleCppStyleBasedOn("llvm")));
+}
+
+TEST_F(FormatTestRawStrings, MatchesDelimitersCaseSensitively) {
+ // Don't touch the 'PB' raw string, format the 'pb' raw string.
+ expect_eq(R"test(
+s = R"PB(item:1)PB";
+t = R"pb(item: 1)pb";)test",
+ format(R"test(
+s = R"PB(item:1)PB";
+t = R"pb(item:1)pb";)test",
+ getRawStringPbStyleWithColumns(40)));
+
+ FormatStyle MixedStyle = getLLVMStyle();
+ MixedStyle.RawStringFormats = {
+ {/*Delimiter=*/"cpp", /*Kind=*/FormatStyle::LK_Cpp,
+ /*BasedOnStyle=*/"llvm"},
+ {/*Delimiter=*/"CPP", /*Kind=*/FormatStyle::LK_Cpp,
+ /*BasedOnStyle=*/"google"}};
+
+ // Format the 'cpp' raw string with '*' on the right.
+ // Format the 'CPP' raw string with '*' on the left.
+ // Do not format the 'Cpp' raw string.
+ // Do not format non-raw strings.
+ expect_eq(R"test(
+a = R"cpp(int *i = 0;)cpp";
+b = R"CPP(int* j = 0;)CPP";
+c = R"Cpp(int * k = 0;)Cpp";
+d = R"cpp(int * k = 0;)Cpp";)test",
+ format(R"test(
+a = R"cpp(int * i = 0;)cpp";
+b = R"CPP(int * j = 0;)CPP";
+c = R"Cpp(int * k = 0;)Cpp";
+d = R"cpp(int * k = 0;)Cpp";)test",
+ MixedStyle));
+}
+
+TEST_F(FormatTestRawStrings, ReformatsShortRawStringsOnSingleLine) {
+ expect_eq(
+ R"test(P p = TP(R"pb()pb");)test",
+ format(
+ R"test(P p = TP(R"pb( )pb");)test",
+ getRawStringPbStyleWithColumns(40)));
+ expect_eq(
+ R"test(P p = TP(R"pb(item_1: 1)pb");)test",
+ format(
+ R"test(P p = TP(R"pb(item_1:1)pb");)test",
+ getRawStringPbStyleWithColumns(40)));
+ expect_eq(
+ R"test(P p = TP(R"pb(item_1: 1)pb");)test",
+ format(
+ R"test(P p = TP(R"pb( item_1 : 1 )pb");)test",
+ getRawStringPbStyleWithColumns(40)));
+ expect_eq(
+ R"test(P p = TP(R"pb(item_1: 1 item_2: 2)pb");)test",
+ format(
+ R"test(P p = TP(R"pb(item_1:1 item_2:2)pb");)test",
+ getRawStringPbStyleWithColumns(40)));
+ expect_eq(
+ R"test(P p = TP(R"pb(item_1 <1> item_2: {2})pb");)test",
+ format(
+ R"test(P p = TP(R"pb(item_1<1> item_2:{2})pb");)test",
+ getRawStringPbStyleWithColumns(40)));
+
+ // Merge two short lines into one.
+ expect_eq(R"test(
+std::string s = R"pb(
+ item_1: 1 item_2: 2
+)pb";
+)test",
+ format(R"test(
+std::string s = R"pb(
+ item_1:1
+ item_2:2
+)pb";
+)test",
+ getRawStringPbStyleWithColumns(40)));
+}
+
+TEST_F(FormatTestRawStrings, BreaksRawStringsExceedingColumnLimit) {
+ expect_eq(R"test(
+P p = TPPPPPPPPPPPPPPP(
+ R"pb(item_1: 1, item_2: 2)pb");)test",
+ format(R"test(
+P p = TPPPPPPPPPPPPPPP(R"pb(item_1: 1, item_2: 2)pb");)test",
+ getRawStringPbStyleWithColumns(40)));
+
+ expect_eq(R"test(
+P p =
+ TPPPPPPPPPPPPPPP(
+ R"pb(item_1: 1,
+ item_2: 2,
+ item_3: 3)pb");)test",
+ format(R"test(
+P p = TPPPPPPPPPPPPPPP(R"pb(item_1: 1, item_2: 2, item_3: 3)pb");)test",
+ getRawStringPbStyleWithColumns(40)));
+
+ expect_eq(R"test(
+P p = TP(R"pb(item_1 <1>
+ item_2: <2>
+ item_3 {})pb");)test",
+ format(R"test(
+P p = TP(R"pb(item_1<1> item_2:<2> item_3{ })pb");)test",
+ getRawStringPbStyleWithColumns(40)));
+
+ expect_eq(
+ R"test(
+P p = TP(R"pb(item_1: 1,
+ item_2: 2,
+ item_3: 3,
+ item_4: 4)pb");)test",
+ format(
+ R"test(
+P p = TP(R"pb(item_1: 1, item_2: 2, item_3: 3, item_4: 4)pb");)test",
+ getRawStringPbStyleWithColumns(40)));
+
+ expect_eq(R"test(
+P p = TPPPPPPPPPPPPPPP(
+ R"pb(item_1 <1>,
+ item_2: {2},
+ item_3: <3>,
+ item_4: {4})pb");)test",
+ format(R"test(
+P p = TPPPPPPPPPPPPPPP(R"pb(item_1<1>, item_2: {2}, item_3: <3>, item_4:{4})pb");)test",
+ getRawStringPbStyleWithColumns(40)));
+
+ // Breaks before a short raw string exceeding the column limit.
+ expect_eq(R"test(
+FFFFFFFFFFFFFFFFFFFFFFFFFFF(
+ R"pb(key: 1)pb");
+P p = TPPPPPPPPPPPPPPPPPPPP(
+ R"pb(key: 2)pb");
+auto TPPPPPPPPPPPPPPPPPPPP =
+ R"pb(key: 3)pb";
+P p = TPPPPPPPPPPPPPPPPPPPP(
+ R"pb(i: 1, j: 2)pb");
+
+int f(string s) {
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF(
+ R"pb(key: 1)pb");
+ P p = TPPPPPPPPPPPPPPPPPPPP(
+ R"pb(key: 2)pb");
+ auto TPPPPPPPPPPPPPPPPPPPP =
+ R"pb(key: 3)pb";
+ if (s.empty())
+ P p = TPPPPPPPPPPPPPPPPPPPP(
+ R"pb(i: 1, j: 2)pb");
+}
+)test",
+ format(R"test(
+FFFFFFFFFFFFFFFFFFFFFFFFFFF(R"pb(key:1)pb");
+P p = TPPPPPPPPPPPPPPPPPPPP(R"pb(key:2)pb");
+auto TPPPPPPPPPPPPPPPPPPPP = R"pb(key:3)pb";
+P p = TPPPPPPPPPPPPPPPPPPPP(R"pb(i: 1, j:2)pb");
+
+int f(string s) {
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF(R"pb(key:1)pb");
+ P p = TPPPPPPPPPPPPPPPPPPPP(R"pb(key:2)pb");
+ auto TPPPPPPPPPPPPPPPPPPPP = R"pb(key:3)pb";
+ if (s.empty())
+ P p = TPPPPPPPPPPPPPPPPPPPP(R"pb(i: 1, j:2)pb");
+}
+)test",
+ getRawStringPbStyleWithColumns(40)));
+}
+
+TEST_F(FormatTestRawStrings, FormatsRawStringArguments) {
+ expect_eq(R"test(
+P p = TP(R"pb(key {1})pb", param_2);)test",
+ format(R"test(
+P p = TP(R"pb(key{1})pb",param_2);)test",
+ getRawStringPbStyleWithColumns(40)));
+
+ expect_eq(R"test(
+PPPPPPPPPPPPP(R"pb(keykeyk)pb",
+ param_2);)test",
+ format(R"test(
+PPPPPPPPPPPPP(R"pb(keykeyk)pb", param_2);)test",
+ getRawStringPbStyleWithColumns(40)));
+
+ expect_eq(R"test(
+P p =
+ TP(R"pb(item: {i: 1, s: 's'}
+ item: {i: 2, s: 't'})pb");)test",
+ format(R"test(
+P p = TP(R"pb(item: {i: 1, s: 's'} item: {i: 2, s: 't'})pb");)test",
+ getRawStringPbStyleWithColumns(40)));
+ expect_eq(R"test(
+FFFFFFFFFFFFFFFFFFF(
+ R"pb(key: "value")pb",
+ R"pb(key2: "value")pb");)test",
+ format(R"test(
+FFFFFFFFFFFFFFFFFFF(R"pb(key: "value")pb", R"pb(key2: "value")pb");)test",
+ getRawStringPbStyleWithColumns(40)));
+
+ // Formats the first out of two arguments.
+ expect_eq(R"test(
+FFFFFFFF(R"pb(key: 1)pb", argument2);
+struct S {
+ const s =
+ f(R"pb(key: 1)pb", argument2);
+ void f() {
+ if (gol)
+ return g(R"pb(key: 1)pb",
+ 132789237);
+ return g(R"pb(key: 1)pb", "172893");
+ }
+};)test",
+ format(R"test(
+FFFFFFFF(R"pb(key:1)pb", argument2);
+struct S {
+const s = f(R"pb(key:1)pb", argument2);
+void f() {
+ if (gol)
+ return g(R"pb(key:1)pb", 132789237);
+ return g(R"pb(key:1)pb", "172893");
+}
+};)test",
+ getRawStringPbStyleWithColumns(40)));
+
+ // Formats the second out of two arguments.
+ expect_eq(R"test(
+FFFFFFFF(argument1, R"pb(key: 2)pb");
+struct S {
+ const s =
+ f(argument1, R"pb(key: 2)pb");
+ void f() {
+ if (gol)
+ return g(12784137,
+ R"pb(key: 2)pb");
+ return g(17283122, R"pb(key: 2)pb");
+ }
+};)test",
+ format(R"test(
+FFFFFFFF(argument1, R"pb(key:2)pb");
+struct S {
+const s = f(argument1, R"pb(key:2)pb");
+void f() {
+ if (gol)
+ return g(12784137, R"pb(key:2)pb");
+ return g(17283122, R"pb(key:2)pb");
+}
+};)test",
+ getRawStringPbStyleWithColumns(40)));
+
+ // Formats two short raw string arguments.
+ expect_eq(R"test(
+FFFFF(R"pb(key: 1)pb", R"pb(key: 2)pb");)test",
+ format(R"test(
+FFFFF(R"pb(key:1)pb", R"pb(key:2)pb");)test",
+ getRawStringPbStyleWithColumns(40)));
+ // TODO(krasimir): The original source code fits on one line, so the
+ // non-optimizing formatter is chosen. But after the formatting in protos is
+ // made, the code doesn't fit on one line anymore and further formatting
+ // splits it.
+ //
+ // Should we disable raw string formatting for the non-optimizing formatter?
+ expect_eq(R"test(
+FFFFFFF(R"pb(key: 1)pb", R"pb(key: 2)pb");)test",
+ format(R"test(
+FFFFFFF(R"pb(key:1)pb", R"pb(key:2)pb");)test",
+ getRawStringPbStyleWithColumns(40)));
+
+ // Formats two short raw string arguments, puts second on newline.
+ expect_eq(R"test(
+FFFFFFFF(R"pb(key: 1)pb",
+ R"pb(key: 2)pb");)test",
+ format(R"test(
+FFFFFFFF(R"pb(key:1)pb", R"pb(key:2)pb");)test",
+ getRawStringPbStyleWithColumns(40)));
+
+ // Formats both arguments.
+ expect_eq(R"test(
+FFFFFFFF(R"pb(key: 1)pb",
+ R"pb(key: 2)pb");
+struct S {
+ const s = f(R"pb(key: 1)pb",
+ R"pb(key: 2)pb");
+ void f() {
+ if (gol)
+ return g(R"pb(key: 1)pb",
+ R"pb(key: 2)pb");
+ return g(R"pb(k1)pb", R"pb(k2)pb");
+ }
+};)test",
+ format(R"test(
+FFFFFFFF(R"pb(key:1)pb", R"pb(key:2)pb");
+struct S {
+const s = f(R"pb(key:1)pb", R"pb(key:2)pb");
+void f() {
+ if (gol)
+ return g(R"pb(key:1)pb", R"pb(key:2)pb");
+ return g(R"pb( k1 )pb", R"pb( k2 )pb");
+}
+};)test",
+ getRawStringPbStyleWithColumns(40)));
+}
+
+TEST_F(FormatTestRawStrings, RawStringStartingWithNewlines) {
+ expect_eq(R"test(
+std::string s = R"pb(
+ item_1: 1
+)pb";
+)test",
+ format(R"test(
+std::string s = R"pb(
+ item_1:1
+)pb";
+)test",
+ getRawStringPbStyleWithColumns(40)));
+
+ expect_eq(R"test(
+std::string s = R"pb(
+
+ item_1: 1
+)pb";
+)test",
+ format(R"test(
+std::string s = R"pb(
+
+ item_1:1
+)pb";
+)test",
+ getRawStringPbStyleWithColumns(40)));
+
+ expect_eq(R"test(
+std::string s = R"pb(
+ item_1: 1
+)pb";
+)test",
+ format(R"test(
+std::string s = R"pb(
+ item_1:1
+
+)pb";
+)test",
+ getRawStringPbStyleWithColumns(40)));
+
+ expect_eq(R"test(
+std::string s = R"pb(
+ item_1: 1,
+ item_2: 2
+)pb";
+)test",
+ format(R"test(
+std::string s = R"pb(
+ item_1:1, item_2:2
+)pb";
+)test",
+ getRawStringPbStyleWithColumns(40)));
+
+ expect_eq(R"test(
+std::string s = R"pb(
+ book {
+ title: "Alice's Adventures"
+ author: "Lewis Caroll"
+ }
+ book {
+ title: "Peter Pan"
+ author: "J. M. Barrie"
+ }
+)pb";
+)test",
+ format(R"test(
+std::string s = R"pb(
+ book { title: "Alice's Adventures" author: "Lewis Caroll" }
+ book { title: "Peter Pan" author: "J. M. Barrie" }
+)pb";
+)test",
+ getRawStringPbStyleWithColumns(40)));
+}
+
+TEST_F(FormatTestRawStrings, BreaksBeforeRawStrings) {
+ expect_eq(R"test(
+ASSERT_TRUE(
+ ParseFromString(R"pb(item_1: 1)pb"),
+ ptr);)test",
+ format(R"test(
+ASSERT_TRUE(ParseFromString(R"pb(item_1: 1)pb"), ptr);)test",
+ getRawStringPbStyleWithColumns(40)));
+
+ expect_eq(R"test(
+ASSERT_TRUE(toolong::ParseFromString(
+ R"pb(item_1: 1)pb"),
+ ptr);)test",
+ format(R"test(
+ASSERT_TRUE(toolong::ParseFromString(R"pb(item_1: 1)pb"), ptr);)test",
+ getRawStringPbStyleWithColumns(40)));
+
+ expect_eq(R"test(
+ASSERT_TRUE(ParseFromString(
+ R"pb(item_1: 1,
+ item_2: 2)pb"),
+ ptr);)test",
+ format(R"test(
+ASSERT_TRUE(ParseFromString(R"pb(item_1: 1, item_2: 2)pb"), ptr);)test",
+ getRawStringPbStyleWithColumns(40)));
+
+ expect_eq(R"test(
+ASSERT_TRUE(
+ ParseFromString(
+ R"pb(item_1: 1 item_2: 2)pb"),
+ ptr);)test",
+ format(R"test(
+ASSERT_TRUE(ParseFromString(R"pb(item_1: 1 item_2: 2)pb"), ptr);)test",
+ getRawStringPbStyleWithColumns(40)));
+
+}
+
+TEST_F(FormatTestRawStrings, RawStringsInOperands) {
+ // Formats the raw string first operand of a binary operator expression.
+ expect_eq(R"test(auto S = R"pb(item_1: 1)pb" + rest;)test",
+ format(R"test(auto S = R"pb(item_1:1)pb" + rest;)test",
+ getRawStringPbStyleWithColumns(40)));
+
+ expect_eq(R"test(
+auto S = R"pb(item_1: 1, item_2: 2)pb" +
+ rest;)test",
+ format(R"test(
+auto S = R"pb(item_1:1,item_2:2)pb"+rest;)test",
+ getRawStringPbStyleWithColumns(40)));
+
+ expect_eq(R"test(
+auto S =
+ R"pb(item_1: 1 item_2: 2)pb" + rest;)test",
+ format(R"test(
+auto S = R"pb(item_1:1 item_2:2)pb"+rest;)test",
+ getRawStringPbStyleWithColumns(40)));
+
+ expect_eq(R"test(
+auto S = R"pb(item_1: 1,
+ item_2: 2,
+ item_3: 3)pb" + rest;)test",
+ format(R"test(
+auto S = R"pb(item_1:1,item_2:2,item_3:3)pb"+rest;)test",
+ getRawStringPbStyleWithColumns(40)));
+
+ expect_eq(R"test(
+auto S = R"pb(item_1: 1,
+ item_2: 2,
+ item_3: 3)pb" +
+ longlongrest;)test",
+ format(R"test(
+auto S = R"pb(item_1:1,item_2:2,item_3:3)pb"+longlongrest;)test",
+ getRawStringPbStyleWithColumns(40)));
+
+ // Formats the raw string second operand of a binary operator expression.
+ expect_eq(R"test(auto S = first + R"pb(item_1: 1)pb";)test",
+ format(R"test(auto S = first + R"pb(item_1:1)pb";)test",
+ getRawStringPbStyleWithColumns(40)));
+
+ expect_eq(R"test(
+auto S = first + R"pb(item_1: 1,
+ item_2: 2)pb";)test",
+ format(R"test(
+auto S = first+R"pb(item_1:1,item_2:2)pb";)test",
+ getRawStringPbStyleWithColumns(40)));
+
+ expect_eq(R"test(
+auto S = first + R"pb(item_1: 1
+ item_2: 2)pb";)test",
+ format(R"test(
+auto S = first+R"pb(item_1:1 item_2:2)pb";)test",
+ getRawStringPbStyleWithColumns(40)));
+
+ expect_eq(R"test(
+auto S = R"pb(item_1: 1,
+ item_2: 2,
+ item_3: 3)pb" + rest;)test",
+ format(R"test(
+auto S = R"pb(item_1:1,item_2:2,item_3:3)pb"+rest;)test",
+ getRawStringPbStyleWithColumns(40)));
+
+ expect_eq(R"test(
+auto S = R"pb(item_1: 1,
+ item_2: 2,
+ item_3: 3)pb" +
+ longlongrest;)test",
+ format(R"test(
+auto S = R"pb(item_1:1,item_2:2,item_3:3)pb"+longlongrest;)test",
+ getRawStringPbStyleWithColumns(40)));
+
+ // Formats the raw string operands in expressions.
+ expect_eq(R"test(
+auto S = R"pb(item_1: 1)pb" +
+ R"pb(item_2: 2)pb";
+)test",
+ format(R"test(
+auto S=R"pb(item_1:1)pb"+R"pb(item_2:2)pb";
+)test",
+ getRawStringPbStyleWithColumns(40)));
+
+ expect_eq(R"test(
+auto S = R"pb(item_1: 1)pb" +
+ R"pb(item_2: 2)pb" +
+ R"pb(item_3: 3)pb";
+)test",
+ format(R"test(
+auto S=R"pb(item_1:1)pb"+R"pb(item_2:2)pb"+R"pb(item_3:3)pb";
+)test",
+ getRawStringPbStyleWithColumns(40)));
+
+ expect_eq(R"test(
+auto S = (count < 3)
+ ? R"pb(item_1: 1)pb"
+ : R"pb(item_2: 2)pb";
+)test",
+ format(R"test(
+auto S=(count<3)?R"pb(item_1:1)pb":R"pb(item_2:2)pb";
+)test",
+ getRawStringPbStyleWithColumns(40)));
+
+ expect_eq(R"test(
+auto S =
+ (count < 3)
+ ? R"pb(item_1: 1, item_2: 2)pb"
+ : R"pb(item_3: 3)pb";
+)test",
+ format(R"test(
+auto S=(count<3)?R"pb(item_1:1,item_2:2)pb":R"pb(item_3:3)pb";
+)test",
+ getRawStringPbStyleWithColumns(40)));
+
+ expect_eq(R"test(
+auto S =
+ (count < 3)
+ ? R"pb(item_1: 1)pb"
+ : R"pb(item_2: 2, item_3: 3)pb";
+)test",
+ format(R"test(
+auto S=(count<3)?R"pb(item_1:1)pb":R"pb(item_2:2,item_3:3)pb";
+)test",
+ getRawStringPbStyleWithColumns(40)));
+
+}
+
+TEST_F(FormatTestRawStrings, PrefixAndSuffixAlignment) {
+ // Keep the suffix at the end of line if not on newline.
+ expect_eq(R"test(
+int s() {
+ auto S = PTP(
+ R"pb(
+ item_1: 1,
+ item_2: 2)pb");
+})test",
+ format(R"test(
+int s() {
+ auto S = PTP(
+ R"pb(
+ item_1: 1,
+ item_2: 2)pb");
+})test",
+ getRawStringPbStyleWithColumns(20)));
+
+ // Align the suffix with the surrounding FirstIndent if the prefix is not on
+ // a line of its own.
+ expect_eq(R"test(
+int s() {
+ auto S = PTP(
+ R"pb(
+ item_1: 1,
+ item_2: 2
+ )pb");
+})test",
+ format(R"test(
+int s() {
+ auto S = PTP(R"pb(
+ item_1: 1,
+ item_2: 2
+ )pb");
+})test",
+ getRawStringPbStyleWithColumns(20)));
+
+ // Align the prefix with the suffix if both the prefix and suffix are on a
+ // line of their own.
+ expect_eq(R"test(
+int s() {
+ auto S = PTP(
+ R"pb(
+ item_1: 1,
+ item_2: 2,
+ )pb");
+})test",
+ format(R"test(
+int s() {
+ auto S = PTP(
+ R"pb(
+ item_1: 1,
+ item_2: 2,
+ )pb");
+})test",
+ getRawStringPbStyleWithColumns(20)));
+}
+
+TEST_F(FormatTestRawStrings, EstimatesPenalty) {
+ // The penalty for characters exceeding the column limit in the raw string
+ // forces 'hh' to be put on a newline.
+ expect_eq(R"test(
+ff(gggggg,
+ hh(R"pb(key {
+ i1: k1
+ i2: k2
+ })pb"));
+)test",
+ format(R"test(
+ff(gggggg, hh(R"pb(key {
+ i1: k1
+ i2: k2
+ })pb"));
+)test",
+ getRawStringPbStyleWithColumns(20)));
+}
+
+TEST_F(FormatTestRawStrings, DontFormatNonRawStrings) {
+ expect_eq(R"test(a = R"pb(key:value)";)test",
+ format(R"test(a = R"pb(key:value)";)test",
+ getRawStringPbStyleWithColumns(20)));
+}
+
+} // end namespace
+} // end namespace format
+} // end namespace clang