Back to Repositories

Validating Annotation Processor Extension Options in Bumptech Glide

This test suite validates Glide’s annotation processing functionality for extension options, focusing on the generation of source files and proper implementation of option-style extensions. It ensures the annotation processor correctly handles extension methods that return values and generates the expected Glide infrastructure classes.

Test Coverage Overview

The test suite provides comprehensive coverage of Glide’s annotation processing system, specifically for extension options.

Key areas tested include:
  • Verification of all generated source files
  • Validation of GlideOptions class generation
  • Testing of GlideRequest and GlideRequests class generation
  • Verification of GlideApp and module implementation classes
  • Testing of RequestManagerFactory generation

Implementation Analysis

The testing approach utilizes JUnit4 framework with custom compilation testing utilities.

Key implementation patterns include:
  • Use of javac compiler API for annotation processing
  • Custom resource regeneration rule implementation
  • Source file comparison for verification
  • Compilation success validation without warnings

Technical Details

Testing infrastructure includes:
  • Google Truth assertion library for enhanced verification
  • Custom CompilationProvider interface implementation
  • RegenerateResourcesRule for resource management
  • JavaFileObject utilities for resource handling
  • Custom test utilities for resource path management

Best Practices Demonstrated

The test suite exemplifies several testing best practices:

  • Proper test setup isolation using @Before
  • Clear test method naming conventions
  • Comprehensive assertion checking
  • Resource cleanup and management
  • Modular test organization with separate resource files
  • Use of custom annotations for special test cases

bumptech/glide

annotation/compiler/test/src/test/java/com/bumptech/glide/annotation/compiler/GlideExtensionWithOptionTest.java

            
package com.bumptech.glide.annotation.compiler;

import static com.bumptech.glide.annotation.compiler.test.Util.appResource;
import static com.bumptech.glide.annotation.compiler.test.Util.emptyAppModule;
import static com.bumptech.glide.annotation.compiler.test.Util.glide;
import static com.bumptech.glide.annotation.compiler.test.Util.subpackage;
import static com.google.testing.compile.CompilationSubject.assertThat;
import static com.google.testing.compile.Compiler.javac;

import com.bumptech.glide.annotation.compiler.test.CompilationProvider;
import com.bumptech.glide.annotation.compiler.test.ReferencedResource;
import com.bumptech.glide.annotation.compiler.test.RegenerateResourcesRule;
import com.bumptech.glide.annotation.compiler.test.Util;
import com.google.common.truth.Truth;
import com.google.testing.compile.Compilation;
import java.io.IOException;
import javax.tools.JavaFileObject;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/**
 * Verifies the output of the processor with a simple single extension option in the new option
 * style where extension methods always return values.
 */
@RunWith(JUnit4.class)
public class GlideExtensionWithOptionTest implements CompilationProvider {
  @Rule
  public final RegenerateResourcesRule regenerateResourcesRule = new RegenerateResourcesRule(this);

  private Compilation compilation;

  @Before
  public void setUp() {
    compilation =
        javac()
            .withProcessors(new GlideAnnotationProcessor())
            .compile(emptyAppModule(), forResource("ExtensionWithOption.java"));
    assertThat(compilation).succeededWithoutWarnings();
  }

  @Test
  public void compilation_generatesAllExpectedFiles() {
    Truth.assertThat(compilation.generatedSourceFiles()).hasSize(7);
  }

  @Test
  public void compilation_generatesExpectedGlideOptionsClass() throws IOException {
    assertThat(compilation)
        .generatedSourceFile(subpackage("GlideOptions"))
        .hasSourceEquivalentTo(forResource("GlideOptions.java"));
  }

  @Test
  public void compilation_generatesExpectedGlideRequestClass() throws IOException {
    assertThat(compilation)
        .generatedSourceFile(subpackage("GlideRequest"))
        .hasSourceEquivalentTo(forResource("GlideRequest.java"));
  }

  @Test
  @ReferencedResource
  public void compilation_generatesExpectedGlideRequestsClass() throws IOException {
    assertThat(compilation)
        .generatedSourceFile(subpackage("GlideRequests"))
        .hasSourceEquivalentTo(appResource("GlideRequests.java"));
  }

  @Test
  @ReferencedResource
  public void compilationGeneratesExpectedGlideAppClass() throws IOException {
    assertThat(compilation)
        .generatedSourceFile(subpackage("GlideApp"))
        .hasSourceEquivalentTo(appResource("GlideApp.java"));
  }

  @Test
  @ReferencedResource
  public void compilation_generatesExpectedGeneratedAppGlideModuleImpl() throws IOException {
    assertThat(compilation)
        .generatedSourceFile(glide("GeneratedAppGlideModuleImpl"))
        .hasSourceEquivalentTo(appResource("GeneratedAppGlideModuleImpl.java"));
  }

  @Test
  @ReferencedResource
  public void compilation_generatesExpectedGeneratedRequestManagerFactory() throws IOException {
    assertThat(compilation)
        .generatedSourceFile(glide("GeneratedRequestManagerFactory"))
        .hasSourceEquivalentTo(appResource("GeneratedRequestManagerFactory.java"));
  }

  private JavaFileObject forResource(String name) {
    return Util.forResource(getClass().getSimpleName(), name);
  }

  @Override
  public Compilation getCompilation() {
    return compilation;
  }
}