### Question:
SourceI { public <SOURCE extends SourceI, EX extends Throwable> SourceIHandler<Void> accept(Class<SOURCE> sourceType, ExceptionalConsumer<SOURCE, EX> action) throws EX { return apply(sourceType, source -> { action.accept(source); return null; }); }  void setContextClass(Class<?> contextClass); Class<?> getContextClass(); abstract boolean isLogicalSource(); SourceIHandler<OUT> apply(Class<SOURCE> sourceType, ExceptionalFunction<SOURCE, OUT, EX> action); SourceIHandler<Void> accept(Class<SOURCE> sourceType, ExceptionalConsumer<SOURCE, EX> action);  }### Answer:
@Test public void testVoidFunctionApplicationNormalCases() { final AtomicReference<String> state = new AtomicReference<>("unset"); final SourceI queueSource = new QueueSource("a"); final SourceI topicSource = new TopicSource("b"); queueSource .accept(QueueSource.class, queue -> state.set("queue")) .accept(TopicSource.class, topic -> state.set("topic")); assertEquals(state.get(), "queue"); state.set("unset"); topicSource .accept(QueueSource.class, queue -> state.set("queue")) .accept(TopicSource.class, topic -> state.set("topic")); assertEquals(state.get(), "topic"); }
@Test public void testVoidFunctionApplicationCaseOrder() { final AtomicReference<String> state = new AtomicReference<>("unset"); final SourceI source = new QueueSource("a"); source .accept(QueueSource.class, queue -> state.set("queue")) .accept(TopicSource.class, topic -> state.set("topic")); final String stateOrderA = state.get(); state.set("unset"); source .accept(TopicSource.class, topic -> state.set("topic")) .accept(QueueSource.class, queue -> state.set("queue")); final String stateOrderB = state.get(); assertEquals(stateOrderA, stateOrderB); }
@Test public void testVoidFunctionApplicationGivesNull() { final SourceI source = new QueueSource("a"); Object o = source .accept(QueueSource.class, queue -> noop()) .get(); assertNull(o); }
@Test public void testUnhandledVoidFunctionApplicationGivesUnhandledException() { final SourceI source = new QueueSource("a"); assertThrows(RuntimeException.class, () -> { source.accept(TopicSource.class, topic -> noop()) .elseUnsupportedError(); }); }