2017-10-30 22:01:50 +08:00
|
|
|
//===- 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) {
|
2018-05-15 21:30:56 +08:00
|
|
|
LLVM_DEBUG(llvm::errs() << "---\n");
|
|
|
|
LLVM_DEBUG(llvm::errs() << Code << "\n\n");
|
2017-10-30 22:01:50 +08:00
|
|
|
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));
|
2018-05-15 21:30:56 +08:00
|
|
|
LLVM_DEBUG(llvm::errs() << "\n" << *Result << "\n\n");
|
2017-10-30 22:01:50 +08:00
|
|
|
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;
|
2018-01-18 00:17:26 +08:00
|
|
|
Style.RawStringFormats = {
|
2018-01-20 00:18:47 +08:00
|
|
|
{
|
|
|
|
/*Language=*/FormatStyle::LK_TextProto,
|
|
|
|
/*Delimiters=*/{"pb"},
|
|
|
|
/*EnclosingFunctions=*/{},
|
|
|
|
/*CanonicalDelimiter=*/"",
|
|
|
|
/*BasedOnStyle=*/"google",
|
|
|
|
},
|
2018-01-18 00:17:26 +08:00
|
|
|
};
|
2017-10-30 22:01:50 +08:00
|
|
|
return Style;
|
|
|
|
}
|
|
|
|
|
|
|
|
FormatStyle getRawStringLLVMCppStyleBasedOn(std::string BasedOnStyle) {
|
|
|
|
FormatStyle Style = getLLVMStyle();
|
2018-01-18 00:17:26 +08:00
|
|
|
Style.RawStringFormats = {
|
2018-01-20 00:18:47 +08:00
|
|
|
{
|
|
|
|
/*Language=*/FormatStyle::LK_Cpp,
|
|
|
|
/*Delimiters=*/{"cpp"},
|
|
|
|
/*EnclosingFunctions=*/{},
|
|
|
|
/*CanonicalDelimiter=*/"",
|
|
|
|
BasedOnStyle,
|
|
|
|
},
|
2018-01-18 00:17:26 +08:00
|
|
|
};
|
2017-10-30 22:01:50 +08:00
|
|
|
return Style;
|
|
|
|
}
|
|
|
|
|
|
|
|
FormatStyle getRawStringGoogleCppStyleBasedOn(std::string BasedOnStyle) {
|
|
|
|
FormatStyle Style = getGoogleStyle(FormatStyle::LK_Cpp);
|
2018-01-18 00:17:26 +08:00
|
|
|
Style.RawStringFormats = {
|
2018-01-20 00:18:47 +08:00
|
|
|
{
|
|
|
|
/*Language=*/FormatStyle::LK_Cpp,
|
|
|
|
/*Delimiters=*/{"cpp"},
|
|
|
|
/*EnclosingFunctions=*/{},
|
|
|
|
/*CanonicalDelimiter=*/"",
|
|
|
|
BasedOnStyle,
|
|
|
|
},
|
2018-01-18 00:17:26 +08:00
|
|
|
};
|
2017-10-30 22:01:50 +08:00
|
|
|
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")));
|
|
|
|
}
|
|
|
|
|
2018-01-17 20:24:59 +08:00
|
|
|
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());
|
2018-01-20 00:18:47 +08:00
|
|
|
Style.RawStringFormats = {{
|
|
|
|
FormatStyle::LK_Cpp,
|
|
|
|
{"cpp"},
|
|
|
|
{},
|
|
|
|
/*CanonicalDelimiter=*/"",
|
|
|
|
/*BasedOnStyle=*/"llvm",
|
|
|
|
}};
|
2018-01-17 20:24:59 +08:00
|
|
|
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));
|
|
|
|
}
|
|
|
|
|
2017-10-30 22:01:50 +08:00
|
|
|
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)));
|
|
|
|
}
|
|
|
|
|
2018-03-12 18:11:30 +08:00
|
|
|
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)));
|
|
|
|
}
|
|
|
|
|
2017-10-30 22:01:50 +08:00
|
|
|
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)));
|
|
|
|
}
|
|
|
|
|
2018-06-11 20:53:25 +08:00
|
|
|
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)));
|
|
|
|
}
|
|
|
|
|
2017-10-30 22:01:50 +08:00
|
|
|
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(
|
2018-02-06 19:34:34 +08:00
|
|
|
P p = TP(R"pb(item_1 < 1 >
|
|
|
|
item_2: < 2 >
|
2017-10-30 22:01:50 +08:00
|
|
|
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(
|
2018-02-06 19:34:34 +08:00
|
|
|
R"pb(item_1 < 1 >,
|
2018-01-31 18:14:10 +08:00
|
|
|
item_2: { 2 },
|
2018-02-06 19:34:34 +08:00
|
|
|
item_3: < 3 >,
|
2018-01-31 18:14:10 +08:00
|
|
|
item_4: { 4 })pb");)test",
|
2017-10-30 22:01:50 +08:00
|
|
|
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(
|
2018-01-31 18:14:10 +08:00
|
|
|
P p = TP(R"pb(key { 1 })pb", param_2);)test",
|
2017-10-30 22:01:50 +08:00
|
|
|
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(
|
2018-01-31 18:14:10 +08:00
|
|
|
P p = TP(
|
|
|
|
R"pb(item: { i: 1, s: 's' }
|
|
|
|
item: { i: 2, s: 't' })pb");)test",
|
2017-10-30 22:01:50 +08:00
|
|
|
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)));
|
|
|
|
|
2018-03-08 19:29:27 +08:00
|
|
|
// Align the suffix with the surrounding indent if the prefix is not on
|
2017-10-30 22:01:50 +08:00
|
|
|
// a line of its own.
|
|
|
|
expect_eq(R"test(
|
|
|
|
int s() {
|
2018-03-08 19:29:27 +08:00
|
|
|
auto S = PTP(R"pb(
|
|
|
|
item_1: 1,
|
|
|
|
item_2: 2
|
|
|
|
)pb");
|
2017-10-30 22:01:50 +08:00
|
|
|
})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)));
|
|
|
|
}
|
|
|
|
|
2018-01-18 00:17:26 +08:00
|
|
|
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));
|
|
|
|
}
|
|
|
|
|
2018-01-20 00:18:47 +08:00
|
|
|
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));
|
|
|
|
}
|
|
|
|
|
2018-03-16 22:01:25 +08:00
|
|
|
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));
|
|
|
|
}
|
|
|
|
|
2018-05-09 17:02:11 +08:00
|
|
|
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));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-10-30 22:01:50 +08:00
|
|
|
} // end namespace
|
|
|
|
} // end namespace format
|
|
|
|
} // end namespace clang
|