### Question:
SourceI { public <SOURCE extends SourceI, OUT, EX extends Throwable> SourceIHandler<OUT> apply(Class<SOURCE> sourceType, ExceptionalFunction<SOURCE, OUT, EX> action) throws EX { return new SourceIHandler<OUT>(this).apply(sourceType, action); }  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 testFunctionApplicationCaseOrder() { final SourceI source = new QueueSource("a"); final String resultOrderA = source .apply(QueueSource.class, queue -> "queue") .apply(TopicSource.class, topic -> "topic") .get(); final String resultOrderB = source .apply(TopicSource.class, topic -> "topic") .apply(QueueSource.class, queue -> "queue") .get(); assertEquals(resultOrderA, resultOrderB); }
@Test public void testFunctionApplicationUnhandledNull() { final SourceI source = new QueueSource("a"); final String result = source .apply(TopicSource.class, topic -> "topic") .get(); assertNull(result); }
@Test public void testGetOrDefaultAfterUhandledFunctionApplicationGivesDefaultValue() { final SourceI source = new QueueSource("a"); final String defaultValue = "default"; final String result = source .apply(TopicSource.class, topic -> "topic") .getOrDefault(defaultValue); assertEquals(defaultValue, result); }
@Test public void testUnhandledFunctionApplicationGivesUnhandledException() { final SourceI source = new QueueSource("a"); assertThrows(RuntimeException.class, () -> { final String result = source .apply(TopicSource.class, topic -> "topic") .elseUnsupportedError(); }); }
@Test public void testHandledFunctionApplicationGivesNoUnhandledException() { final SourceI source = new QueueSource("a"); final String result = source .apply(QueueSource.class, topic -> "queue") .elseUnsupportedError(); }
@Test public void testExceptionalFunctionApplicationThrowsCorrectException() throws JustATestException { final SourceI source = new QueueSource("a"); assertThrows(JustATestException.class, () -> { source.apply(QueueSource.class, queue -> { throw new JustATestException(); }); }); }