### Question:
RateTracker { public synchronized long wantToRequestObjects(final long objectCount) { pruneRequests(); if ((peerRateLimit - requestsWithinWindow) <= 0) { return 0L; } requestsWithinWindow += objectCount; requestCount.compute( timeProvider.getTimeInSeconds(), (key, val) -> val == null ? objectCount : val + objectCount); return objectCount; } RateTracker(
      final int peerRateLimit, final long timeoutSeconds, final TimeProvider timeProvider); synchronized long wantToRequestObjects(final long objectCount);  }### Answer:
@Test public void shouldAllowAddingItemsWithinLimit() { final RateTracker tracker = new RateTracker(1, 1, timeProvider); assertThat(tracker.wantToRequestObjects(1)).isEqualTo(1); }
@Test public void shouldNotUnderflowWhenTimeWindowGreaterThanCurrentTime() { final RateTracker tracker = new RateTracker(1, 15000, timeProvider); assertThat(tracker.wantToRequestObjects(1)).isEqualTo(1); }
@Test public void shouldAllowAddingItemsAfterTimeoutPasses() { final RateTracker tracker = new RateTracker(1, 1, timeProvider); assertThat(tracker.wantToRequestObjects(1)).isEqualTo(1); timeProvider.advanceTimeBySeconds(2L); assertThat(tracker.wantToRequestObjects(1)).isEqualTo(1); }
@Test public void shouldReturnFalseIfCacheFull() { final RateTracker tracker = new RateTracker(1, 1, timeProvider); assertThat(tracker.wantToRequestObjects(1)).isEqualTo(1); assertThat(tracker.wantToRequestObjects(1)).isEqualTo(0); }
@Test public void shouldAddMultipleValuesToCache() throws InterruptedException { final RateTracker tracker = new RateTracker(10, 1, timeProvider); assertThat(tracker.wantToRequestObjects(10)).isEqualTo(10); assertThat(tracker.wantToRequestObjects(10)).isEqualTo(0); timeProvider.advanceTimeBySeconds(2L); assertThat(tracker.wantToRequestObjects(1)).isEqualTo(1); }
@Test public void shouldMaintainCounterOverTime() { final RateTracker tracker = new RateTracker(10, 2, timeProvider); assertThat(tracker.wantToRequestObjects(9)).isEqualTo(9); timeProvider.advanceTimeBySeconds(1L); assertThat(tracker.wantToRequestObjects(5)).isEqualTo(5); timeProvider.advanceTimeBySeconds(1L); assertThat(tracker.wantToRequestObjects(5)).isEqualTo(0); timeProvider.advanceTimeBySeconds(1L); assertThat(tracker.wantToRequestObjects(5)).isEqualTo(5); assertThat(tracker.wantToRequestObjects(5)).isEqualTo(0); timeProvider.advanceTimeBySeconds(3L); assertThat(tracker.wantToRequestObjects(9)).isEqualTo(9); timeProvider.advanceTimeBySeconds(1L); assertThat(tracker.wantToRequestObjects(5)).isEqualTo(5); assertThat(tracker.wantToRequestObjects(1)).isEqualTo(0); timeProvider.advanceTimeBySeconds(2L); assertThat(tracker.wantToRequestObjects(4)).isEqualTo(4); assertThat(tracker.wantToRequestObjects(1)).isEqualTo(1); assertThat(tracker.wantToRequestObjects(1)).isEqualTo(0); }