diff options
Diffstat (limited to 'gnu/llvm/clang/unittests/Format/FormatTestRawStrings.cpp')
-rw-r--r-- | gnu/llvm/clang/unittests/Format/FormatTestRawStrings.cpp | 1000 |
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 |