1 /* 2 * Copyright (c) 2007 Mockito contributors 3 * This program is made available under the terms of the MIT License. 4 */ 5 6 package org.mockito.internal.verification; 7 8 import static org.mockito.internal.exceptions.Reporter.wantedAtMostX; 9 import static org.mockito.internal.invocation.InvocationMarker.markVerified; 10 import static org.mockito.internal.invocation.InvocationsFinder.findInvocations; 11 12 import java.util.Iterator; 13 import java.util.List; 14 import org.mockito.exceptions.base.MockitoException; 15 import org.mockito.invocation.MatchableInvocation; 16 import org.mockito.internal.verification.api.VerificationData; 17 import org.mockito.invocation.Invocation; 18 import org.mockito.verification.VerificationMode; 19 20 public class AtMost implements VerificationMode { 21 22 private final int maxNumberOfInvocations; 23 24 public AtMost(int maxNumberOfInvocations) { 25 if (maxNumberOfInvocations < 0) { 26 throw new MockitoException("Negative value is not allowed here"); 27 } 28 this.maxNumberOfInvocations = maxNumberOfInvocations; 29 } 30 31 public void verify(VerificationData data) { 32 List<Invocation> invocations = data.getAllInvocations(); 33 MatchableInvocation wanted = data.getTarget(); 34 35 List<Invocation> found = findInvocations(invocations, wanted); 36 int foundSize = found.size(); 37 if (foundSize > maxNumberOfInvocations) { 38 throw wantedAtMostX(maxNumberOfInvocations, foundSize); 39 } 40 41 removeAlreadyVerified(found); 42 markVerified(found, wanted); 43 } 44 45 @Override 46 public VerificationMode description(String description) { 47 return VerificationModeFactory.description(this, description); 48 } 49 50 private void removeAlreadyVerified(List<Invocation> invocations) { 51 for (Iterator<Invocation> iterator = invocations.iterator(); iterator.hasNext(); ) { 52 Invocation i = iterator.next(); 53 if (i.isVerified()) { 54 iterator.remove(); 55 } 56 } 57 } 58 } 59