Home | History | Annotate | Download | only in processing
      1 package org.robolectric.annotation.processing;
      2 
      3 import static com.google.common.truth.Truth.assertAbout;
      4 import static com.google.common.truth.Truth.assertThat;
      5 import static com.google.testing.compile.JavaFileObjects.forResource;
      6 import static com.google.testing.compile.JavaFileObjects.forSourceString;
      7 import static com.google.testing.compile.JavaSourcesSubjectFactory.javaSources;
      8 import static java.nio.charset.StandardCharsets.UTF_8;
      9 import static org.robolectric.annotation.processing.RobolectricProcessor.JSON_DOCS_DIR;
     10 import static org.robolectric.annotation.processing.RobolectricProcessor.PACKAGE_OPT;
     11 import static org.robolectric.annotation.processing.RobolectricProcessor.SHOULD_INSTRUMENT_PKG_OPT;
     12 import static org.robolectric.annotation.processing.Utils.DEFAULT_OPTS;
     13 import static org.robolectric.annotation.processing.Utils.SHADOW_EXTRACTOR_SOURCE;
     14 import static org.robolectric.annotation.processing.Utils.SHADOW_PROVIDER_SOURCE;
     15 
     16 import com.google.common.collect.ImmutableList;
     17 import com.google.common.collect.ImmutableMap;
     18 import com.google.common.io.Files;
     19 import java.io.BufferedReader;
     20 import java.io.IOException;
     21 import java.io.InputStream;
     22 import java.io.InputStreamReader;
     23 import java.util.HashMap;
     24 import java.util.Map;
     25 import org.junit.Test;
     26 import org.junit.runner.RunWith;
     27 import org.junit.runners.JUnit4;
     28 
     29 @RunWith(JUnit4.class)
     30 public class RobolectricProcessorTest {
     31   @Test
     32   public void robolectricProcessor_supportsPackageOption() {
     33     assertThat(new RobolectricProcessor(DEFAULT_OPTS).getSupportedOptions()).contains(PACKAGE_OPT);
     34   }
     35 
     36   @Test
     37   public void robolectricProcessor_supportsShouldInstrumentPackageOption() {
     38     assertThat(
     39         new RobolectricProcessor(DEFAULT_OPTS).getSupportedOptions()).contains(SHOULD_INSTRUMENT_PKG_OPT);
     40   }
     41 
     42   @Test
     43   public void unannotatedSource_shouldCompile() {
     44     assertAbout(javaSources())
     45       .that(ImmutableList.of(
     46           SHADOW_PROVIDER_SOURCE,
     47           SHADOW_EXTRACTOR_SOURCE,
     48           forSourceString("HelloWorld", "final class HelloWorld {}")))
     49       .processedWith(new RobolectricProcessor(DEFAULT_OPTS))
     50       .compilesWithoutError();
     51     //.and().generatesNoSources(); Should add this assertion onces
     52     // it becomes available in compile-testing
     53   }
     54 
     55   @Test
     56   public void generatedFile_shouldHandleInnerClassCollisions() {
     57     // Because the Generated annotation has a retention of "source", it can't
     58     // be tested by a unit test - must run a source-level test.
     59     assertAbout(javaSources())
     60       .that(ImmutableList.of(
     61           SHADOW_PROVIDER_SOURCE,
     62           SHADOW_EXTRACTOR_SOURCE,
     63           forResource("org/robolectric/annotation/processing/shadows/ShadowDummy.java"),
     64           forResource("org/robolectric/annotation/processing/shadows/ShadowOuterDummy.java"),
     65           forResource("org/robolectric/annotation/processing/shadows/ShadowUniqueDummy.java")))
     66       .processedWith(new RobolectricProcessor(DEFAULT_OPTS))
     67       .compilesWithoutError()
     68       .and()
     69       .generatesSources(forResource("org/robolectric/Robolectric_InnerClassCollision.java"));
     70   }
     71 
     72   @Test
     73   public void generatedFile_shouldHandleNonPublicClasses() {
     74     assertAbout(javaSources())
     75       .that(ImmutableList.of(
     76           SHADOW_PROVIDER_SOURCE,
     77           SHADOW_EXTRACTOR_SOURCE,
     78           forResource("org/robolectric/annotation/processing/shadows/ShadowPrivate.java"),
     79           forResource("org/robolectric/annotation/processing/shadows/ShadowOuterDummy2.java"),
     80           forResource("org/robolectric/annotation/processing/shadows/ShadowDummy.java")))
     81       .processedWith(new RobolectricProcessor(DEFAULT_OPTS))
     82       .compilesWithoutError()
     83       .and()
     84       .generatesSources(forResource("org/robolectric/Robolectric_HiddenClasses.java"));
     85   }
     86 
     87   @Test
     88   public void generatedFile_shouldComplainAboutNonStaticInnerClasses() {
     89     assertAbout(javaSources())
     90       .that(ImmutableList.of(
     91           SHADOW_PROVIDER_SOURCE,
     92           SHADOW_EXTRACTOR_SOURCE,
     93           forResource("org/robolectric/annotation/processing/shadows/ShadowOuterDummyWithErrs.java")))
     94       .processedWith(new RobolectricProcessor(DEFAULT_OPTS))
     95       .failsToCompile()
     96       .withErrorContaining("inner shadow classes must be static");
     97   }
     98 
     99   @Test
    100   public void generatedFile_shouldHandleClassNameOnlyShadows() {
    101     assertAbout(javaSources())
    102       .that(ImmutableList.of(
    103           SHADOW_PROVIDER_SOURCE,
    104           SHADOW_EXTRACTOR_SOURCE,
    105           forResource("org/robolectric/annotation/processing/shadows/ShadowClassNameOnly.java"),
    106           forResource("org/robolectric/annotation/processing/shadows/ShadowDummy.java")))
    107       .processedWith(new RobolectricProcessor(DEFAULT_OPTS))
    108       .compilesWithoutError()
    109       .and()
    110       .generatesSources(forResource("org/robolectric/Robolectric_ClassNameOnly.java"));
    111   }
    112 
    113   @Test
    114   public void generatedFile_shouldNotGenerateShadowOfMethodsForExcludedClasses() {
    115     assertAbout(javaSources())
    116         .that(ImmutableList.of(
    117             SHADOW_PROVIDER_SOURCE,
    118             SHADOW_EXTRACTOR_SOURCE,
    119             forResource("org/robolectric/annotation/processing/shadows/ShadowExcludedFromAndroidSdk.java")))
    120         .processedWith(new RobolectricProcessor(DEFAULT_OPTS))
    121         .compilesWithoutError()
    122         .and()
    123         .generatesSources(forResource("org/robolectric/Robolectric_NoExcludedTypes.java"));
    124   }
    125 
    126   @Test
    127   public void generatedFile_shouldUseSpecifiedPackage() throws IOException {
    128     StringBuilder expected = new StringBuilder();
    129     InputStream in = RobolectricProcessorTest.class.getClassLoader()
    130         .getResourceAsStream("org/robolectric/Robolectric_ClassNameOnly.java");
    131     BufferedReader reader = new BufferedReader(new InputStreamReader(in, UTF_8));
    132 
    133     String line;
    134     while ((line = reader.readLine()) != null) {
    135       expected.append(line).append("\n");
    136     }
    137     line = expected.toString();
    138     line = line.replace("package org.robolectric", "package my.test.pkg");
    139 
    140     ImmutableMap<String, String> opts =
    141         ImmutableMap.of(
    142             PACKAGE_OPT, "my.test.pkg", JSON_DOCS_DIR, Files.createTempDir().toString());
    143 
    144     assertAbout(javaSources())
    145       .that(ImmutableList.of(
    146           SHADOW_PROVIDER_SOURCE,
    147           SHADOW_EXTRACTOR_SOURCE,
    148           forResource("org/robolectric/annotation/processing/shadows/ShadowClassNameOnly.java"),
    149           forResource("org/robolectric/annotation/processing/shadows/ShadowDummy.java")))
    150       .processedWith(new RobolectricProcessor(opts))
    151       .compilesWithoutError()
    152       .and()
    153       .generatesSources(forSourceString("Shadows", line));
    154   }
    155 
    156   @Test
    157   public void shouldGenerateMetaInfServicesFile() {
    158     assertAbout(javaSources())
    159         .that(ImmutableList.of(
    160             SHADOW_PROVIDER_SOURCE,
    161             SHADOW_EXTRACTOR_SOURCE,
    162             forResource("org/robolectric/annotation/processing/shadows/ShadowClassNameOnly.java"),
    163             forResource("org/robolectric/annotation/processing/shadows/ShadowDummy.java")))
    164         .processedWith(new RobolectricProcessor(DEFAULT_OPTS))
    165         .compilesWithoutError()
    166         .and()
    167         .generatesFiles(forResource("META-INF/services/org.robolectric.internal.ShadowProvider"));
    168   }
    169 
    170   @Test
    171   public void shouldGracefullyHandleUnrecognisedAnnotation() {
    172     assertAbout(javaSources())
    173       .that(ImmutableList.of(
    174           SHADOW_PROVIDER_SOURCE,
    175           SHADOW_EXTRACTOR_SOURCE,
    176           forResource("org/robolectric/annotation/TestWithUnrecognizedAnnotation.java")))
    177       .processedWith(new RobolectricProcessor(DEFAULT_OPTS))
    178       .compilesWithoutError();
    179   }
    180 
    181   @Test
    182   public void shouldGenerateGenericShadowOf() {
    183     assertAbout(javaSources())
    184       .that(ImmutableList.of(
    185           SHADOW_PROVIDER_SOURCE,
    186           SHADOW_EXTRACTOR_SOURCE,
    187           forResource("org/robolectric/annotation/processing/shadows/ShadowDummy.java"),
    188           forResource("org/robolectric/annotation/processing/shadows/ShadowParameterizedDummy.java")))
    189       .processedWith(new RobolectricProcessor(DEFAULT_OPTS))
    190       .compilesWithoutError()
    191       .and()
    192       .generatesSources(forResource("org/robolectric/Robolectric_Parameterized.java"));
    193   }
    194 
    195   @Test
    196   public void generatedShadowProvider_canConfigureInstrumentingPackages() {
    197     Map<String, String> options = new HashMap<>(DEFAULT_OPTS);
    198     options.put(SHOULD_INSTRUMENT_PKG_OPT, "false");
    199 
    200     assertAbout(javaSources())
    201     .that(ImmutableList.of(
    202         SHADOW_PROVIDER_SOURCE,
    203         SHADOW_EXTRACTOR_SOURCE,
    204         forResource("org/robolectric/annotation/processing/shadows/ShadowDummy.java")))
    205     .processedWith(new RobolectricProcessor(options))
    206     .compilesWithoutError()
    207     .and()
    208     .generatesSources(forResource("org/robolectric/Robolectric_EmptyProvidedPackageNames.java"));
    209   }
    210 }
    211