OLD | NEW |
(Empty) | |
| 1 //===- llvm/unittest/Bitcode/NaClTextFormatterTest.cpp --------------------===// |
| 2 // Tests the text formatter for PNaCl bitcode. |
| 3 // |
| 4 // The LLVM Compiler Infrastructure |
| 5 // |
| 6 // This file is distributed under the University of Illinois Open Source |
| 7 // License. See LICENSE.TXT for details. |
| 8 // |
| 9 //===----------------------------------------------------------------------===// |
| 10 |
| 11 // Tests if the text formatter for PNaCl bitcode works as expected. |
| 12 |
| 13 #include "llvm/ADT/STLExtras.h" |
| 14 #include "llvm/Bitcode/NaCl/NaClObjDumpStream.h" |
| 15 |
| 16 #include "gtest/gtest.h" |
| 17 |
| 18 #include <iostream> |
| 19 |
| 20 using namespace llvm; |
| 21 using namespace llvm::naclbitc; |
| 22 |
| 23 namespace { |
| 24 |
| 25 /// Simple test harness for testing a text formatter. This class takes |
| 26 /// an array of tokens, parses it, and then uses the text formatter to |
| 27 /// format it. To test the features of the text formatter, the parser |
| 28 /// detects function calls, and inserts appropriate open/close |
| 29 /// parenthesis directives, as well as clustering directives. |
| 30 /// |
| 31 /// For clustering, we consider each argument, as well as the entire |
| 32 /// function. In case the entire function can't be printed, we add two |
| 33 /// additional clusters as backup strategies: |
| 34 /// |
| 35 /// 1) Cluster the called function with it's first argument. |
| 36 /// 2) Cluster the called function with the open parenthesis. |
| 37 /// |
| 38 /// These rules can be formalized as the following cases, where: |
| 39 /// '<' denotes a StartCluster. |
| 40 /// '>' denotes a FinishCluster. |
| 41 /// '[' represents a regular expression open parenthesis. |
| 42 /// ']' represents a regular expression close parenthesis. |
| 43 /// '*' denotes regular expression repeat operation. |
| 44 /// |
| 45 /// The cases to consider are: |
| 46 /// |
| 47 /// case 1: <<<f(>)>> |
| 48 /// case 2: <<<f(><x>)>> |
| 49 /// case 3: <<<f(><x,>>[<y,>]*<z>)> |
| 50 /// |
| 51 /// Note: In cases 1 and 2, there is an unnecessary pair of clustering |
| 52 /// directives. This is intentional. It has been added so that the |
| 53 /// parser need not build an AST before formatting. Also note that |
| 54 /// case 3 covers all function calls with 2 or more arguments. |
| 55 class FormatterTester { |
| 56 private: |
| 57 // Defines states of the token parser, as it looks for function calls. |
| 58 // These states are used to determine where (and when) clustering |
| 59 // directives should be added to the Tokens() stream. If no |
| 60 // transition applies for a state, the default transition is applied, |
| 61 // which is to add the next token to the Tokens() stream. |
| 62 // |
| 63 // Note: We use '|' to denote the current position of the token parser. |
| 64 // |
| 65 // In all states, the following transition is possible (pushing the |
| 66 // current state onto the parse stack), and is applied after state |
| 67 // specific transitions (below): |
| 68 // |
| 69 // |<<<f(>)>> => StartingFcn: <<<|f(>)>> |
| 70 // |<<<f(><x>)>> => StartingFcn: <<<|f(><x>)>> |
| 71 // |<<<f(><x,>>[<y,>]*<z>)> => StartingFcn: <<<|f(><x,>>[<y,>]*<z>)> |
| 72 // |
| 73 // Note: We use the notation == to state that two expressions are equivalent. |
| 74 // In particular, |
| 75 // |
| 76 // [x|]* == [|x]* |
| 77 // |
| 78 // since being at the end of a repeated instruction also means that |
| 79 // you are at the beginning of the next (unrolled) repetition. |
| 80 enum FormatterState { |
| 81 LookingForFunction, // Start state |
| 82 |
| 83 StartingFcn, |
| 84 // <<<f(|>)>> => BeforeFirstArg: <<<f(>|)>> |
| 85 // <<<f(|><x>)>> => BeforeFirstArg: <<<f(>|<x>(>> |
| 86 // <<<f(|><x,>>[<y,>]*<z>)> => BeforeFirstArg: <<<f(>|<x,>>[<y,>]*<z>)> |
| 87 |
| 88 BeforeFirstArg, |
| 89 // <<<f(>|)>> => EndFcn2: <<<f(>|)>> |
| 90 // <<<f(>|<x>)>> => InFirstArg: <<<f(><|x>)>> |
| 91 // <<<f(>|<x,>>[<y,>]*<z>)> => InFirstArg <<<f(><|x,>>[<y,>]*<z>)> |
| 92 |
| 93 InFirstArg, |
| 94 // <<<f(><x|>)>> => EndFcn2: <<<f(><x>|)>> |
| 95 // <<<f(><x,|>>[<y,>]*<z>)> => BetweenArgs: <<<f(><x,>>[|<y,>]*<z>)> |
| 96 |
| 97 InOtherArg, |
| 98 // <<<f(><x,>>[<y,|>]*<z>)> => BetweenArgs: <<<f(><x,>>[<y,>|]*<z>)> |
| 99 // == <<<f(><x,>>[|<y,>]*<z>)> |
| 100 // => BetweenArgs: <<<f(><x,>>[<y,>]*|<z>)> |
| 101 // <<<f(><x,>>[<y,>]*<z|>)> => EndFcn1: <<<f(><x,>>[<y,>]*<z>|)> |
| 102 |
| 103 BetweenArgs, |
| 104 // <<<f(><x,>>[|<y,>]*<z>)> => InOtherArg: <<<f(><x,>>[<|y,>]*<z>)> |
| 105 // <<<f(><x,>>[<y,>]*|<z>)> => InOtherArg: <<<f(><x,>>[<y,>]*<|z>)> |
| 106 |
| 107 EndFcn2, |
| 108 // <<<f(>)|>> => EndFcn1: <<<f(>)>|> |
| 109 // <<<f(><x>)|>> => EndFcn1: <<<f(><x>)>|> |
| 110 |
| 111 EndFcn1 |
| 112 // <<<f(>)>|> => XXX: <<<f(>)>>| |
| 113 // <<<f(><x>)>|> => XXX: <<<f(><x>)>>| |
| 114 // <<<f(><x,>>[<y,>]*<z>)|> => XXX: <<<f(><x,>>[<y,>]*<z>)>| |
| 115 // |
| 116 // where XXX is the state popped from the parse stack. |
| 117 }; |
| 118 |
| 119 public: |
| 120 FormatterTester(unsigned LineWidth) |
| 121 : AddOpenCloseDirectives(false), |
| 122 AddClusterDirectives(false), |
| 123 Buffer(), |
| 124 BufStream(Buffer), |
| 125 Formatter(BufStream, LineWidth, " "), |
| 126 CommaText(","), |
| 127 SpaceText(" "), |
| 128 OpenParenText("("), |
| 129 CloseParenText(")"), |
| 130 NewlineText("\n"), |
| 131 Comma(&Formatter, CommaText), |
| 132 Space(&Formatter, SpaceText), |
| 133 OpenParen(&Formatter, OpenParenText), |
| 134 CloseParen(&Formatter, CloseParenText), |
| 135 StartCluster(&Formatter), |
| 136 FinishCluster(&Formatter), |
| 137 Tokenize(&Formatter), |
| 138 Endline(&Formatter) |
| 139 { |
| 140 Reset(); |
| 141 Formatter.SetContinuationIndent(Formatter.GetIndent(2)); |
| 142 } |
| 143 |
| 144 /// Runs a test using the given sequence of tokens. If |
| 145 /// AddOpenCloseDirectives is true, then "(" and ")" tokens |
| 146 /// will change the local indent using the corresponding directives. |
| 147 /// If AddClusterDirectives is true, then the clustering rules for |
| 148 /// function calls will be applied. |
| 149 std::string Test(const char *Tokens[], size_t NumTokens, |
| 150 bool AddOpenCloseDirectives, |
| 151 bool AddClusterDirectives, |
| 152 unsigned Indent); |
| 153 |
| 154 private: |
| 155 /// Reset the formatter for next test. |
| 156 void Reset() { |
| 157 BufStream.flush(); |
| 158 Buffer.clear(); |
| 159 State = LookingForFunction; |
| 160 FunctionParseStack.clear(); |
| 161 } |
| 162 |
| 163 /// Collect the sequence of tokens, starting at Index, that |
| 164 /// correspond to spaces, and return the number of spaces found. |
| 165 unsigned CollectSpaces(size_t &Index, |
| 166 const char *Tokens[], |
| 167 size_t NumTokens) const { |
| 168 unsigned Count = 0; |
| 169 for (; Index < NumTokens; ++Index) { |
| 170 std::string Token(Tokens[Index]); |
| 171 if (Token != SpaceText) return Count; |
| 172 ++Count; |
| 173 } |
| 174 return Count; |
| 175 } |
| 176 |
| 177 /// Write out the given number of spaces using a space directive. |
| 178 void WriteSpaces(unsigned Count) { |
| 179 for (unsigned i = 0; i < Count; ++i) Formatter.Tokens() << Space; |
| 180 } |
| 181 |
| 182 /// Insert clustering directives, based on the current state of the |
| 183 /// parser. CurToken is the current (non-whitespace) token being |
| 184 /// processed by the parser. NextToken is the next (non-whitespace) |
| 185 /// token being processed. If BeforeCurrentToken, then the parser |
| 186 /// is just before CurToken. Otherwise, it is just after NextToken. |
| 187 /// |
| 188 /// Note: When BeforeCurrentToken is false, it isn't necessarily |
| 189 /// just before NextToken. This is because there may be space |
| 190 /// (i.e. whitespace) tokens between CurToken and NextToken. |
| 191 void InsertClusterDirectives(std::string &CurToken, |
| 192 std::string &NextToken, |
| 193 bool BeforeCurrentToken); |
| 194 |
| 195 /// Write out the given token. Implicitly uses corresponding directives |
| 196 /// if applicable. |
| 197 void WriteToken(const std::string &Token); |
| 198 |
| 199 // True if Open and Close directives should be used for "(" and ")" tokens. |
| 200 bool AddOpenCloseDirectives; |
| 201 // True if clustering directives (for functions) should be inserted. |
| 202 bool AddClusterDirectives; |
| 203 // The buffer the formatted text is written into. |
| 204 std::string Buffer; |
| 205 // The base stream of the text formatter, which dumps text into the buffer. |
| 206 raw_string_ostream BufStream; |
| 207 // The text formatter to use. |
| 208 TextFormatter Formatter; |
| 209 const std::string CommaText; |
| 210 const std::string SpaceText; |
| 211 const std::string OpenParenText; |
| 212 const std::string CloseParenText; |
| 213 const std::string NewlineText; |
| 214 const TokenTextDirective Comma; |
| 215 SpaceTextDirective Space; |
| 216 OpenTextDirective OpenParen; |
| 217 CloseTextDirective CloseParen; |
| 218 StartClusteringDirective StartCluster; |
| 219 FinishClusteringDirective FinishCluster; |
| 220 TokenizeTextDirective Tokenize; |
| 221 EndlineTextDirective Endline; |
| 222 // The parse state of the function parser, used by the tester. |
| 223 FormatterState State; |
| 224 // The stack of parse states of the function parser. Used to handle |
| 225 // nested functions. |
| 226 std::vector<FormatterState> FunctionParseStack; |
| 227 }; |
| 228 |
| 229 void FormatterTester::WriteToken(const std::string &Token) { |
| 230 if (Token == CommaText) { |
| 231 Formatter.Tokens() << Comma; |
| 232 } else if (Token == SpaceText) { |
| 233 Formatter.Tokens() << Space; |
| 234 } else if (Token == OpenParenText) { |
| 235 if (AddOpenCloseDirectives) { |
| 236 Formatter.Tokens() << OpenParen; |
| 237 } else { |
| 238 Formatter.Tokens() << Token << Tokenize; |
| 239 } |
| 240 } else if (Token == CloseParenText) { |
| 241 if (AddOpenCloseDirectives) { |
| 242 Formatter.Tokens() << CloseParen; |
| 243 } else { |
| 244 Formatter.Tokens() << Token << Tokenize; |
| 245 } |
| 246 } else if (Token == NewlineText) { |
| 247 Formatter.Tokens() << Endline; |
| 248 } else { |
| 249 Formatter.Tokens() << Token << Tokenize; |
| 250 } |
| 251 } |
| 252 |
| 253 std::string FormatterTester::Test(const char *Tokens[], |
| 254 size_t NumTokens, |
| 255 bool NewAddOpenCloseDirectives, |
| 256 bool NewAddClusterDirectives, |
| 257 unsigned Indent) { |
| 258 AddOpenCloseDirectives = NewAddOpenCloseDirectives; |
| 259 AddClusterDirectives = NewAddClusterDirectives; |
| 260 for (unsigned i = 0; i < Indent; ++i) Formatter.Inc(); |
| 261 |
| 262 size_t Index = 0; |
| 263 unsigned SpaceCount = CollectSpaces(Index, Tokens, NumTokens); |
| 264 WriteSpaces(SpaceCount); |
| 265 SpaceCount = 0; |
| 266 |
| 267 // NOTE: We would use ASSERT_LT(Index, NumTokens), but it gets |
| 268 // a compile-time error if not inside the TEST macro. |
| 269 EXPECT_LT(Index, NumTokens); |
| 270 if (Index == NumTokens) return std::string("*W*R*O*N*G*"); |
| 271 |
| 272 // Generate token sequence defined by Tokens. |
| 273 std::string CurToken(Tokens[Index++]); |
| 274 while (Index < NumTokens) { |
| 275 SpaceCount = CollectSpaces(Index, Tokens, NumTokens); |
| 276 if (Index == NumTokens) { |
| 277 WriteSpaces(SpaceCount); |
| 278 SpaceCount = 0; |
| 279 break; |
| 280 } |
| 281 std::string NextToken(Tokens[Index++]); |
| 282 InsertClusterDirectives(CurToken, NextToken, true); |
| 283 WriteToken(CurToken); |
| 284 InsertClusterDirectives(CurToken, NextToken, false); |
| 285 WriteSpaces(SpaceCount); |
| 286 SpaceCount = 0; |
| 287 CurToken = NextToken; |
| 288 } |
| 289 |
| 290 // When reached, all but last token (i.e. CurToken) has been written. |
| 291 // Create dummy newline token, so that the last token can be written. |
| 292 std::string NextToken(NewlineText); |
| 293 InsertClusterDirectives(CurToken, NextToken, true); |
| 294 WriteToken(CurToken); |
| 295 InsertClusterDirectives(CurToken, NextToken, false); |
| 296 WriteSpaces(SpaceCount); |
| 297 Formatter.Tokens() << Endline; |
| 298 |
| 299 EXPECT_TRUE(FunctionParseStack.empty()) |
| 300 << "Missing close parenthesis in example"; |
| 301 |
| 302 std::string Results = BufStream.str(); |
| 303 Reset(); |
| 304 return Results; |
| 305 } |
| 306 |
| 307 void FormatterTester::InsertClusterDirectives(std::string &CurToken, |
| 308 std::string &NextToken, |
| 309 bool BeforeCurToken) { |
| 310 if (!AddClusterDirectives) return; |
| 311 switch (State) { |
| 312 case LookingForFunction: |
| 313 break; |
| 314 case StartingFcn: |
| 315 if (!BeforeCurToken && CurToken == OpenParenText) { |
| 316 // context: <<<f(|>)>> |
| 317 // context: <<<f(|><x>)>> |
| 318 // context: <<<f(|><x,>><y,> ... <z>)> |
| 319 Formatter.Tokens() << FinishCluster; |
| 320 State = BeforeFirstArg; |
| 321 } |
| 322 break; |
| 323 case BeforeFirstArg: |
| 324 EXPECT_TRUE(BeforeCurToken) |
| 325 << "After open paren, but not before current token"; |
| 326 if (CurToken == CloseParenText) { |
| 327 // <<<f(>|)>> => EndFcn2: <<<f(>|)>> |
| 328 State = EndFcn2; |
| 329 } else { |
| 330 // <<<f(>|<x>)>> => InFirstArg: <<<f(><|x>)>> |
| 331 // <<<f(>|<x,>>[<y,>]*<z>)> => InFirstArg <<<f(><|x,>>[<y,>]*<z>)> |
| 332 State = InFirstArg; |
| 333 Formatter.Tokens() << StartCluster; |
| 334 } |
| 335 break; |
| 336 case InFirstArg: |
| 337 if (BeforeCurToken && CurToken == CloseParenText) { |
| 338 // <<<f(><x|>)>> => EndFcn2: <<<f(><x>|)>> |
| 339 Formatter.Tokens() << FinishCluster; |
| 340 State = EndFcn2; |
| 341 } else if (!BeforeCurToken && CurToken == CommaText) { |
| 342 // <<<f(><x,|>>[<y,>]*<z>)> => BetweenArgs: <<<f(><x,>>[|<y,>]*<z>)> |
| 343 Formatter.Tokens() << FinishCluster << FinishCluster; |
| 344 State = BetweenArgs; |
| 345 } |
| 346 break; |
| 347 case InOtherArg: |
| 348 if(BeforeCurToken && CurToken == CloseParenText) { |
| 349 // <<<f(><x,>>[<y,>]*<z|>)> => EndFcn1: <<<f(><x,>>[<y,>]*<z>|)> |
| 350 Formatter.Tokens() << FinishCluster; |
| 351 State = EndFcn1; |
| 352 } else if (!BeforeCurToken && CurToken == CommaText) { |
| 353 // <<<f(><x,>>[<y,|>]*<z>)> => BetweenArgs: <<<f(><x,>>[<y,>|]*<z>)> |
| 354 // => BetweenArgs: <<<f(><x,>>[<y,>]*|<z>)> |
| 355 Formatter.Tokens() << FinishCluster; |
| 356 State = BetweenArgs; |
| 357 } |
| 358 break; |
| 359 case BetweenArgs: |
| 360 // <<<f(><x,>>[|<y,>]*<z>)> => InOtherArg: <<<f(><x,>>[<|y,>]*<z>)> |
| 361 // <<<f(><x,>>[<y,>]*|<z>)> => InOtherArg: <<<f(><x,>>[<y,>]*<|z>)> |
| 362 EXPECT_TRUE(BeforeCurToken) |
| 363 << "Expecting to be before next token after comma"; |
| 364 Formatter.Tokens() << StartCluster; |
| 365 State = InOtherArg; |
| 366 break; |
| 367 case EndFcn2: |
| 368 // <<<f(>)|>> => EndFcn1: <<<f(>)>|> |
| 369 // <<<f(><x>)|>> => EndFcn1: <<<f(><x>)>|> |
| 370 EXPECT_TRUE(!BeforeCurToken && CurToken == CloseParenText) |
| 371 << "Expecting to be after close paren"; |
| 372 Formatter.Tokens() << FinishCluster; |
| 373 // Intentionally drop to the next case. |
| 374 case EndFcn1: |
| 375 // <<<f(>)>|> => XXX: <<<f(>)>>| |
| 376 // <<<f(><x>)>|> => XXX: <<<f(><x>)>>| |
| 377 // <<<f(><x,>>[<y,>]*<z>)|> => XXX: <<<f(><x,>>[<y,>]*<z>)>| |
| 378 EXPECT_TRUE(!BeforeCurToken && CurToken == CloseParenText) |
| 379 << "Expecting to be after close paren"; |
| 380 Formatter.Tokens() << FinishCluster; |
| 381 if (FunctionParseStack.empty()) { |
| 382 EXPECT_TRUE(false) |
| 383 << "No open paren for corresponding close paren"; |
| 384 State = LookingForFunction; |
| 385 } else { |
| 386 State = FunctionParseStack.back(); |
| 387 FunctionParseStack.pop_back(); |
| 388 } |
| 389 break; |
| 390 } |
| 391 |
| 392 // Check if we are at the beginning of a new function. |
| 393 if (BeforeCurToken && NextToken == OpenParenText) { |
| 394 // context: <<<|f(>)>> |
| 395 // context: <<<|f(><x>)>> |
| 396 // context: <<<|f(><x,>><y,> ... <z>)> |
| 397 Formatter.Tokens() << StartCluster << StartCluster << StartCluster; |
| 398 FunctionParseStack.push_back(State); |
| 399 State = StartingFcn; |
| 400 } |
| 401 } |
| 402 |
| 403 std::string RunTest(const char *Tokens[], |
| 404 size_t NumTokens, |
| 405 unsigned LineWidth, |
| 406 bool AddOpenCloseDirectives, |
| 407 bool AddClusterDirectives, |
| 408 unsigned Indent = 0) { |
| 409 FormatterTester Tester(LineWidth); |
| 410 return Tester.Test(Tokens, NumTokens, |
| 411 AddOpenCloseDirectives, |
| 412 AddClusterDirectives, |
| 413 Indent); |
| 414 } |
| 415 |
| 416 // Test simple single function call. |
| 417 TEST(NaClTextFormatterTest, SimpleCall) { |
| 418 static const char *Tokens[] = { |
| 419 "foobar", "(", "Value1", ",", " ", "Value2", "," , " ", "Value3", ")" |
| 420 }; |
| 421 |
| 422 // Print out simple call that can fit on one line. |
| 423 EXPECT_EQ( |
| 424 "foobar(Value1, Value2, Value3)\n", |
| 425 RunTest(Tokens, array_lengthof(Tokens), 30, true, true)); |
| 426 |
| 427 EXPECT_EQ( |
| 428 "foobar(Value1, Value2, Value3)\n", |
| 429 RunTest(Tokens, array_lengthof(Tokens), 30, true, false)); |
| 430 |
| 431 EXPECT_EQ( |
| 432 "foobar(Value1, Value2, Value3)\n", |
| 433 RunTest(Tokens, array_lengthof(Tokens), 30, false, true)); |
| 434 |
| 435 EXPECT_EQ( |
| 436 "foobar(Value1, Value2, Value3)\n", |
| 437 RunTest(Tokens, array_lengthof(Tokens), 30, false, false)); |
| 438 |
| 439 // Test case where it is one character too long (i.e ")" causes wrapping). |
| 440 EXPECT_EQ( |
| 441 "foobar(Value1, Value2, Value3\n" |
| 442 " )\n", |
| 443 RunTest(Tokens, array_lengthof(Tokens), 29, true, true)); |
| 444 |
| 445 EXPECT_EQ( |
| 446 "foobar(Value1, Value2, Value3\n" |
| 447 " )\n", |
| 448 RunTest(Tokens, array_lengthof(Tokens), 29, true, false)); |
| 449 |
| 450 EXPECT_EQ( |
| 451 "foobar(Value1, Value2, Value3\n" |
| 452 " )\n", |
| 453 RunTest(Tokens, array_lengthof(Tokens), 29, false, true)); |
| 454 |
| 455 EXPECT_EQ( |
| 456 "foobar(Value1, Value2, Value3\n" |
| 457 " )\n", |
| 458 RunTest(Tokens, array_lengthof(Tokens), 29, false, false)); |
| 459 |
| 460 // Test case where line length matches the beginning of "Value3". |
| 461 // Note: Only 3 indents for parenthesis directive, because we |
| 462 // stop indenting when there is only 20 columns left in the line |
| 463 // (i.e. 23 - 20 == 3). |
| 464 EXPECT_EQ( |
| 465 "foobar(Value1, Value2, \n" |
| 466 " Value3)\n", |
| 467 RunTest(Tokens, array_lengthof(Tokens), 23, true, true)); |
| 468 |
| 469 EXPECT_EQ( |
| 470 "foobar(Value1, Value2, \n" |
| 471 " Value3)\n", |
| 472 RunTest(Tokens, array_lengthof(Tokens), 23, true, false)); |
| 473 |
| 474 EXPECT_EQ( |
| 475 "foobar(Value1, Value2, \n" |
| 476 " Value3)\n", |
| 477 RunTest(Tokens, array_lengthof(Tokens), 23, false, true)); |
| 478 |
| 479 EXPECT_EQ( |
| 480 "foobar(Value1, Value2, \n" |
| 481 " Value3)\n", |
| 482 RunTest(Tokens, array_lengthof(Tokens), 23, false, false)); |
| 483 |
| 484 // Test case where line length matches the beginning of " Value3" |
| 485 // (i.e. the last test, but move the space to the next line). |
| 486 // Note: Only 2 indents for parenthesis directive, because we |
| 487 // stop indenting when there is only 20 columns left in the line |
| 488 // (i.e. 22 - 20 == 2). |
| 489 EXPECT_EQ( |
| 490 "foobar(Value1, Value2,\n" |
| 491 " Value3)\n", |
| 492 RunTest(Tokens, array_lengthof(Tokens), 22, true, true)); |
| 493 |
| 494 EXPECT_EQ( |
| 495 "foobar(Value1, Value2,\n" |
| 496 " Value3)\n", |
| 497 RunTest(Tokens, array_lengthof(Tokens), 22, true, false)); |
| 498 |
| 499 EXPECT_EQ( |
| 500 "foobar(Value1, Value2,\n" |
| 501 " Value3)\n", |
| 502 RunTest(Tokens, array_lengthof(Tokens), 22, false, true)); |
| 503 |
| 504 EXPECT_EQ( |
| 505 "foobar(Value1, Value2,\n" |
| 506 " Value3)\n", |
| 507 RunTest(Tokens, array_lengthof(Tokens), 22, false, false)); |
| 508 |
| 509 // Test case where last comma causes line wrap. |
| 510 EXPECT_EQ( |
| 511 "foobar(Value1, \n" |
| 512 " Value2, Value3)\n", |
| 513 RunTest(Tokens, array_lengthof(Tokens), 21, true, true)); |
| 514 |
| 515 EXPECT_EQ( |
| 516 "foobar(Value1, Value2\n" |
| 517 " , Value3)\n", |
| 518 RunTest(Tokens, array_lengthof(Tokens), 21, true, false)); |
| 519 |
| 520 EXPECT_EQ( |
| 521 "foobar(Value1, \n" |
| 522 " Value2, Value3)\n", |
| 523 RunTest(Tokens, array_lengthof(Tokens), 21, false, true)); |
| 524 |
| 525 EXPECT_EQ( |
| 526 "foobar(Value1, Value2\n" |
| 527 " , Value3)\n", |
| 528 RunTest(Tokens, array_lengthof(Tokens), 21, false, false)); |
| 529 |
| 530 // Test case where Value2 runs over the line width. |
| 531 EXPECT_EQ( |
| 532 "foobar(Value1, \n" |
| 533 "Value2, Value3)\n", |
| 534 RunTest(Tokens, array_lengthof(Tokens), 20, true, true)); |
| 535 |
| 536 EXPECT_EQ( |
| 537 "foobar(Value1, \n" |
| 538 "Value2, Value3)\n", |
| 539 RunTest(Tokens, array_lengthof(Tokens), 20, true, false)); |
| 540 |
| 541 EXPECT_EQ( |
| 542 "foobar(Value1, \n" |
| 543 "Value2, Value3)\n", |
| 544 RunTest(Tokens, array_lengthof(Tokens), 20, false, true)); |
| 545 |
| 546 EXPECT_EQ( |
| 547 "foobar(Value1, \n" |
| 548 "Value2, Value3)\n", |
| 549 RunTest(Tokens, array_lengthof(Tokens), 20, false, false)); |
| 550 |
| 551 // Run test where first comma (after value 1) causes line wrap. |
| 552 EXPECT_EQ( |
| 553 "foobar(\n" |
| 554 "Value1, \n" |
| 555 "Value2, \n" |
| 556 "Value3)\n", |
| 557 RunTest(Tokens, array_lengthof(Tokens), 13, true, true)); |
| 558 |
| 559 EXPECT_EQ( |
| 560 "foobar(Value1\n" |
| 561 ", Value2, \n" |
| 562 "Value3)\n", |
| 563 RunTest(Tokens, array_lengthof(Tokens), 13, true, false)); |
| 564 |
| 565 EXPECT_EQ( |
| 566 "foobar(\n" |
| 567 "Value1, \n" |
| 568 "Value2, \n" |
| 569 "Value3)\n", |
| 570 RunTest(Tokens, array_lengthof(Tokens), 13, false, true)); |
| 571 |
| 572 EXPECT_EQ( |
| 573 "foobar(Value1\n" |
| 574 ", Value2, \n" |
| 575 "Value3)\n", |
| 576 RunTest(Tokens, array_lengthof(Tokens), 13, false, false)); |
| 577 |
| 578 // Run test where only "foobar(" can fit on a line. |
| 579 EXPECT_EQ( |
| 580 "foobar(\n" |
| 581 "Value1,\n" |
| 582 "Value2,\n" |
| 583 "Value3)\n", |
| 584 RunTest(Tokens, array_lengthof(Tokens), 7, true, true)); |
| 585 |
| 586 EXPECT_EQ( |
| 587 "foobar(\n" |
| 588 "Value1,\n" |
| 589 "Value2,\n" |
| 590 "Value3)\n", |
| 591 RunTest(Tokens, array_lengthof(Tokens), 7, true, false)); |
| 592 |
| 593 EXPECT_EQ( |
| 594 "foobar(\n" |
| 595 "Value1,\n" |
| 596 "Value2,\n" |
| 597 "Value3)\n", |
| 598 RunTest(Tokens, array_lengthof(Tokens), 7, false, true)); |
| 599 |
| 600 EXPECT_EQ( |
| 601 "foobar(\n" |
| 602 "Value1,\n" |
| 603 "Value2,\n" |
| 604 "Value3)\n", |
| 605 RunTest(Tokens, array_lengthof(Tokens), 7, false, false)); |
| 606 |
| 607 // Run case where most tokens don't fit on a line. |
| 608 EXPECT_EQ( |
| 609 "foobar\n" |
| 610 "(\n" |
| 611 "Value1\n" |
| 612 ", \n" |
| 613 "Value2\n" |
| 614 ", \n" |
| 615 "Value3\n" |
| 616 ")\n", |
| 617 RunTest(Tokens, array_lengthof(Tokens), 4, true, true)); |
| 618 |
| 619 EXPECT_EQ( |
| 620 "foobar\n" |
| 621 "(\n" |
| 622 "Value1\n" |
| 623 ", \n" |
| 624 "Value2\n" |
| 625 ", \n" |
| 626 "Value3\n" |
| 627 ")\n", |
| 628 RunTest(Tokens, array_lengthof(Tokens), 4, true, false)); |
| 629 |
| 630 EXPECT_EQ( |
| 631 "foobar\n" |
| 632 "(\n" |
| 633 "Value1\n" |
| 634 ", \n" |
| 635 "Value2\n" |
| 636 ", \n" |
| 637 "Value3\n" |
| 638 ")\n", |
| 639 RunTest(Tokens, array_lengthof(Tokens), 4, false, true)); |
| 640 |
| 641 EXPECT_EQ( |
| 642 "foobar\n" |
| 643 "(\n" |
| 644 "Value1\n" |
| 645 ", \n" |
| 646 "Value2\n" |
| 647 ", \n" |
| 648 "Value3\n" |
| 649 ")\n", |
| 650 RunTest(Tokens, array_lengthof(Tokens), 4, false, false)); |
| 651 } |
| 652 |
| 653 // Test case where call isn't at the beginning of sequence of tokens. |
| 654 TEST(NaClTextFormatterTest, TokensPlusSimpleCall) { |
| 655 static const char *Tokens[] = { |
| 656 "354", " ", "+", " ", "the", " ", "best", " ", "+", " ", |
| 657 "foobar", "(", "Value1", ",", " ", "Value2", "," , " ", "Value3", ")" |
| 658 }; |
| 659 |
| 660 // Print out where all tokens fit on one line. |
| 661 EXPECT_EQ( |
| 662 "354 + the best + foobar(Value1, Value2, Value3)\n", |
| 663 RunTest(Tokens, array_lengthof(Tokens), 47, true, true)); |
| 664 |
| 665 EXPECT_EQ( |
| 666 "354 + the best + foobar(Value1, Value2, Value3)\n", |
| 667 RunTest(Tokens, array_lengthof(Tokens), 47, true, false)); |
| 668 |
| 669 EXPECT_EQ( |
| 670 "354 + the best + foobar(Value1, Value2, Value3)\n", |
| 671 RunTest(Tokens, array_lengthof(Tokens), 47, false, true)); |
| 672 |
| 673 EXPECT_EQ( |
| 674 "354 + the best + foobar(Value1, Value2, Value3)\n", |
| 675 RunTest(Tokens, array_lengthof(Tokens), 47, false, false)); |
| 676 |
| 677 // Format cases where buffer is one character too short to fit |
| 678 // all tokens. |
| 679 EXPECT_EQ( |
| 680 "354 + the best + \n" |
| 681 " foobar(Value1, Value2, Value3)\n", |
| 682 RunTest(Tokens, array_lengthof(Tokens), 46, true, true)); |
| 683 |
| 684 EXPECT_EQ( |
| 685 "354 + the best + foobar(Value1, Value2, Value3\n" |
| 686 " )\n", |
| 687 RunTest(Tokens, array_lengthof(Tokens), 46, true, false)); |
| 688 |
| 689 EXPECT_EQ( |
| 690 "354 + the best + \n" |
| 691 " foobar(Value1, Value2, Value3)\n", |
| 692 RunTest(Tokens, array_lengthof(Tokens), 46, false, true)); |
| 693 |
| 694 EXPECT_EQ( |
| 695 "354 + the best + foobar(Value1, Value2, Value3\n" |
| 696 " )\n", |
| 697 RunTest(Tokens, array_lengthof(Tokens), 46, false, false)); |
| 698 |
| 699 // Show case where function call just fits on continuation line. |
| 700 EXPECT_EQ( |
| 701 "354 + the best + \n" |
| 702 " foobar(Value1, Value2, Value3)\n", |
| 703 RunTest(Tokens, array_lengthof(Tokens), 34, true, true)); |
| 704 |
| 705 EXPECT_EQ( |
| 706 "354 + the best + foobar(Value1, \n" |
| 707 " Value2, Value3)\n", |
| 708 RunTest(Tokens, array_lengthof(Tokens), 34, true, false)); |
| 709 |
| 710 EXPECT_EQ( |
| 711 "354 + the best + \n" |
| 712 " foobar(Value1, Value2, Value3)\n", |
| 713 RunTest(Tokens, array_lengthof(Tokens), 34, false, true)); |
| 714 |
| 715 EXPECT_EQ( |
| 716 "354 + the best + foobar(Value1, \n" |
| 717 " Value2, Value3)\n", |
| 718 RunTest(Tokens, array_lengthof(Tokens), 34, false, false)); |
| 719 |
| 720 // Show case were close parenthesis doesn't fit on continuation line. |
| 721 EXPECT_EQ( |
| 722 "354 + the best + \n" |
| 723 " foobar(Value1, Value2, Value3\n" |
| 724 " )\n", |
| 725 RunTest(Tokens, array_lengthof(Tokens), 33, true, true)); |
| 726 |
| 727 EXPECT_EQ( |
| 728 "354 + the best + foobar(Value1, \n" |
| 729 " Value2, Value3)\n", |
| 730 RunTest(Tokens, array_lengthof(Tokens), 33, true, false)); |
| 731 |
| 732 EXPECT_EQ( |
| 733 "354 + the best + \n" |
| 734 " foobar(Value1, Value2, Value3\n" |
| 735 " )\n", |
| 736 RunTest(Tokens, array_lengthof(Tokens), 33, false, true)); |
| 737 |
| 738 EXPECT_EQ( |
| 739 "354 + the best + foobar(Value1, \n" |
| 740 " Value2, Value3)\n", |
| 741 RunTest(Tokens, array_lengthof(Tokens), 33, false, false)); |
| 742 |
| 743 // Show case where "Value1," just fits on the first continuation line. |
| 744 EXPECT_EQ( |
| 745 "354 + the best\n" |
| 746 "+ \n" |
| 747 "foobar(Value1,\n" |
| 748 "Value2, Value3\n" |
| 749 ")\n", |
| 750 RunTest(Tokens, array_lengthof(Tokens), 14, true, true)); |
| 751 |
| 752 EXPECT_EQ( |
| 753 "354 + the best\n" |
| 754 "+ foobar(\n" |
| 755 "Value1, Value2\n" |
| 756 ", Value3)\n", |
| 757 RunTest(Tokens, array_lengthof(Tokens), 14, true, false)); |
| 758 |
| 759 EXPECT_EQ( |
| 760 "354 + the best\n" |
| 761 "+ \n" |
| 762 "foobar(Value1,\n" |
| 763 "Value2, Value3\n" |
| 764 ")\n", |
| 765 RunTest(Tokens, array_lengthof(Tokens), 14, false, true)); |
| 766 |
| 767 EXPECT_EQ( |
| 768 "354 + the best\n" |
| 769 "+ foobar(\n" |
| 770 "Value1, Value2\n," |
| 771 " Value3)\n", |
| 772 RunTest(Tokens, array_lengthof(Tokens), 14, false, false)); |
| 773 |
| 774 // Show case where "Value1," moves to a new line. |
| 775 EXPECT_EQ( |
| 776 "354 + the \n" |
| 777 "best + \n" |
| 778 "foobar(\n" |
| 779 "Value1, \n" |
| 780 "Value2, \n" |
| 781 "Value3)\n", |
| 782 RunTest(Tokens, array_lengthof(Tokens), 13, true, true)); |
| 783 |
| 784 EXPECT_EQ( |
| 785 "354 + the \n" |
| 786 "best + foobar\n" |
| 787 "(Value1, \n" |
| 788 "Value2, \n" |
| 789 "Value3)\n", |
| 790 RunTest(Tokens, array_lengthof(Tokens), 13, true, false)); |
| 791 |
| 792 EXPECT_EQ( |
| 793 "354 + the \n" |
| 794 "best + \n" |
| 795 "foobar(\n" |
| 796 "Value1, \n" |
| 797 "Value2, \n" |
| 798 "Value3)\n", |
| 799 RunTest(Tokens, array_lengthof(Tokens), 13, false, true)); |
| 800 |
| 801 EXPECT_EQ( |
| 802 "354 + the \n" |
| 803 "best + foobar\n" |
| 804 "(Value1, \n" |
| 805 "Value2, \n" |
| 806 "Value3)\n", |
| 807 RunTest(Tokens, array_lengthof(Tokens), 13, false, false)); |
| 808 |
| 809 } |
| 810 |
| 811 // Test case of nested functions. |
| 812 TEST(NaClTextFormatterTest, NestedCalls) { |
| 813 static const char *Tokens[] = { |
| 814 "354", " ", "+", " ", "foo", "(", "g", "(", "blah", ")", ",", " ", |
| 815 "h", "(", ")", " ", "+", " ", "1", ")", " ", "+", " ", "10" |
| 816 }; |
| 817 |
| 818 // Run test case where all text fits on one line. |
| 819 EXPECT_EQ( |
| 820 "354 + foo(g(blah), h() + 1) + 10\n", |
| 821 RunTest(Tokens, array_lengthof(Tokens), 32, true, true)); |
| 822 |
| 823 EXPECT_EQ( |
| 824 "354 + foo(g(blah), h() + 1) + 10\n", |
| 825 RunTest(Tokens, array_lengthof(Tokens), 32, true, false)); |
| 826 |
| 827 EXPECT_EQ( |
| 828 "354 + foo(g(blah), h() + 1) + 10\n", |
| 829 RunTest(Tokens, array_lengthof(Tokens), 32, false, true)); |
| 830 |
| 831 EXPECT_EQ( |
| 832 "354 + foo(g(blah), h() + 1) + 10\n", |
| 833 RunTest(Tokens, array_lengthof(Tokens), 32, false, false)); |
| 834 |
| 835 // Run test case where all text to end of top-level function call |
| 836 // fit on first line. |
| 837 EXPECT_EQ( |
| 838 "354 + foo(g(blah), h() + 1)\n" |
| 839 " + 10\n", |
| 840 RunTest(Tokens, array_lengthof(Tokens), 27, true, true)); |
| 841 |
| 842 EXPECT_EQ( |
| 843 "354 + foo(g(blah), h() + 1)\n" |
| 844 " + 10\n", |
| 845 RunTest(Tokens, array_lengthof(Tokens), 27, true, false)); |
| 846 |
| 847 EXPECT_EQ( |
| 848 "354 + foo(g(blah), h() + 1)\n" |
| 849 " + 10\n", |
| 850 RunTest(Tokens, array_lengthof(Tokens), 27, false, true)); |
| 851 |
| 852 EXPECT_EQ( |
| 853 "354 + foo(g(blah), h() + 1)\n" |
| 854 " + 10\n", |
| 855 RunTest(Tokens, array_lengthof(Tokens), 27, false, false)); |
| 856 |
| 857 // Run test where call to foo doesn't fit on first line. |
| 858 EXPECT_EQ( |
| 859 "354 + \n" |
| 860 " foo(g(blah), h() + 1) \n" |
| 861 " + 10\n", |
| 862 RunTest(Tokens, array_lengthof(Tokens), 26, true, true)); |
| 863 |
| 864 EXPECT_EQ( |
| 865 "354 + foo(g(blah), h() + 1\n" |
| 866 " ) + 10\n", |
| 867 RunTest(Tokens, array_lengthof(Tokens), 26, true, false)); |
| 868 |
| 869 EXPECT_EQ( |
| 870 "354 + \n" |
| 871 " foo(g(blah), h() + 1) \n" |
| 872 " + 10\n", |
| 873 RunTest(Tokens, array_lengthof(Tokens), 26, false, true)); |
| 874 |
| 875 EXPECT_EQ( |
| 876 "354 + foo(g(blah), h() + 1\n" |
| 877 " ) + 10\n", |
| 878 RunTest(Tokens, array_lengthof(Tokens), 26, false, false)); |
| 879 |
| 880 // Run test where call to foo doesn't fit on continuation line. |
| 881 EXPECT_EQ( |
| 882 "354 + \n" |
| 883 " foo(g(blah), h() + 1\n" |
| 884 " ) + 10\n", |
| 885 RunTest(Tokens, array_lengthof(Tokens), 24, true, true)); |
| 886 |
| 887 EXPECT_EQ( |
| 888 "354 + foo(g(blah), h() +\n" |
| 889 " 1) + 10\n", |
| 890 RunTest(Tokens, array_lengthof(Tokens), 24, true, false)); |
| 891 |
| 892 EXPECT_EQ( |
| 893 "354 + \n" |
| 894 " foo(g(blah), h() + 1\n" |
| 895 " ) + 10\n", |
| 896 RunTest(Tokens, array_lengthof(Tokens), 24, false, true)); |
| 897 |
| 898 EXPECT_EQ( |
| 899 "354 + foo(g(blah), h() +\n" |
| 900 " 1) + 10\n", |
| 901 RunTest(Tokens, array_lengthof(Tokens), 24, false, false)); |
| 902 |
| 903 // Run test where call to foo doesn't fit on continuation line. |
| 904 // Note: same as above, except for loss of continuation indent, |
| 905 // since we don't indent when printable space shrinks to 20. |
| 906 EXPECT_EQ( |
| 907 "354 + \n" |
| 908 "foo(g(blah), h() + 1\n" |
| 909 ") + 10\n", |
| 910 RunTest(Tokens, array_lengthof(Tokens), 20, true, true)); |
| 911 |
| 912 EXPECT_EQ( |
| 913 "354 + foo(g(blah), h\n" |
| 914 "() + 1) + 10\n", |
| 915 RunTest(Tokens, array_lengthof(Tokens), 20, true, false)); |
| 916 |
| 917 EXPECT_EQ( |
| 918 "354 + \n" |
| 919 "foo(g(blah), h() + 1\n" |
| 920 ") + 10\n", |
| 921 RunTest(Tokens, array_lengthof(Tokens), 20, false, true)); |
| 922 |
| 923 EXPECT_EQ( |
| 924 "354 + foo(g(blah), h\n" |
| 925 "() + 1) + 10\n", |
| 926 RunTest(Tokens, array_lengthof(Tokens), 20, false, false)); |
| 927 |
| 928 // Run case where first argument of foo (i.e. g(blah)) fits |
| 929 // on single continuation line. |
| 930 EXPECT_EQ( |
| 931 "354 + \n" |
| 932 "foo(g(blah), \n" |
| 933 "h() + 1) + 10\n", |
| 934 RunTest(Tokens, array_lengthof(Tokens), 19, true, true)); |
| 935 |
| 936 EXPECT_EQ( |
| 937 "354 + foo(g(blah), \n" |
| 938 "h() + 1) + 10\n", |
| 939 RunTest(Tokens, array_lengthof(Tokens), 19, true, false)); |
| 940 |
| 941 EXPECT_EQ( |
| 942 "354 + \n" |
| 943 "foo(g(blah), \n" |
| 944 "h() + 1) + 10\n", |
| 945 RunTest(Tokens, array_lengthof(Tokens), 19, false, true)); |
| 946 |
| 947 EXPECT_EQ( |
| 948 "354 + foo(g(blah), \n" |
| 949 "h() + 1) + 10\n", |
| 950 RunTest(Tokens, array_lengthof(Tokens), 19, false, false)); |
| 951 |
| 952 // Run case where no room for call to foo and its first argument. |
| 953 EXPECT_EQ( |
| 954 "354 + \n" |
| 955 "foo(\n" |
| 956 "g(blah), \n" |
| 957 "h() + 1) + \n" |
| 958 "10\n", |
| 959 RunTest(Tokens, array_lengthof(Tokens), 11, true, true)); |
| 960 |
| 961 EXPECT_EQ( |
| 962 "354 + foo(g\n" |
| 963 "(blah), h()\n" |
| 964 "+ 1) + 10\n", |
| 965 RunTest(Tokens, array_lengthof(Tokens), 11, true, false)); |
| 966 |
| 967 EXPECT_EQ( |
| 968 "354 + \n" |
| 969 "foo(\n" |
| 970 "g(blah), \n" |
| 971 "h() + 1) + \n" |
| 972 "10\n", |
| 973 RunTest(Tokens, array_lengthof(Tokens), 11, false, true)); |
| 974 |
| 975 EXPECT_EQ( |
| 976 "354 + foo(g\n" |
| 977 "(blah), h()\n" |
| 978 "+ 1) + 10\n", |
| 979 RunTest(Tokens, array_lengthof(Tokens), 11, false, false)); |
| 980 } |
| 981 |
| 982 // Test example with many arguments (which can't be printed on one line). |
| 983 TEST(NaClTextFormatterTest, ManyArgs) { |
| 984 static const char *Tokens[] = { |
| 985 "10", " ", "+", " ", "f", "(", |
| 986 "g", "(", "a", ",", " ", "b", ")", ",", " ", |
| 987 "abcdef", " ", "+", " ", "gh1196", " ", "+", " ", "z", "(", ")", ",", " ", |
| 988 "53267", " ", "*", " ", "1234", " ", "+", " ", "567", ",", " ", |
| 989 "why", "(", "is", ",", " ", "this", ",", " ", "so", ",", " ", "hard", |
| 990 ",", " ", "to", ",", " ", "do", ")", ",", " ", |
| 991 "g", "(", "a", ",", " ", "b", ")", ",", " ", |
| 992 "abcdef", " ", "+", " ", "gh1196", " ", "+", " ", "z", "(", ")", ",", " ", |
| 993 "53267", " ", "*", " ", "1234", " ", "+", " ", "567", " ", "*", " ", |
| 994 "somemorestuff", ")", " ", "+", " ", "1" |
| 995 }; |
| 996 |
| 997 // Show layout with linewidth 70 |
| 998 EXPECT_EQ( |
| 999 "10 + \n" |
| 1000 " f(g(a, b), abcdef + gh1196 + z(), 53267 * 1234 + 567, \n" |
| 1001 " why(is, this, so, hard, to, do), g(a, b), abcdef + gh1196 + z(),\n" |
| 1002 " 53267 * 1234 + 567 * somemorestuff) + 1\n", |
| 1003 RunTest(Tokens, array_lengthof(Tokens), 70, true, true)); |
| 1004 |
| 1005 EXPECT_EQ( |
| 1006 "10 + f(g(a, b), abcdef + gh1196 + z(), 53267 * 1234 + 567, why(is, \n" |
| 1007 " this, so, hard, to, \n" |
| 1008 " do), g(a, b), abcdef\n" |
| 1009 " + gh1196 + z(), 53267 * 1234 + 567 * somemorestuff) + 1\n", |
| 1010 RunTest(Tokens, array_lengthof(Tokens), 70, true, false)); |
| 1011 |
| 1012 EXPECT_EQ( |
| 1013 "10 + \n" |
| 1014 " f(g(a, b), abcdef + gh1196 + z(), 53267 * 1234 + 567, \n" |
| 1015 " why(is, this, so, hard, to, do), g(a, b), abcdef + gh1196 + z(), \n" |
| 1016 " 53267 * 1234 + 567 * somemorestuff) + 1\n", |
| 1017 RunTest(Tokens, array_lengthof(Tokens), 70, false, true)); |
| 1018 |
| 1019 EXPECT_EQ( |
| 1020 "10 + f(g(a, b), abcdef + gh1196 + z(), 53267 * 1234 + 567, why(is, \n" |
| 1021 " this, so, hard, to, do), g(a, b), abcdef + gh1196 + z(), 53267 * \n" |
| 1022 " 1234 + 567 * somemorestuff) + 1\n", |
| 1023 RunTest(Tokens, array_lengthof(Tokens), 70, false, false)); |
| 1024 |
| 1025 // Show layout with linewidth 60 |
| 1026 EXPECT_EQ( |
| 1027 "10 + \n" |
| 1028 " f(g(a, b), abcdef + gh1196 + z(), 53267 * 1234 + 567, \n" |
| 1029 " why(is, this, so, hard, to, do), g(a, b), \n" |
| 1030 " abcdef + gh1196 + z(), \n" |
| 1031 " 53267 * 1234 + 567 * somemorestuff) + 1\n", |
| 1032 RunTest(Tokens, array_lengthof(Tokens), 60, true, true)); |
| 1033 |
| 1034 EXPECT_EQ( |
| 1035 "10 + f(g(a, b), abcdef + gh1196 + z(), 53267 * 1234 + 567, \n" |
| 1036 " why(is, this, so, hard, to, do), g(a, b), abcdef + \n" |
| 1037 " gh1196 + z(), 53267 * 1234 + 567 * somemorestuff) + 1\n", |
| 1038 RunTest(Tokens, array_lengthof(Tokens), 60, true, false)); |
| 1039 |
| 1040 EXPECT_EQ( |
| 1041 "10 + \n" |
| 1042 " f(g(a, b), abcdef + gh1196 + z(), 53267 * 1234 + 567, \n" |
| 1043 " why(is, this, so, hard, to, do), g(a, b), \n" |
| 1044 " abcdef + gh1196 + z(), \n" |
| 1045 " 53267 * 1234 + 567 * somemorestuff) + 1\n", |
| 1046 RunTest(Tokens, array_lengthof(Tokens), 60, false, true)); |
| 1047 |
| 1048 EXPECT_EQ( |
| 1049 "10 + f(g(a, b), abcdef + gh1196 + z(), 53267 * 1234 + 567, \n" |
| 1050 " why(is, this, so, hard, to, do), g(a, b), abcdef + \n" |
| 1051 " gh1196 + z(), 53267 * 1234 + 567 * somemorestuff) + 1\n", |
| 1052 RunTest(Tokens, array_lengthof(Tokens), 60, false, false)); |
| 1053 |
| 1054 // Show layout with linewidth 50. |
| 1055 EXPECT_EQ( |
| 1056 "10 + \n" |
| 1057 " f(g(a, b), abcdef + gh1196 + z(), \n" |
| 1058 " 53267 * 1234 + 567, \n" |
| 1059 " why(is, this, so, hard, to, do), g(a, b), \n" |
| 1060 " abcdef + gh1196 + z(), \n" |
| 1061 " 53267 * 1234 + 567 * somemorestuff) + 1\n", |
| 1062 RunTest(Tokens, array_lengthof(Tokens), 50, true, true)); |
| 1063 |
| 1064 EXPECT_EQ( |
| 1065 "10 + f(g(a, b), abcdef + gh1196 + z(), 53267 * \n" |
| 1066 " 1234 + 567, why(is, this, so, hard, to, do)\n" |
| 1067 " , g(a, b), abcdef + gh1196 + z(), 53267 * \n" |
| 1068 " 1234 + 567 * somemorestuff) + 1\n", |
| 1069 RunTest(Tokens, array_lengthof(Tokens), 50, true, false)); |
| 1070 |
| 1071 EXPECT_EQ( |
| 1072 "10 + \n" |
| 1073 " f(g(a, b), abcdef + gh1196 + z(), \n" |
| 1074 " 53267 * 1234 + 567, \n" |
| 1075 " why(is, this, so, hard, to, do), g(a, b), \n" |
| 1076 " abcdef + gh1196 + z(), \n" |
| 1077 " 53267 * 1234 + 567 * somemorestuff) + 1\n", |
| 1078 RunTest(Tokens, array_lengthof(Tokens), 50, false, true)); |
| 1079 |
| 1080 EXPECT_EQ( |
| 1081 "10 + f(g(a, b), abcdef + gh1196 + z(), 53267 * \n" |
| 1082 " 1234 + 567, why(is, this, so, hard, to, do), g\n" |
| 1083 " (a, b), abcdef + gh1196 + z(), 53267 * 1234 + \n" |
| 1084 " 567 * somemorestuff) + 1\n", |
| 1085 RunTest(Tokens, array_lengthof(Tokens), 50, false, false)); |
| 1086 |
| 1087 // Show layout with linewidth 40 |
| 1088 EXPECT_EQ( |
| 1089 "10 + \n" |
| 1090 " f(g(a, b), abcdef + gh1196 + z(), \n" |
| 1091 " 53267 * 1234 + 567, \n" |
| 1092 " why(is, this, so, hard, to, do), \n" |
| 1093 " g(a, b), abcdef + gh1196 + z(), \n" |
| 1094 " 53267 * 1234 + 567 * somemorestuff\n" |
| 1095 " ) + 1\n", |
| 1096 RunTest(Tokens, array_lengthof(Tokens), 40, true, true)); |
| 1097 |
| 1098 EXPECT_EQ( |
| 1099 "10 + f(g(a, b), abcdef + gh1196 + z(), \n" |
| 1100 " 53267 * 1234 + 567, why(is, this,\n" |
| 1101 " so, hard, to, do), g\n" |
| 1102 " (a, b), abcdef + gh1196 + z(), \n" |
| 1103 " 53267 * 1234 + 567 * \n" |
| 1104 " somemorestuff) + 1\n", |
| 1105 RunTest(Tokens, array_lengthof(Tokens), 40, true, false)); |
| 1106 |
| 1107 EXPECT_EQ( |
| 1108 "10 + \n" |
| 1109 " f(g(a, b), abcdef + gh1196 + z(), \n" |
| 1110 " 53267 * 1234 + 567, \n" |
| 1111 " why(is, this, so, hard, to, do), \n" |
| 1112 " g(a, b), abcdef + gh1196 + z(), \n" |
| 1113 " 53267 * 1234 + 567 * somemorestuff) \n" |
| 1114 " + 1\n", |
| 1115 RunTest(Tokens, array_lengthof(Tokens), 40, false, true)); |
| 1116 |
| 1117 EXPECT_EQ( |
| 1118 "10 + f(g(a, b), abcdef + gh1196 + z(), \n" |
| 1119 " 53267 * 1234 + 567, why(is, this, so\n" |
| 1120 " , hard, to, do), g(a, b), abcdef + \n" |
| 1121 " gh1196 + z(), 53267 * 1234 + 567 * \n" |
| 1122 " somemorestuff) + 1\n", |
| 1123 RunTest(Tokens, array_lengthof(Tokens), 40, false, false)); |
| 1124 |
| 1125 // Show layout with linewidth 30 |
| 1126 EXPECT_EQ( |
| 1127 "10 + \n" |
| 1128 " f(g(a, b), \n" |
| 1129 " abcdef + gh1196 + z(), \n" |
| 1130 " 53267 * 1234 + 567, \n" |
| 1131 " why(is, this, so, hard, \n" |
| 1132 " to, do), g(a, b), \n" |
| 1133 " abcdef + gh1196 + z(), \n" |
| 1134 " 53267 * 1234 + 567 * \n" |
| 1135 " somemorestuff) + 1\n", |
| 1136 RunTest(Tokens, array_lengthof(Tokens), 30, true, true)); |
| 1137 |
| 1138 EXPECT_EQ( |
| 1139 "10 + f(g(a, b), abcdef + \n" |
| 1140 " gh1196 + z(), 53267 * \n" |
| 1141 " 1234 + 567, why(is, \n" |
| 1142 " this, so, hard, to, \n" |
| 1143 " do), g(a, b), abcdef\n" |
| 1144 " + gh1196 + z(), 53267 *\n" |
| 1145 " 1234 + 567 * \n" |
| 1146 " somemorestuff) + 1\n", |
| 1147 RunTest(Tokens, array_lengthof(Tokens), 30, true, false)); |
| 1148 |
| 1149 EXPECT_EQ( |
| 1150 "10 + \n" |
| 1151 " f(g(a, b), \n" |
| 1152 " abcdef + gh1196 + z(), \n" |
| 1153 " 53267 * 1234 + 567, \n" |
| 1154 " why(is, this, so, hard, \n" |
| 1155 " to, do), g(a, b), \n" |
| 1156 " abcdef + gh1196 + z(), \n" |
| 1157 " 53267 * 1234 + 567 * \n" |
| 1158 " somemorestuff) + 1\n", |
| 1159 RunTest(Tokens, array_lengthof(Tokens), 30, false, true)); |
| 1160 |
| 1161 EXPECT_EQ( |
| 1162 "10 + f(g(a, b), abcdef + \n" |
| 1163 " gh1196 + z(), 53267 * 1234\n" |
| 1164 " + 567, why(is, this, so, \n" |
| 1165 " hard, to, do), g(a, b), \n" |
| 1166 " abcdef + gh1196 + z(), \n" |
| 1167 " 53267 * 1234 + 567 * \n" |
| 1168 " somemorestuff) + 1\n", |
| 1169 RunTest(Tokens, array_lengthof(Tokens), 30, false, false)); |
| 1170 |
| 1171 // Show layout with linewidth 20. Note: Continuation indents no |
| 1172 // longer apply. |
| 1173 EXPECT_EQ( |
| 1174 "10 + \n" |
| 1175 "f(g(a, b), \n" |
| 1176 "abcdef + gh1196 + \n" |
| 1177 "z(), \n" |
| 1178 "53267 * 1234 + 567, \n" |
| 1179 "why(is, this, so, \n" |
| 1180 "hard, to, do), \n" |
| 1181 "g(a, b), \n" |
| 1182 "abcdef + gh1196 + \n" |
| 1183 "z(), \n" |
| 1184 "53267 * 1234 + 567 *\n" |
| 1185 "somemorestuff) + 1\n", |
| 1186 RunTest(Tokens, array_lengthof(Tokens), 20, true, true)); |
| 1187 |
| 1188 EXPECT_EQ( |
| 1189 "10 + f(g(a, b), \n" |
| 1190 "abcdef + gh1196 + z(\n" |
| 1191 "), 53267 * 1234 + \n" |
| 1192 "567, why(is, this, \n" |
| 1193 "so, hard, to, do), g\n" |
| 1194 "(a, b), abcdef + \n" |
| 1195 "gh1196 + z(), 53267 \n" |
| 1196 "* 1234 + 567 * \n" |
| 1197 "somemorestuff) + 1\n", |
| 1198 RunTest(Tokens, array_lengthof(Tokens), 20, true, false)); |
| 1199 |
| 1200 EXPECT_EQ( |
| 1201 "10 + \n" |
| 1202 "f(g(a, b), \n" |
| 1203 "abcdef + gh1196 + \n" |
| 1204 "z(), \n" |
| 1205 "53267 * 1234 + 567, \n" |
| 1206 "why(is, this, so, \n" |
| 1207 "hard, to, do), \n" |
| 1208 "g(a, b), \n" |
| 1209 "abcdef + gh1196 + \n" |
| 1210 "z(), \n" |
| 1211 "53267 * 1234 + 567 *\n" |
| 1212 "somemorestuff) + 1\n", |
| 1213 RunTest(Tokens, array_lengthof(Tokens), 20, false, true)); |
| 1214 |
| 1215 EXPECT_EQ( |
| 1216 "10 + f(g(a, b), \n" |
| 1217 "abcdef + gh1196 + z(\n" |
| 1218 "), 53267 * 1234 + \n" |
| 1219 "567, why(is, this, \n" |
| 1220 "so, hard, to, do), g\n" |
| 1221 "(a, b), abcdef + \n" |
| 1222 "gh1196 + z(), 53267 \n" |
| 1223 "* 1234 + 567 * \n" |
| 1224 "somemorestuff) + 1\n", |
| 1225 RunTest(Tokens, array_lengthof(Tokens), 20, false, false)); |
| 1226 |
| 1227 // Show layout with linewidth 10, where some tokens ("somemorestuff") |
| 1228 // exceed the line width requirement. |
| 1229 EXPECT_EQ( |
| 1230 "10 + \n" |
| 1231 "f(g(a, b),\n" |
| 1232 "abcdef + \n" |
| 1233 "gh1196 + \n" |
| 1234 "z(), \n" |
| 1235 "53267 * \n" |
| 1236 "1234 + 567\n" |
| 1237 ", \n" |
| 1238 "why(is, \n" |
| 1239 "this, so, \n" |
| 1240 "hard, to, \n" |
| 1241 "do), \n" |
| 1242 "g(a, b), \n" |
| 1243 "abcdef + \n" |
| 1244 "gh1196 + \n" |
| 1245 "z(), \n" |
| 1246 "53267 * \n" |
| 1247 "1234 + 567\n" |
| 1248 "* \n" |
| 1249 "somemorestuff\n" |
| 1250 ") + 1\n", |
| 1251 RunTest(Tokens, array_lengthof(Tokens), 10, true, true)); |
| 1252 |
| 1253 EXPECT_EQ( |
| 1254 "10 + f(g(a\n" |
| 1255 ", b), \n" |
| 1256 "abcdef + \n" |
| 1257 "gh1196 + z\n" |
| 1258 "(), 53267 \n" |
| 1259 "* 1234 + \n" |
| 1260 "567, why(\n" |
| 1261 "is, this, \n" |
| 1262 "so, hard, \n" |
| 1263 "to, do), g\n" |
| 1264 "(a, b), \n" |
| 1265 "abcdef + \n" |
| 1266 "gh1196 + z\n" |
| 1267 "(), 53267 \n" |
| 1268 "* 1234 + \n" |
| 1269 "567 * \n" |
| 1270 "somemorestuff\n" |
| 1271 ") + 1\n", |
| 1272 RunTest(Tokens, array_lengthof(Tokens), 10, true, false)); |
| 1273 |
| 1274 EXPECT_EQ( |
| 1275 "10 + \n" |
| 1276 "f(g(a, b),\n" |
| 1277 "abcdef + \n" |
| 1278 "gh1196 + \n" |
| 1279 "z(), \n" |
| 1280 "53267 * \n" |
| 1281 "1234 + 567\n" |
| 1282 ", \n" |
| 1283 "why(is, \n" |
| 1284 "this, so, \n" |
| 1285 "hard, to, \n" |
| 1286 "do), \n" |
| 1287 "g(a, b), \n" |
| 1288 "abcdef + \n" |
| 1289 "gh1196 + \n" |
| 1290 "z(), \n" |
| 1291 "53267 * \n" |
| 1292 "1234 + 567\n" |
| 1293 "* \n" |
| 1294 "somemorestuff\n" |
| 1295 ") + 1\n", |
| 1296 RunTest(Tokens, array_lengthof(Tokens), 10, false, true)); |
| 1297 |
| 1298 EXPECT_EQ( |
| 1299 "10 + f(g(a\n" |
| 1300 ", b), \n" |
| 1301 "abcdef + \n" |
| 1302 "gh1196 + z\n" |
| 1303 "(), 53267 \n" |
| 1304 "* 1234 + \n" |
| 1305 "567, why(\n" |
| 1306 "is, this, \n" |
| 1307 "so, hard, \n" |
| 1308 "to, do), g\n" |
| 1309 "(a, b), \n" |
| 1310 "abcdef + \n" |
| 1311 "gh1196 + z\n" |
| 1312 "(), 53267 \n" |
| 1313 "* 1234 + \n" |
| 1314 "567 * \n" |
| 1315 "somemorestuff\n" |
| 1316 ") + 1\n", |
| 1317 RunTest(Tokens, array_lengthof(Tokens), 10, false, false)); |
| 1318 } |
| 1319 |
| 1320 // Turn test case that checks if indenting works. |
| 1321 TEST(NaClTextFormatterTest, Indenting) { |
| 1322 static const char *Tokens[] = { |
| 1323 "354", " ", "+", " ", "foo", "(", "g", "(", "blah", ")", ",", " ", |
| 1324 "h", "(", ")", " ", "+", " ", "1", ")", " ", "+", " ", "10" |
| 1325 }; |
| 1326 |
| 1327 // Run with no indentation. |
| 1328 EXPECT_EQ( |
| 1329 "354 + foo(g(blah), h() + 1) + 10\n", |
| 1330 RunTest(Tokens, array_lengthof(Tokens), 32, true, true, 0)); |
| 1331 |
| 1332 EXPECT_EQ( |
| 1333 "354 + foo(g(blah), h() + 1) + 10\n", |
| 1334 RunTest(Tokens, array_lengthof(Tokens), 32, true, false, 0)); |
| 1335 |
| 1336 EXPECT_EQ( |
| 1337 "354 + foo(g(blah), h() + 1) + 10\n", |
| 1338 RunTest(Tokens, array_lengthof(Tokens), 32, false, true, 0)); |
| 1339 |
| 1340 EXPECT_EQ( |
| 1341 "354 + foo(g(blah), h() + 1) + 10\n", |
| 1342 RunTest(Tokens, array_lengthof(Tokens), 32, false, false, 0)); |
| 1343 |
| 1344 // Run with one indent. |
| 1345 EXPECT_EQ( |
| 1346 " 354 + foo(g(blah), h() + 1) + \n" |
| 1347 " 10\n", |
| 1348 RunTest(Tokens, array_lengthof(Tokens), 32, true, true, 1)); |
| 1349 |
| 1350 EXPECT_EQ( |
| 1351 " 354 + foo(g(blah), h() + 1) + \n" |
| 1352 " 10\n", |
| 1353 RunTest(Tokens, array_lengthof(Tokens), 32, true, false, 1)); |
| 1354 |
| 1355 EXPECT_EQ( |
| 1356 " 354 + foo(g(blah), h() + 1) + \n" |
| 1357 " 10\n", |
| 1358 RunTest(Tokens, array_lengthof(Tokens), 32, false, true, 1)); |
| 1359 |
| 1360 EXPECT_EQ( |
| 1361 " 354 + foo(g(blah), h() + 1) + \n" |
| 1362 " 10\n", |
| 1363 RunTest(Tokens, array_lengthof(Tokens), 32, false, false, 1)); |
| 1364 |
| 1365 |
| 1366 // Run with two indents. |
| 1367 EXPECT_EQ( |
| 1368 " 354 + foo(g(blah), h() + 1) \n" |
| 1369 " + 10\n", |
| 1370 RunTest(Tokens, array_lengthof(Tokens), 32, true, true, 2)); |
| 1371 |
| 1372 EXPECT_EQ( |
| 1373 " 354 + foo(g(blah), h() + 1) \n" |
| 1374 " + 10\n", |
| 1375 RunTest(Tokens, array_lengthof(Tokens), 32, true, false, 2)); |
| 1376 |
| 1377 EXPECT_EQ( |
| 1378 " 354 + foo(g(blah), h() + 1) \n" |
| 1379 " + 10\n", |
| 1380 RunTest(Tokens, array_lengthof(Tokens), 32, false, true, 2)); |
| 1381 |
| 1382 EXPECT_EQ( |
| 1383 " 354 + foo(g(blah), h() + 1) \n" |
| 1384 " + 10\n", |
| 1385 RunTest(Tokens, array_lengthof(Tokens), 32, false, false, 2)); |
| 1386 |
| 1387 // Run with five indents. |
| 1388 EXPECT_EQ( |
| 1389 " 354 + \n" |
| 1390 " foo(g(blah), h() + 1\n" |
| 1391 " ) + 10\n", |
| 1392 RunTest(Tokens, array_lengthof(Tokens), 32, true, true, 5)); |
| 1393 |
| 1394 EXPECT_EQ( |
| 1395 " 354 + foo(g(blah), h()\n" |
| 1396 " + 1) + 10\n", |
| 1397 RunTest(Tokens, array_lengthof(Tokens), 32, true, false, 5)); |
| 1398 |
| 1399 EXPECT_EQ( |
| 1400 " 354 + \n" |
| 1401 " foo(g(blah), h() + 1\n" |
| 1402 " ) + 10\n", |
| 1403 RunTest(Tokens, array_lengthof(Tokens), 32, false, true, 5)); |
| 1404 |
| 1405 EXPECT_EQ( |
| 1406 " 354 + foo(g(blah), h()\n" |
| 1407 " + 1) + 10\n", |
| 1408 RunTest(Tokens, array_lengthof(Tokens), 32, false, false, 5)); |
| 1409 } |
| 1410 } |
OLD | NEW |