ResultSet implements Iterable<Result> { public CompletableFuture<Void> allItemsAvailableAsync() { final CompletableFuture<Void> allAvailable = new CompletableFuture<>(); readCompleted.thenRun(() -> allAvailable.complete(null)); readCompleted.exceptionally(t -> { allAvailable.completeExceptionally(t); return null; }); return allAvailable; } 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 shouldHaveAllItemsAvailableAsynchronouslyOnReadComplete() { final CompletableFuture<Void> all = resultSet.allItemsAvailableAsync(); assertThat(all.isDone(), is(false)); readCompleted.complete(null); assertThat(all.isDone(), is(true)); }
@Test public void shouldHaveAllItemsAvailableAsynchronouslyOnReadCompleteWhileLoading() throws Exception { final CompletableFuture<Void> all = resultSet.allItemsAvailableAsync(); assertThat(all.isDone(), is(false)); final AtomicBoolean atLeastOnce = new AtomicBoolean(false); addToQueue(1000, 1, true, true); while (!readCompleted.isDone()) { atLeastOnce.set(true); if (!atLeastOnce.get()) assertThat(all.isDone(), is(false)); } assertThat(atLeastOnce.get(), is(true)); all.get(30000, TimeUnit.MILLISECONDS); assertThat(all.isDone(), is(true)); }