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