//===- unittest/Format/FormatTestProto.cpp --------------------------------===// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// #include "FormatTestUtils.h" #include "clang/Format/Format.h" #include "llvm/Support/Debug.h" #include "gtest/gtest.h" #define DEBUG_TYPE "format-test" namespace clang { namespace format { class FormatTestTextProto : public ::testing::Test { protected: static std::string format(llvm::StringRef Code, unsigned Offset, unsigned Length, const FormatStyle &Style) { DEBUG(llvm::errs() << "---\n"); DEBUG(llvm::errs() << Code << "\n\n"); std::vector Ranges(1, tooling::Range(Offset, Length)); tooling::Replacements Replaces = reformat(Style, Code, Ranges); auto Result = applyAllReplacements(Code, Replaces); EXPECT_TRUE(static_cast(Result)); DEBUG(llvm::errs() << "\n" << *Result << "\n\n"); return *Result; } static std::string format(llvm::StringRef Code) { FormatStyle Style = getGoogleStyle(FormatStyle::LK_TextProto); Style.ColumnLimit = 60; // To make writing tests easier. return format(Code, 0, Code.size(), Style); } static void verifyFormat(llvm::StringRef Code) { EXPECT_EQ(Code.str(), format(test::messUp(Code))); } }; TEST_F(FormatTestTextProto, KeepsTopLevelEntriesFittingALine) { verifyFormat("field_a: OK field_b: OK field_c: OK field_d: OK field_e: OK"); } TEST_F(FormatTestTextProto, SupportsMessageFields) { verifyFormat("msg_field: {}"); verifyFormat("msg_field: {field_a: A}"); verifyFormat("msg_field: {field_a: \"OK\" field_b: 123}"); verifyFormat("msg_field: {\n" " field_a: 1\n" " field_b: OK\n" " field_c: \"OK\"\n" " field_d: 123\n" " field_e: 23\n" "}"); verifyFormat("msg_field {}"); verifyFormat("msg_field {field_a: A}"); verifyFormat("msg_field {field_a: \"OK\" field_b: 123}"); verifyFormat("msg_field {\n" " field_a: 1\n" " field_b: OK\n" " field_c: \"OK\"\n" " field_d: 123\n" " field_e: 23.0\n" " field_f: false\n" " field_g: 'lala'\n" " field_h: 1234.567e-89\n" "}"); verifyFormat("msg_field: {msg_field {field_a: 1}}"); verifyFormat("id: \"ala.bala\"\n" "item {type: ITEM_A rank: 1 score: 90.0}\n" "item {type: ITEM_B rank: 2 score: 70.5}\n" "item {\n" " type: ITEM_A\n" " rank: 3\n" " score: 20.0\n" " description: \"the third item has a description\"\n" "}"); } TEST_F(FormatTestTextProto, AvoidsTopLevelBinPacking) { verifyFormat("field_a: OK\n" "field_b: OK\n" "field_c: OK\n" "field_d: OK\n" "field_e: OK\n" "field_f: OK"); verifyFormat("field_a: OK\n" "field_b: \"OK\"\n" "field_c: \"OK\"\n" "msg_field: {field_d: 123}\n" "field_e: OK\n" "field_f: OK"); verifyFormat("field_a: OK\n" "field_b: \"OK\"\n" "field_c: \"OK\"\n" "msg_field: {field_d: 123 field_e: OK}"); verifyFormat("a: {\n" " field_a: OK\n" " field_b {field_c: OK}\n" " field_d: OKOKOK\n" " field_e: OK\n" "}"); verifyFormat("field_a: OK,\n" "field_b {field_c: OK},\n" "field_d: OKOKOK,\n" "field_e: OK"); } TEST_F(FormatTestTextProto, AddsNewlinesAfterTrailingComments) { verifyFormat("field_a: OK // Comment\n" "field_b: 1"); verifyFormat("field_a: OK\n" "msg_field: {\n" " field_b: OK // Comment\n" "}"); verifyFormat("field_a: OK\n" "msg_field {\n" " field_b: OK // Comment\n" "}"); } TEST_F(FormatTestTextProto, SupportsAngleBracketMessageFields) { // Single-line tests verifyFormat("msg_field <>"); verifyFormat("msg_field: <>"); verifyFormat("msg_field "); verifyFormat("msg_field: "); verifyFormat("msg_field >"); verifyFormat("msg_field >>"); verifyFormat("msg_field: >>"); verifyFormat("msg_field "); verifyFormat("msg_field , field_c: OK>"); verifyFormat("msg_field >"); verifyFormat("msg_field: "); verifyFormat("msg_field: , field_c: OK>"); verifyFormat("msg_field: >"); verifyFormat("field_a: \"OK\", msg_field: , field_c: {}"); verifyFormat("field_a , msg_field: , field_c <>"); verifyFormat("field_a msg_field: field_c <>"); verifyFormat("field >, field <>> field: "); // Multiple lines tests verifyFormat("msg_field <\n" " field_a: OK\n" " field_b: \"OK\"\n" " field_c: 1\n" " field_d: 12.5\n" " field_e: OK\n" ">"); verifyFormat("msg_field: <>\n" "field_c: \"OK\",\n" "msg_field: \n" "field_e: OK\n" "msg_field: "); verifyFormat("field_a: OK,\n" "field_b ,\n" "field_d: <12.5>,\n" "field_e: OK"); verifyFormat("field_a: OK\n" "field_b \n" "field_d: <12.5>\n" "field_e: OKOKOK"); verifyFormat("msg_field <\n" " field_a: OK,\n" " field_b ,\n" " field_d: <12.5>,\n" " field_e: OK\n" ">"); verifyFormat("msg_field <\n" " field_a: ,\n" " field_b ,\n" " field_d: <12.5>,\n" " field_e: OK,\n" ">"); verifyFormat("msg_field: <\n" " field_a: \"OK\"\n" " msg_field: {field_b: OK}\n" " field_g: OK\n" " field_g: OK\n" " field_g: OK\n" ">"); verifyFormat("field_a {\n" " field_d: ok\n" " field_b: \n" " field_d: ok\n" " field_d: ok\n" "}"); verifyFormat("field_a: {\n" " field_d: ok\n" " field_b: \n" " field_d: ok\n" " field_d: ok\n" "}"); verifyFormat("field_a: >\n" "field_b <\n" " field_b1: <>\n" " field_b2: ok,\n" " field_b3: <\n" " field_x {} // Comment\n" " field_y: {field_z: 1}\n" " field_w: ok\n" " >\n" " field {\n" " field_x <> // Comment\n" " field_y: \n" " field_w: ok\n" " msg_field: <\n" " field: <>\n" " field: \n" " field: \n" " field: \n" " field: \n" " field: ok\n" " >\n" " }\n" ">\n" "field: OK,\n" "field_c >>"); verifyFormat("app_id: 'com.javax.swing.salsa.latino'\n" "head_id: 1\n" "data "); verifyFormat("app_id: 'com.javax.swing.salsa.latino'\n" "head_id: 1\n" "data \n" "tail_id: 2"); verifyFormat("app_id: 'com.javax.swing.salsa.latino'\n" "head_id: 1\n" "data \n" "data {key: value}"); verifyFormat("app {\n" " app_id: 'com.javax.swing.salsa.latino'\n" " head_id: 1\n" " data \n" "}"); verifyFormat("app: {\n" " app_id: 'com.javax.swing.salsa.latino'\n" " head_id: 1\n" " data \n" "}"); verifyFormat("app_id: 'com.javax.swing.salsa.latino'\n" "headheadheadheadheadhead_id: 1\n" "product_data {product {1}}"); verifyFormat("app_id: 'com.javax.swing.salsa.latino'\n" "headheadheadheadheadhead_id: 1\n" "product_data "); verifyFormat("app_id: 'com.javax.swing.salsa.latino'\n" "headheadheadheadheadhead_id: 1\n" "product_data >"); verifyFormat("app <\n" " app_id: 'com.javax.swing.salsa.latino'\n" " headheadheadheadheadhead_id: 1\n" " product_data \n" ">"); } } // end namespace tooling } // end namespace clang