@Test
public void testNewProgressCheckEventConsumer() {

    final List<Map.Entry<ProgressCheck, Exception>> errorEvents = new ArrayList<>();
    final BiConsumer<ProgressCheck, Exception> onError =
            (check, error) -> errorEvents.add(toEntry(check, error));
    final Consumer<ProgressCheck> silencedConsumer =
            OakMachine.newProgressCheckEventConsumer(true,
                    ProgressCheck::finishedScan, onError);
    final Consumer<ProgressCheck> vocalConsumer =
            OakMachine.newProgressCheckEventConsumer(false,
                    ProgressCheck::finishedScan, onError);
    final AtomicInteger normalCallCount = new AtomicInteger(0);
    final ProgressCheck normalCheck = mock(ProgressCheck.class);
    doAnswer(call -> normalCallCount.incrementAndGet()).when(normalCheck).finishedScan();
    silencedConsumer.accept(normalCheck);
    assertEquals("expect normal:silent empty errors", 0, errorEvents.size());
    assertEquals("expect normal:silent call count", 0, normalCallCount.get());
    errorEvents.clear();
    normalCallCount.set(0);
    vocalConsumer.accept(normalCheck);
    assertEquals("expect normal:vocal empty errors", 0, errorEvents.size());
    assertEquals("expect normal:vocal call count", 1, normalCallCount.get());
    errorEvents.clear();
    normalCallCount.set(0);
    doThrow(RuntimeException.class).when(normalCheck).finishedScan();
    silencedConsumer.accept(normalCheck);
    assertEquals("expect normal:silent empty errors", 0, errorEvents.size());
    assertEquals("expect normal:silent call count", 0, normalCallCount.get());
    errorEvents.clear();
    normalCallCount.set(0);
    vocalConsumer.accept(normalCheck);
    assertEquals("expect normal:vocal one error", 1, errorEvents.size());
    assertEquals("expect normal:vocal call count", 0, normalCallCount.get());
    errorEvents.clear();
    normalCallCount.set(0);
    final AtomicInteger watcherCallCount = new AtomicInteger(0);
    final List<Boolean> silencedEvents = new ArrayList<>();
    final SilenceableCheck silenceableCheck = mock(SilenceableCheck.class);
    doAnswer(call -> silencedEvents.add(call.getArgument(0)))
            .when(silenceableCheck).setSilenced(anyBoolean());
    doAnswer(call -> watcherCallCount.incrementAndGet()).when(silenceableCheck).finishedScan();
    silencedConsumer.accept(silenceableCheck);
    assertEquals("expect watcher:silent empty errors", 0, errorEvents.size());
    assertEquals("expect watcher:silent call count", 1, watcherCallCount.get());
    assertEquals("expect watcher:silent silenced events",
            Arrays.asList(true, false), silencedEvents);
    errorEvents.clear();
    watcherCallCount.set(0);
    silencedEvents.clear();
    vocalConsumer.accept(silenceableCheck);
    assertEquals("expect watcher:vocal empty errors", 0, errorEvents.size());
    assertEquals("expect watcher:vocal call count", 1, watcherCallCount.get());
    assertEquals("expect watcher:vocal silenced events",
            Collections.emptyList(), silencedEvents);
    errorEvents.clear();
    watcherCallCount.set(0);
    silencedEvents.clear();
    doThrow(RuntimeException.class).when(silenceableCheck).finishedScan();
    silencedConsumer.accept(silenceableCheck);
    assertEquals("expect watcher:silent empty errors", 0, errorEvents.size());
    assertEquals("expect watcher:silent call count", 0, watcherCallCount.get());
    assertEquals("expect watcher:silent silenced events",
            Arrays.asList(true, false), silencedEvents);
    errorEvents.clear();
    watcherCallCount.set(0);
    silencedEvents.clear();
    vocalConsumer.accept(silenceableCheck);
    assertEquals("expect watcher:vocal one error", 1, errorEvents.size());
    assertEquals("expect watcher:vocal call count", 0, watcherCallCount.get());
    assertEquals("expect watcher:vocal silenced events",
            Collections.emptyList(), silencedEvents);
}