package com.xebialabs.restito.builder.verify; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import com.xebialabs.restito.semantics.Call; import com.xebialabs.restito.semantics.Condition; import com.xebialabs.restito.server.StubServer; import static java.lang.String.format; /** * <p>Responsible for building verifications (e.g. something happened x times).</p> */ public class VerifyHttp { private final List<Call> calls; /** * Static factory */ public static VerifyHttp verifyHttp(StubServer stubServer) { return new VerifyHttp(stubServer.getCalls()); } /** * Static factory */ public static VerifyHttp verifyHttp(List<Call> calls) { return new VerifyHttp(calls); } private VerifyHttp(List<Call> calls) { this.calls = calls; } /** * There should be only one call which satisfies given conditions */ public VerifySequenced once(Condition... conditions) { return times(1, conditions); } /** * There should be no calls which satisfies given conditions */ public VerifySequenced never(Condition... conditions) { return times(0, conditions); } /** * There should be <i>t</i> calls which satisfies given conditions */ public VerifySequenced times(int t, Condition... conditions) { final List<Call> foundCalls = filterByConditions(conditions); if (t != foundCalls.size()) { throw new AssertionError(format("Expected to happen %s time(s), but happened %s times instead", t, foundCalls.size())); } return new VerifySequenced(getCallsAfterLastFound(foundCalls)); } /** * There should be at least <i>t</i> calls which satisfies the given conditions */ public VerifySequenced atLeast(int t, Condition... conditions) { final List<Call> foundCalls = filterByConditions(conditions); if (t > foundCalls.size()) { throw new AssertionError(format("Expected to happen at least %s time(s), but happened %s times instead", t, foundCalls.size())); } return new VerifySequenced(getCallsAfterLastFound(foundCalls)); } private List<Call> getCallsAfterLastFound(final List<Call> foundCalls) { return foundCalls.size() == 0 ? calls : calls.subList( calls.indexOf(foundCalls.get(foundCalls.size() - 1)) + 1, calls.size() ); } private List<Call> filterByConditions(Condition[] conditions) { List<Call> filteredCalls = new ArrayList<>(calls); for (Condition condition : conditions) { Iterator<Call> callsIterator = filteredCalls.iterator(); while (callsIterator.hasNext()) { Call call = callsIterator.next(); if (!condition.getPredicate().test(call)) { callsIterator.remove(); } } } return filteredCalls; } }