ResultSet implements Iterable<Result> { @Override public Iterator<Result> iterator() { return new Iterator<Result>() { private Result nextOne = null; @Override public boolean hasNext() { if (null == nextOne) { nextOne = one(); } return nextOne != null; } @Override public Result next() { if (null != nextOne || hasNext()) { final Result r = nextOne; nextOne = null; return r; } else throw new NoSuchElementException(); } @Override public void remove() { throw new UnsupportedOperationException(); } }; } ResultSet(final ResultQueue resultQueue, final ExecutorService executor,
                     final CompletableFuture<Void> readCompleted, final RequestMessage originalRequestMessage,
                     final Host host); RequestMessage getOriginalRequestMessage(); Host getHost(); CompletableFuture<Map<String,Object>> statusAttributes(); boolean allItemsAvailable(); CompletableFuture<Void> allItemsAvailableAsync(); int getAvailableItemCount(); Result one(); CompletableFuture<List<Result>> some(final int items); CompletableFuture<List<Result>> all(); Stream<Result> stream(); @Override Iterator<Result> iterator();  }
@Test public void shouldIterate() throws Exception { final Iterator itty = resultSet.iterator(); final AtomicInteger counter = new AtomicInteger(0); addToQueue(100, 1, true, true); while (itty.hasNext()) { itty.next(); counter.incrementAndGet(); } assertEquals(100, counter.get()); }
@Test public void shouldIterateWithoutCheckingHasNext() throws Exception { final Iterator itty = resultSet.iterator(); final AtomicInteger counter = new AtomicInteger(0); addToQueue(100, 1, true, true); for (int ix = 0; ix < 100; ix++) { itty.next(); counter.incrementAndGet(); } assertEquals(100, counter.get()); assertThat(itty.hasNext(), is(false)); }
@Test public void shouldIterateAndThenThrowIfCallToNextExceedsAvailableResultItems() throws Exception { final Iterator itty = resultSet.iterator(); addToQueue(3, 1, true, true); assertThat(itty.hasNext(), is(true)); itty.next(); assertThat(itty.hasNext(), is(true)); itty.next(); itty.next(); assertThat(itty.hasNext(), is(false)); try { itty.next(); fail("Should throw exception"); } catch (NoSuchElementException ignore) { } }
@Test public void shouldCallHasNextWithoutSideEffect() throws Exception { final Iterator itty = resultSet.iterator(); final AtomicInteger counter = new AtomicInteger(0); addToQueue(100, 1, true, true); for (int i = 0; i < 101; i++) { assertThat(itty.hasNext(), is(true)); } while (itty.hasNext()) { itty.next(); counter.incrementAndGet(); } assertEquals(100, counter.get()); }