147d431f63a66505a645f282416659a9758a91f1cBrett Chabot/* 247d431f63a66505a645f282416659a9758a91f1cBrett Chabot * Copyright 2001-2009 OFFIS, Tammo Freese 347d431f63a66505a645f282416659a9758a91f1cBrett Chabot * 447d431f63a66505a645f282416659a9758a91f1cBrett Chabot * Licensed under the Apache License, Version 2.0 (the "License"); 547d431f63a66505a645f282416659a9758a91f1cBrett Chabot * you may not use this file except in compliance with the License. 647d431f63a66505a645f282416659a9758a91f1cBrett Chabot * You may obtain a copy of the License at 747d431f63a66505a645f282416659a9758a91f1cBrett Chabot * 847d431f63a66505a645f282416659a9758a91f1cBrett Chabot * http://www.apache.org/licenses/LICENSE-2.0 947d431f63a66505a645f282416659a9758a91f1cBrett Chabot * 1047d431f63a66505a645f282416659a9758a91f1cBrett Chabot * Unless required by applicable law or agreed to in writing, software 1147d431f63a66505a645f282416659a9758a91f1cBrett Chabot * distributed under the License is distributed on an "AS IS" BASIS, 1247d431f63a66505a645f282416659a9758a91f1cBrett Chabot * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1347d431f63a66505a645f282416659a9758a91f1cBrett Chabot * See the License for the specific language governing permissions and 1447d431f63a66505a645f282416659a9758a91f1cBrett Chabot * limitations under the License. 1547d431f63a66505a645f282416659a9758a91f1cBrett Chabot */ 1647d431f63a66505a645f282416659a9758a91f1cBrett Chabotpackage org.easymock.internal; 1747d431f63a66505a645f282416659a9758a91f1cBrett Chabot 1847d431f63a66505a645f282416659a9758a91f1cBrett Chabotimport java.io.Serializable; 1947d431f63a66505a645f282416659a9758a91f1cBrett Chabotimport java.lang.reflect.Method; 2047d431f63a66505a645f282416659a9758a91f1cBrett Chabotimport java.util.ArrayList; 2147d431f63a66505a645f282416659a9758a91f1cBrett Chabotimport java.util.List; 2247d431f63a66505a645f282416659a9758a91f1cBrett Chabot 2347d431f63a66505a645f282416659a9758a91f1cBrett Chabotimport org.easymock.EasyMock; 2447d431f63a66505a645f282416659a9758a91f1cBrett Chabot 2547d431f63a66505a645f282416659a9758a91f1cBrett Chabotpublic class MocksBehavior implements IMocksBehavior, Serializable { 2647d431f63a66505a645f282416659a9758a91f1cBrett Chabot 2747d431f63a66505a645f282416659a9758a91f1cBrett Chabot private static final long serialVersionUID = 3265727009370529027L; 2847d431f63a66505a645f282416659a9758a91f1cBrett Chabot 2947d431f63a66505a645f282416659a9758a91f1cBrett Chabot private final List<UnorderedBehavior> behaviorLists = new ArrayList<UnorderedBehavior>(); 3047d431f63a66505a645f282416659a9758a91f1cBrett Chabot 3147d431f63a66505a645f282416659a9758a91f1cBrett Chabot private final List<ExpectedInvocationAndResult> stubResults = new ArrayList<ExpectedInvocationAndResult>(); 3247d431f63a66505a645f282416659a9758a91f1cBrett Chabot 3347d431f63a66505a645f282416659a9758a91f1cBrett Chabot private final boolean nice; 3447d431f63a66505a645f282416659a9758a91f1cBrett Chabot 3547d431f63a66505a645f282416659a9758a91f1cBrett Chabot private boolean checkOrder; 3647d431f63a66505a645f282416659a9758a91f1cBrett Chabot 3747d431f63a66505a645f282416659a9758a91f1cBrett Chabot private boolean isThreadSafe; 3847d431f63a66505a645f282416659a9758a91f1cBrett Chabot 3947d431f63a66505a645f282416659a9758a91f1cBrett Chabot private boolean shouldBeUsedInOneThread; 4047d431f63a66505a645f282416659a9758a91f1cBrett Chabot 4147d431f63a66505a645f282416659a9758a91f1cBrett Chabot private int position = 0; 4247d431f63a66505a645f282416659a9758a91f1cBrett Chabot 4347d431f63a66505a645f282416659a9758a91f1cBrett Chabot private transient volatile Thread lastThread; 4447d431f63a66505a645f282416659a9758a91f1cBrett Chabot 4547d431f63a66505a645f282416659a9758a91f1cBrett Chabot private LegacyMatcherProvider legacyMatcherProvider; 4647d431f63a66505a645f282416659a9758a91f1cBrett Chabot 4747d431f63a66505a645f282416659a9758a91f1cBrett Chabot public MocksBehavior(boolean nice) { 4847d431f63a66505a645f282416659a9758a91f1cBrett Chabot this.nice = nice; 4947d431f63a66505a645f282416659a9758a91f1cBrett Chabot this.isThreadSafe = !Boolean.valueOf(EasyMockProperties.getInstance() 5047d431f63a66505a645f282416659a9758a91f1cBrett Chabot .getProperty(EasyMock.NOT_THREAD_SAFE_BY_DEFAULT)); 5147d431f63a66505a645f282416659a9758a91f1cBrett Chabot this.shouldBeUsedInOneThread = Boolean.valueOf(EasyMockProperties 5247d431f63a66505a645f282416659a9758a91f1cBrett Chabot .getInstance().getProperty( 5347d431f63a66505a645f282416659a9758a91f1cBrett Chabot EasyMock.ENABLE_THREAD_SAFETY_CHECK_BY_DEFAULT)); 5447d431f63a66505a645f282416659a9758a91f1cBrett Chabot } 5547d431f63a66505a645f282416659a9758a91f1cBrett Chabot 5647d431f63a66505a645f282416659a9758a91f1cBrett Chabot public final void addStub(ExpectedInvocation expected, Result result) { 5747d431f63a66505a645f282416659a9758a91f1cBrett Chabot stubResults.add(new ExpectedInvocationAndResult(expected, result)); 5847d431f63a66505a645f282416659a9758a91f1cBrett Chabot } 5947d431f63a66505a645f282416659a9758a91f1cBrett Chabot 6047d431f63a66505a645f282416659a9758a91f1cBrett Chabot public void addExpected(ExpectedInvocation expected, Result result, 6147d431f63a66505a645f282416659a9758a91f1cBrett Chabot Range count) { 6247d431f63a66505a645f282416659a9758a91f1cBrett Chabot if (legacyMatcherProvider != null) { 6347d431f63a66505a645f282416659a9758a91f1cBrett Chabot expected = expected.withMatcher(legacyMatcherProvider 6447d431f63a66505a645f282416659a9758a91f1cBrett Chabot .getMatcher(expected.getMethod())); 6547d431f63a66505a645f282416659a9758a91f1cBrett Chabot } 6647d431f63a66505a645f282416659a9758a91f1cBrett Chabot addBehaviorListIfNecessary(expected); 6747d431f63a66505a645f282416659a9758a91f1cBrett Chabot lastBehaviorList().addExpected(expected, result, count); 6847d431f63a66505a645f282416659a9758a91f1cBrett Chabot } 6947d431f63a66505a645f282416659a9758a91f1cBrett Chabot 7047d431f63a66505a645f282416659a9758a91f1cBrett Chabot private final Result getStubResult(Invocation actual) { 7147d431f63a66505a645f282416659a9758a91f1cBrett Chabot for (ExpectedInvocationAndResult each : stubResults) { 7247d431f63a66505a645f282416659a9758a91f1cBrett Chabot if (each.getExpectedInvocation().matches(actual)) { 7347d431f63a66505a645f282416659a9758a91f1cBrett Chabot return each.getResult(); 7447d431f63a66505a645f282416659a9758a91f1cBrett Chabot } 7547d431f63a66505a645f282416659a9758a91f1cBrett Chabot } 7647d431f63a66505a645f282416659a9758a91f1cBrett Chabot return null; 7747d431f63a66505a645f282416659a9758a91f1cBrett Chabot } 7847d431f63a66505a645f282416659a9758a91f1cBrett Chabot 7947d431f63a66505a645f282416659a9758a91f1cBrett Chabot private void addBehaviorListIfNecessary(ExpectedInvocation expected) { 8047d431f63a66505a645f282416659a9758a91f1cBrett Chabot if (behaviorLists.isEmpty() 8147d431f63a66505a645f282416659a9758a91f1cBrett Chabot || !lastBehaviorList().allowsExpectedInvocation(expected, 8247d431f63a66505a645f282416659a9758a91f1cBrett Chabot checkOrder)) { 8347d431f63a66505a645f282416659a9758a91f1cBrett Chabot behaviorLists.add(new UnorderedBehavior(checkOrder)); 8447d431f63a66505a645f282416659a9758a91f1cBrett Chabot } 8547d431f63a66505a645f282416659a9758a91f1cBrett Chabot } 8647d431f63a66505a645f282416659a9758a91f1cBrett Chabot 8747d431f63a66505a645f282416659a9758a91f1cBrett Chabot private UnorderedBehavior lastBehaviorList() { 8847d431f63a66505a645f282416659a9758a91f1cBrett Chabot return behaviorLists.get(behaviorLists.size() - 1); 8947d431f63a66505a645f282416659a9758a91f1cBrett Chabot } 9047d431f63a66505a645f282416659a9758a91f1cBrett Chabot 9147d431f63a66505a645f282416659a9758a91f1cBrett Chabot @SuppressWarnings("deprecation") 9247d431f63a66505a645f282416659a9758a91f1cBrett Chabot public final Result addActual(Invocation actual) { 9347d431f63a66505a645f282416659a9758a91f1cBrett Chabot int initialPosition = position; 9447d431f63a66505a645f282416659a9758a91f1cBrett Chabot 9547d431f63a66505a645f282416659a9758a91f1cBrett Chabot while (position < behaviorLists.size()) { 9647d431f63a66505a645f282416659a9758a91f1cBrett Chabot Result result = behaviorLists.get(position).addActual(actual); 9747d431f63a66505a645f282416659a9758a91f1cBrett Chabot if (result != null) { 9847d431f63a66505a645f282416659a9758a91f1cBrett Chabot return result; 9947d431f63a66505a645f282416659a9758a91f1cBrett Chabot } 10047d431f63a66505a645f282416659a9758a91f1cBrett Chabot if (!behaviorLists.get(position).verify()) { 10147d431f63a66505a645f282416659a9758a91f1cBrett Chabot break; 10247d431f63a66505a645f282416659a9758a91f1cBrett Chabot } 10347d431f63a66505a645f282416659a9758a91f1cBrett Chabot position++; 10447d431f63a66505a645f282416659a9758a91f1cBrett Chabot } 10547d431f63a66505a645f282416659a9758a91f1cBrett Chabot Result stubOrNice = getStubResult(actual); 10647d431f63a66505a645f282416659a9758a91f1cBrett Chabot if (stubOrNice == null && nice) { 10747d431f63a66505a645f282416659a9758a91f1cBrett Chabot stubOrNice = Result.createReturnResult(RecordState 10847d431f63a66505a645f282416659a9758a91f1cBrett Chabot .emptyReturnValueFor(actual.getMethod().getReturnType())); 10947d431f63a66505a645f282416659a9758a91f1cBrett Chabot } 11047d431f63a66505a645f282416659a9758a91f1cBrett Chabot 11147d431f63a66505a645f282416659a9758a91f1cBrett Chabot int endPosition = position; 11247d431f63a66505a645f282416659a9758a91f1cBrett Chabot 11347d431f63a66505a645f282416659a9758a91f1cBrett Chabot // Do not move the cursor in case of stub, nice or error 11447d431f63a66505a645f282416659a9758a91f1cBrett Chabot position = initialPosition; 11547d431f63a66505a645f282416659a9758a91f1cBrett Chabot 11647d431f63a66505a645f282416659a9758a91f1cBrett Chabot if (stubOrNice != null) { 11747d431f63a66505a645f282416659a9758a91f1cBrett Chabot actual.validateCaptures(); 11847d431f63a66505a645f282416659a9758a91f1cBrett Chabot actual.clearCaptures(); 11947d431f63a66505a645f282416659a9758a91f1cBrett Chabot return stubOrNice; 12047d431f63a66505a645f282416659a9758a91f1cBrett Chabot } 12147d431f63a66505a645f282416659a9758a91f1cBrett Chabot 12247d431f63a66505a645f282416659a9758a91f1cBrett Chabot // Case where the loop was exited at the end of the behaviorLists 12347d431f63a66505a645f282416659a9758a91f1cBrett Chabot if (endPosition == behaviorLists.size()) { 12447d431f63a66505a645f282416659a9758a91f1cBrett Chabot endPosition--; 12547d431f63a66505a645f282416659a9758a91f1cBrett Chabot } 12647d431f63a66505a645f282416659a9758a91f1cBrett Chabot 12747d431f63a66505a645f282416659a9758a91f1cBrett Chabot // Loop all around the behaviors left to generate the message 12847d431f63a66505a645f282416659a9758a91f1cBrett Chabot StringBuilder errorMessage = new StringBuilder(70 * (endPosition 12947d431f63a66505a645f282416659a9758a91f1cBrett Chabot - initialPosition + 1)); // rough approximation of the length 13047d431f63a66505a645f282416659a9758a91f1cBrett Chabot errorMessage.append("\n Unexpected method call ").append( 13147d431f63a66505a645f282416659a9758a91f1cBrett Chabot actual.toString(org.easymock.MockControl.EQUALS_MATCHER)); 13247d431f63a66505a645f282416659a9758a91f1cBrett Chabot 13347d431f63a66505a645f282416659a9758a91f1cBrett Chabot List<ErrorMessage> messages = new ArrayList<ErrorMessage>(); 13447d431f63a66505a645f282416659a9758a91f1cBrett Chabot 13547d431f63a66505a645f282416659a9758a91f1cBrett Chabot int matches = 0; 13647d431f63a66505a645f282416659a9758a91f1cBrett Chabot 13747d431f63a66505a645f282416659a9758a91f1cBrett Chabot // First find how many match we have 13847d431f63a66505a645f282416659a9758a91f1cBrett Chabot for (int i = initialPosition; i <= endPosition; i++) { 13947d431f63a66505a645f282416659a9758a91f1cBrett Chabot List<ErrorMessage> thisListMessages = behaviorLists.get(i) 14047d431f63a66505a645f282416659a9758a91f1cBrett Chabot .getMessages(actual); 14147d431f63a66505a645f282416659a9758a91f1cBrett Chabot messages.addAll(thisListMessages); 14247d431f63a66505a645f282416659a9758a91f1cBrett Chabot for (ErrorMessage m : thisListMessages) { 14347d431f63a66505a645f282416659a9758a91f1cBrett Chabot if (m.isMatching()) { 14447d431f63a66505a645f282416659a9758a91f1cBrett Chabot matches++; 14547d431f63a66505a645f282416659a9758a91f1cBrett Chabot } 14647d431f63a66505a645f282416659a9758a91f1cBrett Chabot } 14747d431f63a66505a645f282416659a9758a91f1cBrett Chabot } 14847d431f63a66505a645f282416659a9758a91f1cBrett Chabot 14947d431f63a66505a645f282416659a9758a91f1cBrett Chabot if (matches > 1) { 15047d431f63a66505a645f282416659a9758a91f1cBrett Chabot errorMessage 15147d431f63a66505a645f282416659a9758a91f1cBrett Chabot .append(". Possible matches are marked with (+1):"); 15247d431f63a66505a645f282416659a9758a91f1cBrett Chabot } else { 15347d431f63a66505a645f282416659a9758a91f1cBrett Chabot errorMessage.append(":"); 15447d431f63a66505a645f282416659a9758a91f1cBrett Chabot } 15547d431f63a66505a645f282416659a9758a91f1cBrett Chabot 15647d431f63a66505a645f282416659a9758a91f1cBrett Chabot for (ErrorMessage m : messages) { 15747d431f63a66505a645f282416659a9758a91f1cBrett Chabot m.appendTo(errorMessage, matches); 15847d431f63a66505a645f282416659a9758a91f1cBrett Chabot } 15947d431f63a66505a645f282416659a9758a91f1cBrett Chabot 16047d431f63a66505a645f282416659a9758a91f1cBrett Chabot // And finally throw the error 16147d431f63a66505a645f282416659a9758a91f1cBrett Chabot throw new AssertionErrorWrapper(new AssertionError(errorMessage)); 16247d431f63a66505a645f282416659a9758a91f1cBrett Chabot } 16347d431f63a66505a645f282416659a9758a91f1cBrett Chabot 16447d431f63a66505a645f282416659a9758a91f1cBrett Chabot public void verify() { 16547d431f63a66505a645f282416659a9758a91f1cBrett Chabot boolean verified = true; 16647d431f63a66505a645f282416659a9758a91f1cBrett Chabot 16747d431f63a66505a645f282416659a9758a91f1cBrett Chabot for (UnorderedBehavior behaviorList : behaviorLists.subList(position, 16847d431f63a66505a645f282416659a9758a91f1cBrett Chabot behaviorLists.size())) { 16947d431f63a66505a645f282416659a9758a91f1cBrett Chabot if (!behaviorList.verify()) { 17047d431f63a66505a645f282416659a9758a91f1cBrett Chabot verified = false; 17147d431f63a66505a645f282416659a9758a91f1cBrett Chabot } 17247d431f63a66505a645f282416659a9758a91f1cBrett Chabot } 17347d431f63a66505a645f282416659a9758a91f1cBrett Chabot if (verified) { 17447d431f63a66505a645f282416659a9758a91f1cBrett Chabot return; 17547d431f63a66505a645f282416659a9758a91f1cBrett Chabot } 17647d431f63a66505a645f282416659a9758a91f1cBrett Chabot 17747d431f63a66505a645f282416659a9758a91f1cBrett Chabot StringBuilder errorMessage = new StringBuilder(70 * (behaviorLists 17847d431f63a66505a645f282416659a9758a91f1cBrett Chabot .size() 17947d431f63a66505a645f282416659a9758a91f1cBrett Chabot - position + 1)); 18047d431f63a66505a645f282416659a9758a91f1cBrett Chabot 18147d431f63a66505a645f282416659a9758a91f1cBrett Chabot errorMessage.append("\n Expectation failure on verify:"); 18247d431f63a66505a645f282416659a9758a91f1cBrett Chabot for (UnorderedBehavior behaviorList : behaviorLists.subList(position, 18347d431f63a66505a645f282416659a9758a91f1cBrett Chabot behaviorLists.size())) { 18447d431f63a66505a645f282416659a9758a91f1cBrett Chabot for (ErrorMessage m : behaviorList.getMessages(null)) { 18547d431f63a66505a645f282416659a9758a91f1cBrett Chabot m.appendTo(errorMessage, 0); 18647d431f63a66505a645f282416659a9758a91f1cBrett Chabot } 18747d431f63a66505a645f282416659a9758a91f1cBrett Chabot } 18847d431f63a66505a645f282416659a9758a91f1cBrett Chabot 18947d431f63a66505a645f282416659a9758a91f1cBrett Chabot throw new AssertionErrorWrapper(new AssertionError(errorMessage 19047d431f63a66505a645f282416659a9758a91f1cBrett Chabot .toString())); 19147d431f63a66505a645f282416659a9758a91f1cBrett Chabot } 19247d431f63a66505a645f282416659a9758a91f1cBrett Chabot 19347d431f63a66505a645f282416659a9758a91f1cBrett Chabot public void checkOrder(boolean value) { 19447d431f63a66505a645f282416659a9758a91f1cBrett Chabot this.checkOrder = value; 19547d431f63a66505a645f282416659a9758a91f1cBrett Chabot } 19647d431f63a66505a645f282416659a9758a91f1cBrett Chabot 19747d431f63a66505a645f282416659a9758a91f1cBrett Chabot public void makeThreadSafe(boolean isThreadSafe) { 19847d431f63a66505a645f282416659a9758a91f1cBrett Chabot this.isThreadSafe = isThreadSafe; 19947d431f63a66505a645f282416659a9758a91f1cBrett Chabot } 20047d431f63a66505a645f282416659a9758a91f1cBrett Chabot 20147d431f63a66505a645f282416659a9758a91f1cBrett Chabot public void shouldBeUsedInOneThread(boolean shouldBeUsedInOneThread) { 20247d431f63a66505a645f282416659a9758a91f1cBrett Chabot this.shouldBeUsedInOneThread = shouldBeUsedInOneThread; 20347d431f63a66505a645f282416659a9758a91f1cBrett Chabot } 20447d431f63a66505a645f282416659a9758a91f1cBrett Chabot 20547d431f63a66505a645f282416659a9758a91f1cBrett Chabot public boolean isThreadSafe() { 20647d431f63a66505a645f282416659a9758a91f1cBrett Chabot return this.isThreadSafe; 20747d431f63a66505a645f282416659a9758a91f1cBrett Chabot } 20847d431f63a66505a645f282416659a9758a91f1cBrett Chabot 20947d431f63a66505a645f282416659a9758a91f1cBrett Chabot public void checkThreadSafety() { 21047d431f63a66505a645f282416659a9758a91f1cBrett Chabot if (!shouldBeUsedInOneThread) { 21147d431f63a66505a645f282416659a9758a91f1cBrett Chabot return; 21247d431f63a66505a645f282416659a9758a91f1cBrett Chabot } 21347d431f63a66505a645f282416659a9758a91f1cBrett Chabot if (lastThread == null) { 21447d431f63a66505a645f282416659a9758a91f1cBrett Chabot lastThread = Thread.currentThread(); 21547d431f63a66505a645f282416659a9758a91f1cBrett Chabot } else if(lastThread != Thread.currentThread()) { 21647d431f63a66505a645f282416659a9758a91f1cBrett Chabot throw new AssertionErrorWrapper(new AssertionError( 21747d431f63a66505a645f282416659a9758a91f1cBrett Chabot "\n Mock isn't supposed to be called from multiple threads. Last: " 21847d431f63a66505a645f282416659a9758a91f1cBrett Chabot + lastThread + 21947d431f63a66505a645f282416659a9758a91f1cBrett Chabot " Current: " + Thread.currentThread())); 22047d431f63a66505a645f282416659a9758a91f1cBrett Chabot } 22147d431f63a66505a645f282416659a9758a91f1cBrett Chabot } 22247d431f63a66505a645f282416659a9758a91f1cBrett Chabot 22347d431f63a66505a645f282416659a9758a91f1cBrett Chabot public LegacyMatcherProvider getLegacyMatcherProvider() { 22447d431f63a66505a645f282416659a9758a91f1cBrett Chabot if (legacyMatcherProvider == null) { 22547d431f63a66505a645f282416659a9758a91f1cBrett Chabot legacyMatcherProvider = new LegacyMatcherProvider(); 22647d431f63a66505a645f282416659a9758a91f1cBrett Chabot } 22747d431f63a66505a645f282416659a9758a91f1cBrett Chabot return legacyMatcherProvider; 22847d431f63a66505a645f282416659a9758a91f1cBrett Chabot } 22947d431f63a66505a645f282416659a9758a91f1cBrett Chabot 23047d431f63a66505a645f282416659a9758a91f1cBrett Chabot @SuppressWarnings("deprecation") 23147d431f63a66505a645f282416659a9758a91f1cBrett Chabot public void setDefaultMatcher(org.easymock.ArgumentsMatcher matcher) { 23247d431f63a66505a645f282416659a9758a91f1cBrett Chabot getLegacyMatcherProvider().setDefaultMatcher(matcher); 23347d431f63a66505a645f282416659a9758a91f1cBrett Chabot } 23447d431f63a66505a645f282416659a9758a91f1cBrett Chabot 23547d431f63a66505a645f282416659a9758a91f1cBrett Chabot @SuppressWarnings("deprecation") 23647d431f63a66505a645f282416659a9758a91f1cBrett Chabot public void setMatcher(Method method, org.easymock.ArgumentsMatcher matcher) { 23747d431f63a66505a645f282416659a9758a91f1cBrett Chabot getLegacyMatcherProvider().setMatcher(method, matcher); 23847d431f63a66505a645f282416659a9758a91f1cBrett Chabot } 23947d431f63a66505a645f282416659a9758a91f1cBrett Chabot} 240