Back to Repositories

Testing EXIF Orientation Stream Processing in Glide Library

This test suite validates the ExifOrientationStream functionality in Glide’s image loading system, specifically focusing on EXIF orientation handling for both landscape and portrait images. The tests ensure proper orientation metadata processing across different image rotations.

Test Coverage Overview

The test suite provides comprehensive coverage of EXIF orientation handling for image streams.

Key areas tested include:
  • Orientation validation for 8 different EXIF orientations
  • Testing both landscape and portrait image variations
  • Verification of orientation metadata preservation
  • Integration with DefaultImageHeaderParser

Implementation Analysis

The testing approach employs a systematic matrix-based verification, testing all possible orientation combinations for both image types. The implementation leverages Robolectric for Android environment simulation and JUnit for test structure.

Technical patterns include:
  • Nested loop testing for exhaustive coverage
  • Resource file handling with TestResourceUtil
  • ArrayPool implementation for memory management

Technical Details

Testing infrastructure includes:
  • JUnit 4 test framework
  • Robolectric test runner with SDK configuration
  • LruArrayPool for byte array management
  • TestResourceUtil for test resource loading
  • DefaultImageHeaderParser for EXIF parsing

Best Practices Demonstrated

The test suite exemplifies several testing best practices in image processing validation.

Notable practices include:
  • Systematic test organization with @Before setup
  • Comprehensive edge case coverage
  • Resource cleanup and management
  • Clear test method naming and structure
  • Efficient test resource utilization

bumptech/glide

library/test/src/test/java/com/bumptech/glide/load/data/ExifOrientationStreamTest.java

            
package com.bumptech.glide.load.data;

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

import com.bumptech.glide.load.engine.bitmap_recycle.ArrayPool;
import com.bumptech.glide.load.engine.bitmap_recycle.LruArrayPool;
import com.bumptech.glide.load.resource.bitmap.DefaultImageHeaderParser;
import com.bumptech.glide.testutil.TestResourceUtil;
import java.io.IOException;
import java.io.InputStream;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;

@RunWith(RobolectricTestRunner.class)
@Config(sdk = ROBOLECTRIC_SDK)
public class ExifOrientationStreamTest {
  private ArrayPool byteArrayPool;

  private InputStream openOrientationExample(boolean isLandscape, int item) {
    String filePrefix = isLandscape ? "Landscape" : "Portrait";
    return TestResourceUtil.openResource(getClass(), filePrefix + "_" + item + ".jpg");
  }

  @Before
  public void setUp() {
    byteArrayPool = new LruArrayPool();
  }

  @Test
  public void testIncludesGivenExifOrientation() throws IOException {
    for (int i = 0; i < 8; i++) {
      for (int j = 0; j < 8; j++) {
        InputStream toWrap = openOrientationExample(true /*isLandscape*/, j + 1);
        InputStream wrapped = new ExifOrientationStream(toWrap, i);
        DefaultImageHeaderParser parser = new DefaultImageHeaderParser();
        assertThat(parser.getOrientation(wrapped, byteArrayPool)).isEqualTo(i);

        toWrap = openOrientationExample(false /*isLandscape*/, j + 1);
        wrapped = new ExifOrientationStream(toWrap, i);
        assertThat(parser.getOrientation(wrapped, byteArrayPool)).isEqualTo(i);
      }
    }
  }
}