summaryrefslogtreecommitdiffstats
path: root/gnu/llvm/clang/unittests/Format/FormatTestRawStrings.cpp
diff options
context:
space:
mode:
authorpatrick <patrick@openbsd.org>2020-08-03 14:31:31 +0000
committerpatrick <patrick@openbsd.org>2020-08-03 14:31:31 +0000
commite5dd70708596ae51455a0ffa086a00c5b29f8583 (patch)
tree5d676f27b570bacf71e786c3b5cff3e6f6679b59 /gnu/llvm/clang/unittests/Format/FormatTestRawStrings.cpp
parentImport LLVM 10.0.0 release including clang, lld and lldb. (diff)
downloadwireguard-openbsd-e5dd70708596ae51455a0ffa086a00c5b29f8583.tar.xz
wireguard-openbsd-e5dd70708596ae51455a0ffa086a00c5b29f8583.zip
Import LLVM 10.0.0 release including clang, lld and lldb.
ok hackroom tested by plenty
Diffstat (limited to 'gnu/llvm/clang/unittests/Format/FormatTestRawStrings.cpp')
-rw-r--r--gnu/llvm/clang/unittests/Format/FormatTestRawStrings.cpp1000
1 files changed, 1000 insertions, 0 deletions
diff --git a/gnu/llvm/clang/unittests/Format/FormatTestRawStrings.cpp b/gnu/llvm/clang/unittests/Format/FormatTestRawStrings.cpp
new file mode 100644
index 00000000000..dc2f6b51807
--- /dev/null
+++ b/gnu/llvm/clang/unittests/Format/FormatTestRawStrings.cpp
@@ -0,0 +1,1000 @@
+//===- unittest/Format/FormatTestRawStrings.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 "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) {
+ LLVM_DEBUG(llvm::errs() << "---\n");
+ LLVM_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));
+ 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);
+ }
+
+ int ReplacementCount;
+
+ FormatStyle getRawStringPbStyleWithColumns(unsigned ColumnLimit) {
+ FormatStyle Style = getLLVMStyle();
+ Style.ColumnLimit = ColumnLimit;
+ Style.RawStringFormats = {
+ {
+ /*Language=*/FormatStyle::LK_TextProto,
+ /*Delimiters=*/{"pb"},
+ /*EnclosingFunctions=*/{},
+ /*CanonicalDelimiter=*/"",
+ /*BasedOnStyle=*/"google",
+ },
+ };
+ return Style;
+ }
+
+ FormatStyle getRawStringLLVMCppStyleBasedOn(std::string BasedOnStyle) {
+ FormatStyle Style = getLLVMStyle();
+ Style.RawStringFormats = {
+ {
+ /*Language=*/FormatStyle::LK_Cpp,
+ /*Delimiters=*/{"cpp"},
+ /*EnclosingFunctions=*/{},
+ /*CanonicalDelimiter=*/"",
+ BasedOnStyle,
+ },
+ };
+ return Style;
+ }
+
+ FormatStyle getRawStringGoogleCppStyleBasedOn(std::string BasedOnStyle) {
+ FormatStyle Style = getGoogleStyle(FormatStyle::LK_Cpp);
+ Style.RawStringFormats = {
+ {
+ /*Language=*/FormatStyle::LK_Cpp,
+ /*Delimiters=*/{"cpp"},
+ /*EnclosingFunctions=*/{},
+ /*CanonicalDelimiter=*/"",
+ 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, UsesConfigurationOverBaseStyle) {
+ // llvm style puts '*' on the right.
+ // google style puts '*' on the left.
+
+ // Uses the configured google style inside raw strings even if BasedOnStyle in
+ // the raw string format is llvm.
+ FormatStyle Style = getGoogleStyle(FormatStyle::LK_Cpp);
+ EXPECT_EQ(0, parseConfiguration("---\n"
+ "Language: Cpp\n"
+ "BasedOnStyle: Google", &Style).value());
+ Style.RawStringFormats = {{
+ FormatStyle::LK_Cpp,
+ {"cpp"},
+ {},
+ /*CanonicalDelimiter=*/"",
+ /*BasedOnStyle=*/"llvm",
+ }};
+ expect_eq(R"test(int* i = R"cpp(int* j = 0;)cpp";)test",
+ format(R"test(int * i = R"cpp(int * j = 0;)cpp";)test", Style));
+}
+
+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)));
+}
+
+TEST_F(FormatTestRawStrings, RespectsClangFormatOff) {
+ expect_eq(R"test(
+// clang-format off
+s = R"pb(item: 1)pb";
+// clang-format on
+t = R"pb(item: 1)pb";)test",
+ format(R"test(
+// clang-format off
+s = R"pb(item: 1)pb";
+// clang-format on
+t = R"pb(item: 1)pb";)test",
+ getRawStringPbStyleWithColumns(40)));
+}
+
+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)));
+ // 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, BreaksShortRawStringsWhenNeeded) {
+ // The raw string contains multiple submessage entries, so break for
+ // readability.
+ 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)));
+}
+
+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)));
+
+ // `rest` fits on the line after )pb", but forced on newline since the raw
+ // string literal is multiline.
+ 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 indent 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)));
+}
+
+TEST_F(FormatTestRawStrings, FormatsRawStringsWithEnclosingFunctionName) {
+ FormatStyle Style = getRawStringPbStyleWithColumns(40);
+ Style.RawStringFormats[0].EnclosingFunctions.push_back(
+ "PARSE_TEXT_PROTO");
+ Style.RawStringFormats[0].EnclosingFunctions.push_back("ParseTextProto");
+ expect_eq(R"test(a = PARSE_TEXT_PROTO(R"(key: value)");)test",
+ format(R"test(a = PARSE_TEXT_PROTO(R"(key:value)");)test", Style));
+
+ expect_eq(R"test(
+a = PARSE_TEXT_PROTO /**/ (
+ /**/ R"(key: value)");)test",
+ format(R"test(
+a = PARSE_TEXT_PROTO/**/(/**/R"(key:value)");)test",
+ Style));
+
+ expect_eq(R"test(
+a = ParseTextProto<ProtoType>(
+ R"(key: value)");)test",
+ format(R"test(
+a = ParseTextProto<ProtoType>(R"(key:value)");)test",
+ Style));
+}
+
+TEST_F(FormatTestRawStrings, UpdatesToCanonicalDelimiters) {
+ FormatStyle Style = getRawStringPbStyleWithColumns(25);
+ Style.RawStringFormats[0].CanonicalDelimiter = "proto";
+ expect_eq(R"test(a = R"proto(key: value)proto";)test",
+ format(R"test(a = R"pb(key:value)pb";)test", Style));
+
+ // Don't update to canonical delimiter if it occurs as a raw string suffix in
+ // the raw string content.
+ expect_eq(R"test(a = R"pb(key: ")proto")pb";)test",
+ format(R"test(a = R"pb(key:")proto")pb";)test", Style));
+}
+
+TEST_F(FormatTestRawStrings, PenalizesPrefixExcessChars) {
+ FormatStyle Style = getRawStringPbStyleWithColumns(60);
+
+ // The '(' in R"pb is at column 60, no break.
+ expect_eq(R"test(
+xxxxxxxaaaaax wwwwwww = _Verxrrrrrrrr(PARSE_TEXT_PROTO(R"pb(
+ Category: aaaaaaaaaaaaaaaaaaaaaaaaaa
+)pb"));
+)test",
+ format(R"test(
+xxxxxxxaaaaax wwwwwww = _Verxrrrrrrrr(PARSE_TEXT_PROTO(R"pb(
+ Category: aaaaaaaaaaaaaaaaaaaaaaaaaa
+)pb"));
+)test", Style));
+ // The '(' in R"pb is at column 61, break.
+ expect_eq(R"test(
+xxxxxxxaaaaax wwwwwww =
+ _Verxrrrrrrrrr(PARSE_TEXT_PROTO(R"pb(
+ Category: aaaaaaaaaaaaaaaaaaaaaaaaaa
+ )pb"));
+)test",
+ format(R"test(
+xxxxxxxaaaaax wwwwwww = _Verxrrrrrrrrr(PARSE_TEXT_PROTO(R"pb(
+ Category: aaaaaaaaaaaaaaaaaaaaaaaaaa
+)pb"));
+)test", Style));
+}
+
+TEST_F(FormatTestRawStrings, KeepsRBraceFolloedByMoreLBracesOnSameLine) {
+ FormatStyle Style = getRawStringPbStyleWithColumns(80);
+
+ expect_eq(
+ R"test(
+int f() {
+ if (1) {
+ TTTTTTTTTTTTTTTTTTTTT s = PARSE_TEXT_PROTO(R"pb(
+ ttttttttt {
+ ppppppppppppp {
+ [cccccccccc.pppppppppppppp.TTTTTTTTTTTTTTTTTTTT] { field_1: "123_1" }
+ [cccccccccc.pppppppppppppp.TTTTTTTTTTTTTTTTTTTT] { field_2: "123_2" }
+ }
+ }
+ )pb");
+ }
+}
+)test",
+ format(
+ R"test(
+int f() {
+ if (1) {
+ TTTTTTTTTTTTTTTTTTTTT s = PARSE_TEXT_PROTO(R"pb(
+ ttttttttt {
+ ppppppppppppp {
+ [cccccccccc.pppppppppppppp.TTTTTTTTTTTTTTTTTTTT] { field_1: "123_1" }
+ [cccccccccc.pppppppppppppp.TTTTTTTTTTTTTTTTTTTT] { field_2: "123_2" }}}
+ )pb");
+ }
+}
+)test",
+ Style));
+}
+
+TEST_F(FormatTestRawStrings,
+ DoNotFormatUnrecognizedDelimitersInRecognizedFunctions) {
+ FormatStyle Style = getRawStringPbStyleWithColumns(60);
+ Style.RawStringFormats[0].EnclosingFunctions.push_back(
+ "EqualsProto");
+ // EqualsProto is a recognized function, but the Raw delimiter is
+ // unrecognized. Do not touch the string in this case, since it might be
+ // special.
+ expect_eq(R"test(
+void f() {
+ aaaaaaaaa(bbbbbbbbb, EqualsProto(R"Raw(
+item {
+ key: value
+}
+)Raw"));
+})test",
+ format(R"test(
+void f() {
+ aaaaaaaaa(bbbbbbbbb, EqualsProto(R"Raw(
+item {
+ key: value
+}
+)Raw"));
+})test",
+ Style));
+}
+
+TEST_F(FormatTestRawStrings,
+ BreaksBeforeNextParamAfterMultilineRawStringParam) {
+ FormatStyle Style = getRawStringPbStyleWithColumns(60);
+ expect_eq(R"test(
+int f() {
+ int a = g(x, R"pb(
+ key: 1 #
+ key: 2
+ )pb",
+ 3, 4);
+}
+)test",
+ format(R"test(
+int f() {
+ int a = g(x, R"pb(
+ key: 1 #
+ key: 2
+ )pb", 3, 4);
+}
+)test",
+ Style));
+
+ // Breaks after a parent of a multiline param.
+ expect_eq(R"test(
+int f() {
+ int a = g(x, h(R"pb(
+ key: 1 #
+ key: 2
+ )pb"),
+ 3, 4);
+}
+)test",
+ format(R"test(
+int f() {
+ int a = g(x, h(R"pb(
+ key: 1 #
+ key: 2
+ )pb"), 3, 4);
+}
+)test",
+ Style));
+
+ expect_eq(R"test(
+int f() {
+ int a = g(x,
+ h(R"pb(
+ key: 1 #
+ key: 2
+ )pb",
+ 2),
+ 3, 4);
+}
+)test",
+ format(R"test(
+int f() {
+ int a = g(x, h(R"pb(
+ key: 1 #
+ key: 2
+ )pb", 2), 3, 4);
+}
+)test",
+ Style));
+ // Breaks if formatting introduces a multiline raw string.
+ expect_eq(R"test(
+int f() {
+ int a = g(x, R"pb(key1: value111111111
+ key2: value2222222222)pb",
+ 3, 4);
+}
+)test",
+ format(R"test(
+int f() {
+ int a = g(x, R"pb(key1: value111111111 key2: value2222222222)pb", 3, 4);
+}
+)test",
+ Style));
+ // Does not force a break after an original multiline param that is
+ // reformatterd as on single line.
+ expect_eq(R"test(
+int f() {
+ int a = g(R"pb(key: 1)pb", 2);
+})test",
+ format(R"test(
+int f() {
+ int a = g(R"pb(key:
+ 1)pb", 2);
+})test", Style));
+}
+
+TEST_F(FormatTestRawStrings, IndentsLastParamAfterNewline) {
+ FormatStyle Style = getRawStringPbStyleWithColumns(60);
+ expect_eq(R"test(
+fffffffffffffffffffff("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
+ R"pb(
+ b: c
+ )pb");)test",
+ format(R"test(
+fffffffffffffffffffff("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
+ R"pb(
+ b: c
+ )pb");)test",
+ Style));
+}
+} // end namespace
+} // end namespace format
+} // end namespace clang