From 650ea04ef9a1eaa5513713a2cda0b980512aa7b5 Mon Sep 17 00:00:00 2001 From: Krasimir Georgiev Date: Mon, 3 Jul 2017 15:05:14 +0000 Subject: [clang-format] Support text proto messages Summary: This patch adds support for textual protocol buffer messages. Reviewers: djasper Reviewed By: djasper Subscribers: cfe-commits, klimek, mgorny Differential Revision: https://reviews.llvm.org/D34441 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@307029 91177308-0d34-0410-b5e6-96231b3b80d8 --- unittests/Format/CMakeLists.txt | 1 + unittests/Format/FormatTestTextProto.cpp | 251 +++++++++++++++++++++++++++++++ 2 files changed, 252 insertions(+) create mode 100644 unittests/Format/FormatTestTextProto.cpp (limited to 'unittests') diff --git a/unittests/Format/CMakeLists.txt b/unittests/Format/CMakeLists.txt index 5c04ba1143..fa7e32c33d 100644 --- a/unittests/Format/CMakeLists.txt +++ b/unittests/Format/CMakeLists.txt @@ -11,6 +11,7 @@ add_clang_unittest(FormatTests FormatTestObjC.cpp FormatTestProto.cpp FormatTestSelective.cpp + FormatTestTextProto.cpp NamespaceEndCommentsFixerTest.cpp SortImportsTestJS.cpp SortIncludesTest.cpp diff --git a/unittests/Format/FormatTestTextProto.cpp b/unittests/Format/FormatTestTextProto.cpp new file mode 100644 index 0000000000..83e5892214 --- /dev/null +++ b/unittests/Format/FormatTestTextProto.cpp @@ -0,0 +1,251 @@ +//===- 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>>"); +} + +} // end namespace tooling +} // end namespace clang -- cgit v1.2.3