/*
* 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.cache;
import java.util.LinkedHashMap;
import java.util.List;
import com.android.internal.util.Predicate;
import org.junit.*;
import org.junit.runner.*;
import org.robolectric.*;
import static org.junit.Assert.*;
@RunWith(RobolectricTestRunner.class)
public class CountingLruMapTest {
private CountingLruMap<String, Integer> mCountingLruMap;
@Before
public void setUp() {
ValueDescriptor<Integer> valueDescriptor =
new ValueDescriptor<Integer>() {
@Override
public int getSizeInBytes(Integer value) {
return value;
}
};
mCountingLruMap = new CountingLruMap<>(valueDescriptor);
}
@Test
public void testInitialState() {
assertEquals(0, mCountingLruMap.getCount());
assertEquals(0, mCountingLruMap.getSizeInBytes());
}
@Test
public void testPut() {
// last inserted element should be last in the queue
mCountingLruMap.put("key1", 110);
assertEquals(1, mCountingLruMap.getCount());
assertEquals(110, mCountingLruMap.getSizeInBytes());
assertKeyOrder("key1");
assertValueOrder(110);
mCountingLruMap.put("key2", 120);
assertEquals(2, mCountingLruMap.getCount());
assertEquals(230, mCountingLruMap.getSizeInBytes());
assertKeyOrder("key1", "key2");
assertValueOrder(110, 120);
mCountingLruMap.put("key3", 130);
assertEquals(3, mCountingLruMap.getCount());
assertEquals(360, mCountingLruMap.getSizeInBytes());
assertKeyOrder("key1", "key2", "key3");
assertValueOrder(110, 120, 130);
}
@Test
public void testPut_SameKeyTwice() {
mCountingLruMap.put("key1", 110);
mCountingLruMap.put("key2", 120);
mCountingLruMap.put("key3", 130);
// last inserted element should be last in the queue
mCountingLruMap.put("key2", 150);
assertEquals(3, mCountingLruMap.getCount());
assertEquals(390, mCountingLruMap.getSizeInBytes());
assertKeyOrder("key1", "key3", "key2");
assertValueOrder(110, 130, 150);
}
@Test
public void testGet() {
mCountingLruMap.put("key1", 110);
mCountingLruMap.put("key2", 120);
mCountingLruMap.put("key3", 130);
// get shouldn't affect the ordering, nor the size
assertEquals(120, (Object) mCountingLruMap.get("key2"));
assertEquals(3, mCountingLruMap.getCount());
assertEquals(360, mCountingLruMap.getSizeInBytes());
assertKeyOrder("key1", "key2", "key3");
assertValueOrder(110, 120, 130);
assertEquals(110, (Object) mCountingLruMap.get("key1"));
assertEquals(3, mCountingLruMap.getCount());
assertEquals(360, mCountingLruMap.getSizeInBytes());
assertKeyOrder("key1", "key2", "key3");
assertValueOrder(110, 120, 130);
assertEquals(null, (Object) mCountingLruMap.get("key4"));
assertEquals(3, mCountingLruMap.getCount());
assertEquals(360, mCountingLruMap.getSizeInBytes());
assertKeyOrder("key1", "key2", "key3");
assertValueOrder(110, 120, 130);
assertEquals(130, (Object) mCountingLruMap.get("key3"));
assertEquals(3, mCountingLruMap.getCount());
assertEquals(360, mCountingLruMap.getSizeInBytes());
assertKeyOrder("key1", "key2", "key3");
assertValueOrder(110, 120, 130);
}
@Test
public void testContains() {
mCountingLruMap.put("key1", 110);
mCountingLruMap.put("key2", 120);
mCountingLruMap.put("key3", 130);
// contains shouldn't affect the ordering, nor the size
assertTrue(mCountingLruMap.contains("key2"));
assertEquals(3, mCountingLruMap.getCount());
assertEquals(360, mCountingLruMap.getSizeInBytes());
assertKeyOrder("key1", "key2", "key3");
assertValueOrder(110, 120, 130);
assertTrue(mCountingLruMap.contains("key1"));
assertEquals(3, mCountingLruMap.getCount());
assertEquals(360, mCountingLruMap.getSizeInBytes());
assertKeyOrder("key1", "key2", "key3");
assertValueOrder(110, 120, 130);
assertFalse(mCountingLruMap.contains("key4"));
assertEquals(3, mCountingLruMap.getCount());
assertEquals(360, mCountingLruMap.getSizeInBytes());
assertKeyOrder("key1", "key2", "key3");
assertValueOrder(110, 120, 130);
assertTrue(mCountingLruMap.contains("key3"));
assertEquals(3, mCountingLruMap.getCount());
assertEquals(360, mCountingLruMap.getSizeInBytes());
assertKeyOrder("key1", "key2", "key3");
assertValueOrder(110, 120, 130);
}
@Test
public void testRemove() {
mCountingLruMap.put("key1", 110);
mCountingLruMap.put("key2", 120);
mCountingLruMap.put("key3", 130);
assertEquals(120, (Object) mCountingLruMap.remove("key2"));
assertEquals(2, mCountingLruMap.getCount());
assertEquals(240, mCountingLruMap.getSizeInBytes());
assertKeyOrder("key1", "key3");
assertValueOrder(110, 130);
assertEquals(130, (Object) mCountingLruMap.remove("key3"));
assertEquals(1, mCountingLruMap.getCount());
assertEquals(110, mCountingLruMap.getSizeInBytes());
assertKeyOrder("key1");
assertValueOrder(110);
assertEquals(null, (Object) mCountingLruMap.remove("key4"));
assertEquals(1, mCountingLruMap.getCount());
assertEquals(110, mCountingLruMap.getSizeInBytes());
assertKeyOrder("key1");
assertValueOrder(110);
assertEquals(110, (Object) mCountingLruMap.remove("key1"));
assertEquals(0, mCountingLruMap.getCount());
assertEquals(0, mCountingLruMap.getSizeInBytes());
assertKeyOrder();
assertValueOrder();
}
@Test
public void testRemoveAll() {
mCountingLruMap.put("key1", 110);
mCountingLruMap.put("key2", 120);
mCountingLruMap.put("key3", 130);
mCountingLruMap.put("key4", 140);
mCountingLruMap.removeAll(
new Predicate<String>() {
@Override
public boolean apply(String key) {
return key.equals("key2") || key.equals("key3");
}
});
assertEquals(2, mCountingLruMap.getCount());
assertEquals(250, mCountingLruMap.getSizeInBytes());
assertKeyOrder("key1", "key4");
assertValueOrder(110, 140);
}
@Test
public void testClear() {
mCountingLruMap.put("key1", 110);
mCountingLruMap.put("key2", 120);
mCountingLruMap.put("key3", 130);
mCountingLruMap.put("key4", 140);
mCountingLruMap.clear();
assertEquals(0, mCountingLruMap.getCount());
assertEquals(0, mCountingLruMap.getSizeInBytes());
assertKeyOrder();
assertValueOrder();
}
@Test
public void testGetMatchingEntries() {
mCountingLruMap.put("key1", 110);
mCountingLruMap.put("key2", 120);
mCountingLruMap.put("key3", 130);
mCountingLruMap.put("key4", 140);
List<LinkedHashMap.Entry<String, Integer>> entries = mCountingLruMap.getMatchingEntries(
new Predicate<String>() {
@Override
public boolean apply(String key) {
return key.equals("key2") || key.equals("key3");
}
});
assertNotNull(entries);
assertEquals(2, entries.size());
assertEquals("key2", entries.get(0).getKey());
assertEquals(120, (int) entries.get(0).getValue());
assertEquals("key3", entries.get(1).getKey());
assertEquals(130, (int) entries.get(1).getValue());
// getting entries should not affect the order nor the size
assertEquals(4, mCountingLruMap.getCount());
assertEquals(500, mCountingLruMap.getSizeInBytes());
assertKeyOrder("key1", "key2", "key3", "key4");
assertValueOrder(110, 120, 130, 140);
}
@Test
public void testGetFirstKey() {
mCountingLruMap.put("key1", 110);
assertKeyOrder("key1");
assertValueOrder(110);
assertEquals("key1", mCountingLruMap.getFirstKey());
mCountingLruMap.put("key2", 120);
assertKeyOrder("key1", "key2");
assertValueOrder(110, 120);
assertEquals("key1", mCountingLruMap.getFirstKey());
mCountingLruMap.put("key3", 130);
assertKeyOrder("key1", "key2", "key3");
assertValueOrder(110, 120, 130);
assertEquals("key1", mCountingLruMap.getFirstKey());
mCountingLruMap.put("key1", 140);
assertKeyOrder("key2", "key3", "key1");
assertValueOrder(120, 130, 140);
assertEquals("key2", mCountingLruMap.getFirstKey());
mCountingLruMap.remove("key3");
assertKeyOrder("key2", "key1");
assertValueOrder(120, 140);
assertEquals("key2", mCountingLruMap.getFirstKey());
mCountingLruMap.remove("key2");
assertKeyOrder("key1");
assertValueOrder(140);
assertEquals("key1", mCountingLruMap.getFirstKey());
mCountingLruMap.remove("key1");
assertKeyOrder();
assertValueOrder();
assertEquals(null, mCountingLruMap.getFirstKey());
}
private void assertKeyOrder(String... expectedKeys) {
assertArrayEquals(expectedKeys, mCountingLruMap.getKeys().toArray());
}
private void assertValueOrder(Integer... expectedVlues) {
assertArrayEquals(expectedVlues, mCountingLruMap.getValues().toArray());
}
}