Back to Repositories

Validating AppGlideModule Uniqueness Constraints in Glide

This test suite validates the enforcement of single AppGlideModule restriction in the Glide image loading library. It ensures that the annotation processor correctly handles module configurations and prevents multiple AppGlideModule implementations in a project.

Test Coverage Overview

The test suite provides comprehensive coverage of AppGlideModule validation scenarios:

  • Verification of compilation failure with multiple AppGlideModules
  • Validation of successful compilation with single module configurations
  • Edge case handling for different module combinations
  • Integration with Glide’s annotation processing system

Implementation Analysis

The testing approach utilizes JUnit4 framework with custom compilation testing utilities. It implements a systematic verification pattern using javac compilation tests and assertion checks.

Key testing patterns include:
  • Compilation result validation
  • Exception handling verification
  • Resource management through RegenerateResourcesRule
  • Modular test case organization

Technical Details

Testing infrastructure includes:

  • JUnit4 test runner and annotations
  • Google’s compile-testing library for compilation validation
  • Custom CompilationProvider interface implementation
  • RegenerateResourcesRule for resource management
  • GlideAnnotationProcessor for annotation processing

Best Practices Demonstrated

The test suite exemplifies high-quality testing practices through clean separation of concerns and robust validation approaches.

  • Isolated test cases for each scenario
  • Proper exception handling and verification
  • Clear test method naming conventions
  • Effective use of JUnit rules and annotations
  • Comprehensive compilation result validation

bumptech/glide

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

            
package com.bumptech.glide.annotation.compiler;

import static com.google.testing.compile.CompilationSubject.assertThat;
import static com.google.testing.compile.Compiler.javac;
import static org.junit.Assert.assertThrows;

import com.bumptech.glide.annotation.compiler.test.CompilationProvider;
import com.bumptech.glide.annotation.compiler.test.RegenerateResourcesRule;
import com.bumptech.glide.annotation.compiler.test.Util;
import com.google.testing.compile.Compilation;
import javax.tools.JavaFileObject;
import org.junit.Rule;
import org.junit.Test;
import org.junit.function.ThrowingRunnable;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/**
 * Ensures that adding more than one {@link com.bumptech.glide.module.AppGlideModule} to a project
 * will fail.
 */
@RunWith(JUnit4.class)
public class MultipleAppGlideModuleTest implements CompilationProvider {
  private static final String FIRST_MODULE = "EmptyAppModule1.java";
  private static final String SECOND_MODULE = "EmptyAppModule2.java";

  @Rule
  public final RegenerateResourcesRule regenerateResourcesRule = new RegenerateResourcesRule(this);

  private Compilation compilation;

  // Throws.
  @SuppressWarnings("ResultOfMethodCallIgnored")
  @Test
  public void compilation_withTwoAppModules_fails() {
    assertThrows(
        RuntimeException.class,
        new ThrowingRunnable() {
          @Override
          public void run() throws Throwable {
            javac()
                .withProcessors(new GlideAnnotationProcessor())
                .compile(forResource(FIRST_MODULE), forResource(SECOND_MODULE));
          }
        });
  }

  @Test
  public void compilation_withFirstModuleOnly_succeeds() {
    compilation =
        javac().withProcessors(new GlideAnnotationProcessor()).compile(forResource(FIRST_MODULE));
    assertThat(compilation).succeededWithoutWarnings();
  }

  @Test
  public void compilation_withSecondModuleOnly_succeeds() {
    compilation =
        javac().withProcessors(new GlideAnnotationProcessor()).compile(forResource(SECOND_MODULE));
    assertThat(compilation).succeededWithoutWarnings();
  }

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

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