@@ -0,0 +1,2556 @@
+package org.whaka.mock;%0A%0Aimport java.util.ArrayList;%0Aimport java.util.Arrays;%0Aimport java.util.Collection;%0Aimport java.util.Collections;%0Aimport java.util.HashSet;%0Aimport java.util.List;%0Aimport java.util.Set;%0Aimport java.util.function.BiConsumer;%0Aimport java.util.function.Predicate;%0Aimport java.util.stream.Collectors;%0Aimport org.mockito.Matchers;%0Aimport org.mockito.MockSettings;%0Aimport org.mockito.Mockito;%0Aimport org.mockito.invocation.DescribedInvocation;%0A%0A/**%0A * Collect arguments from the called method (may be used with listeners).%0A *%0A * @param %3CTarget%3E  the target class%0A * @param %3CEvent%3E  the event type%0A */%0Apublic class EventCollector%3CTarget, Event%3E %7B%0A%0A%09private final List%3CEvent%3E events = Collections.synchronizedList(new ArrayList%3C%3E());%0A%09private final Target target;%0A%0A%09@SafeVarargs%0A%09@SuppressWarnings(%22unchecked%22)%0A%09public EventCollector(Class%3CTarget%3E targetClass, BiConsumer%3CTarget, Event%3E targetMethod, Predicate%3CEvent%3E... filters) %7B%0A%09%09this(targetClass, targetMethod, new HashSet%3C%3E(Arrays.asList(filters)));%0A%09%7D%0A%0A%09@SuppressWarnings(%22unchecked%22)%0A%09public EventCollector(Class%3CTarget%3E targetClass, BiConsumer%3CTarget, Event%3E targetMethod, Collection%3CPredicate%3CEvent%3E%3E filters) %7B%0A%0A%09%09List%3CDescribedInvocation%3E invokes = new ArrayList%3C%3E();%0A%09%09MockSettings settings = Mockito.withSettings()%0A%09%09%09%09.invocationListeners(report -%3E invokes.add(report.getInvocation()));%0A%0A%09%09this.target = Mockito.mock(targetClass, settings);%0A%0A%09%09Set%3CEventHandler%3CEvent%3E%3E eventHandlers = filters.stream()%0A%09%09%09%09.filter(p -%3E p instanceof EventHandler)%0A%09%09%09%09.map(p -%3E (EventHandler%3CEvent%3E) p)%0A%09%09%09%09.collect(Collectors.toSet());%0A%0A%09%09targetMethod.accept(Mockito.doAnswer(invoke -%3E %7B%0A%09%09%09Event event = (Event) invoke.getArguments()%5B0%5D;%0A%09%09%09boolean filterFail = filters.stream().map(p -%3E p.test(event)).collect(Collectors.toSet()).contains(false);%0A%09%09%09if(!filterFail) %7B%0A%09%09%09%09events.add(event);%0A%09%09%09%09eventHandlers.forEach(c -%3E c.accepted(event));%0A%09%09%09%7D%0A%0A%09%09%09return null;%0A%09%09%7D).when(this.target), Matchers.any());%0A%0A%09%09if (invokes.size() != 1)%0A%09%09%09throw new IllegalStateException(%22Single listener interaction was expected! But actual: %22 + invokes);%0A%09%7D%0A%0A%09public Target getTarget() %7B%0A%09%09return target;%0A%09%7D%0A%0A%09public List%3CEvent%3E getEvents() %7B%0A%09%09return events;%0A%09%7D%0A%0A%09public Event getLastEvent() %7B%0A%09%09return events.isEmpty() ? null : events.get(events.size() - 1);%0A%09%7D%0A%0A%0A%09public interface EventHandler%3CEvent%3E extends Predicate%3CEvent%3E %7B%0A%0A%09%09/**%0A%09%09 * Is called when ALL filters from the %7B@link EventCollector%7D are passed successfully%0A%09%09 *%0A%09%09 * @param event the processed event%0A%09%09 */%0A%09%09void accepted(Event event);%0A%09%7D%0A%7D%0A

Create event collector #60