Back to Repositories

Testing GIF Stream Decoder Implementation in Glide

This test suite validates the StreamGifDecoder functionality in Glide, focusing on GIF animation handling and header detection. It ensures proper decoding behavior for GIF streams with various configuration options and header validations.

Test Coverage Overview

The test suite provides comprehensive coverage of StreamGifDecoder’s core functionality, particularly focusing on GIF stream handling and animation control.

  • Tests GIF header detection and validation
  • Verifies animation disable/enable options
  • Covers stream handling with different input conditions
  • Validates decoder behavior with various configuration states

Implementation Analysis

The testing approach utilizes JUnit and Robolectric for Android environment simulation. It implements systematic validation of the GIF decoder’s handling capabilities.

The tests use Mockito for dependency injection and employ byte array manipulation to simulate GIF data streams. The implementation follows a clear arrange-act-assert pattern with proper test isolation.

Technical Details

  • JUnit 4 test framework with Robolectric test runner
  • Mockito for mocking dependencies
  • Custom GifOptions configuration
  • ByteArrayInputStream for stream simulation
  • LruArrayPool for memory management
  • DefaultImageHeaderParser integration

Best Practices Demonstrated

The test suite exemplifies high-quality testing practices with clear separation of concerns and thorough setup management.

  • Proper test initialization with @Before setup
  • Consistent naming conventions
  • Focused test methods with single responsibilities
  • Effective use of mocking and dependency injection
  • Clear test case organization and structure

bumptech/glide

library/test/src/test/java/com/bumptech/glide/load/resource/gif/StreamGifDecoderTest.java

            
package com.bumptech.glide.load.resource.gif;

import static com.bumptech.glide.RobolectricConstants.ROBOLECTRIC_SDK;
import static com.google.common.truth.Truth.assertThat;

import com.bumptech.glide.load.ImageHeaderParser;
import com.bumptech.glide.load.Options;
import com.bumptech.glide.load.ResourceDecoder;
import com.bumptech.glide.load.engine.bitmap_recycle.LruArrayPool;
import com.bumptech.glide.load.resource.bitmap.DefaultImageHeaderParser;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;

@RunWith(RobolectricTestRunner.class)
@Config(sdk = ROBOLECTRIC_SDK)
public class StreamGifDecoderTest {
  private static final byte[] GIF_HEADER = new byte[] {0x47, 0x49, 0x46};

  @Mock private ResourceDecoder<ByteBuffer, GifDrawable> byteBufferDecoder;
  private StreamGifDecoder decoder;
  private Options options;

  @Before
  public void setUp() {
    MockitoAnnotations.initMocks(this);

    List<ImageHeaderParser> parsers = new ArrayList<>();
    parsers.add(new DefaultImageHeaderParser());

    decoder = new StreamGifDecoder(parsers, byteBufferDecoder, new LruArrayPool());
    options = new Options();
  }

  @Test
  public void testDoesNotHandleStreamIfEnabledButNotAGif() throws IOException {
    assertThat(decoder.handles(new ByteArrayInputStream(new byte[0]), options)).isFalse();
  }

  @Test
  public void testHandlesStreamIfContainsGifHeaderAndDisabledIsNotSet() throws IOException {
    assertThat(decoder.handles(new ByteArrayInputStream(GIF_HEADER), options)).isTrue();
  }

  @Test
  public void testHandlesStreamIfContainsGifHeaderAndDisabledIsFalse() throws IOException {
    options.set(GifOptions.DISABLE_ANIMATION, false);
    assertThat(decoder.handles(new ByteArrayInputStream(GIF_HEADER), options)).isTrue();
  }

  @Test
  public void testDoesNotHandleStreamIfDisabled() throws IOException {
    options.set(GifOptions.DISABLE_ANIMATION, true);
    assertThat(decoder.handles(new ByteArrayInputStream(GIF_HEADER), options)).isFalse();
  }
}