/*
* Copyright 2014 Google Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package com.google.errorprone.refaster;
import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertThrows;
import com.google.common.collect.Iterables;
import com.google.errorprone.BugPattern.SeverityLevel;
import com.google.errorprone.apply.DescriptionBasedDiff;
import com.google.errorprone.apply.ImportOrganizer;
import com.google.errorprone.fixes.SuggestedFix;
import com.google.errorprone.matchers.Description;
import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
/**
* Tests for {@code DescriptionBasedDiff}.
*
* @author lowasser@google.com (Louis Wasserman)
*/
@RunWith(JUnit4.class)
public class DescriptionBasedDiffTest extends CompilerBasedTest {
private JCCompilationUnit compilationUnit;
private static final String[] lines = {
"package foo.bar;",
"import com.foo.Bar;",
"",
"class Foo {",
" public static void main(String[] args) {",
" System.out.println(\"foo\");",
" }",
"}"
};
@Before
public void setUp() {
compile(lines);
compilationUnit = Iterables.getOnlyElement(compilationUnits);
}
private DescriptionBasedDiff createDescriptionBasedDiff() {
return DescriptionBasedDiff.create(compilationUnit, ImportOrganizer.STATIC_FIRST_ORGANIZER);
}
@Test
public void noDiffs() {
DescriptionBasedDiff diff = createDescriptionBasedDiff();
diff.applyDifferences(sourceFile);
assertThat(sourceFile.getLines()).containsExactly((Object[]) lines).inOrder();
}
@Test
public void oneDiff() {
DescriptionBasedDiff diff = createDescriptionBasedDiff();
diff.onDescribed(
new Description(
null, "message", SuggestedFix.replace(117, 120, "bar"), SeverityLevel.SUGGESTION));
diff.applyDifferences(sourceFile);
assertThat(sourceFile.getLines())
.containsExactly(
"package foo.bar;",
"import com.foo.Bar;",
"",
"class Foo {",
" public static void main(String[] args) {",
" System.out.println(\"bar\");",
" }",
"}")
.inOrder();
}
@Test
public void prefixDiff() {
DescriptionBasedDiff diff = createDescriptionBasedDiff();
diff.onDescribed(
new Description(
null, "message", SuggestedFix.replace(120, 120, "bar"), SeverityLevel.SUGGESTION));
diff.applyDifferences(sourceFile);
assertThat(sourceFile.getLines())
.containsExactly(
"package foo.bar;",
"import com.foo.Bar;",
"",
"class Foo {",
" public static void main(String[] args) {",
" System.out.println(\"foobar\");",
" }",
"}")
.inOrder();
}
@Test
public void twoDiffs() {
DescriptionBasedDiff diff = createDescriptionBasedDiff();
diff.onDescribed(
new Description(
null,
"message",
SuggestedFix.builder().replace(104, 107, "longer").replace(117, 120, "bar").build(),
SeverityLevel.SUGGESTION));
diff.applyDifferences(sourceFile);
assertThat(sourceFile.getLines())
.containsExactly(
"package foo.bar;",
"import com.foo.Bar;",
"",
"class Foo {",
" public static void main(String[] args) {",
" System.longer.println(\"bar\");",
" }",
"}")
.inOrder();
}
@Test
public void overlappingDiffs_throws() {
DescriptionBasedDiff diff = createDescriptionBasedDiff();
assertThrows(
IllegalArgumentException.class,
() ->
diff.onDescribed(
new Description(
null,
"message",
SuggestedFix.builder()
.replace(117, 120, "baz")
.replace(117, 120, "bar")
.build(),
SeverityLevel.SUGGESTION)));
DescriptionBasedDiff diff2 = createDescriptionBasedDiff();
diff2.onDescribed(
new Description(
null,
"bah",
SuggestedFix.builder().replace(117, 120, "baz").build(),
SeverityLevel.SUGGESTION));
assertThrows(
IllegalArgumentException.class,
() ->
diff2.onDescribed(
new Description(
null,
"message",
SuggestedFix.builder().replace(117, 120, "bar").build(),
SeverityLevel.SUGGESTION)));
DescriptionBasedDiff diff3 =
DescriptionBasedDiff.createIgnoringOverlaps(
compilationUnit, ImportOrganizer.STATIC_FIRST_ORGANIZER);
diff3.onDescribed(
new Description(
null,
"bah",
SuggestedFix.builder().replace(117, 120, "baz").build(),
SeverityLevel.SUGGESTION));
// No throw, since it's lenient. Refactors to the first "baz" replacement and ignores this.
diff3.onDescribed(
new Description(
null,
"message",
SuggestedFix.builder().replace(117, 120, "bar").build(),
SeverityLevel.SUGGESTION));
diff3.applyDifferences(sourceFile);
assertThat(sourceFile.getLines())
.containsExactly(
"package foo.bar;",
"import com.foo.Bar;",
"",
"class Foo {",
" public static void main(String[] args) {",
" System.out.println(\"baz\");",
" }",
"}")
.inOrder();
}
@Test
public void addImport() {
DescriptionBasedDiff diff = createDescriptionBasedDiff();
diff.onDescribed(
new Description(
null,
"message",
SuggestedFix.builder().addImport("com.google.foo.Bar").build(),
SeverityLevel.SUGGESTION));
diff.applyDifferences(sourceFile);
assertThat(sourceFile.getLines())
.containsExactly(
"package foo.bar;",
"import com.foo.Bar;",
"import com.google.foo.Bar;",
"",
"class Foo {",
" public static void main(String[] args) {",
" System.out.println(\"foo\");",
" }",
"}")
.inOrder();
}
@Test
public void removeImport() {
DescriptionBasedDiff diff = createDescriptionBasedDiff();
diff.onDescribed(
new Description(
null,
"message",
SuggestedFix.builder().removeImport("com.foo.Bar").build(),
SeverityLevel.SUGGESTION));
diff.applyDifferences(sourceFile);
assertThat(sourceFile.getLines())
.containsExactly(
"package foo.bar;",
"",
"",
"class Foo {",
" public static void main(String[] args) {",
" System.out.println(\"foo\");",
" }",
"}")
.inOrder();
}
@Test
public void twoDiffsWithImport() {
DescriptionBasedDiff diff = createDescriptionBasedDiff();
diff.onDescribed(
new Description(
null,
"message",
SuggestedFix.builder()
.replace(104, 107, "longer")
.replace(117, 120, "bar")
.addImport("com.google.foo.Bar")
.build(),
SeverityLevel.SUGGESTION));
diff.applyDifferences(sourceFile);
assertThat(sourceFile.getLines())
.containsExactly(
"package foo.bar;",
"import com.foo.Bar;",
"import com.google.foo.Bar;",
"",
"class Foo {",
" public static void main(String[] args) {",
" System.longer.println(\"bar\");",
" }",
"}")
.inOrder();
}
}