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