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