• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2007 Mockito contributors
3  * This program is made available under the terms of the MIT License.
4  */
5 package org.mockito.internal.invocation;
6 
7 import org.hamcrest.Matcher;
8 import org.mockito.internal.matchers.MatcherDecorator;
9 import org.mockito.internal.matchers.VarargMatcher;
10 import org.mockito.invocation.Invocation;
11 
12 import java.util.List;
13 
14 @SuppressWarnings("unchecked")
15 public class ArgumentsComparator {
argumentsMatch(InvocationMatcher invocationMatcher, Invocation actual)16     public boolean argumentsMatch(InvocationMatcher invocationMatcher, Invocation actual) {
17         Object[] actualArgs = actual.getArguments();
18         return argumentsMatch(invocationMatcher, actualArgs) || varArgsMatch(invocationMatcher, actual);
19     }
20 
argumentsMatch(InvocationMatcher invocationMatcher, Object[] actualArgs)21     public boolean argumentsMatch(InvocationMatcher invocationMatcher, Object[] actualArgs) {
22         if (actualArgs.length != invocationMatcher.getMatchers().size()) {
23             return false;
24         }
25         for (int i = 0; i < actualArgs.length; i++) {
26             if (!invocationMatcher.getMatchers().get(i).matches(actualArgs[i])) {
27                 return false;
28             }
29         }
30         return true;
31     }
32 
33     //ok, this method is a little bit messy but the vararg business unfortunately is messy...
varArgsMatch(InvocationMatcher invocationMatcher, Invocation actual)34     private boolean varArgsMatch(InvocationMatcher invocationMatcher, Invocation actual) {
35         if (!actual.getMethod().isVarArgs()) {
36             //if the method is not vararg forget about it
37             return false;
38         }
39 
40         //we must use raw arguments, not arguments...
41         Object[] rawArgs = actual.getRawArguments();
42         List<Matcher> matchers = invocationMatcher.getMatchers();
43 
44         if (rawArgs.length != matchers.size()) {
45             return false;
46         }
47 
48         for (int i = 0; i < rawArgs.length; i++) {
49             Matcher m = matchers.get(i);
50             //it's a vararg because it's the last array in the arg list
51             if (rawArgs[i] != null && rawArgs[i].getClass().isArray() && i == rawArgs.length-1) {
52                 Matcher actualMatcher;
53                 //this is necessary as the framework often decorates matchers
54                 if (m instanceof MatcherDecorator) {
55                     actualMatcher = ((MatcherDecorator)m).getActualMatcher();
56                 } else {
57                     actualMatcher = m;
58                 }
59                 //this is very important to only allow VarargMatchers here. If you're not sure why remove it and run all tests.
60                 if (!(actualMatcher instanceof VarargMatcher) || !actualMatcher.matches(rawArgs[i])) {
61                     return false;
62                 }
63             //it's not a vararg (i.e. some ordinary argument before varargs), just do the ordinary check
64             } else if (!m.matches(rawArgs[i])){
65                 return false;
66             }
67         }
68 
69         return true;
70     }
71 }