xref: /llvm-project/clang/unittests/Format/FormatTestTextProto.cpp (revision 91700e07938908adb720e616fcc61062b8da1fc0)
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 FormatTestTextProto : 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_TextProto);
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(FormatTestTextProto, KeepsTopLevelEntriesFittingALine) {
46   verifyFormat("field_a: OK field_b: OK field_c: OK field_d: OK field_e: OK");
47 }
48 
49 TEST_F(FormatTestTextProto, SupportsMessageFields) {
50   verifyFormat("msg_field: {}");
51 
52   verifyFormat("msg_field: {field_a: A}");
53 
54   verifyFormat("msg_field: {field_a: \"OK\" field_b: 123}");
55 
56   verifyFormat("msg_field: {\n"
57                "  field_a: 1\n"
58                "  field_b: OK\n"
59                "  field_c: \"OK\"\n"
60                "  field_d: 123\n"
61                "  field_e: 23\n"
62                "}");
63 
64   verifyFormat("msg_field {}");
65 
66   verifyFormat("msg_field {field_a: A}");
67 
68   verifyFormat("msg_field {field_a: \"OK\" field_b: 123}");
69 
70   verifyFormat("msg_field {\n"
71                "  field_a: 1\n"
72                "  field_b: OK\n"
73                "  field_c: \"OK\"\n"
74                "  field_d: 123\n"
75                "  field_e: 23.0\n"
76                "  field_f: false\n"
77                "  field_g: 'lala'\n"
78                "  field_h: 1234.567e-89\n"
79                "}");
80 
81   verifyFormat("msg_field: {msg_field {field_a: 1}}");
82 
83   verifyFormat("id: \"ala.bala\"\n"
84                "item {type: ITEM_A rank: 1 score: 90.0}\n"
85                "item {type: ITEM_B rank: 2 score: 70.5}\n"
86                "item {\n"
87                "  type: ITEM_A\n"
88                "  rank: 3\n"
89                "  score: 20.0\n"
90                "  description: \"the third item has a description\"\n"
91                "}");
92 }
93 
94 TEST_F(FormatTestTextProto, AvoidsTopLevelBinPacking) {
95   verifyFormat("field_a: OK\n"
96                "field_b: OK\n"
97                "field_c: OK\n"
98                "field_d: OK\n"
99                "field_e: OK\n"
100                "field_f: OK");
101 
102   verifyFormat("field_a: OK\n"
103                "field_b: \"OK\"\n"
104                "field_c: \"OK\"\n"
105                "msg_field: {field_d: 123}\n"
106                "field_e: OK\n"
107                "field_f: OK");
108 
109   verifyFormat("field_a: OK\n"
110                "field_b: \"OK\"\n"
111                "field_c: \"OK\"\n"
112                "msg_field: {field_d: 123 field_e: OK}");
113 
114   verifyFormat("a: {\n"
115                "  field_a: OK\n"
116                "  field_b {field_c: OK}\n"
117                "  field_d: OKOKOK\n"
118                "  field_e: OK\n"
119                "}");
120 
121   verifyFormat("field_a: OK,\n"
122                "field_b {field_c: OK},\n"
123                "field_d: OKOKOK,\n"
124                "field_e: OK");
125 }
126 
127 TEST_F(FormatTestTextProto, AddsNewlinesAfterTrailingComments) {
128   verifyFormat("field_a: OK  // Comment\n"
129                "field_b: 1");
130 
131   verifyFormat("field_a: OK\n"
132                "msg_field: {\n"
133                "  field_b: OK  // Comment\n"
134                "}");
135 
136   verifyFormat("field_a: OK\n"
137                "msg_field {\n"
138                "  field_b: OK  // Comment\n"
139                "}");
140 }
141 
142 TEST_F(FormatTestTextProto, SupportsAngleBracketMessageFields) {
143   // Single-line tests
144   verifyFormat("msg_field <>");
145   verifyFormat("msg_field: <>");
146   verifyFormat("msg_field <field_a: OK>");
147   verifyFormat("msg_field: <field_a: 123>");
148   verifyFormat("msg_field <field_a <>>");
149   verifyFormat("msg_field <field_a <field_b <>>>");
150   verifyFormat("msg_field: <field_a <field_b: <>>>");
151   verifyFormat("msg_field <field_a: OK, field_b: \"OK\">");
152   verifyFormat("msg_field <field_a: OK field_b: <>, field_c: OK>");
153   verifyFormat("msg_field <field_a {field_b: 1}, field_c: <field_d: 2>>");
154   verifyFormat("msg_field: <field_a: OK, field_b: \"OK\">");
155   verifyFormat("msg_field: <field_a: OK field_b: <>, field_c: OK>");
156   verifyFormat("msg_field: <field_a {field_b: 1}, field_c: <field_d: 2>>");
157   verifyFormat("field_a: \"OK\", msg_field: <field_b: 123>, field_c: {}");
158   verifyFormat("field_a <field_b: 1>, msg_field: <field_b: 123>, field_c <>");
159   verifyFormat("field_a <field_b: 1> msg_field: <field_b: 123> field_c <>");
160   verifyFormat("field <field <field: <>>, field <>> field: <field: 1>");
161 
162   // Multiple lines tests
163   verifyFormat("msg_field <\n"
164                "  field_a: OK\n"
165                "  field_b: \"OK\"\n"
166                "  field_c: 1\n"
167                "  field_d: 12.5\n"
168                "  field_e: OK\n"
169                ">");
170 
171   verifyFormat("msg_field: <>\n"
172                "field_c: \"OK\",\n"
173                "msg_field: <field_d: 123>\n"
174                "field_e: OK\n"
175                "msg_field: <field_d: 12>");
176 
177   verifyFormat("field_a: OK,\n"
178                "field_b <field_c: OK>,\n"
179                "field_d: <12.5>,\n"
180                "field_e: OK");
181 
182   verifyFormat("field_a: OK\n"
183                "field_b <field_c: OK>\n"
184                "field_d: <12.5>\n"
185                "field_e: OKOKOK");
186 
187   verifyFormat("msg_field <\n"
188                "  field_a: OK,\n"
189                "  field_b <field_c: OK>,\n"
190                "  field_d: <12.5>,\n"
191                "  field_e: OK\n"
192                ">");
193 
194   verifyFormat("msg_field <\n"
195                "  field_a: <field: OK>,\n"
196                "  field_b <field_c: OK>,\n"
197                "  field_d: <12.5>,\n"
198                "  field_e: OK,\n"
199                ">");
200 
201   verifyFormat("msg_field: <\n"
202                "  field_a: \"OK\"\n"
203                "  msg_field: {field_b: OK}\n"
204                "  field_g: OK\n"
205                "  field_g: OK\n"
206                "  field_g: OK\n"
207                ">");
208 
209   verifyFormat("field_a {\n"
210                "  field_d: ok\n"
211                "  field_b: <field_c: 1>\n"
212                "  field_d: ok\n"
213                "  field_d: ok\n"
214                "}");
215 
216   verifyFormat("field_a: {\n"
217                "  field_d: ok\n"
218                "  field_b: <field_c: 1>\n"
219                "  field_d: ok\n"
220                "  field_d: ok\n"
221                "}");
222 
223   verifyFormat("field_a: <f1: 1, f2: <>>\n"
224                "field_b <\n"
225                "  field_b1: <>\n"
226                "  field_b2: ok,\n"
227                "  field_b3: <\n"
228                "    field_x {}  // Comment\n"
229                "    field_y: {field_z: 1}\n"
230                "    field_w: ok\n"
231                "  >\n"
232                "  field {\n"
233                "    field_x <>  // Comment\n"
234                "    field_y: <field_z: 1>\n"
235                "    field_w: ok\n"
236                "    msg_field: <\n"
237                "      field: <>\n"
238                "      field: <field: 1>\n"
239                "      field: <field: 2>\n"
240                "      field: <field: 3>\n"
241                "      field: <field: 4>\n"
242                "      field: ok\n"
243                "    >\n"
244                "  }\n"
245                ">\n"
246                "field: OK,\n"
247                "field_c <field <field <>>>");
248 
249   verifyFormat("app_id: 'com.javax.swing.salsa.latino'\n"
250                "head_id: 1\n"
251                "data <key: value>");
252 
253   verifyFormat("app_id: 'com.javax.swing.salsa.latino'\n"
254                "head_id: 1\n"
255                "data <key: value>\n"
256                "tail_id: 2");
257 
258   verifyFormat("app_id: 'com.javax.swing.salsa.latino'\n"
259                "head_id: 1\n"
260                "data <key: value>\n"
261                "data {key: value}");
262 
263   verifyFormat("app {\n"
264                "  app_id: 'com.javax.swing.salsa.latino'\n"
265                "  head_id: 1\n"
266                "  data <key: value>\n"
267                "}");
268 
269   verifyFormat("app: {\n"
270                "  app_id: 'com.javax.swing.salsa.latino'\n"
271                "  head_id: 1\n"
272                "  data <key: value>\n"
273                "}");
274 
275   verifyFormat("app_id: 'com.javax.swing.salsa.latino'\n"
276                "headheadheadheadheadhead_id: 1\n"
277                "product_data {product {1}}");
278 
279   verifyFormat("app_id: 'com.javax.swing.salsa.latino'\n"
280                "headheadheadheadheadhead_id: 1\n"
281                "product_data <product {1}>");
282 
283   verifyFormat("app_id: 'com.javax.swing.salsa.latino'\n"
284                "headheadheadheadheadhead_id: 1\n"
285                "product_data <product <1>>");
286 
287   verifyFormat("app <\n"
288                "  app_id: 'com.javax.swing.salsa.latino'\n"
289                "  headheadheadheadheadhead_id: 1\n"
290                "  product_data <product {1}>\n"
291                ">");
292 
293   verifyFormat("dcccwrnfioeruvginerurneitinfo {\n"
294                "  exte3nsionrnfvui {key: value}\n"
295                "}");
296 }
297 
298 TEST_F(FormatTestTextProto, DiscardsUnbreakableTailIfCanBreakAfter) {
299   // The two closing braces count towards the string UnbreakableTailLength, but
300   // since we have broken after the corresponding opening braces, we don't
301   // consider that length for string breaking.
302   verifyFormat(
303       "foo: {\n"
304       "  bar: {\n"
305       "    text: \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\"\n"
306       "  }\n"
307       "}");
308 }
309 } // end namespace tooling
310 } // end namespace clang
311