org.mockito.internal.invocation.InvocationMatcher Maven / Gradle / Ivy
/*
* Copyright (c) 2007 Mockito contributors
* This program is made available under the terms of the MIT License.
*/
package org.mockito.internal.invocation;
import java.io.Serializable;
import java.lang.reflect.Method;
import java.util.Collections;
import java.util.List;
import org.hamcrest.Matcher;
import org.mockito.exceptions.PrintableInvocation;
import org.mockito.internal.debugging.Location;
import org.mockito.internal.matchers.CapturesArguments;
import org.mockito.internal.reporting.PrintSettings;
import org.mockito.internal.reporting.PrintingFriendlyInvocation;
@SuppressWarnings("unchecked")
public class InvocationMatcher implements PrintableInvocation, PrintingFriendlyInvocation, CapturesArgumensFromInvocation, Serializable {
private static final long serialVersionUID = -3047126096857467610L;
private final Invocation invocation;
private final List matchers;
public InvocationMatcher(Invocation invocation, List matchers) {
this.invocation = invocation;
if (matchers.isEmpty()) {
this.matchers = invocation.argumentsToMatchers();
} else {
this.matchers = matchers;
}
}
public InvocationMatcher(Invocation invocation) {
this(invocation, Collections.emptyList());
}
public Method getMethod() {
return invocation.getMethod();
}
public Invocation getInvocation() {
return this.invocation;
}
public List getMatchers() {
return this.matchers;
}
public String toString() {
return invocation.toString(matchers, new PrintSettings());
}
public boolean matches(Invocation actual) {
return invocation.getMock().equals(actual.getMock())
&& hasSameMethod(actual)
&& new ArgumentsComparator().argumentsMatch(this, actual);
}
private boolean safelyArgumentsMatch(Object[] actualArgs) {
try {
return new ArgumentsComparator().argumentsMatch(this, actualArgs);
} catch (Throwable t) {
return false;
}
}
/**
* similar means the same method name, same mock, unverified
* and: if arguments are the same cannot be overloaded
*/
public boolean hasSimilarMethod(Invocation candidate) {
String wantedMethodName = getMethod().getName();
String currentMethodName = candidate.getMethod().getName();
final boolean methodNameEquals = wantedMethodName.equals(currentMethodName);
final boolean isUnverified = !candidate.isVerified();
final boolean mockIsTheSame = getInvocation().getMock() == candidate.getMock();
final boolean methodEquals = hasSameMethod(candidate);
if (!methodNameEquals || !isUnverified || !mockIsTheSame) {
return false;
}
final boolean overloadedButSameArgs = !methodEquals && safelyArgumentsMatch(candidate.getArguments());
return !overloadedButSameArgs;
}
public boolean hasSameMethod(Invocation candidate) {
return invocation.getMethod().equals(candidate.getMethod());
}
public Location getLocation() {
return invocation.getLocation();
}
public String toString(PrintSettings printSettings) {
return invocation.toString(matchers, printSettings);
}
public void captureArgumentsFrom(Invocation i) {
int k = 0;
for (Matcher m : matchers) {
if (m instanceof CapturesArguments) {
((CapturesArguments) m).captureFrom(i.getArguments()[k]);
}
k++;
}
}
}