0

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());
1
  • I see a few tests in your code. Which ones are failing and why?
    – Abra
    Commented Jul 9 at 5:59

1 Answer 1

0

You never decrement size, the value always increases regardless of the number of expired items the cache array holds:

 cacheArray[size++] = entry;

To fix, you'd need to make size() count the number of entries with condition !isExpired(entry), rather than just return size.

Not the answer you're looking for? Browse other questions tagged or ask your own question.