package org.testory.plumbing; import static org.testory.common.Chain.chain; import static org.testory.plumbing.PlumbingException.check; import org.testory.common.Chain; import org.testory.common.Optional; import org.testory.proxy.Invocation; import org.testory.proxy.InvocationMatcher; public class VerifyingInOrder { public final Chain<Object> unverified; private VerifyingInOrder(Chain<Object> unverified) { this.unverified = unverified; } public static VerifyingInOrder verifyingInOrder(Chain<Object> unverified) { check(unverified != null); return new VerifyingInOrder(unverified); } public static Optional<VerifyingInOrder> verifyInOrder(InvocationMatcher invocationMatcher, Chain<Object> history) { Chain<Object> unverified = unverifiedReversed(history); while (unverified.size() > 0) { Object event = unverified.get(); unverified = unverified.remove(); if (event instanceof Invocation && invocationMatcher.matches((Invocation) event)) { return Optional.of(verifyingInOrder(unverified.reverse())); } } return Optional.empty(); } private static Chain<Object> unverifiedReversed(Chain<Object> history) { Chain<Object> unverified = chain(); for (Object event : history) { if (event instanceof VerifyingInOrder) { for (Object oldEvent : ((VerifyingInOrder) event).unverified) { unverified = unverified.add(oldEvent); } break; } else { unverified = unverified.add(event); } } return unverified; } }