Skip to content

Commit

Permalink
Suggestions
Browse files Browse the repository at this point in the history
  • Loading branch information
Stephan202 committed Aug 1, 2022
1 parent 0eb0391 commit 5ce5a50
Show file tree
Hide file tree
Showing 11 changed files with 79 additions and 62 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package tech.picnic.errorprone.refastertemplates;

import static java.util.function.Predicate.not;

import com.google.common.collect.ImmutableSet;
import java.util.stream.Stream;
import org.junit.jupiter.params.ParameterizedTest;
Expand Down Expand Up @@ -64,9 +66,10 @@ final class RefasterTemplatesTest {
// XXX: Create a JUnit extension to automatically discover the template collections in a given
// context to make sure the list is exhaustive.
private static Stream<Arguments> validateTemplateCollectionTestCases() {
// XXX: Drop the filter once we have added tests for AssertJ!
// XXX: Drop the filter once we have added tests for AssertJ! We can then also replace this
// method with `@ValueSource(classes = {...})`.
return TEMPLATE_COLLECTIONS.stream()
.filter(tc -> tc != AssertJTemplates.class)
.filter(not(AssertJTemplates.class::equals))
.map(Arguments::arguments);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,10 @@
import java.util.Optional;
import java.util.function.Supplier;

/** Scans the classpath for `.refaster` files and loads them as {@link CodeTransformer}s. */
/**
* Scans the classpath for {@value #REFASTER_TEMPLATE_SUFFIX} files and loads them as {@link
* CodeTransformer}s.
*/
public final class CodeTransformers {
private static final String REFASTER_TEMPLATE_SUFFIX = ".refaster";
private static final Supplier<ImmutableListMultimap<String, CodeTransformer>>
Expand Down Expand Up @@ -88,7 +91,7 @@ private static Optional<CodeTransformer> loadCodeTransformer(ResourceInfo resour
/* This resource does not appear to be compatible with the current classpath. */
// XXX: Should we log this?
return Optional.empty();
} catch (IOException | ClassNotFoundException e) {
} catch (ClassNotFoundException | IOException e) {
throw new IllegalStateException("Can't load `CodeTransformer` from " + resource, e);
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/** Classes used to find Refaster templates on the classpath and to apply them. */
/** Classes used to locate and apply compiled Refaster templates on. */
@com.google.errorprone.annotations.CheckReturnValue
@javax.annotation.ParametersAreNonnullByDefault
package tech.picnic.errorprone.refaster.runner;
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,12 @@

final class CodeTransformersTest {
/**
* Verifies that {@link CodeTransformers#getAllCodeTransformers()} finds at least one code
* transformer on the classpath.
*
* <p>It is expected that the template collection from this package, {@link FooTemplates}, is one
* of these transformers.
* Verifies that {@link CodeTransformers#getAllCodeTransformers()} finds the code transformer
* compiled from {@link FooTemplates} on the classpath.
*/
@Test
void loadAllCodeTransformers() {
void getAllCodeTransformers() {
assertThat(CodeTransformers.getAllCodeTransformers().keySet())
.contains("FooTemplates$SimpleTemplate");
.containsExactly("FooTemplates$SimpleTemplate");
}
}
61 changes: 30 additions & 31 deletions refaster-test-support/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ This module provides utilities to validate Refaster template collections.
## What does this module do?

These utilities allow validating the rewrites (or their absence) performed by
Refaster templates. Each collection of Refaster templates defined in the same
Refaster templates. Each collection of Refaster templates defined in a single
top-level class is applied to an input file, and the resulting rewrites should
match the associated output file.

Expand All @@ -17,12 +17,12 @@ irregularity will be reported, and the associated template collection test will
fail. This way developers receive guidance on how to write Refaster template
tests and assurance that every template is properly tested.

## How to test a collection of Refaster templates?
## How to test a collection of Refaster templates

In summary, to test Refaster templates using the
`RefasterTemplateCollectionValidator`, one should create an input and output
file. The Refaster templates from the collection are applied to the input file
and should exactly match the contents of the provided output file.
In a nutshell, to test a Refaster template collection class using
`RefasterTemplateCollectionValidator`, one should create suitably named input
and output files. The collection's Refaster templates are applied to the input
file and must exactly match the contents of the provided output file.

To test Refaster templates, one can create a (parameterized) test for every
class containing the Refaster templates to invoke the
Expand Down Expand Up @@ -54,30 +54,29 @@ To adopt this setup, the following requirements have to be met:

As a result from these tests, unexpected output will be shown in the console.

An example of a folder structure for such a setup is as follows:

An example directory structure for such a setup is as follows:
```
main/
java/
tech.picnic.errorprone.refastertemplates
└── ExampleTemplates.java -- Contains multiple Refaster templates.
└── Example1Template
└── Example2Template
test/
java/
└── tech.picnic.errorprone.refastertemplates
└── RefasterCollectionTest.java
-- Here the test invokes
-- `RefasterTemplateCollectionValidator#validate`.
resources/
└── tech.picnic.errorprone.refastertemplates
└── ExampleTemplatesTestInput.java
-- Contains a class named `ExampleTemplatesTest` and
-- two methods named `testExample1Template` and
-- `testExample2Template`.
└── ExampleTemplatesTestOutput.java
-- Contains a class named `ExampleTemplatesTest` and
-- two methods named `testExample1Template` and
-- `testExample2Template`.
src/
main/
java/
tech.picnic.errorprone.refastertemplates
└── ExampleTemplates.java -- Contains multiple Refaster templates.
└── Example1Template
└── Example2Template
test/
java/
tech.picnic.errorprone.refastertemplates
└── RefasterCollectionTest.java
-- This test class invokes
-- `RefasterTemplateCollectionValidator#validate`.
resources/
tech.picnic.errorprone.refastertemplates
└── ExampleTemplatesTestInput.java
-- Contains a class named `ExampleTemplatesTest` and
-- two methods named `testExample1Template` and
-- `testExample2Template`.
└── ExampleTemplatesTestOutput.java
-- Contains a class named `ExampleTemplatesTest` and
-- two methods named `testExample1Template` and
-- `testExample2Template`.
```
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,9 @@
import tech.picnic.errorprone.refaster.runner.RefasterCheck;

/**
* A {@link BugChecker} that applies a Refaster template collection by delegating to {@link
* RefasterCheck} and subsequently validates that each template modifies exactly one distinct
* method, as indicated by each method's name.
* A {@link BugChecker} that applies a Refaster template collection to an associated test input file
* by delegating to {@link RefasterCheck}, and subsequently validates that each template modifies
* exactly one distinct method, as indicated by each method's name.
*/
@BugPattern(
name = "RefasterTemplateCollectionValidator",
Expand Down Expand Up @@ -118,7 +118,7 @@ public static void validate(Class<?> clazz) {
String className = clazz.getSimpleName();

BugCheckerRefactoringTestHelper.newInstance(RefasterTemplateCollectionValidator.class, clazz)
.setArgs(ImmutableList.of("-XepOpt:" + TEMPLATE_COLLECTION_FLAG + "=" + className))
.setArgs(ImmutableList.of("-XepOpt:" + TEMPLATE_COLLECTION_FLAG + '=' + className))
.addInput(className + "TestInput.java")
.addOutput(className + "TestOutput.java")
.doTest(TEXT_MATCH);
Expand Down Expand Up @@ -151,7 +151,7 @@ private static ImmutableRangeMap<Integer, String> indexTemplateMatches(
Iterables.getOnlyElement(description.fixes).getReplacements(endPositions);
for (Replacement replacement : replacements) {
templateMatches.put(
replacement.range(), getSubstringAfterLastChar('.', description.checkName));
replacement.range(), getSubstringAfterFinalDelimiter('.', description.checkName));
}
}

Expand All @@ -172,7 +172,7 @@ private void reportMissingMatches(
tree,
String.format(
"Did not encounter a test in `%s` for the following template(s)",
getSubstringAfterLastChar('/', sourceFile)),
getSubstringAfterFinalDelimiter('/', sourceFile)),
templatesWithoutMatch,
state);
}
Expand All @@ -194,11 +194,11 @@ private void reportViolations(
SuggestedFix fixWithComment =
tree instanceof MethodTree
? SuggestedFix.prefixWith(tree, comment)
: SuggestedFix.postfixWith(tree, "\n" + comment);
: SuggestedFix.postfixWith(tree, '\n' + comment);
state.reportMatch(describeMatch(tree, fixWithComment));
}

private static String getSubstringAfterLastChar(char delimiter, String value) {
private static String getSubstringAfterFinalDelimiter(char delimiter, String value) {
int index = value.lastIndexOf(delimiter);
checkState(index >= 0, "String '%s' does not contain character '%s'", value, delimiter);
return value.substring(index + 1);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
import com.google.errorprone.refaster.annotation.AfterTemplate;
import com.google.errorprone.refaster.annotation.BeforeTemplate;

/**
* Refaster template collection to validate that matches for one template in a test method meant to
* cover another template are reported.
*/
final class PartialTestMatchTemplates {
private PartialTestMatchTemplates() {}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@
import org.junit.jupiter.params.provider.ValueSource;

/**
* Validate error reporting of the Refaster template collections.
* Validates {@link RefasterTemplateCollectionValidator} error reporting.
*
* <p>The goal of the Refaster template collections under test is to verify the reporting of {@link
* RefasterTemplateCollectionValidator} using the associated `TestInput` and `TestOutput` files.
* Normally, {@link RefasterTemplateCollectionValidator} will report error messages directly in the
* console where the results of the tests are shown. However, to verify that these messages are
* correct, the `*TestOutput` files in this package contain error reporting that is normally not
* written.
* <p>The goal of the Refaster template collections under test is to verify the reporting of
* violations by {@link RefasterTemplateCollectionValidator} using the associated {@code
* TestInput.java} and {@code TestOutput.java} files. Normally, {@link
* RefasterTemplateCollectionValidator} will raise error messages to be rendered in the console or
* IDE. However, to verify that these error messages are as intended, the {@code *TestOutput.java}
* files in this package contain error reporting that is normally not present.
*/
final class RefasterTemplateCollectionValidatorTest {
@ParameterizedTest
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,7 @@
import java.util.Set;
import javax.annotation.Nullable;

/**
* Refaster template collection with arbitrary valid examples to validate that having no violations
* works as expected.
*/
/** Refaster template collection to validate that having no violations works as expected. */
final class ValidTemplates {
private ValidTemplates() {}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
package tech.picnic.errorprone.refaster.test;

import com.google.common.collect.ImmutableSet;

/** Code to test the Refaster templates from {@link MethodWithoutPrefixTemplates}. */
final class MethodWithoutPrefixTemplatesTest implements RefasterTemplateTestCase {
@Override
public ImmutableSet<?> elidedTypesAndStaticImports() {
return ImmutableSet.of();
}

boolean testStringIsEmpty() {
return "foo".equals("");
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
package tech.picnic.errorprone.refaster.test;

import com.google.common.collect.ImmutableSet;

/** Code to test the Refaster templates from {@link MethodWithoutPrefixTemplates}. */
final class MethodWithoutPrefixTemplatesTest implements RefasterTemplateTestCase {
@Override
public ImmutableSet<?> elidedTypesAndStaticImports() {
return ImmutableSet.of();
}

boolean testStringIsEmpty() {
return "foo".isEmpty();
}
Expand Down

0 comments on commit 5ce5a50

Please sign in to comment.