1 /* 2 * Copyright 2015 Google Inc. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 * in compliance with the License. You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software distributed under the License 10 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 * or implied. See the License for the specific language governing permissions and limitations under 12 * the License. 13 */ 14 15 package com.google.googlejavaformat.java; 16 17 import static com.google.common.truth.Truth.assertThat; 18 import static java.nio.charset.StandardCharsets.UTF_8; 19 import static org.junit.Assert.assertEquals; 20 21 import com.google.common.base.Joiner; 22 import com.google.common.collect.ImmutableList; 23 import com.google.common.collect.ObjectArrays; 24 import com.google.common.collect.Range; 25 import java.io.IOException; 26 import java.io.PrintWriter; 27 import java.io.StringWriter; 28 import java.nio.file.Files; 29 import java.nio.file.Path; 30 import java.util.ArrayList; 31 import java.util.List; 32 import org.junit.Rule; 33 import org.junit.Test; 34 import org.junit.rules.TemporaryFolder; 35 import org.junit.runner.RunWith; 36 import org.junit.runners.Parameterized; 37 import org.junit.runners.Parameterized.Parameters; 38 39 /** Tests formatting parts of files. */ 40 @RunWith(Parameterized.class) 41 public final class PartialFormattingTest { 42 43 @Parameters parameters()44 public static Iterable<Object[]> parameters() { 45 return ImmutableList.copyOf(new Object[][] {{"\n"}, {"\r"}, {"\r\n"}}); 46 } 47 48 @Rule public TemporaryFolder testFolder = new TemporaryFolder(); 49 50 private final String newline; 51 PartialFormattingTest(String newline)52 public PartialFormattingTest(String newline) { 53 this.newline = newline; 54 } 55 lines(String... args)56 String lines(String... args) { 57 return Joiner.on(newline).join(args); 58 } 59 60 @Test testGetFormatReplacements0()61 public void testGetFormatReplacements0() throws Exception { 62 String input = 63 lines( 64 /* line 0 character 0 */ "class Foo{", 65 /* line 1 character 11 */ "void f", 66 /* line 2 character 18 */ "() {", 67 /* line 3 character 23 */ "}", 68 /* line 4 character 25 */ "}", 69 ""); 70 String expectedOutput = 71 lines( 72 73 /* line 0 character 0 */ "class Foo{", 74 /* line 1 character 11 */ " void f() {}", 75 /* line 2 character 25 */ "}", 76 ""); 77 // Claim to have modified the parentheses. 78 int start = input.indexOf("() {"); 79 String output = doGetFormatReplacements(input, start, start + 1); 80 assertThat(output).isEqualTo(expectedOutput); 81 } 82 83 @Test testGetFormatReplacements1()84 public void testGetFormatReplacements1() throws Exception { 85 String input = 86 lines( 87 /* line 0 character 0 */ "class Foo{", 88 /* line 1 character 11 */ "void f", 89 /* line 2 character 18 */ "() {", 90 /* line 3 character 23 */ "}", 91 /* line 4 character 25 */ "}", 92 ""); 93 String expectedOutput = 94 lines( 95 /* line 0 character 0 */ "class Foo{", 96 /* line 1 character 11 */ " void f() {}", 97 /* line 2 character 25 */ "}", 98 ""); 99 // Claim to have modified everything after the parentheses. 100 String output = doGetFormatReplacements(input, 20, 21); 101 assertThat(output).isEqualTo(expectedOutput); 102 } 103 104 @Test expandToStatement()105 public void expandToStatement() throws Exception { 106 String input = 107 lines( 108 "class Foo {{", 109 "ImmutableList<Integer> ids = ImmutableList.builder()", 110 ".add(1)", 111 ".add(2)", 112 ".add(3)", 113 ".build();", 114 "}}", 115 ""); 116 String expectedOutput = 117 lines( 118 "class Foo {{", 119 " ImmutableList<Integer> ids =" 120 + " ImmutableList.builder().add(1).add(2).add(3).build();", 121 "}}", 122 ""); 123 int idx = input.indexOf("add(2)"); 124 String output = doGetFormatReplacements(input, idx, idx + 1); 125 assertThat(output).isEqualTo(expectedOutput); 126 } 127 128 @Test expandToMethodSignature()129 public void expandToMethodSignature() throws Exception { 130 String input = 131 lines( 132 "class Foo {", 133 "void ", 134 " m() ", 135 " {", 136 "ImmutableList<Integer> ids = ImmutableList.builder()", 137 ".add(1)", 138 ".add(2)", 139 ".build();", 140 "}}", 141 ""); 142 String expectedOutput = 143 lines( 144 "class Foo {", 145 " void m() {", 146 "ImmutableList<Integer> ids = ImmutableList.builder()", 147 ".add(1)", 148 ".add(2)", 149 ".build();", 150 "}}", 151 ""); 152 int idx = input.indexOf("void"); 153 String output = doGetFormatReplacements(input, idx, idx + 1); 154 assertThat(output).isEqualTo(expectedOutput); 155 } 156 157 @Test expandToClassSignature()158 public void expandToClassSignature() throws Exception { 159 String input = 160 lines( 161 "class", 162 "Foo<XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX," 163 + "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX," 164 + "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX> {", 165 "void ", 166 " m() ", 167 " {", 168 "}}", 169 ""); 170 String expectedOutput = 171 lines( 172 "class Foo<", 173 " XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX,", 174 " XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX,", 175 " XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX> {", 176 "void ", 177 " m() ", 178 " {", 179 "}}", 180 ""); 181 int idx = input.indexOf("class"); 182 String output = doGetFormatReplacements(input, idx, idx + 1); 183 assertThat(output).isEqualTo(expectedOutput); 184 } 185 186 @Test ignoreNeighbouringStatements()187 public void ignoreNeighbouringStatements() throws Exception { 188 String input = 189 lines( 190 "class Test {", 191 "int ", 192 " xxx ", 193 " = 1;", 194 "int ", 195 " yyy ", 196 " = 1;", 197 "int ", 198 " zzz ", 199 " = 1;", 200 "}", 201 ""); 202 String expectedOutput = 203 lines( 204 "class Test {", 205 "int ", 206 " xxx ", 207 " = 1;", 208 " int yyy = 1;", 209 "int ", 210 " zzz ", 211 " = 1;", 212 "}", 213 ""); 214 int idx = input.indexOf("yyy"); 215 String output = doGetFormatReplacements(input, idx, idx + 1); 216 assertThat(output).isEqualTo(expectedOutput); 217 } 218 219 @Test insertLeadingNewlines()220 public void insertLeadingNewlines() throws Exception { 221 String input = 222 lines( 223 "class Test { int xxx = 1; int yyy = 1; int zzz = 1; }", // 224 ""); 225 String expectedOutput = 226 lines( 227 "class Test { int xxx = 1;", // 228 " int yyy = 1;", 229 " int zzz = 1; }", 230 ""); 231 int idx = input.indexOf("yyy"); 232 String output = doGetFormatReplacements(input, idx, idx + 1); 233 assertThat(output).isEqualTo(expectedOutput); 234 } 235 236 @Test insertLeadingNewlines2()237 public void insertLeadingNewlines2() throws Exception { 238 String input = 239 lines( 240 "class Test { int xxx = 1;", // 241 "", 242 " int yyy = 1; int zzz = 1; }"); 243 String expectedOutput = 244 lines( 245 "class Test { int xxx = 1;", // 246 "", // 247 " int yyy = 1;", 248 " int zzz = 1; }"); 249 int idx = input.indexOf("yyy"); 250 String output = doGetFormatReplacements(input, idx, idx + 1); 251 assertThat(output).isEqualTo(expectedOutput); 252 } 253 254 @Test insertTrailingNewlines()255 public void insertTrailingNewlines() throws Exception { 256 String input = 257 lines( 258 "class Test { int xxx = 1;", // 259 " int yyy = 1; int zzz = 1; }"); 260 String expectedOutput = 261 lines( 262 "class Test { int xxx = 1;", // 263 " int yyy = 1;", 264 " int zzz = 1; }"); 265 int idx = input.indexOf("yyy"); 266 String output = doGetFormatReplacements(input, idx, idx + 1); 267 assertThat(output).isEqualTo(expectedOutput); 268 } 269 270 @Test rejoinMethodSignatureLines()271 public void rejoinMethodSignatureLines() throws Exception { 272 String input = 273 lines( 274 "class Test { void zzz", // 275 "() { int x; } }"); 276 String expectedOutput = 277 lines( 278 "class Test {", // 279 " void zzz() {", 280 " int x; } }"); 281 int idx = input.indexOf("zzz"); 282 String output = doGetFormatReplacements(input, idx, idx); 283 assertThat(output).isEqualTo(expectedOutput); 284 } 285 286 @Test formatTrailingBrace()287 public void formatTrailingBrace() throws Exception { 288 String input = 289 lines( 290 "class Test { void f() { return; } }", // 291 ""); 292 String expectedOutput = 293 lines( 294 "class Test { void f() { return;", // 295 " }", 296 "}", 297 ""); 298 int idx = input.indexOf("}"); 299 String output = doGetFormatReplacements(input, idx, idx); 300 assertThat(output).isEqualTo(expectedOutput); 301 } 302 303 @Test formatTrailingBraceEmptyMethodBody()304 public void formatTrailingBraceEmptyMethodBody() throws Exception { 305 String input = 306 lines( 307 "class Test { void f() {} }", // 308 ""); 309 String expectedOutput = 310 lines( 311 "class Test {", // 312 " void f() {}", 313 "}", 314 ""); 315 int idx = input.indexOf("}"); 316 String output = doGetFormatReplacements(input, idx, idx); 317 assertThat(output).isEqualTo(expectedOutput); 318 } 319 320 @Test formatTrailingBraceEmptyClassBody()321 public void formatTrailingBraceEmptyClassBody() throws Exception { 322 String input = 323 lines( 324 "class Test { int x; }", // 325 ""); 326 String expectedOutput = 327 lines( 328 "class Test { int x;", // 329 "}", 330 ""); 331 int idx = input.indexOf("}"); 332 String output = doGetFormatReplacements(input, idx, idx); 333 assertThat(output).isEqualTo(expectedOutput); 334 } 335 336 @Test formatTrailingBraceEmptyClassBody2()337 public void formatTrailingBraceEmptyClassBody2() throws Exception { 338 String input = 339 lines( 340 "class Test {", // 341 "}", 342 ""); 343 String expectedOutput = 344 lines( 345 "class Test {}", // 346 ""); 347 int idx = input.indexOf("}"); 348 String output = doGetFormatReplacements(input, idx, idx); 349 assertThat(output).isEqualTo(expectedOutput); 350 } 351 352 @Test onlyPackage()353 public void onlyPackage() throws Exception { 354 String input = 355 lines( 356 "package", // 357 "test", 358 ";", 359 "class Test {}", 360 ""); 361 String expectedOutput = 362 lines( 363 "package test;", // 364 "", 365 "class Test {}", 366 ""); 367 int idx = input.indexOf("test"); 368 String output = doGetFormatReplacements(input, idx, idx); 369 assertThat(output).isEqualTo(expectedOutput); 370 } 371 doGetFormatReplacements(String input, int characterILo, int characterIHi)372 private static String doGetFormatReplacements(String input, int characterILo, int characterIHi) 373 throws Exception { 374 return new Formatter() 375 .formatSource(input, ImmutableList.of(Range.closedOpen(characterILo, characterIHi + 1))); 376 } 377 378 @Test testLength()379 public void testLength() throws Exception { 380 String input = 381 lines( 382 "class Foo{", // 383 "int xxx;", 384 "int yyy;", 385 "int zzz;", 386 "}", 387 ""); 388 String expectedOutput = 389 lines( 390 "class Foo{", // 391 "int xxx;", 392 " int yyy;", 393 "int zzz;", 394 "}", 395 ""); 396 397 Path tmpdir = testFolder.newFolder().toPath(); 398 Path path = tmpdir.resolve("Foo.java"); 399 Files.write(path, input.getBytes(UTF_8)); 400 401 StringWriter out = new StringWriter(); 402 StringWriter err = new StringWriter(); 403 404 Main main = new Main(new PrintWriter(out, true), new PrintWriter(err, true), System.in); 405 String[] args = {"-lines", "3", path.toString()}; 406 assertThat(main.format(args)).isEqualTo(0); 407 assertThat(out.toString()).isEqualTo(expectedOutput); 408 } 409 410 @Test testLengthRange()411 public void testLengthRange() throws Exception { 412 String input = 413 lines( 414 "class Foo{", // 415 "int xxx;", 416 "int yyy;", 417 "int zzz;", 418 "}", 419 ""); 420 String expectedOutput = 421 lines( 422 "class Foo{", // 423 "int xxx;", 424 " int yyy;", 425 " int zzz;", 426 "}", 427 ""); 428 429 Path tmpdir = testFolder.newFolder().toPath(); 430 Path path = tmpdir.resolve("Foo.java"); 431 Files.write(path, input.getBytes(UTF_8)); 432 433 StringWriter out = new StringWriter(); 434 StringWriter err = new StringWriter(); 435 436 Main main = new Main(new PrintWriter(out, true), new PrintWriter(err, true), System.in); 437 String[] args = {"-lines", "3:4", path.toString()}; 438 assertThat(main.format(args)).isEqualTo(0); 439 assertThat(out.toString()).isEqualTo(expectedOutput); 440 } 441 442 @Test statementAndComments()443 public void statementAndComments() throws Exception { 444 String input = 445 lines( 446 "public class MyTest {", 447 "{", 448 "// asd", 449 "int x = 1;", 450 "// asd", 451 "int y = 2;", 452 "// asd", 453 "int z = 3;", 454 "// asd", 455 "}", 456 "}", 457 "", 458 ""); 459 String expectedOutput = 460 lines( 461 "public class MyTest {", 462 "{", 463 "// asd", 464 "int x = 1;", 465 " // asd", 466 " int y = 2;", 467 "// asd", 468 "int z = 3;", 469 "// asd", 470 "}", 471 "}", 472 "", 473 ""); 474 475 Path tmpdir = testFolder.newFolder().toPath(); 476 Path path = tmpdir.resolve("Foo.java"); 477 Files.write(path, input.getBytes(UTF_8)); 478 479 StringWriter out = new StringWriter(); 480 StringWriter err = new StringWriter(); 481 482 Main main = new Main(new PrintWriter(out, true), new PrintWriter(err, true), System.in); 483 String[] args = {"-lines", "5", path.toString()}; 484 assertThat(main.format(args)).isEqualTo(0); 485 assertThat(out.toString()).isEqualTo(expectedOutput); 486 } 487 488 @Test statementAndComments2()489 public void statementAndComments2() throws Exception { 490 String input = 491 lines( 492 "public class MyTest {", 493 "{", 494 "// asd", 495 "int x = 1;", 496 "// asd", 497 "int y = 2;", 498 "// asd", 499 "int z = 3;", 500 "// asd", 501 "}", 502 "}", 503 "", 504 ""); 505 String expectedOutput = 506 lines( 507 "public class MyTest {", 508 "{", 509 "// asd", 510 "int x = 1;", 511 " // asd", 512 " int y = 2;", 513 "// asd", 514 "int z = 3;", 515 "// asd", 516 "}", 517 "}", 518 "", 519 ""); 520 521 Path tmpdir = testFolder.newFolder().toPath(); 522 Path path = tmpdir.resolve("Foo.java"); 523 Files.write(path, input.getBytes(UTF_8)); 524 525 StringWriter out = new StringWriter(); 526 StringWriter err = new StringWriter(); 527 528 Main main = new Main(new PrintWriter(out, true), new PrintWriter(err, true), System.in); 529 String[] args = {"-lines", "6", path.toString()}; 530 assertThat(main.format(args)).isEqualTo(0); 531 assertThat(out.toString()).isEqualTo(expectedOutput); 532 } 533 534 @Test statementAndComments3()535 public void statementAndComments3() throws Exception { 536 String input = 537 lines( 538 "public class MyTest {", 539 "{", 540 "// asd", 541 "int x = 1;", 542 "// asd", 543 "int y = 2;", 544 "// asd", 545 "int z = 3;", 546 "// asd", 547 "}", 548 "}", 549 "", 550 ""); 551 String expectedOutput = 552 lines( 553 "public class MyTest {", 554 "{", 555 "// asd", 556 "int x = 1;", 557 "// asd", 558 "int y = 2;", 559 " // asd", 560 " int z = 3;", 561 "// asd", 562 "}", 563 "}", 564 "", 565 ""); 566 567 Path tmpdir = testFolder.newFolder().toPath(); 568 Path path = tmpdir.resolve("Foo.java"); 569 Files.write(path, input.getBytes(UTF_8)); 570 571 StringWriter out = new StringWriter(); 572 StringWriter err = new StringWriter(); 573 574 Main main = new Main(new PrintWriter(out, true), new PrintWriter(err, true), System.in); 575 String[] args = {"-lines", "7", path.toString()}; 576 assertThat(main.format(args)).isEqualTo(0); 577 assertThat(out.toString()).isEqualTo(expectedOutput); 578 } 579 580 @Test blankAndComment()581 public void blankAndComment() throws Exception { 582 String input = 583 lines( 584 "public class MyTest {", 585 " public void testListDefinitions() throws Exception {", 586 " definitionService.insert(createDefinition(1));", 587 " definitionService.insert(createIncrementalDefinition(2));", 588 " definitionService.insert(createDefinition(3));", 589 " definitionService.insert(createIncrementalDefinition(4));", 590 "", 591 " // No maxResults", 592 " assertThat(achievementFirstPartyHelper.listDefinitionsByApplication(", 593 " STUB_GAIA_ID, STUB_APPLICATION_ID, Optional.<Integer>absent(),", 594 " " 595 + " Optional.<String>absent()).getAchievements()).containsExactly(createExpectedDefinition(1)," 596 + " createIncrementalExpectedDefinition(2), createExpectedDefinition(3)," 597 + " createIncrementalExpectedDefinition(4)).inOrder();", 598 " }", 599 "}", 600 "", 601 ""); 602 String expectedOutput = 603 lines( 604 "public class MyTest {", 605 " public void testListDefinitions() throws Exception {", 606 " definitionService.insert(createDefinition(1));", 607 " definitionService.insert(createIncrementalDefinition(2));", 608 " definitionService.insert(createDefinition(3));", 609 " definitionService.insert(createIncrementalDefinition(4));", 610 "", 611 " // No maxResults", 612 " assertThat(", 613 " achievementFirstPartyHelper", 614 " .listDefinitionsByApplication(", 615 " STUB_GAIA_ID,", 616 " STUB_APPLICATION_ID,", 617 " Optional.<Integer>absent(),", 618 " Optional.<String>absent())", 619 " .getAchievements())", 620 " .containsExactly(", 621 " createExpectedDefinition(1),", 622 " createIncrementalExpectedDefinition(2),", 623 " createExpectedDefinition(3),", 624 " createIncrementalExpectedDefinition(4))", 625 " .inOrder();", 626 " }", 627 "}", 628 "", 629 ""); 630 631 String toFormat = 632 lines( 633 " assertThat(achievementFirstPartyHelper.listDefinitionsByApplication(", // 634 ""); 635 int idx = input.indexOf(toFormat); 636 String output = doGetFormatReplacements(input, idx, idx + toFormat.length()); 637 assertThat(output).isEqualTo(expectedOutput); 638 } 639 640 @Test emptyFile()641 public void emptyFile() throws Exception { 642 new Formatter().formatSource(""); 643 new Formatter() 644 .formatSource( 645 lines( 646 "", // 647 ""), 648 ImmutableList.of(Range.closedOpen(0, 1))); 649 } 650 651 @Test testGetFormatReplacementRanges()652 public void testGetFormatReplacementRanges() throws Exception { 653 String input = 654 lines( 655 /* line 0 character 0 */ "class Foo{", 656 /* line 1 character 11 */ "void f", 657 /* line 2 character 18 */ "() {", 658 /* line 3 character 23 */ "}", 659 /* line 4 character 25 */ "}", 660 ""); 661 // Claim to have modified the parentheses. 662 int start = input.indexOf("() {"); 663 ImmutableList<Replacement> ranges = 664 new Formatter() 665 .getFormatReplacements(input, ImmutableList.of(Range.closedOpen(start, start + 1))); 666 assertThat(ranges).hasSize(1); 667 Replacement replacement = ranges.get(0); 668 assertThat(replacement.getReplacementString()) 669 .isEqualTo( 670 lines( 671 "", // 672 " void f() {}")); 673 int replaceFrom = input.indexOf("void f") - newline.length(); 674 assertThat(replacement.getReplaceRange().lowerEndpoint()).isEqualTo(replaceFrom); 675 } 676 677 @Test noTokensOnLine()678 public void noTokensOnLine() throws Exception { 679 String input = 680 lines( 681 " package com.google.googlejavaformat.java;", 682 "", 683 "/*", 684 " * Copyright 2015 Google Inc.", 685 " *", 686 " * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not", 687 " * in compliance with the License. You may obtain a copy of the License at", 688 " *", 689 " * http://www.apache.org/licenses/LICENSE-2.0", 690 " *", 691 " * Unless required by applicable law or agreed to in writing, software distribute", 692 " * is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY", 693 " * or implied. See the License for the specific language governing permissions an", 694 " * the License.", 695 " */", 696 "", 697 "import com.google.googlejavaformat.FormatterDiagnostic;", 698 "import java.util.List;", 699 "", 700 "/** Checked exception class for formatter errors. */", 701 "public final class FormatterException extends Exception {", 702 "", 703 " FormatterException(String message) {", 704 " super(message);", 705 " }", 706 "", 707 " /**", 708 " * @param errors", 709 " */", 710 " public FormatterException(List<FormatterDiagnostic> errors) {", 711 " // TODO(cushon): Auto-generated constructor stub", 712 " }", 713 "}"); 714 715 Path tmpdir = testFolder.newFolder().toPath(); 716 Path path = tmpdir.resolve("FormatterException.java"); 717 Files.write(path, input.getBytes(UTF_8)); 718 719 StringWriter out = new StringWriter(); 720 StringWriter err = new StringWriter(); 721 722 Main main = new Main(new PrintWriter(out, true), new PrintWriter(err, true), System.in); 723 String[] args = {"-lines", "3:4", path.toString()}; 724 assertThat(main.format(args)).isEqualTo(0); 725 assertThat(out.toString()).isEqualTo(input); 726 } 727 728 @Test nestedStatement1()729 public void nestedStatement1() throws Exception { 730 String input = 731 lines( 732 "public class MyTest {{", 733 "int x = ", 734 " 1;", 735 "int y = new Runnable() {", 736 " void run() {", 737 " System.err.println(42);", 738 " }", 739 "};", 740 "int z = ", 741 " 1;", 742 "}}", 743 "", 744 ""); 745 String expectedOutput = 746 lines( 747 "public class MyTest {{", 748 "int x = ", 749 " 1;", 750 " int y =", 751 " new Runnable() {", 752 " void run() {", 753 " System.err.println(42);", 754 " }", 755 " };", 756 "int z = ", 757 " 1;", 758 "}}", 759 "", 760 ""); 761 762 String toFormat = "Runnable"; 763 int idx = input.indexOf(toFormat); 764 String output = doGetFormatReplacements(input, idx, idx + toFormat.length()); 765 assertThat(output).isEqualTo(expectedOutput); 766 } 767 768 @Test nestedStatement2()769 public void nestedStatement2() throws Exception { 770 String input = 771 lines( 772 "public class MyTest {", 773 "int x = ", 774 " 1;", 775 "int y = new Runnable() {", 776 " void run() {", 777 " System.err.println(42);", 778 " }", 779 "};", 780 "int z = ", 781 " 1;", 782 "}", 783 "", 784 ""); 785 String expectedOutput = 786 lines( 787 "public class MyTest {", 788 "int x = ", 789 " 1;", 790 " int y =", 791 " new Runnable() {", 792 " void run() {", 793 " System.err.println(42);", 794 " }", 795 " };", 796 "int z = ", 797 " 1;", 798 "}", 799 "", 800 ""); 801 802 String toFormat = "Runnable"; 803 int idx = input.indexOf(toFormat); 804 String output = doGetFormatReplacements(input, idx, idx + toFormat.length()); 805 assertThat(output).isEqualTo(expectedOutput); 806 } 807 808 @Test blankLine()809 public void blankLine() throws Exception { 810 String input = 811 lines( 812 "public class MyTest {", // 813 "int x = 1;", 814 "", 815 "int y = 1;", 816 "}", 817 "", 818 ""); 819 String expectedOutput = input; 820 821 testFormatLine(input, expectedOutput, 3); 822 } 823 824 @Test lineWithIdentifier()825 public void lineWithIdentifier() throws Exception { 826 String input = 827 lines( 828 "public class MyTest {", // 829 "int", 830 "y", 831 "= 1;", 832 "}", 833 "", 834 ""); 835 String expectedOutput = 836 lines( 837 "public class MyTest {", // 838 " int y = 1;", 839 "}", 840 "", 841 ""); 842 843 testFormatLine(input, expectedOutput, 3); 844 } 845 846 // formatted region expands to include entire comment 847 @Test lineInsideComment()848 public void lineInsideComment() throws Exception { 849 String input = 850 lines( 851 "public class MyTest {", 852 "/* This is a", 853 " poorly indented", 854 " comment*/", 855 "int x;", 856 "}", 857 "", 858 ""); 859 String expectedOutput = 860 lines( 861 "public class MyTest {", 862 " /* This is a", 863 " poorly indented", 864 " comment*/", 865 " int x;", 866 "}", 867 "", 868 ""); 869 870 testFormatLine(input, expectedOutput, 3); 871 } 872 873 @Test testReplacementsSorted()874 public void testReplacementsSorted() throws Exception { 875 String input = 876 lines( 877 "class Test {", 878 "int a = 1;", 879 "int b = 2;", 880 "int c = 3;", 881 "int d = 4;", 882 "int e = 5;", 883 "}"); 884 List<Range<Integer>> ranges = new ArrayList<>(); 885 for (int i = 1; i <= 5; i += 2) { 886 int idx = input.indexOf(String.valueOf(i)); 887 ranges.add(Range.closedOpen(idx, idx + 1)); 888 } 889 890 ImmutableList<Replacement> replacements = new Formatter().getFormatReplacements(input, ranges); 891 892 // expect replacements in ascending order, by start position 893 List<Integer> startPositions = new ArrayList<>(); 894 for (Replacement replacement : replacements) { 895 startPositions.add(replacement.getReplaceRange().lowerEndpoint()); 896 } 897 assertThat(startPositions).hasSize(3); 898 assertThat(startPositions).isInStrictOrder(); 899 } 900 901 @Test testReplacementsSorted_DescendingInput()902 public void testReplacementsSorted_DescendingInput() throws Exception { 903 String input = 904 lines( 905 "class Test {", 906 "int a = 1;", 907 "int b = 2;", 908 "int c = 3;", 909 "int d = 4;", 910 "int e = 5;", 911 "}"); 912 List<Range<Integer>> ranges = new ArrayList<>(); 913 for (int i = 5; i >= 1; i -= 2) { 914 int idx = input.indexOf(String.valueOf(i)); 915 ranges.add(Range.closedOpen(idx, idx + 1)); 916 } 917 918 ImmutableList<Replacement> replacements = new Formatter().getFormatReplacements(input, ranges); 919 920 // expect replacements in ascending order, by start position 921 List<Integer> startPositions = new ArrayList<>(); 922 for (Replacement replacement : replacements) { 923 startPositions.add(replacement.getReplaceRange().lowerEndpoint()); 924 } 925 assertThat(startPositions).hasSize(3); 926 assertThat(startPositions).isInStrictOrder(); 927 } 928 testFormatLine(String input, String expectedOutput, int i)929 private void testFormatLine(String input, String expectedOutput, int i) throws Exception { 930 Path tmpdir = testFolder.newFolder().toPath(); 931 Path path = tmpdir.resolve("Foo.java"); 932 Files.write(path, input.getBytes(UTF_8)); 933 934 StringWriter out = new StringWriter(); 935 StringWriter err = new StringWriter(); 936 937 Main main = new Main(new PrintWriter(out, true), new PrintWriter(err, true), System.in); 938 String[] args = {"-lines", Integer.toString(i), path.toString()}; 939 assertThat(main.format(args)).isEqualTo(0); 940 assertThat(out.toString()).isEqualTo(expectedOutput); 941 } 942 943 @Test lineWithTrailingComment()944 public void lineWithTrailingComment() throws Exception { 945 String input = 946 lines( 947 "class Foo{", // 948 "int xxx; // asd", 949 "}", 950 ""); 951 String expectedOutput = 952 lines( 953 "class Foo{", // 954 " int xxx; // asd", 955 "}", 956 ""); 957 958 Path tmpdir = testFolder.newFolder().toPath(); 959 Path path = tmpdir.resolve("Foo.java"); 960 Files.write(path, input.getBytes(UTF_8)); 961 962 StringWriter out = new StringWriter(); 963 StringWriter err = new StringWriter(); 964 965 Main main = new Main(new PrintWriter(out, true), new PrintWriter(err, true), System.in); 966 String[] args = {"-lines", "2", path.toString()}; 967 assertThat(main.format(args)).isEqualTo(0); 968 assertThat(out.toString()).isEqualTo(expectedOutput); 969 } 970 971 // Nested statements are OK as long as they're nested inside "block-like" constructs. 972 @Test nestedStatement_allowPartial()973 public void nestedStatement_allowPartial() throws Exception { 974 String input = 975 lines( 976 "public class MyTest {{", 977 "if (true) {", 978 "if (true) {", 979 "System.err.println(\"Hello\");", 980 "} else {", 981 "System.err.println(\"Goodbye\");", 982 "}", 983 "}", 984 "}}", 985 ""); 986 String expectedOutput = 987 lines( 988 "public class MyTest {{", 989 "if (true) {", 990 "if (true) {", 991 " System.err.println(\"Hello\");", 992 "} else {", 993 "System.err.println(\"Goodbye\");", 994 "}", 995 "}", 996 "}}", 997 ""); 998 999 String toFormat = "Hello"; 1000 int idx = input.indexOf(toFormat); 1001 String output = doGetFormatReplacements(input, idx, idx + toFormat.length()); 1002 assertThat(output).isEqualTo(expectedOutput); 1003 } 1004 1005 // regression test for b/b22196513 1006 @Test noTrailingWhitespace()1007 public void noTrailingWhitespace() throws Exception { 1008 String input = 1009 lines( 1010 "", // 1011 "class Test {", 1012 " {", 1013 " {", 1014 " {", 1015 " }", 1016 " }", 1017 "}}", 1018 ""); 1019 String expected = 1020 lines( 1021 "", // 1022 "class Test {", 1023 " {", 1024 " {", 1025 " {", 1026 " }", 1027 " }", 1028 " }", 1029 "}", 1030 ""); 1031 int start = input.indexOf(newline + "}}"); 1032 ImmutableList<Range<Integer>> ranges = 1033 ImmutableList.of(Range.closedOpen(start, start + newline.length() + 2)); 1034 String output = new Formatter().formatSource(input, ranges); 1035 assertEquals("bad output", expected, output); 1036 } 1037 1038 // regression test for b/b22196513 1039 @Test trailingNonBreakingWhitespace()1040 public void trailingNonBreakingWhitespace() throws Exception { 1041 String input = 1042 lines( 1043 "", // 1044 "class Test {", 1045 " {", 1046 " int x;int y;", 1047 " }", 1048 "}", 1049 ""); 1050 String expected = 1051 lines( 1052 "", // 1053 "class Test {", 1054 " {", 1055 " int x;", 1056 " int y;", 1057 " }", 1058 "}", 1059 ""); 1060 String match = "int x;"; 1061 int start = input.indexOf(match); 1062 int end = start + match.length(); 1063 ImmutableList<Range<Integer>> ranges = ImmutableList.of(Range.closedOpen(start, end)); 1064 String output = new Formatter().formatSource(input, ranges); 1065 assertEquals("bad output", expected, output); 1066 } 1067 1068 @Test outOfRangeStartLine()1069 public void outOfRangeStartLine() throws Exception { 1070 String input = 1071 lines( 1072 "class Foo {", // 1073 "int x = 1;", 1074 "}"); 1075 String expectedOutput = 1076 lines( 1077 "class Foo {", // 1078 " int x = 1;", 1079 "}", 1080 ""); 1081 1082 Path tmpdir = testFolder.newFolder().toPath(); 1083 Path path = tmpdir.resolve("Foo.java"); 1084 Files.write(path, input.getBytes(UTF_8)); 1085 1086 StringWriter out = new StringWriter(); 1087 StringWriter err = new StringWriter(); 1088 1089 Main main = new Main(new PrintWriter(out, true), new PrintWriter(err, true), System.in); 1090 String[] args = {"-lines", "-1:3", path.toString()}; 1091 assertThat(main.format(args)).isEqualTo(0); 1092 assertThat(out.toString()).isEqualTo(expectedOutput); 1093 } 1094 1095 @Test outOfRangeEndLine()1096 public void outOfRangeEndLine() throws Exception { 1097 String input = 1098 lines( 1099 "class Foo {", // 1100 "int x = 1;", 1101 "}"); 1102 String expectedOutput = 1103 lines( 1104 "class Foo {", // 1105 " int x = 1;", 1106 "}", 1107 ""); 1108 1109 Path tmpdir = testFolder.newFolder().toPath(); 1110 Path path = tmpdir.resolve("Foo.java"); 1111 Files.write(path, input.getBytes(UTF_8)); 1112 1113 StringWriter out = new StringWriter(); 1114 StringWriter err = new StringWriter(); 1115 1116 Main main = new Main(new PrintWriter(out, true), new PrintWriter(err, true), System.in); 1117 String[] args = {"-lines", "1:5", path.toString()}; 1118 assertThat(main.format(args)).isEqualTo(0); 1119 assertThat(out.toString()).isEqualTo(expectedOutput); 1120 } 1121 1122 @Test testOutOfRangeLines()1123 public void testOutOfRangeLines() throws Exception { 1124 String input = 1125 lines( 1126 "class Foo {", // 1127 "}", 1128 ""); 1129 String expectedOutput = 1130 lines( 1131 "class Foo {}", // 1132 ""); 1133 1134 Path tmpdir = testFolder.newFolder().toPath(); 1135 Path path = tmpdir.resolve("Foo.java"); 1136 Files.write(path, input.getBytes(UTF_8)); 1137 1138 StringWriter out = new StringWriter(); 1139 StringWriter err = new StringWriter(); 1140 1141 Main main = new Main(new PrintWriter(out, true), new PrintWriter(err, true), System.in); 1142 String[] args = {"-lines=23:27", "-lines=31:35", "-lines=52:63", "-lines=1:1", path.toString()}; 1143 assertThat(main.format(args)).isEqualTo(0); 1144 assertThat(out.toString()).isEqualTo(expectedOutput); 1145 } 1146 1147 @Test testEmptyFirstLine()1148 public void testEmptyFirstLine() throws Exception { 1149 String input = 1150 lines( 1151 "", // 1152 "", 1153 "class Foo {", 1154 "}", 1155 ""); 1156 1157 Path tmpdir = testFolder.newFolder().toPath(); 1158 Path path = tmpdir.resolve("Foo.java"); 1159 Files.write(path, input.getBytes(UTF_8)); 1160 1161 StringWriter out = new StringWriter(); 1162 StringWriter err = new StringWriter(); 1163 1164 Main main = new Main(new PrintWriter(out, true), new PrintWriter(err, true), System.in); 1165 String[] args = {"-lines=1:1", path.toString()}; 1166 assertThat(main.format(args)).isEqualTo(0); 1167 } 1168 1169 @Test testEmptyLastLine()1170 public void testEmptyLastLine() throws Exception { 1171 String input = 1172 lines( 1173 "class Foo {", // 1174 "}", 1175 "", 1176 ""); 1177 1178 Path tmpdir = testFolder.newFolder().toPath(); 1179 Path path = tmpdir.resolve("Foo.java"); 1180 Files.write(path, input.getBytes(UTF_8)); 1181 1182 StringWriter out = new StringWriter(); 1183 StringWriter err = new StringWriter(); 1184 1185 Main main = new Main(new PrintWriter(out, true), new PrintWriter(err, true), System.in); 1186 String[] args = {"-lines=5:5", path.toString()}; 1187 assertThat(main.format(args)).isEqualTo(0); 1188 } 1189 1190 // Regression test for b/22872933 1191 // Don't extend partial formatting ranges across switch cases. 1192 @Test switchCase()1193 public void switchCase() throws Exception { 1194 String input = 1195 lines( 1196 "class Test {", 1197 " {", 1198 " switch (foo) {", 1199 " case FOO:", 1200 " f();", 1201 " break;", 1202 " case BAR:", 1203 " g();", 1204 " break;", 1205 " }", 1206 " }", 1207 "}"); 1208 String expectedOutput = 1209 lines( 1210 "class Test {", 1211 " {", 1212 " switch (foo) {", 1213 " case FOO:", 1214 " f();", 1215 " break;", 1216 " case BAR:", // we deliberately only format the first case 1217 " g();", 1218 " break;", 1219 " }", 1220 " }", 1221 "}"); 1222 1223 int idx = input.indexOf("f()"); 1224 String output = doGetFormatReplacements(input, idx, idx + 1); 1225 assertThat(output).isEqualTo(expectedOutput); 1226 } 1227 1228 // regression test for b/23349153 1229 @Test emptyStatement()1230 public void emptyStatement() throws Exception { 1231 String input = 1232 lines( 1233 "class Test {{", // 1234 "Object o = f();;", 1235 "}}", 1236 ""); 1237 String expectedOutput = 1238 lines( 1239 "class Test {{", // 1240 " Object o = f();", 1241 " ;", 1242 "}}", 1243 ""); 1244 int idx = input.indexOf("Object o"); 1245 String output = doGetFormatReplacements(input, idx, idx + 1); 1246 assertThat(output).isEqualTo(expectedOutput); 1247 } 1248 1249 @Test preserveTrailingWhitespaceAfterNewline()1250 public void preserveTrailingWhitespaceAfterNewline() throws Exception { 1251 String input = 1252 lines( 1253 "class Test {{", // 1254 "Object o = f(); ", 1255 " int x;", 1256 "}}", 1257 ""); 1258 String expectedOutput = 1259 lines( 1260 "class Test {{", // 1261 " Object o = f();", 1262 " int x;", 1263 "}}", 1264 ""); 1265 int idx = input.indexOf("Object o"); 1266 String output = doGetFormatReplacements(input, idx, idx + 1); 1267 assertThat(output).isEqualTo(expectedOutput); 1268 } 1269 1270 @Test trailingWhitespace()1271 public void trailingWhitespace() throws Exception { 1272 String input = 1273 lines( 1274 "class Test {{", // 1275 "Object o = f(); ", 1276 " ;", 1277 "}}", 1278 ""); 1279 String expectedOutput = 1280 lines( 1281 "class Test {{", // 1282 " Object o = f();", 1283 " ;", 1284 "}}", 1285 ""); 1286 int idx = input.indexOf("Object o"); 1287 String output = doGetFormatReplacements(input, idx, idx + 1); 1288 assertThat(output).isEqualTo(expectedOutput); 1289 } 1290 1291 // Regression test for b/18479811 1292 @Test onNewline()1293 public void onNewline() throws Exception { 1294 1295 String line1 = "for (Integer x : Arrays.asList(1, 2, 3)) {"; 1296 String line2 = "System.err.println(x);"; 1297 String input = 1298 lines( 1299 "class Test {{", // 1300 line1, 1301 line2, 1302 "}}}", 1303 ""); 1304 1305 int startOffset = input.indexOf(line1); 1306 int length = 1; 1307 1308 String expectedFormatLine1 = 1309 lines( 1310 "class Test {{", 1311 " for (Integer x : Arrays.asList(1, 2, 3)) {", 1312 "System.err.println(x);", 1313 "}}}", 1314 ""); 1315 1316 for (; length <= line1.length() + newline.length(); length++) { 1317 Range<Integer> range = Range.closedOpen(startOffset, startOffset + length); 1318 String output = new Formatter().formatSource(input, ImmutableList.of(range)); 1319 assertEquals("bad output", expectedFormatLine1, output); 1320 } 1321 1322 String expectedFormatLine1And2 = 1323 lines( 1324 "class Test {{", 1325 " for (Integer x : Arrays.asList(1, 2, 3)) {", 1326 " System.err.println(x);", 1327 "}}}", 1328 ""); 1329 1330 for (; length <= line1.length() + line2.length() + 2 * newline.length(); length++) { 1331 Range<Integer> range = Range.closedOpen(startOffset, startOffset + length); 1332 String output = new Formatter().formatSource(input, ImmutableList.of(range)); 1333 assertEquals("bad output", expectedFormatLine1And2, output); 1334 } 1335 } 1336 1337 @Test afterNewline()1338 public void afterNewline() throws Exception { 1339 1340 String line1 = "for (Integer x : Arrays.asList(1, 2, 3)) {"; 1341 String line2 = " System.err.println(x);"; 1342 String input = 1343 lines( 1344 "class Test {{", // 1345 line1, 1346 line2, 1347 "}}}", 1348 ""); 1349 1350 String expectedFormatLine1 = 1351 lines( 1352 "class Test {{", // 1353 " for (Integer x : Arrays.asList(1, 2, 3)) {", // 1354 line2, 1355 "}}}", 1356 ""); 1357 1358 String expectedFormatLine2 = 1359 lines( 1360 "class Test {{", // 1361 line1, 1362 " System.err.println(x);", 1363 "}}}", 1364 ""); 1365 1366 int line2Start = input.indexOf(line2); 1367 int nonWhitespaceLine2Start = input.indexOf("System.err"); 1368 int start; 1369 // formatting a range that touches non-whitespace characters in line2 should format line2 1370 for (start = nonWhitespaceLine2Start; start > (line2Start - newline.length()); start--) { 1371 Range<Integer> range = Range.closedOpen(start, nonWhitespaceLine2Start + newline.length()); 1372 String output = new Formatter().formatSource(input, ImmutableList.of(range)); 1373 assertThat(output).isEqualTo(expectedFormatLine2); 1374 } 1375 // formatting a range that touches whitespace characters between line1 and line2 should 1376 // not result in any formatting 1377 assertThat(input.substring(start, start + newline.length())).isEqualTo(newline); 1378 int line1End = input.indexOf(line1) + line1.length(); 1379 for (; start >= line1End; start--) { 1380 Range<Integer> range = Range.closedOpen(start, line2Start); 1381 String output = new Formatter().formatSource(input, ImmutableList.of(range)); 1382 assertThat(output).isEqualTo(input); 1383 } 1384 // formatting a range that touches non-whitespace characters in line1 should format line1 1385 assertThat(input.substring(start + 1, start + 1 + newline.length())).isEqualTo(newline); 1386 int line1Start = input.indexOf(line1); 1387 for (; start >= line1Start; start--) { 1388 Range<Integer> range = Range.closedOpen(start, line2Start); 1389 String output = new Formatter().formatSource(input, ImmutableList.of(range)); 1390 assertThat(output).isEqualTo(expectedFormatLine1); 1391 } 1392 } 1393 1394 @Test commentBeforeBadConstructor()1395 public void commentBeforeBadConstructor() throws Exception { 1396 String[] lines = { 1397 "class D {", // 1398 " /** */", 1399 " F() {}", 1400 "}", 1401 }; 1402 String output = new Formatter().formatSource(lines(lines)); 1403 String[] expected = { 1404 "class D {", // 1405 " /** */", 1406 " F() {}", 1407 "}", 1408 "", 1409 }; 1410 assertThat(output).isEqualTo(lines(expected)); 1411 } 1412 1413 @Test partialEnum()1414 public void partialEnum() throws Exception { 1415 String[] input = { 1416 "enum E {", // 1417 "ONE,", 1418 "TWO,", 1419 "THREE;", 1420 "}", 1421 }; 1422 String[] expected = { 1423 "enum E {", // 1424 "ONE,", 1425 " TWO,", 1426 "THREE;", 1427 "}", 1428 }; 1429 1430 Path tmpdir = testFolder.newFolder().toPath(); 1431 Path path = tmpdir.resolve("Foo.java"); 1432 Files.write(path, lines(input).getBytes(UTF_8)); 1433 1434 StringWriter out = new StringWriter(); 1435 StringWriter err = new StringWriter(); 1436 1437 Main main = new Main(new PrintWriter(out, true), new PrintWriter(err, true), System.in); 1438 String[] args = {"-lines", "3", path.toString()}; 1439 assertThat(main.format(args)).isEqualTo(0); 1440 assertThat(out.toString()).isEqualTo(lines(expected)); 1441 } 1442 1443 @Test partialModifierOrder()1444 public void partialModifierOrder() throws Exception { 1445 String[] input = { 1446 "class T {", // 1447 "final private int a = 0;", 1448 "final private int b = 0;", 1449 "final private int c = 0;", 1450 "}", 1451 }; 1452 String[] expected = { 1453 "class T {", // 1454 "final private int a = 0;", 1455 " private final int b = 0;", 1456 "final private int c = 0;", 1457 "}", 1458 }; 1459 1460 Path tmpdir = testFolder.newFolder().toPath(); 1461 Path path = tmpdir.resolve("Foo.java"); 1462 Files.write(path, lines(input).getBytes(UTF_8)); 1463 1464 StringWriter out = new StringWriter(); 1465 StringWriter err = new StringWriter(); 1466 1467 Main main = new Main(new PrintWriter(out, true), new PrintWriter(err, true), System.in); 1468 String[] args = {"-lines", "3", path.toString()}; 1469 assertThat(main.format(args)).isEqualTo(0); 1470 assertThat(out.toString()).isEqualTo(lines(expected)); 1471 } 1472 1473 @Test endOfLine()1474 public void endOfLine() throws Exception { 1475 String[] input = { 1476 "class foo {", 1477 " foo(", 1478 " int aaaaaaaaaaaaaaa,", 1479 " int ccccccccccccc) {", 1480 " int a = 0;", 1481 " int c = 0;", 1482 " }", 1483 "}", 1484 }; 1485 String[] expected = { 1486 "class foo {", 1487 " foo(int aaaaaaaaaaaaaaa, int ccccccccccccc) {", 1488 " int a = 0;", 1489 " int c = 0;", 1490 " }", 1491 "}", 1492 }; 1493 String in = lines(input); 1494 // request partial formatting of the end of the first parameter 1495 int start = in.indexOf(lines(",", " int ccccccccccccc")); 1496 assertThat(in.substring(start, start + 1)).isEqualTo(","); 1497 1498 assertThat(new Formatter().formatSource(in, ImmutableList.of(Range.closedOpen(start, start)))) 1499 .isEqualTo(lines(expected)); 1500 1501 assertThat(formatMain(lines(input), "-offset", String.valueOf(start), "-length", "0")) 1502 .isEqualTo(lines(expected)); 1503 } 1504 formatMain(String input, String... args)1505 private String formatMain(String input, String... args) throws Exception { 1506 Path tmpdir = testFolder.newFolder().toPath(); 1507 Path path = tmpdir.resolve("Test.java"); 1508 Files.write(path, input.getBytes(UTF_8)); 1509 1510 StringWriter out = new StringWriter(); 1511 StringWriter err = new StringWriter(); 1512 1513 Main main = new Main(new PrintWriter(out, true), new PrintWriter(err, true), System.in); 1514 assertThat(main.format(ObjectArrays.concat(args, path.toString()))).isEqualTo(0); 1515 return out.toString(); 1516 } 1517 1518 // formatting the newlinea after a statement is a no-op 1519 @Test endOfLineStatement()1520 public void endOfLineStatement() throws Exception { 1521 String[] input = { 1522 "class foo {{", // 1523 " int a = 0; ", 1524 " int c = 0;", 1525 "}}", 1526 }; 1527 String[] expected = { 1528 "class foo {{", // 1529 " int a = 0;", 1530 " int c = 0;", 1531 "}}", 1532 }; 1533 String in = lines(input); 1534 int idx = in.indexOf(';'); 1535 assertThat(new Formatter().formatSource(in, ImmutableList.of(Range.closedOpen(idx, idx)))) 1536 .isEqualTo(lines(expected)); 1537 } 1538 1539 // formatting trailing whitespace at the end of the line doesn't format the line on either side 1540 @Test endOfLineStatementNewline()1541 public void endOfLineStatementNewline() throws Exception { 1542 String[] input = { 1543 "class foo {{", // 1544 " int a = 0; ", 1545 " int c = 0;", 1546 "}}", 1547 }; 1548 String in = lines(input); 1549 int idx = in.indexOf(';'); 1550 assertThat( 1551 new Formatter().formatSource(in, ImmutableList.of(Range.closedOpen(idx + 1, idx + 1)))) 1552 .isEqualTo(in); 1553 } 1554 1555 @Test importNewlines()1556 public void importNewlines() throws Exception { 1557 String input = 1558 lines( 1559 "package p;", 1560 "import java.util.ArrayList;", 1561 "class Foo {", 1562 " ArrayList<String> xs = new ArrayList<>();", 1563 "}", 1564 ""); 1565 String expectedOutput = 1566 lines( 1567 "package p;", 1568 "", 1569 "import java.util.ArrayList;", 1570 "", 1571 "class Foo {", 1572 " ArrayList<String> xs = new ArrayList<>();", 1573 "}", 1574 ""); 1575 1576 String output = runFormatter(input, new String[] {"-lines", "2"}); 1577 assertThat(output).isEqualTo(expectedOutput); 1578 } 1579 1580 @Test b36458607()1581 public void b36458607() throws Exception { 1582 String input = 1583 lines( 1584 "// copyright", 1585 "", 1586 "package p;", 1587 "import static c.g.I.c;", 1588 "", 1589 "/** */", 1590 "class Foo {{ c(); }}", 1591 ""); 1592 String expectedOutput = 1593 lines( 1594 "// copyright", 1595 "", 1596 "package p;", 1597 "", 1598 "import static c.g.I.c;", 1599 "", 1600 "/** */", 1601 "class Foo {{ c(); }}", 1602 ""); 1603 1604 String output = runFormatter(input, new String[] {"-lines", "4"}); 1605 assertThat(output).isEqualTo(expectedOutput); 1606 } 1607 1608 @Test b32159971()1609 public void b32159971() throws Exception { 1610 String input = 1611 lines( 1612 "", // 1613 "", 1614 "package p;", 1615 "class X {}", 1616 ""); 1617 String expectedOutput = 1618 lines( 1619 "package p;", // 1620 "", 1621 "class X {}", 1622 ""); 1623 1624 String output = runFormatter(input, new String[] {"-lines", "3"}); 1625 assertThat(output).isEqualTo(expectedOutput); 1626 } 1627 1628 @Test b21668189()1629 public void b21668189() throws Exception { 1630 String input = 1631 lines( 1632 "class Foo {", // 1633 " {", 1634 " int x = 1;", 1635 " ", 1636 " int y = 2;", 1637 " }", 1638 "}", 1639 ""); 1640 String expectedOutput = 1641 lines( 1642 "class Foo {", // 1643 " {", 1644 " int x = 1;", 1645 "", 1646 " int y = 2;", 1647 " }", 1648 "}", 1649 ""); 1650 1651 String output = runFormatter(input, new String[] {"-lines", "4:5"}); 1652 assertThat(output).isEqualTo(expectedOutput); 1653 } 1654 runFormatter(String input, String[] args)1655 private String runFormatter(String input, String[] args) throws IOException, UsageException { 1656 Path tmpdir = testFolder.newFolder().toPath(); 1657 Path path = tmpdir.resolve("Foo.java"); 1658 Files.write(path, input.getBytes(UTF_8)); 1659 1660 StringWriter out = new StringWriter(); 1661 StringWriter err = new StringWriter(); 1662 1663 Main main = new Main(new PrintWriter(out, true), new PrintWriter(err, true), System.in); 1664 assertThat(main.format(ObjectArrays.concat(args, path.toString()))).isEqualTo(0); 1665 return out.toString(); 1666 } 1667 1668 @Test trailing()1669 public void trailing() throws Exception { 1670 String input = 1671 lines( 1672 "package foo.bar.baz;", 1673 "", 1674 "public class B {", 1675 " public void f() {", 1676 " int a = 7 +4;", 1677 " int b = 7 +4;", 1678 " int c = 7 +4;", 1679 " int d = 7 +4;", 1680 "", 1681 " int e = 7 +4;", 1682 " }", 1683 "}"); 1684 String expected = 1685 lines( 1686 "package foo.bar.baz;", 1687 "", 1688 "public class B {", 1689 " public void f() {", 1690 " int a = 7 +4;", 1691 " int b = 7 +4;", 1692 " int c = 7 + 4;", 1693 " int d = 7 +4;", 1694 "", 1695 " int e = 7 +4;", 1696 " }", 1697 "}"); 1698 String actual = 1699 new Formatter().formatSource(input, ImmutableList.of(rangeOf(input, "int c = 7 +4"))); 1700 assertThat(actual).isEqualTo(expected); 1701 } 1702 rangeOf(String input, String needle)1703 private Range<Integer> rangeOf(String input, String needle) { 1704 int idx = input.indexOf(needle); 1705 return Range.closedOpen(idx, idx + needle.length()); 1706 } 1707 1708 @Test importJavadocNewlines()1709 public void importJavadocNewlines() throws Exception { 1710 String input = 1711 lines( 1712 "package p;", 1713 "import java.util.ArrayList;", 1714 "/** */", 1715 "class Foo {", 1716 " ArrayList<String> xs = new ArrayList<>();", 1717 "}", 1718 ""); 1719 String expectedOutput = 1720 lines( 1721 "package p;", 1722 "", 1723 "import java.util.ArrayList;", 1724 "", 1725 "/** */", 1726 "class Foo {", 1727 " ArrayList<String> xs = new ArrayList<>();", 1728 "}", 1729 ""); 1730 1731 String output = runFormatter(input, new String[] {"-lines", "2"}); 1732 assertThat(output).isEqualTo(expectedOutput); 1733 } 1734 1735 @Test nestedSwitchCase()1736 public void nestedSwitchCase() throws Exception { 1737 String input = 1738 lines( 1739 "class Test {", 1740 " {", 1741 " switch (foo) {", 1742 " case FOO:", 1743 " f();", 1744 " break;", 1745 " case BAR:", 1746 " switch (bar) {", 1747 " case BAZ:", 1748 " h();", 1749 " break;", 1750 " case BOZ:", 1751 " i();", 1752 " break;", 1753 " }", 1754 " }", 1755 " }", 1756 "}"); 1757 String expectedOutput = 1758 lines( 1759 "class Test {", 1760 " {", 1761 " switch (foo) {", 1762 " case FOO:", 1763 " f();", 1764 " break;", 1765 " case BAR:", 1766 " switch (bar) {", 1767 " case BAZ:", 1768 " h();", 1769 " break;", 1770 " case BOZ:", 1771 " i();", 1772 " break;", 1773 " }", 1774 " }", 1775 " }", 1776 "}"); 1777 1778 int idx = input.indexOf("h()"); 1779 String output = doGetFormatReplacements(input, idx, idx + 1); 1780 assertThat(output).isEqualTo(expectedOutput); 1781 } 1782 1783 @Test b117602702()1784 public void b117602702() throws Exception { 1785 String input = 1786 lines( 1787 "class Foo {", // 1788 "private Foo () {};", 1789 "}", 1790 ""); 1791 String expectedOutput = 1792 lines( 1793 "class Foo {", // 1794 " private Foo() {}", 1795 " ;", 1796 "}", 1797 ""); 1798 1799 String output = runFormatter(input, new String[] {"-offset", "13", "-length", "1"}); 1800 assertThat(output).isEqualTo(expectedOutput); 1801 } 1802 } 1803