I'm new to coding and programming, and I found an interesting SimpleAgedCache exercise on GitHub that uses JavaScript. I feel like I've done the correct coding, and the exercise should pass its tests. However, the test keeps failing. Can someone explain to me why this is the case and what I'm doing wrong? Thanks.
package test.collective;
import io.collective.SimpleAgedCache;
import org.junit.Before;
import org.junit.Test;
import java.time.Clock;
import java.time.Duration;
import java.time.Instant;
import java.time.ZoneId;
import static junit.framework.TestCase.*;
class ExpirableEntry {
String key;
String value;
long expirationTime;
ExpirableEntry(String key, String value, long expirationTime) {
this.key = key;
this.value = value;
this.expirationTime = expirationTime;
}
}
public class SimpleAgedCacheTest {
private SimpleAgedCache empty;
private SimpleAgedCache nonempty;
private ExpirableEntry[] cacheArray;
private Clock clock;
private int size;
public SimpleAgedCacheTest() {
this.empty = new SimpleAgedCache();
this.nonempty = new SimpleAgedCache();
this.cacheArray = new ExpirableEntry[10];
this.clock = Clock.systemUTC();
this.size = 0;
}
public void put(String key, String value, long durationMillis) {
long expirationTime = clock.instant().plusMillis(durationMillis).toEpochMilli();
ExpirableEntry entry = new ExpirableEntry(key, value, expirationTime);
cacheArray[size++] = entry;
}
public String get(String key) {
for (int i = 0; i < size; i++) {
ExpirableEntry entry = cacheArray[i];
if (entry.key.equals(key) && !isExpired(entry)) {
return entry.value;
}
}
return null;
}
public boolean isEmpty() {
return size == 0;
}
public int size() {
return size;
}
private boolean isExpired(ExpirableEntry entry) {
return clock.instant().toEpochMilli() > entry.expirationTime;
}
@Before
public void setup() {
nonempty.put("aKey", "aValue", 2000);
nonempty.put("anotherKey", "anotherValue", 4000);
}
@Test
public void isEmptyTest() {
assertTrue(empty.isEmpty());
assertFalse(nonempty.isEmpty());
}
@Test
public void sizeTest() {
assertEquals(0, empty.size());
assertEquals(2, nonempty.size());
}
@Test
public void getTest() {
assertNull(empty.get("aKey"));
assertEquals("anotherValue", nonempty.get("anotherKey"));
assertEquals("aValue", nonempty.get("aKey"));
}
@Test
public void getExpiredTest() {
TestClock clock = new TestClock();
SimpleAgedCache expired = new SimpleAgedCache(clock);
expired.put("aKey", "aValue", 2000);
expired.put("anotherKey", "anotherValue", 4000);
clock.offset(Duration.ofMillis(3000));
assertEquals("anotherValue", expired.get("anotherKey"));
assertEquals(1, expired.size());
}
static class TestClock extends Clock {
Duration offset = Duration.ZERO;
@Override
public ZoneId getZone() {
return Clock.systemDefaultZone().getZone();
}
@Override
public Clock withZone(ZoneId zone) {
return Clock.offset(Clock.system(zone), offset);
}
@Override
public Instant instant() {
return Clock.offset(Clock.systemDefaultZone(), offset).instant();
}
public void offset(Duration offset) {
this.offset = offset;
}
}
}
I've tried flip flopping the order of
assertEquals("anotherValue", expired.get("anotherKey));
and
assertEquals(1, expired.size());
but to no avail.
@Test
public void getExpiredTest() {
TestClock clock = new TestClock();
SimpleAgedCache expired = new SimpleAgedCache(clock);
expired.put("aKey", "aValue", 2000);
expired.put("anotherKey", "anotherValue", 4000);
clock.offset(Duration.ofMillis(3000));
assertEquals("anotherValue", expired.get("anotherKey"));
assertEquals(1, expired.size());