Home | History | Annotate | Download | only in Format
      1 //===- unittest/Format/FormatTestProto.cpp --------------------------------===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 
     10 #include "FormatTestUtils.h"
     11 #include "clang/Format/Format.h"
     12 #include "llvm/Support/Debug.h"
     13 #include "gtest/gtest.h"
     14 
     15 #define DEBUG_TYPE "format-test"
     16 
     17 namespace clang {
     18 namespace format {
     19 
     20 class FormatTestProto : public ::testing::Test {
     21 protected:
     22   static std::string format(llvm::StringRef Code, unsigned Offset,
     23                             unsigned Length, const FormatStyle &Style) {
     24     DEBUG(llvm::errs() << "---\n");
     25     DEBUG(llvm::errs() << Code << "\n\n");
     26     std::vector<tooling::Range> Ranges(1, tooling::Range(Offset, Length));
     27     tooling::Replacements Replaces = reformat(Style, Code, Ranges);
     28     auto Result = applyAllReplacements(Code, Replaces);
     29     EXPECT_TRUE(static_cast<bool>(Result));
     30     DEBUG(llvm::errs() << "\n" << *Result << "\n\n");
     31     return *Result;
     32   }
     33 
     34   static std::string format(llvm::StringRef Code) {
     35     FormatStyle Style = getGoogleStyle(FormatStyle::LK_Proto);
     36     Style.ColumnLimit = 60; // To make writing tests easier.
     37     return format(Code, 0, Code.size(), Style);
     38   }
     39 
     40   static void verifyFormat(llvm::StringRef Code) {
     41     EXPECT_EQ(Code.str(), format(test::messUp(Code)));
     42   }
     43 };
     44 
     45 TEST_F(FormatTestProto, FormatsMessages) {
     46   verifyFormat("message SomeMessage {\n"
     47                "  required int32 field1 = 1;\n"
     48                "}");
     49   verifyFormat("message SomeMessage {\n"
     50                "  required .absolute.Reference field1 = 1;\n"
     51                "}");
     52   verifyFormat("message SomeMessage {\n"
     53                "  required int32 field1 = 1;\n"
     54                "  optional string field2 = 2 [default = \"2\"]\n"
     55                "}");
     56 
     57   verifyFormat("message SomeMessage {\n"
     58                "  optional really.really.long.qualified.type.aaa.aaaaaaa\n"
     59                "      fiiiiiiiiiiiiiiiiiiiiiiiiield = 1;\n"
     60                "  optional\n"
     61                "      really.really.long.qualified.type.aaa.aaaaaaa.aaaaaaaa\n"
     62                "          another_fiiiiiiiiiiiiiiiiiiiiield = 2;\n"
     63                "}");
     64 }
     65 
     66 TEST_F(FormatTestProto, KeywordsInOtherLanguages) {
     67   verifyFormat("optional string operator = 1;");
     68 }
     69 
     70 TEST_F(FormatTestProto, FormatsEnums) {
     71   verifyFormat("enum Type {\n"
     72                "  UNKNOWN = 0;\n"
     73                "  TYPE_A = 1;\n"
     74                "  TYPE_B = 2;\n"
     75                "};");
     76   verifyFormat("enum Type {\n"
     77                "  UNKNOWN = 0 [(some_options) = {a: aa, b: bb}];\n"
     78                "};");
     79   verifyFormat("enum Type {\n"
     80                "  UNKNOWN = 0 [(some_options) = {\n"
     81                "    a: aa,  // wrap\n"
     82                "    b: bb\n"
     83                "  }];\n"
     84                "};");
     85 }
     86 
     87 TEST_F(FormatTestProto, UnderstandsReturns) {
     88   verifyFormat("rpc Search(SearchRequest) returns (SearchResponse);");
     89 }
     90 
     91 TEST_F(FormatTestProto, MessageFieldAttributes) {
     92   verifyFormat("optional string test = 1 [default = \"test\"];");
     93   verifyFormat("optional bool a = 1 [default = true, deprecated = true];");
     94   verifyFormat("optional LongMessageType long_proto_field = 1 [\n"
     95                "  default = REALLY_REALLY_LONG_CONSTANT_VALUE,\n"
     96                "  deprecated = true\n"
     97                "];");
     98   verifyFormat("optional LongMessageType long_proto_field = 1\n"
     99                "    [default = REALLY_REALLY_LONG_CONSTANT_VALUE];");
    100   verifyFormat("repeated double value = 1\n"
    101                "    [(aaaaaaa.aaaaaaaaa) = {aaaaaaaaaaaaaaaaa: AAAAAAAA}];");
    102   verifyFormat("repeated double value = 1 [(aaaaaaa.aaaaaaaaa) = {\n"
    103                "  aaaaaaaaaaaaaaaa: AAAAAAAAAA,\n"
    104                "  bbbbbbbbbbbbbbbb: BBBBBBBBBB\n"
    105                "}];");
    106   verifyFormat("repeated double value = 1 [(aaaaaaa.aaaaaaaaa) = {\n"
    107                "  aaaaaaaaaaaaaaaa: AAAAAAAAAA\n"
    108                "  bbbbbbbbbbbbbbbb: BBBBBBBBBB\n"
    109                "}];");
    110   verifyFormat("repeated double value = 1 [\n"
    111                "  (aaaaaaa.aaaaaaaaa) = {\n"
    112                "    aaaaaaaaaaaaaaaa: AAAAAAAAAA\n"
    113                "    bbbbbbbbbbbbbbbb: BBBBBBBBBB\n"
    114                "  },\n"
    115                "  (bbbbbbb.bbbbbbbbb) = {\n"
    116                "    aaaaaaaaaaaaaaaa: AAAAAAAAAA\n"
    117                "    bbbbbbbbbbbbbbbb: BBBBBBBBBB\n"
    118                "  }\n"
    119                "];");
    120   verifyFormat("repeated double value = 1 [(aaaaaaa.aaaaaaaaa) = {\n"
    121                "  type: \"AAAAAAAAAA\"\n"
    122                "  is: \"AAAAAAAAAA\"\n"
    123                "  or: \"BBBBBBBBBB\"\n"
    124                "}];");
    125   verifyFormat("repeated double value = 1 [(aaaaaaa.aaaaaaaaa) = {\n"
    126                "  aaaaaaaaaaaaaaaa: AAAAAAAAAA,\n"
    127                "  bbbbbbb: BBBB,\n"
    128                "  bbbb: BBB\n"
    129                "}];");
    130   verifyFormat("optional AAA aaa = 1 [\n"
    131                "  foo = {\n"
    132                "    key: 'a'  //\n"
    133                "  },\n"
    134                "  bar = {\n"
    135                "    key: 'a'  //\n"
    136                "  }\n"
    137                "];");
    138 }
    139 
    140 TEST_F(FormatTestProto, DoesntWrapFileOptions) {
    141   EXPECT_EQ(
    142       "option java_package = "
    143       "\"some.really.long.package.that.exceeds.the.column.limit\";",
    144       format("option    java_package   =    "
    145              "\"some.really.long.package.that.exceeds.the.column.limit\";"));
    146 }
    147 
    148 TEST_F(FormatTestProto, FormatsOptions) {
    149   verifyFormat("option (MyProto.options) = {\n"
    150                "  field_a: OK\n"
    151                "  field_b: \"OK\"\n"
    152                "  field_c: \"OK\"\n"
    153                "  msg_field: {field_d: 123}\n"
    154                "};");
    155   verifyFormat("option (MyProto.options) = {\n"
    156                "  field_a: OK\n"
    157                "  field_b: \"OK\"\n"
    158                "  field_c: \"OK\"\n"
    159                "  msg_field: {field_d: 123 field_e: OK}\n"
    160                "};");
    161   verifyFormat("option (MyProto.options) = {\n"
    162                "  field_a: OK  // Comment\n"
    163                "  field_b: \"OK\"\n"
    164                "  field_c: \"OK\"\n"
    165                "  msg_field: {field_d: 123}\n"
    166                "};");
    167   verifyFormat("option (MyProto.options) = {\n"
    168                "  field_c: \"OK\"\n"
    169                "  msg_field{field_d: 123}\n"
    170                "};");
    171 
    172   // Support syntax with <> instead of {}.
    173   verifyFormat("option (MyProto.options) = {\n"
    174                "  field_c: \"OK\",\n"
    175                "  msg_field: <field_d: 123>\n"
    176                "};");
    177 }
    178 
    179 TEST_F(FormatTestProto, FormatsService) {
    180   verifyFormat("service SearchService {\n"
    181                "  rpc Search(SearchRequest) returns (SearchResponse) {\n"
    182                "    option foo = true;\n"
    183                "  }\n"
    184                "};");
    185 }
    186 
    187 TEST_F(FormatTestProto, ExtendingMessage) {
    188   verifyFormat("extend .foo.Bar {\n"
    189                "}");
    190 }
    191 
    192 TEST_F(FormatTestProto, FormatsImports) {
    193   verifyFormat("import \"a.proto\";\n"
    194                "import \"b.proto\";\n"
    195                "// comment\n"
    196                "message A {\n"
    197                "}");
    198 
    199   verifyFormat("import public \"a.proto\";\n"
    200                "import \"b.proto\";\n"
    201                "// comment\n"
    202                "message A {\n"
    203                "}");
    204 
    205   // Missing semicolons should not confuse clang-format.
    206   verifyFormat("import \"a.proto\"\n"
    207                "import \"b.proto\"\n"
    208                "// comment\n"
    209                "message A {\n"
    210                "}");
    211 }
    212 
    213 } // end namespace tooling
    214 } // end namespace clang
    215