/* * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. */ package com.facebook.imagepipeline.animated.impl; import com.facebook.cache.common.CacheKey; import com.facebook.cache.common.SimpleCacheKey; import com.facebook.common.internal.Supplier; import com.facebook.common.memory.MemoryTrimmableRegistry; import com.facebook.common.references.CloseableReference; import com.facebook.common.util.ByteConstants; import com.facebook.imagepipeline.bitmaps.PlatformBitmapFactory; import com.facebook.imagepipeline.cache.BitmapCountingMemoryCacheFactory; import com.facebook.imagepipeline.cache.CountingMemoryCache; import com.facebook.imagepipeline.cache.MemoryCacheParams; import com.facebook.imagepipeline.image.CloseableImage; 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 static junit.framework.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotSame; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @RunWith(RobolectricTestRunner.class) public class AnimatedFrameCacheTest { @Mock public MemoryTrimmableRegistry mMemoryTrimmableRegistry; @Mock public Supplier<MemoryCacheParams> mMemoryCacheParamsSupplier; @Mock public PlatformBitmapFactory mPlatformBitmapFactory; private CacheKey mCacheKey; private AnimatedFrameCache mAnimatedFrameCache; private CloseableReference<CloseableImage> mFrame1; private CloseableReference<CloseableImage> mFrame2; @Before public void setUp() { MockitoAnnotations.initMocks(this); MemoryCacheParams params = new MemoryCacheParams( 4 * ByteConstants.MB, 256, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE); when(mMemoryCacheParamsSupplier.get()).thenReturn(params); CountingMemoryCache<CacheKey, CloseableImage> countingMemoryCache = BitmapCountingMemoryCacheFactory.get( mMemoryCacheParamsSupplier, mMemoryTrimmableRegistry, mPlatformBitmapFactory, true); mCacheKey = new SimpleCacheKey("key"); mAnimatedFrameCache = new AnimatedFrameCache(mCacheKey, countingMemoryCache); mFrame1 = CloseableReference.of(mock(CloseableImage.class)); mFrame2 = CloseableReference.of(mock(CloseableImage.class)); } @Test public void testBasic() { CloseableReference<CloseableImage> ret = mAnimatedFrameCache.cache(1, mFrame1); assertSame(ret.get(), mFrame1.get()); } @Test public void testMultipleFrames() { mAnimatedFrameCache.cache(1, mFrame1); mAnimatedFrameCache.cache(2, mFrame2); assertSame(mFrame1.get(), mAnimatedFrameCache.get(1).get()); assertSame(mFrame2.get(), mAnimatedFrameCache.get(2).get()); } @Test public void testReplace() { mAnimatedFrameCache.cache(1, mFrame1); mAnimatedFrameCache.cache(1, mFrame2); assertNotSame(mFrame1.get(), mAnimatedFrameCache.get(1).get()); assertSame(mFrame2.get(), mAnimatedFrameCache.get(1).get()); } @Test public void testReuse() { CloseableReference<CloseableImage> ret = mAnimatedFrameCache.cache(1, mFrame1); ret.close(); CloseableReference<CloseableImage> free = mAnimatedFrameCache.getForReuse(); assertNotNull(free); } @Test public void testCantReuseIfNotClosed() { CloseableReference<CloseableImage> ret = mAnimatedFrameCache.cache(1, mFrame1); CloseableReference<CloseableImage> free = mAnimatedFrameCache.getForReuse(); assertNull(free); } @Test public void testStillThereIfClosed() { CloseableReference<CloseableImage> ret = mAnimatedFrameCache.cache(1, mFrame1); ret.close(); assertNotNull(mAnimatedFrameCache.get(1)); } @Test public void testContains() { assertFalse(mAnimatedFrameCache.contains(1)); CloseableReference<CloseableImage> ret = mAnimatedFrameCache.cache(1, mFrame1); assertTrue(mAnimatedFrameCache.contains(1)); assertFalse(mAnimatedFrameCache.contains(2)); ret.close(); assertTrue(mAnimatedFrameCache.contains(1)); assertFalse(mAnimatedFrameCache.contains(2)); } @Test public void testContainsWhenReused() { CloseableReference<CloseableImage> ret = mAnimatedFrameCache.cache(1, mFrame1); ret.close(); assertTrue(mAnimatedFrameCache.contains(1)); assertFalse(mAnimatedFrameCache.contains(2)); CloseableReference<CloseableImage> free = mAnimatedFrameCache.getForReuse(); free.close(); assertFalse(mAnimatedFrameCache.contains(1)); assertFalse(mAnimatedFrameCache.contains(2)); } @Test public void testContainsFullReuseFlowWithMultipleItems() { assertFalse(mAnimatedFrameCache.contains(1)); assertFalse(mAnimatedFrameCache.contains(2)); CloseableReference<CloseableImage> ret = mAnimatedFrameCache.cache(1, mFrame1); CloseableReference<CloseableImage> ret2 = mAnimatedFrameCache.cache(2, mFrame2); assertTrue(mAnimatedFrameCache.contains(1)); assertTrue(mAnimatedFrameCache.contains(2)); ret.close(); ret2.close(); assertTrue(mAnimatedFrameCache.contains(1)); assertTrue(mAnimatedFrameCache.contains(2)); CloseableReference<CloseableImage> free = mAnimatedFrameCache.getForReuse(); free.close(); assertFalse(mAnimatedFrameCache.contains(1)); assertTrue(mAnimatedFrameCache.contains(2)); free = mAnimatedFrameCache.getForReuse(); free.close(); assertFalse(mAnimatedFrameCache.contains(1)); assertFalse(mAnimatedFrameCache.contains(2)); } }