blob: 3e30cb03b97d18c1795cfd082561c95af863d26d [file] [log] [blame]
/*
* Copyright (c) 2007 Mockito contributors
* This program is made available under the terms of the MIT License.
*/
package org.mockito.internal.invocation;
import java.util.LinkedList;
import java.util.List;
import org.mockito.internal.util.collections.ListUtil;
import org.mockito.internal.util.collections.ListUtil.Filter;
import org.mockito.internal.verification.api.InOrderContext;
import org.mockito.invocation.Invocation;
import org.mockito.invocation.Location;
public class InvocationsFinder {
public List<Invocation> findInvocations(List<Invocation> invocations, InvocationMatcher wanted) {
return ListUtil.filter(invocations, new RemoveNotMatching(wanted));
}
public List<Invocation> findAllMatchingUnverifiedChunks(List<Invocation> invocations, InvocationMatcher wanted, InOrderContext orderingContext) {
List<Invocation> unverified = removeVerifiedInOrder(invocations, orderingContext);
return ListUtil.filter(unverified, new RemoveNotMatching(wanted));
}
/**
* some examples how it works:
*
* Given invocations sequence:
* 1,1,2,1
*
* if wanted is 1 and mode is times(2) then returns
* 1,1
*
* if wanted is 1 and mode is atLeast() then returns
* 1,1,1
*
* if wanted is 1 and mode is times(x), where x != 2 then returns
* 1,1,1
*/
public List<Invocation> findMatchingChunk(List<Invocation> invocations, InvocationMatcher wanted, int wantedCount, InOrderContext context) {
List<Invocation> unverified = removeVerifiedInOrder(invocations, context);
List<Invocation> firstChunk = getFirstMatchingChunk(wanted, unverified);
if (wantedCount != firstChunk.size()) {
return this.findAllMatchingUnverifiedChunks(invocations, wanted, context);
} else {
return firstChunk;
}
}
private List<Invocation> getFirstMatchingChunk(InvocationMatcher wanted, List<Invocation> unverified) {
List<Invocation> firstChunk = new LinkedList<Invocation>();
for (Invocation invocation : unverified) {
if (wanted.matches(invocation)) {
firstChunk.add(invocation);
} else if (!firstChunk.isEmpty()) {
break;
}
}
return firstChunk;
}
public Invocation findFirstMatchingUnverifiedInvocation( List<Invocation> invocations, InvocationMatcher wanted, InOrderContext context ){
for( Invocation invocation : removeVerifiedInOrder( invocations, context )){
if( wanted.matches( invocation )){
return invocation;
}
}
return null;
}
public Invocation findSimilarInvocation(List<Invocation> invocations, InvocationMatcher wanted) {
Invocation firstSimilar = null;
for (Invocation invocation : invocations) {
if (!wanted.hasSimilarMethod(invocation)) {
continue;
}
if (firstSimilar == null) {
firstSimilar = invocation;
}
if (wanted.hasSameMethod(invocation)) {
return invocation;
}
}
return firstSimilar;
}
public Invocation findFirstUnverified(List<Invocation> invocations) {
return findFirstUnverified(invocations, null);
}
Invocation findFirstUnverified(List<Invocation> invocations, Object mock) {
for (Invocation i : invocations) {
boolean mockIsValid = mock == null || mock == i.getMock();
if (!i.isVerified() && mockIsValid) {
return i;
}
}
return null;
}
public Location getLastLocation(List<Invocation> invocations) {
if (invocations.isEmpty()) {
return null;
} else {
Invocation last = invocations.get(invocations.size() - 1);
return last.getLocation();
}
}
public Invocation findPreviousVerifiedInOrder(List<Invocation> invocations, InOrderContext context) {
LinkedList<Invocation> verifiedOnly = ListUtil.filter(invocations, new RemoveUnverifiedInOrder(context));
if (verifiedOnly.isEmpty()) {
return null;
} else {
return verifiedOnly.getLast();
}
}
private List<Invocation> removeVerifiedInOrder(List<Invocation> invocations, InOrderContext orderingContext) {
List<Invocation> unverified = new LinkedList<Invocation>();
for (Invocation i : invocations) {
if (orderingContext.isVerified(i)) {
unverified.clear();
} else {
unverified.add(i);
}
}
return unverified;
}
private static class RemoveNotMatching implements Filter<Invocation> {
private final InvocationMatcher wanted;
private RemoveNotMatching(InvocationMatcher wanted) {
this.wanted = wanted;
}
public boolean isOut(Invocation invocation) {
return !wanted.matches(invocation);
}
}
private static class RemoveUnverifiedInOrder implements Filter<Invocation> {
private final InOrderContext orderingContext;
public RemoveUnverifiedInOrder(InOrderContext orderingContext) {
this.orderingContext = orderingContext;
}
public boolean isOut(Invocation invocation) {
return !orderingContext.isVerified(invocation);
}
}
/**
* i3 is unverified here:
*
* i1, i2, i3
* v
*
* all good here:
*
* i1, i2, i3
* v v
*
* @param context
* @param orderedInvocations
*/
public Invocation findFirstUnverifiedInOrder(InOrderContext context, List<Invocation> orderedInvocations) {
Invocation candidate = null;
for(Invocation i : orderedInvocations) {
if (!context.isVerified(i)) {
candidate = candidate != null ? candidate : i;
} else {
candidate = null;
}
}
return candidate;
}
}