diff options
author | Lázaro Clapp <lazaro@uber.com> | 2021-12-22 16:37:04 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-12-22 16:37:04 -0500 |
commit | 3a52c312ecddc9790253c34bd8873bf531fc049b (patch) | |
tree | 447de958ac0d71831548841a2a011a315ab89e28 | |
parent | 025ebf04c434a3d1b43738422b499a6628b9929d (diff) | |
download | nullaway-3a52c312ecddc9790253c34bd8873bf531fc049b.tar.gz |
Test that DummyOptionsConfig's methods throw IllegalStateException (#525)
By design, this class is intended to fail whenever called, as an instance will only be generated when failing to produce an instance of `ErrorProneCLIFlagsConfig`.
See the javadoc documentation on `DummyOptionsConfig` itself as to why the class is needed to build NullAway.
Since we want NullAway to fail fast if this dummy options object is ever passed, we test that all declared methods in the class throw an exception if ever called. Our test uses reflection to account for future methods being added to the `Config` interface.
4 files changed, 85 insertions, 31 deletions
diff --git a/nullaway/src/main/java/com/uber/nullaway/DummyOptionsConfig.java b/nullaway/src/main/java/com/uber/nullaway/DummyOptionsConfig.java index d6cd7e8..b424eb9 100644 --- a/nullaway/src/main/java/com/uber/nullaway/DummyOptionsConfig.java +++ b/nullaway/src/main/java/com/uber/nullaway/DummyOptionsConfig.java @@ -40,7 +40,7 @@ import javax.annotation.Nullable; */ public class DummyOptionsConfig implements Config { - private final String error_msg = + public static final String ERROR_MESSAGE = "To run the " + EP_FL_NAMESPACE + " analysis plugin please specify analysis " @@ -55,143 +55,143 @@ public class DummyOptionsConfig implements Config { @Override public boolean fromAnnotatedPackage(Symbol.ClassSymbol symbol) { - throw new IllegalStateException(error_msg); + throw new IllegalStateException(ERROR_MESSAGE); } @Override public boolean isExcludedClass(String className) { - throw new IllegalStateException(error_msg); + throw new IllegalStateException(ERROR_MESSAGE); } @Override public boolean isUnannotatedClass(Symbol.ClassSymbol symbol) { - throw new IllegalStateException(error_msg); + throw new IllegalStateException(ERROR_MESSAGE); } @Override public ImmutableSet<String> getExcludedClassAnnotations() { - throw new IllegalStateException(error_msg); + throw new IllegalStateException(ERROR_MESSAGE); } @Override public boolean exhaustiveOverride() { - throw new IllegalStateException(error_msg); + throw new IllegalStateException(ERROR_MESSAGE); } @Override public boolean isKnownInitializerMethod(Symbol.MethodSymbol methodSymbol) { - throw new IllegalStateException(error_msg); + throw new IllegalStateException(ERROR_MESSAGE); } @Override public boolean isExternalInitClassAnnotation(String annotationName) { - throw new IllegalStateException(error_msg); + throw new IllegalStateException(ERROR_MESSAGE); } @Override public boolean isContractAnnotation(String annotationName) { - throw new IllegalStateException(error_msg); + throw new IllegalStateException(ERROR_MESSAGE); } @Override public boolean isExcludedFieldAnnotation(String annotationName) { - throw new IllegalStateException(error_msg); + throw new IllegalStateException(ERROR_MESSAGE); } @Override public boolean isInitializerMethodAnnotation(String annotationName) { - throw new IllegalStateException(error_msg); + throw new IllegalStateException(ERROR_MESSAGE); } @Override public boolean isCustomNullableAnnotation(String annotationName) { - return false; + throw new IllegalStateException(ERROR_MESSAGE); } @Override public boolean isCustomNonnullAnnotation(String annotationName) { - return false; + throw new IllegalStateException(ERROR_MESSAGE); } @Override public boolean suggestSuppressions() { - throw new IllegalStateException(error_msg); + throw new IllegalStateException(ERROR_MESSAGE); } @Override public boolean assertsEnabled() { - throw new IllegalStateException(error_msg); + throw new IllegalStateException(ERROR_MESSAGE); } @Override public boolean acknowledgeRestrictiveAnnotations() { - throw new IllegalStateException(error_msg); + throw new IllegalStateException(ERROR_MESSAGE); } @Override public boolean checkOptionalEmptiness() { - throw new IllegalStateException(error_msg); + throw new IllegalStateException(ERROR_MESSAGE); } @Override public boolean checkContracts() { - throw new IllegalStateException(error_msg); + throw new IllegalStateException(ERROR_MESSAGE); } @Override public boolean handleTestAssertionLibraries() { - throw new IllegalStateException(error_msg); + throw new IllegalStateException(ERROR_MESSAGE); } @Override public Set<String> getOptionalClassPaths() { - throw new IllegalStateException(error_msg); + throw new IllegalStateException(ERROR_MESSAGE); } @Override @Nullable public String getCastToNonNullMethod() { - throw new IllegalStateException(error_msg); + throw new IllegalStateException(ERROR_MESSAGE); } @Override public String getAutofixSuppressionComment() { - throw new IllegalStateException(error_msg); + throw new IllegalStateException(ERROR_MESSAGE); } @Override public boolean isJarInferEnabled() { - throw new IllegalStateException(error_msg); + throw new IllegalStateException(ERROR_MESSAGE); } /** --- JarInfer configs --- */ @Override public boolean isJarInferUseReturnAnnotations() { - throw new IllegalStateException(error_msg); + throw new IllegalStateException(ERROR_MESSAGE); } @Override public String getJarInferRegexStripModelJarName() { - throw new IllegalStateException(error_msg); + throw new IllegalStateException(ERROR_MESSAGE); } @Override public String getJarInferRegexStripCodeJarName() { - throw new IllegalStateException(error_msg); + throw new IllegalStateException(ERROR_MESSAGE); } @Override public String getErrorURL() { - throw new IllegalStateException(error_msg); + throw new IllegalStateException(ERROR_MESSAGE); } @Override public boolean treatGeneratedAsUnannotated() { - throw new IllegalStateException(error_msg); + throw new IllegalStateException(ERROR_MESSAGE); } @Override public boolean acknowledgeAndroidRecent() { - throw new IllegalStateException(error_msg); + throw new IllegalStateException(ERROR_MESSAGE); } } diff --git a/nullaway/src/test/java/com/uber/nullaway/DummyOptionsConfigTest.java b/nullaway/src/test/java/com/uber/nullaway/DummyOptionsConfigTest.java new file mode 100644 index 0000000..530d8ee --- /dev/null +++ b/nullaway/src/test/java/com/uber/nullaway/DummyOptionsConfigTest.java @@ -0,0 +1,56 @@ +package com.uber.nullaway; + +import static org.hamcrest.CoreMatchers.instanceOf; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThat; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.Arrays; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +@RunWith(JUnit4.class) +public class DummyOptionsConfigTest { + + DummyOptionsConfig dummyOptionsConfig; + + @Before + public void setup() { + dummyOptionsConfig = new DummyOptionsConfig(); + } + + @Test + public void allDeclaredMethodsThrowIllegalStateException() { + // DummyOptionsConfig is expected to throw a runtime exception if ever used (see documentation + // on that class) + // this test guarantees that all methods declared in the class throw the exception + Class<? extends DummyOptionsConfig> klass = dummyOptionsConfig.getClass(); + for (Method method : klass.getDeclaredMethods()) { + if (method.getName().contains("jacocoInit")) { + // Declared method added by jacoco coverage reporting (via reflection?). Plots within + // plots... + continue; + } + Class<?>[] parameterTypes = method.getParameterTypes(); + Object[] nullParams = Arrays.stream(parameterTypes).map((t) -> null).toArray(); + Exception reflectionException = + assertThrows( + InvocationTargetException.class, + () -> { + method.invoke(dummyOptionsConfig, nullParams); + }, + String.format( + "Expected method DummyOptionsConfig.%s to fail with IllegalStateException.", + method.getName())); + // The real exception, not wrapped by reflection exceptions + Throwable cause = reflectionException.getCause(); + assertThat(cause, instanceOf(IllegalStateException.class)); + IllegalStateException exception = (IllegalStateException) cause; + assertEquals(exception.getMessage(), DummyOptionsConfig.ERROR_MESSAGE); + } + } +} diff --git a/nullaway/src/test/java/com/uber/nullaway/NullAwayAndroidTest.java b/nullaway/src/test/java/com/uber/nullaway/NullAwayAndroidTest.java index ef2f622..5a63cef 100644 --- a/nullaway/src/test/java/com/uber/nullaway/NullAwayAndroidTest.java +++ b/nullaway/src/test/java/com/uber/nullaway/NullAwayAndroidTest.java @@ -11,7 +11,6 @@ import org.junit.runners.JUnit4; /** Unit tests for {@link com.uber.nullaway.NullAway}. */ @RunWith(JUnit4.class) -@SuppressWarnings("CheckTestExtendsBaseClass") public class NullAwayAndroidTest { @Rule public final TemporaryFolder temporaryFolder = new TemporaryFolder(); diff --git a/nullaway/src/test/java/com/uber/nullaway/NullAwayTest.java b/nullaway/src/test/java/com/uber/nullaway/NullAwayTest.java index 3521f66..f370821 100644 --- a/nullaway/src/test/java/com/uber/nullaway/NullAwayTest.java +++ b/nullaway/src/test/java/com/uber/nullaway/NullAwayTest.java @@ -35,7 +35,6 @@ import org.junit.runners.JUnit4; /** Unit tests for {@link com.uber.nullaway.NullAway}. */ @RunWith(JUnit4.class) -@SuppressWarnings("CheckTestExtendsBaseClass") public class NullAwayTest { @Rule public final TemporaryFolder temporaryFolder = new TemporaryFolder(); |