summaryrefslogtreecommitdiff
path: root/src/org/easymock/internal
diff options
context:
space:
mode:
Diffstat (limited to 'src/org/easymock/internal')
-rw-r--r--src/org/easymock/internal/AlwaysMatcher.java32
-rw-r--r--src/org/easymock/internal/ArgumentToString.java51
-rw-r--r--src/org/easymock/internal/ArrayMatcher.java30
-rw-r--r--src/org/easymock/internal/AssertionErrorWrapper.java31
-rw-r--r--src/org/easymock/internal/EasyMockProperties.java146
-rw-r--r--src/org/easymock/internal/EqualsMatcher.java24
-rw-r--r--src/org/easymock/internal/ErrorMessage.java58
-rw-r--r--src/org/easymock/internal/ExpectedInvocation.java135
-rw-r--r--src/org/easymock/internal/ExpectedInvocationAndResult.java41
-rw-r--r--src/org/easymock/internal/ExpectedInvocationAndResults.java46
-rw-r--r--src/org/easymock/internal/ILegacyMatcherMethods.java27
-rw-r--r--src/org/easymock/internal/ILegacyMethods.java24
-rw-r--r--src/org/easymock/internal/IMocksBehavior.java40
-rw-r--r--src/org/easymock/internal/IMocksControlState.java55
-rw-r--r--src/org/easymock/internal/IProxyFactory.java22
-rw-r--r--src/org/easymock/internal/Invocation.java218
-rw-r--r--src/org/easymock/internal/JavaProxyFactory.java27
-rw-r--r--src/org/easymock/internal/LastControl.java124
-rw-r--r--src/org/easymock/internal/LegacyMatcherProvider.java102
-rw-r--r--src/org/easymock/internal/MethodSerializationWrapper.java81
-rw-r--r--src/org/easymock/internal/MockInvocationHandler.java54
-rw-r--r--src/org/easymock/internal/MocksBehavior.java239
-rw-r--r--src/org/easymock/internal/MocksControl.java315
-rw-r--r--src/org/easymock/internal/ObjectMethodsFilter.java109
-rw-r--r--src/org/easymock/internal/Range.java85
-rw-r--r--src/org/easymock/internal/RecordState.java389
-rw-r--r--src/org/easymock/internal/ReplayState.java165
-rw-r--r--src/org/easymock/internal/Result.java114
-rw-r--r--src/org/easymock/internal/Results.java89
-rw-r--r--src/org/easymock/internal/RuntimeExceptionWrapper.java31
-rw-r--r--src/org/easymock/internal/ThrowableWrapper.java31
-rw-r--r--src/org/easymock/internal/UnorderedBehavior.java113
-rw-r--r--src/org/easymock/internal/matchers/And.java53
-rw-r--r--src/org/easymock/internal/matchers/Any.java39
-rw-r--r--src/org/easymock/internal/matchers/ArrayEquals.java69
-rw-r--r--src/org/easymock/internal/matchers/Captures.java54
-rw-r--r--src/org/easymock/internal/matchers/Compare.java53
-rw-r--r--src/org/easymock/internal/matchers/CompareEqual.java35
-rw-r--r--src/org/easymock/internal/matchers/CompareTo.java49
-rw-r--r--src/org/easymock/internal/matchers/Contains.java40
-rw-r--r--src/org/easymock/internal/matchers/EndsWith.java39
-rw-r--r--src/org/easymock/internal/matchers/Equals.java63
-rw-r--r--src/org/easymock/internal/matchers/EqualsWithDelta.java46
-rw-r--r--src/org/easymock/internal/matchers/Find.java41
-rw-r--r--src/org/easymock/internal/matchers/GreaterOrEqual.java35
-rw-r--r--src/org/easymock/internal/matchers/GreaterThan.java35
-rw-r--r--src/org/easymock/internal/matchers/InstanceOf.java39
-rw-r--r--src/org/easymock/internal/matchers/LessOrEqual.java35
-rw-r--r--src/org/easymock/internal/matchers/LessThan.java35
-rw-r--r--src/org/easymock/internal/matchers/Matches.java40
-rw-r--r--src/org/easymock/internal/matchers/Not.java41
-rw-r--r--src/org/easymock/internal/matchers/NotNull.java39
-rw-r--r--src/org/easymock/internal/matchers/Null.java38
-rw-r--r--src/org/easymock/internal/matchers/Or.java53
-rw-r--r--src/org/easymock/internal/matchers/Same.java42
-rw-r--r--src/org/easymock/internal/matchers/StartsWith.java40
56 files changed, 4101 insertions, 0 deletions
diff --git a/src/org/easymock/internal/AlwaysMatcher.java b/src/org/easymock/internal/AlwaysMatcher.java
new file mode 100644
index 0000000..f301936
--- /dev/null
+++ b/src/org/easymock/internal/AlwaysMatcher.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2001-2009 OFFIS, Tammo Freese
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.easymock.internal;
+
+import org.easymock.AbstractMatcher;
+
+@SuppressWarnings("deprecation")
+public class AlwaysMatcher extends AbstractMatcher {
+
+ private static final long serialVersionUID = 592339838132342008L;
+
+ public boolean matches(Object[] expected, Object[] actual) {
+ return true;
+ }
+
+ protected String argumentToString(Object argument) {
+ return "<any>";
+ }
+} \ No newline at end of file
diff --git a/src/org/easymock/internal/ArgumentToString.java b/src/org/easymock/internal/ArgumentToString.java
new file mode 100644
index 0000000..81d5676
--- /dev/null
+++ b/src/org/easymock/internal/ArgumentToString.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2003-2009 OFFIS, Henri Tremblay
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.easymock.internal;
+
+import java.lang.reflect.Array;
+
+public final class ArgumentToString {
+
+ // ///CLOVER:OFF
+ private ArgumentToString() {
+ }
+ // ///CLOVER:ON
+
+ public static void appendArgument(Object value, StringBuffer buffer) {
+ if (value == null) {
+ buffer.append("null");
+ } else if (value instanceof String) {
+ buffer.append("\"");
+ buffer.append(value);
+ buffer.append("\"");
+ } else if (value instanceof Character) {
+ buffer.append("'");
+ buffer.append(value);
+ buffer.append("'");
+ } else if (value.getClass().isArray()) {
+ buffer.append("[");
+ for (int i = 0; i < Array.getLength(value); i++) {
+ if (i > 0) {
+ buffer.append(", ");
+ }
+ appendArgument(Array.get(value, i), buffer);
+ }
+ buffer.append("]");
+ } else {
+ buffer.append(value);
+ }
+ }
+}
diff --git a/src/org/easymock/internal/ArrayMatcher.java b/src/org/easymock/internal/ArrayMatcher.java
new file mode 100644
index 0000000..807149f
--- /dev/null
+++ b/src/org/easymock/internal/ArrayMatcher.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2001-2009 OFFIS, Tammo Freese
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.easymock.internal;
+
+import org.easymock.AbstractMatcher;
+import org.easymock.internal.matchers.ArrayEquals;
+
+@SuppressWarnings("deprecation")
+public class ArrayMatcher extends AbstractMatcher {
+
+ private static final long serialVersionUID = -4594659581004800814L;
+
+ @Override
+ public boolean argumentMatches(Object expected, Object actual) {
+ return new ArrayEquals(expected).matches(actual);
+ }
+} \ No newline at end of file
diff --git a/src/org/easymock/internal/AssertionErrorWrapper.java b/src/org/easymock/internal/AssertionErrorWrapper.java
new file mode 100644
index 0000000..d36a3c7
--- /dev/null
+++ b/src/org/easymock/internal/AssertionErrorWrapper.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2001-2009 OFFIS, Tammo Freese
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.easymock.internal;
+
+public class AssertionErrorWrapper extends RuntimeException {
+
+ private static final long serialVersionUID = -2087349195182278608L;
+
+ private final AssertionError error;
+
+ public AssertionErrorWrapper(AssertionError error) {
+ this.error = error;
+ }
+
+ public AssertionError getAssertionError() {
+ return error;
+ }
+}
diff --git a/src/org/easymock/internal/EasyMockProperties.java b/src/org/easymock/internal/EasyMockProperties.java
new file mode 100644
index 0000000..5094104
--- /dev/null
+++ b/src/org/easymock/internal/EasyMockProperties.java
@@ -0,0 +1,146 @@
+/*
+ * Copyright 2003-2009 OFFIS, Henri Tremblay
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.easymock.internal;
+
+import java.io.BufferedInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Map;
+import java.util.Properties;
+
+/**
+ * Contains properties used by EasyMock to change its default behavior. The
+ * loading order is (any step being able to overload the properties of the
+ * previous step):
+ * <ul>
+ * <li>easymock.properties in classpath default package</li>
+ * <li>System properties</li>
+ * <li>explicit call to setProperty</li>
+ * </ul>
+ */
+public final class EasyMockProperties {
+
+ private static final String PREFIX = "easymock.";
+
+ // volatile for double-checked locking
+ private static volatile EasyMockProperties instance;
+
+ private final Properties properties = new Properties();
+
+ public static EasyMockProperties getInstance() {
+ if (instance == null) {
+ synchronized (EasyMockProperties.class) {
+ // ///CLOVER:OFF
+ if (instance == null) {
+ // ///CLOVER:ON
+ instance = new EasyMockProperties();
+ }
+ }
+ }
+ return instance;
+ }
+
+ private EasyMockProperties() {
+ // Load the easymock.properties file
+ InputStream in = getClassLoader().getResourceAsStream(
+ "easymock.properties");
+ if (in != null) {
+ in = new BufferedInputStream(in);
+ try {
+ properties.load(in);
+ } catch (IOException e) {
+ throw new RuntimeException(
+ "Failed to read easymock.properties file");
+ } finally {
+ try {
+ in.close();
+ } catch (IOException e) {
+ // Doesn't matter
+ }
+ }
+ }
+ // Then overload it with system properties
+ for (Map.Entry<Object, Object> entry : System.getProperties()
+ .entrySet()) {
+ if (entry.getKey() instanceof String
+ && entry.getKey().toString().startsWith(PREFIX)) {
+ properties.put(entry.getKey(), entry.getValue());
+ }
+ }
+ }
+
+ /**
+ * Searches for the property with the specified key. If the key is not
+ * found, return the default value.
+ *
+ * @param key
+ * key leading to the property
+ * @param defaultValue
+ * the value to be returned if the key isn't found
+ * @return the value found for the key or the default value
+ */
+ public String getProperty(String key, String defaultValue) {
+ return properties.getProperty(key, defaultValue);
+ }
+
+ /**
+ * Searches for the property with the specified key. Return null if the key
+ * is not found.
+ *
+ * @param key
+ * key leading to the property
+ * @return the value found for the key or null
+ */
+ public String getProperty(String key) {
+ return properties.getProperty(key);
+ }
+
+ /**
+ * Add a value referenced by the provided key. A null value will remove the
+ * key
+ *
+ * @param key
+ * the key of the new property
+ * @param value
+ * the value corresponding to <tt>key</tt>.
+ * @return the property previous value
+ */
+ public String setProperty(String key, String value) {
+ if (!key.startsWith(PREFIX)) {
+ throw new IllegalArgumentException("Invalid key (" + key
+ + "), an easymock property starts with \"" + PREFIX + "\"");
+ }
+ if (value == null) {
+ return (String) properties.remove(key);
+ }
+ return (String) properties.setProperty(key, value);
+ }
+
+ private ClassLoader getClassLoader() {
+ ClassLoader cl = null;
+ try {
+ cl = Thread.currentThread().getContextClassLoader();
+ } catch (Throwable ex) {
+ // Cannot access thread context ClassLoader - falling back to system
+ // class loader
+ }
+ if (cl == null) {
+ // No thread context class loader -> use class loader of this class.
+ cl = getClass().getClassLoader();
+ }
+ return cl;
+ }
+}
diff --git a/src/org/easymock/internal/EqualsMatcher.java b/src/org/easymock/internal/EqualsMatcher.java
new file mode 100644
index 0000000..ee49098
--- /dev/null
+++ b/src/org/easymock/internal/EqualsMatcher.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2001-2009 OFFIS, Tammo Freese
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.easymock.internal;
+
+import org.easymock.AbstractMatcher;
+
+@SuppressWarnings("deprecation")
+public class EqualsMatcher extends AbstractMatcher {
+
+ private static final long serialVersionUID = 4152805764785966978L;
+} \ No newline at end of file
diff --git a/src/org/easymock/internal/ErrorMessage.java b/src/org/easymock/internal/ErrorMessage.java
new file mode 100644
index 0000000..9284f6c
--- /dev/null
+++ b/src/org/easymock/internal/ErrorMessage.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2003-2009 OFFIS, Henri Tremblay
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.easymock.internal;
+
+public class ErrorMessage {
+
+ private final boolean matching;
+
+ private final String message;
+
+ private final int actualCount;
+
+ public ErrorMessage(boolean matching, String message, int actualCount) {
+ this.matching = matching;
+ this.message = message;
+ this.actualCount = actualCount;
+ }
+
+ public boolean isMatching() {
+ return matching;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public int getActualCount() {
+ return actualCount;
+ }
+
+ public void appendTo(StringBuilder buffer, int matches) {
+ buffer.append("\n ").append(message).append(", actual: ");
+ if (matching) {
+ if (matches == 1) {
+ buffer.append(getActualCount() + 1);
+ } else {
+ buffer.append(getActualCount());
+ buffer.append(" (+1)");
+ }
+ }
+ else {
+ buffer.append(getActualCount());
+ }
+ }
+}
diff --git a/src/org/easymock/internal/ExpectedInvocation.java b/src/org/easymock/internal/ExpectedInvocation.java
new file mode 100644
index 0000000..7bff86c
--- /dev/null
+++ b/src/org/easymock/internal/ExpectedInvocation.java
@@ -0,0 +1,135 @@
+/*
+ * Copyright 2001-2009 OFFIS, Tammo Freese
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.easymock.internal;
+
+import java.io.Serializable;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.easymock.IArgumentMatcher;
+import org.easymock.internal.matchers.Equals;
+
+public class ExpectedInvocation implements Serializable {
+
+ private static final long serialVersionUID = -5554816464613350531L;
+
+ private final Invocation invocation;
+
+ @SuppressWarnings("deprecation")
+ private final org.easymock.ArgumentsMatcher matcher;
+
+ private final List<IArgumentMatcher> matchers;
+
+ public ExpectedInvocation(Invocation invocation,
+ List<IArgumentMatcher> matchers) {
+ this(invocation, matchers, null);
+ }
+
+ private ExpectedInvocation(Invocation invocation,
+ List<IArgumentMatcher> matchers, @SuppressWarnings("deprecation")
+ org.easymock.ArgumentsMatcher matcher) {
+ this.invocation = invocation;
+ this.matcher = matcher;
+ this.matchers = (matcher == null) ? createMissingMatchers(invocation,
+ matchers) : null;
+ }
+
+ private List<IArgumentMatcher> createMissingMatchers(Invocation invocation,
+ List<IArgumentMatcher> matchers) {
+ if (matchers != null) {
+ if (matchers.size() != invocation.getArguments().length) {
+ throw new IllegalStateException(""
+ + invocation.getArguments().length
+ + " matchers expected, " + matchers.size()
+ + " recorded.");
+ }
+ return matchers;
+ }
+ List<IArgumentMatcher> result = new ArrayList<IArgumentMatcher>();
+ for (Object argument : invocation.getArguments()) {
+ result.add(new Equals(argument));
+ }
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (o == null || !this.getClass().equals(o.getClass()))
+ return false;
+
+ ExpectedInvocation other = (ExpectedInvocation) o;
+ return this.invocation.equals(other.invocation)
+ && ((this.matcher == null && other.matcher == null) || (this.matcher != null && this.matcher
+ .equals(other.matcher)))
+ && ((this.matchers == null && other.matchers == null) || (this.matchers != null && this.matchers
+ .equals(other.matchers)));
+ }
+
+ @Override
+ public int hashCode() {
+ throw new UnsupportedOperationException("hashCode() is not implemented");
+ }
+
+ public boolean matches(Invocation actual) {
+ return matchers != null ? this.invocation.getMock().equals(
+ actual.getMock())
+ && this.invocation.getMethod().equals(actual.getMethod())
+ && matches(actual.getArguments()) : this.invocation.matches(
+ actual, matcher);
+ }
+
+ private boolean matches(Object[] arguments) {
+ if (arguments.length != matchers.size()) {
+ return false;
+ }
+ for (int i = 0; i < arguments.length; i++) {
+ if (!matchers.get(i).matches(arguments[i])) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ @Override
+ public String toString() {
+ return matchers != null ? myToString() : invocation.toString(matcher);
+ }
+
+ private String myToString() {
+ StringBuffer result = new StringBuffer();
+ result.append(invocation.getMockAndMethodName());
+ result.append("(");
+ for (Iterator<IArgumentMatcher> it = matchers.iterator(); it.hasNext();) {
+ it.next().appendTo(result);
+ if (it.hasNext()) {
+ result.append(", ");
+ }
+ }
+ result.append(")");
+ return result.toString();
+ }
+
+ public Method getMethod() {
+ return invocation.getMethod();
+ }
+
+ public ExpectedInvocation withMatcher(@SuppressWarnings("deprecation")
+ org.easymock.ArgumentsMatcher matcher) {
+ return new ExpectedInvocation(invocation, null, matcher);
+ }
+}
diff --git a/src/org/easymock/internal/ExpectedInvocationAndResult.java b/src/org/easymock/internal/ExpectedInvocationAndResult.java
new file mode 100644
index 0000000..b33be7f
--- /dev/null
+++ b/src/org/easymock/internal/ExpectedInvocationAndResult.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2001-2009 OFFIS, Tammo Freese
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.easymock.internal;
+
+import java.io.Serializable;
+
+public class ExpectedInvocationAndResult implements Serializable {
+
+ private static final long serialVersionUID = -1951159588262854559L;
+
+ ExpectedInvocation expectedInvocation;
+
+ Result result;
+
+ public ExpectedInvocationAndResult(ExpectedInvocation expectedInvocation,
+ Result result) {
+ this.expectedInvocation = expectedInvocation;
+ this.result = result;
+ }
+
+ public ExpectedInvocation getExpectedInvocation() {
+ return expectedInvocation;
+ }
+
+ public Result getResult() {
+ return result;
+ }
+} \ No newline at end of file
diff --git a/src/org/easymock/internal/ExpectedInvocationAndResults.java b/src/org/easymock/internal/ExpectedInvocationAndResults.java
new file mode 100644
index 0000000..52b6743
--- /dev/null
+++ b/src/org/easymock/internal/ExpectedInvocationAndResults.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2001-2009 OFFIS, Tammo Freese
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.easymock.internal;
+
+import java.io.Serializable;
+
+public class ExpectedInvocationAndResults implements Serializable {
+
+ private static final long serialVersionUID = 8189985418895395472L;
+
+ ExpectedInvocation expectedInvocation;
+
+ Results results;
+
+ public ExpectedInvocationAndResults(ExpectedInvocation expectedInvocation,
+ Results results) {
+ this.expectedInvocation = expectedInvocation;
+ this.results = results;
+ }
+
+ public ExpectedInvocation getExpectedInvocation() {
+ return expectedInvocation;
+ }
+
+ public Results getResults() {
+ return results;
+ }
+
+ @Override
+ public String toString() {
+ return expectedInvocation.toString() + ": " + results.toString();
+ }
+} \ No newline at end of file
diff --git a/src/org/easymock/internal/ILegacyMatcherMethods.java b/src/org/easymock/internal/ILegacyMatcherMethods.java
new file mode 100644
index 0000000..48f8fb2
--- /dev/null
+++ b/src/org/easymock/internal/ILegacyMatcherMethods.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2001-2009 OFFIS, Tammo Freese
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.easymock.internal;
+
+import java.lang.reflect.Method;
+
+public interface ILegacyMatcherMethods {
+
+ @SuppressWarnings("deprecation")
+ void setDefaultMatcher(org.easymock.ArgumentsMatcher matcher);
+
+ @SuppressWarnings("deprecation")
+ void setMatcher(Method method, org.easymock.ArgumentsMatcher matcher);
+} \ No newline at end of file
diff --git a/src/org/easymock/internal/ILegacyMethods.java b/src/org/easymock/internal/ILegacyMethods.java
new file mode 100644
index 0000000..45c8de2
--- /dev/null
+++ b/src/org/easymock/internal/ILegacyMethods.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2001-2009 OFFIS, Tammo Freese
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.easymock.internal;
+
+public interface ILegacyMethods extends ILegacyMatcherMethods {
+ void setDefaultReturnValue(Object value);
+
+ void setDefaultThrowable(Throwable throwable);
+
+ void setDefaultVoidCallable();
+}
diff --git a/src/org/easymock/internal/IMocksBehavior.java b/src/org/easymock/internal/IMocksBehavior.java
new file mode 100644
index 0000000..b72ec59
--- /dev/null
+++ b/src/org/easymock/internal/IMocksBehavior.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2001-2009 OFFIS, Tammo Freese
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.easymock.internal;
+
+public interface IMocksBehavior extends ILegacyMatcherMethods {
+
+ // record
+ void addExpected(ExpectedInvocation expected, Result result, Range count);
+
+ void addStub(ExpectedInvocation expected, Result result);
+
+ void checkOrder(boolean value);
+
+ void makeThreadSafe(boolean isThreadSafe);
+
+ void shouldBeUsedInOneThread(boolean shouldBeUsedInOneThread);
+
+ // replay
+ Result addActual(Invocation invocation);
+
+ boolean isThreadSafe();
+
+ void checkThreadSafety();
+
+ // verify
+ void verify();
+}
diff --git a/src/org/easymock/internal/IMocksControlState.java b/src/org/easymock/internal/IMocksControlState.java
new file mode 100644
index 0000000..4ff2842
--- /dev/null
+++ b/src/org/easymock/internal/IMocksControlState.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2001-2009 OFFIS, Tammo Freese
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.easymock.internal;
+
+import org.easymock.IAnswer;
+
+public interface IMocksControlState extends ILegacyMethods {
+
+ Object invoke(Invocation invocation) throws Throwable;
+
+ void assertRecordState();
+
+ void andReturn(Object value);
+
+ void andThrow(Throwable throwable);
+
+ void andAnswer(IAnswer<?> answer);
+
+ void andDelegateTo(Object answer);
+
+ void andStubReturn(Object value);
+
+ void andStubThrow(Throwable throwable);
+
+ void andStubAnswer(IAnswer<?> answer);
+
+ void andStubDelegateTo(Object delegateTo);
+
+ void asStub();
+
+ void times(Range range);
+
+ void checkOrder(boolean value);
+
+ void makeThreadSafe(boolean threadSafe);
+
+ void checkIsUsedInOneThread(boolean shouldBeUsedInOneThread);
+
+ void replay();
+
+ void verify();
+}
diff --git a/src/org/easymock/internal/IProxyFactory.java b/src/org/easymock/internal/IProxyFactory.java
new file mode 100644
index 0000000..9e22062
--- /dev/null
+++ b/src/org/easymock/internal/IProxyFactory.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2001-2009 OFFIS, Tammo Freese
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.easymock.internal;
+
+import java.lang.reflect.InvocationHandler;
+
+public interface IProxyFactory<T> {
+ T createProxy(Class<T> toMock, InvocationHandler handler);
+}
diff --git a/src/org/easymock/internal/Invocation.java b/src/org/easymock/internal/Invocation.java
new file mode 100644
index 0000000..c058524
--- /dev/null
+++ b/src/org/easymock/internal/Invocation.java
@@ -0,0 +1,218 @@
+/*
+ * Copyright 2001-2009 OFFIS, Tammo Freese
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.easymock.internal;
+
+import static java.lang.Character.*;
+
+import java.io.IOException;
+import java.io.Serializable;
+import java.lang.reflect.Array;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Collection;
+
+import org.easymock.internal.matchers.Captures;
+
+public class Invocation implements Serializable {
+
+ private static final long serialVersionUID = 1604995470419943411L;
+
+ private final Object mock;
+
+ private transient Method method;
+
+ private final Object[] arguments;
+
+ private final Collection<Captures<?>> currentCaptures = new ArrayList<Captures<?>>(
+ 0);
+
+ public Invocation(Object mock, Method method, Object[] args) {
+ this.mock = mock;
+ this.method = method;
+ this.arguments = expandVarArgs(method.isVarArgs(), args);
+ }
+
+ private static Object[] expandVarArgs(final boolean isVarArgs,
+ final Object[] args) {
+ if (!isVarArgs) {
+ return args == null ? new Object[0] : args;
+ }
+ if (args[args.length - 1] == null) {
+ return args;
+ }
+ Object[] varArgs = createObjectArray(args[args.length - 1]);
+ final int nonVarArgsCount = args.length - 1;
+ final int varArgsCount = varArgs.length;
+ Object[] newArgs = new Object[nonVarArgsCount + varArgsCount];
+ System.arraycopy(args, 0, newArgs, 0, nonVarArgsCount);
+ System.arraycopy(varArgs, 0, newArgs, nonVarArgsCount, varArgsCount);
+ return newArgs;
+ }
+
+ private static Object[] createObjectArray(Object array) {
+ if (array instanceof Object[]) {
+ return (Object[]) array;
+ }
+ Object[] result = new Object[Array.getLength(array)];
+ for (int i = 0; i < Array.getLength(array); i++) {
+ result[i] = Array.get(array, i);
+ }
+ return result;
+ }
+
+ public Object getMock() {
+ return mock;
+ }
+
+ public Method getMethod() {
+ return method;
+ }
+
+ public Object[] getArguments() {
+ return arguments;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (o == null || !o.getClass().equals(this.getClass()))
+ return false;
+
+ Invocation other = (Invocation) o;
+
+ return this.mock.equals(other.mock) && this.method.equals(other.method)
+ && this.equalArguments(other.arguments);
+ }
+
+ @Override
+ public int hashCode() {
+ throw new UnsupportedOperationException("hashCode() is not implemented");
+ }
+
+ private boolean equalArguments(Object[] arguments) {
+ if (this.arguments.length != arguments.length) {
+ return false;
+ }
+ for (int i = 0; i < this.arguments.length; i++) {
+ Object myArgument = this.arguments[i];
+ Object otherArgument = arguments[i];
+
+ if (isPrimitiveParameter(i)) {
+ if (!myArgument.equals(otherArgument)) {
+ return false;
+ }
+ } else {
+ if (myArgument != otherArgument) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+ private boolean isPrimitiveParameter(int parameterPosition) {
+ Class<?>[] parameterTypes = method.getParameterTypes();
+ if (method.isVarArgs()) {
+ parameterPosition = Math.min(parameterPosition,
+ parameterTypes.length - 1);
+ }
+ return parameterTypes[parameterPosition].isPrimitive();
+ }
+
+ @SuppressWarnings("deprecation")
+ public boolean matches(Invocation actual, org.easymock.ArgumentsMatcher matcher) {
+ return this.mock.equals(actual.mock)
+ && this.method.equals(actual.method)
+ && matcher.matches(this.arguments, actual.arguments);
+ }
+
+ @SuppressWarnings("deprecation")
+ public String toString(org.easymock.ArgumentsMatcher matcher) {
+ return getMockAndMethodName() + "(" + matcher.toString(arguments) + ")";
+ }
+
+ public String getMockAndMethodName() {
+ String mockName = mock.toString();
+ String methodName = method.getName();
+ if (toStringIsDefined(mock) && isJavaIdentifier(mockName)) {
+ return mockName + "." + methodName;
+ } else {
+ return methodName;
+ }
+ }
+
+ public void addCapture(Captures<Object> capture, Object value) {
+ capture.setPotentialValue(value);
+ currentCaptures.add(capture);
+ }
+
+ public void validateCaptures() {
+ for (Captures<?> c : currentCaptures) {
+ c.validateCapture();
+ }
+ }
+
+ public void clearCaptures() {
+ for (Captures<?> c : currentCaptures) {
+ c.setPotentialValue(null);
+ }
+ currentCaptures.clear();
+ }
+
+ private boolean toStringIsDefined(Object o) {
+ try {
+ o.getClass().getDeclaredMethod("toString", (Class[]) null)
+ .getModifiers();
+ return true;
+ } catch (SecurityException ignored) {
+ // ///CLOVER:OFF
+ return false;
+ // ///CLOVER:ON
+ } catch (NoSuchMethodException shouldNeverHappen) {
+ // ///CLOVER:OFF
+ throw new RuntimeException("The toString() method could not be found!");
+ // ///CLOVER:ON
+ }
+ }
+
+ public static boolean isJavaIdentifier(String mockName) {
+ if (mockName.length() == 0 || mockName.indexOf(' ') > -1
+ || !Character.isJavaIdentifierStart(mockName.charAt(0))) {
+ return false;
+ }
+ for (char c : mockName.substring(1).toCharArray()) {
+ if (!isJavaIdentifierPart(c)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ private void readObject(java.io.ObjectInputStream stream) throws IOException, ClassNotFoundException {
+ stream.defaultReadObject();
+ try {
+ method = ((MethodSerializationWrapper) stream.readObject()).getMethod();
+ } catch (NoSuchMethodException e) {
+ // ///CLOVER:OFF
+ throw new IOException(e.toString());
+ // ///CLOVER:ON
+ }
+ }
+
+ private void writeObject(java.io.ObjectOutputStream stream) throws IOException {
+ stream.defaultWriteObject();
+ stream.writeObject(new MethodSerializationWrapper(method));
+ }
+}
diff --git a/src/org/easymock/internal/JavaProxyFactory.java b/src/org/easymock/internal/JavaProxyFactory.java
new file mode 100644
index 0000000..2d1c47d
--- /dev/null
+++ b/src/org/easymock/internal/JavaProxyFactory.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2001-2009 OFFIS, Tammo Freese
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.easymock.internal;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Proxy;
+
+public class JavaProxyFactory<T> implements IProxyFactory<T> {
+ @SuppressWarnings("unchecked")
+ public T createProxy(Class<T> toMock, InvocationHandler handler) {
+ return (T) Proxy.newProxyInstance(toMock.getClassLoader(),
+ new Class[] { toMock }, handler);
+ }
+}
diff --git a/src/org/easymock/internal/LastControl.java b/src/org/easymock/internal/LastControl.java
new file mode 100644
index 0000000..2acc1e6
--- /dev/null
+++ b/src/org/easymock/internal/LastControl.java
@@ -0,0 +1,124 @@
+/*
+ * Copyright 2001-2009 OFFIS, Tammo Freese
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.easymock.internal;
+
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Stack;
+
+import org.easymock.IArgumentMatcher;
+import org.easymock.internal.matchers.And;
+import org.easymock.internal.matchers.Not;
+import org.easymock.internal.matchers.Or;
+
+public class LastControl {
+ private static final ThreadLocal<MocksControl> threadToControl = new ThreadLocal<MocksControl>();
+
+ private static final ThreadLocal<Stack<Invocation>> threadToCurrentInvocation = new ThreadLocal<Stack<Invocation>>();
+
+ private static final ThreadLocal<Stack<IArgumentMatcher>> threadToArgumentMatcherStack = new ThreadLocal<Stack<IArgumentMatcher>>();
+
+ public static void reportLastControl(MocksControl control) {
+ if (control != null) {
+ threadToControl.set(control);
+ } else {
+ threadToControl.remove();
+ }
+ }
+
+ public static MocksControl lastControl() {
+ return threadToControl.get();
+ }
+
+ public static void reportMatcher(IArgumentMatcher matcher) {
+ Stack<IArgumentMatcher> stack = threadToArgumentMatcherStack.get();
+ if (stack == null) {
+ stack = new Stack<IArgumentMatcher>();
+ threadToArgumentMatcherStack.set(stack);
+ }
+ stack.push(matcher);
+ }
+
+ public static List<IArgumentMatcher> pullMatchers() {
+ Stack<IArgumentMatcher> stack = threadToArgumentMatcherStack.get();
+ if (stack == null) {
+ return null;
+ }
+ threadToArgumentMatcherStack.remove();
+ return new ArrayList<IArgumentMatcher>(stack);
+ }
+
+ public static void reportAnd(int count) {
+ Stack<IArgumentMatcher> stack = threadToArgumentMatcherStack.get();
+ assertState(stack != null, "no matchers found.");
+ stack.push(new And(popLastArgumentMatchers(count)));
+ }
+
+ public static void reportNot() {
+ Stack<IArgumentMatcher> stack = threadToArgumentMatcherStack.get();
+ assertState(stack != null, "no matchers found.");
+ stack.push(new Not(popLastArgumentMatchers(1).get(0)));
+ }
+
+ private static List<IArgumentMatcher> popLastArgumentMatchers(int count) {
+ Stack<IArgumentMatcher> stack = threadToArgumentMatcherStack.get();
+ assertState(stack != null, "no matchers found.");
+ assertState(stack.size() >= count, "" + count + " matchers expected, "
+ + stack.size() + " recorded.");
+ List<IArgumentMatcher> result = new LinkedList<IArgumentMatcher>();
+ result.addAll(stack.subList(stack.size() - count, stack.size()));
+ for (int i = 0; i < count; i++) {
+ stack.pop();
+ }
+ return result;
+ }
+
+ private static void assertState(boolean toAssert, String message) {
+ if (!toAssert) {
+ threadToArgumentMatcherStack.remove();
+ throw new IllegalStateException(message);
+ }
+ }
+
+ public static void reportOr(int count) {
+ Stack<IArgumentMatcher> stack = threadToArgumentMatcherStack.get();
+ assertState(stack != null, "no matchers found.");
+ stack.push(new Or(popLastArgumentMatchers(count)));
+ }
+
+ public static Invocation getCurrentInvocation() {
+ Stack<Invocation> stack = threadToCurrentInvocation.get();
+ if (stack == null || stack.empty()) {
+ return null;
+ }
+ return stack.lastElement();
+ }
+
+ public static void pushCurrentInvocation(Invocation invocation) {
+ Stack<Invocation> stack = threadToCurrentInvocation.get();
+ if (stack == null) {
+ stack = new Stack<Invocation>();
+ threadToCurrentInvocation.set(stack);
+ }
+ stack.push(invocation);
+ }
+
+ public static void popCurrentInvocation() {
+ Stack<Invocation> stack = threadToCurrentInvocation.get();
+ stack.pop();
+ }
+}
diff --git a/src/org/easymock/internal/LegacyMatcherProvider.java b/src/org/easymock/internal/LegacyMatcherProvider.java
new file mode 100644
index 0000000..b8665e9
--- /dev/null
+++ b/src/org/easymock/internal/LegacyMatcherProvider.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright 2001-2009 OFFIS, Tammo Freese
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.easymock.internal;
+
+import java.io.IOException;
+import java.io.Serializable;
+import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.easymock.ArgumentsMatcher;
+import org.easymock.MockControl;
+
+@SuppressWarnings("deprecation")
+public class LegacyMatcherProvider implements Serializable {
+
+ private static final long serialVersionUID = -4143082656571251917L;
+
+ private ArgumentsMatcher defaultMatcher;
+
+ private boolean defaultMatcherSet;
+
+ private transient Map<Method, ArgumentsMatcher> matchers = new HashMap<Method, ArgumentsMatcher>();
+
+ public ArgumentsMatcher getMatcher(Method method) {
+ if (!matchers.containsKey(method)) {
+ if (!defaultMatcherSet) {
+ setDefaultMatcher(MockControl.EQUALS_MATCHER);
+ }
+ matchers.put(method, defaultMatcher);
+ }
+ return matchers.get(method);
+ }
+
+ public void setDefaultMatcher(ArgumentsMatcher matcher) {
+ if (defaultMatcherSet) {
+ throw new RuntimeExceptionWrapper(
+ new IllegalStateException(
+ "default matcher can only be set once directly after creation of the MockControl"));
+ }
+ defaultMatcher = matcher;
+ defaultMatcherSet = true;
+ }
+
+ public void setMatcher(Method method, ArgumentsMatcher matcher) {
+ if (matchers.containsKey(method) && matchers.get(method) != matcher) {
+ throw new RuntimeExceptionWrapper(new IllegalStateException(
+ "for method "
+ + method.getName()
+ + "("
+ + (method.getParameterTypes().length == 0 ? ""
+ : "...")
+ + "), a matcher has already been set"));
+ }
+ matchers.put(method, matcher);
+ }
+
+ @SuppressWarnings("unchecked")
+ private void readObject(java.io.ObjectInputStream stream)
+ throws IOException, ClassNotFoundException {
+ stream.defaultReadObject();
+ Map<MethodSerializationWrapper, ArgumentsMatcher> map = (Map<MethodSerializationWrapper, ArgumentsMatcher>) stream
+ .readObject();
+ matchers = new HashMap<Method, ArgumentsMatcher>(map.size());
+ for (Map.Entry<MethodSerializationWrapper, ArgumentsMatcher> entry : map
+ .entrySet()) {
+ try {
+ Method method = entry.getKey().getMethod();
+ matchers.put(method, entry.getValue());
+ } catch (NoSuchMethodException e) {
+ // ///CLOVER:OFF
+ throw new IOException(e.toString());
+ // ///CLOVER:ON
+ }
+ }
+ }
+
+ private void writeObject(java.io.ObjectOutputStream stream)
+ throws IOException {
+ stream.defaultWriteObject();
+ Map<MethodSerializationWrapper, ArgumentsMatcher> map = new HashMap<MethodSerializationWrapper, ArgumentsMatcher>(
+ matchers.size());
+ for (Map.Entry<Method, ArgumentsMatcher> matcher : matchers.entrySet()) {
+ map.put(new MethodSerializationWrapper(matcher.getKey()), matcher
+ .getValue());
+ }
+ stream.writeObject(map);
+ }
+}
diff --git a/src/org/easymock/internal/MethodSerializationWrapper.java b/src/org/easymock/internal/MethodSerializationWrapper.java
new file mode 100644
index 0000000..924331c
--- /dev/null
+++ b/src/org/easymock/internal/MethodSerializationWrapper.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2003-2009 OFFIS, Henri Tremblay
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.easymock.internal;
+
+import java.io.Serializable;
+import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.Map;
+
+public class MethodSerializationWrapper implements Serializable {
+
+ private static final long serialVersionUID = 1775475200823842126L;
+
+ private static final Map<String, Class<?>> primitiveTypes = new HashMap<String, Class<?>>(
+ 10);
+
+ static {
+ primitiveTypes.put(Boolean.TYPE.getName(), Boolean.TYPE);
+ primitiveTypes.put(Byte.TYPE.getName(), Byte.TYPE);
+ primitiveTypes.put(Short.TYPE.getName(), Short.TYPE);
+ primitiveTypes.put(Character.TYPE.getName(), Character.TYPE);
+ primitiveTypes.put(Integer.TYPE.getName(), Integer.TYPE);
+ primitiveTypes.put(Long.TYPE.getName(), Long.TYPE);
+ primitiveTypes.put(Float.TYPE.getName(), Float.TYPE);
+ primitiveTypes.put(Double.TYPE.getName(), Double.TYPE);
+ }
+
+ private String className;
+
+ private String methodName;
+
+ private String[] parameterTypeNames;
+
+ public MethodSerializationWrapper(Method m) {
+ className = m.getDeclaringClass().getName();
+ methodName = m.getName();
+
+ Class<?>[] parameterTypes = m.getParameterTypes();
+
+ parameterTypeNames = new String[parameterTypes.length];
+
+ for (int i = 0; i < parameterTypes.length; i++) {
+ parameterTypeNames[i] = parameterTypes[i].getName();
+ }
+ }
+
+ public Method getMethod() throws ClassNotFoundException,
+ NoSuchMethodException {
+ Class<?> clazz = Class.forName(className, true, Thread.currentThread()
+ .getContextClassLoader());
+
+ Class<?>[] parameterTypes = new Class[parameterTypeNames.length];
+
+ for (int i = 0; i < parameterTypeNames.length; i++) {
+ Class<?> primitiveType = primitiveTypes.get(parameterTypeNames[i]);
+ if (primitiveType != null) {
+ parameterTypes[i] = primitiveType;
+ } else {
+ parameterTypes[i] = Class.forName(parameterTypeNames[i], true,
+ Thread.currentThread().getContextClassLoader());
+ }
+ }
+
+ Method m = clazz.getMethod(methodName, parameterTypes);
+
+ return m;
+ }
+}
diff --git a/src/org/easymock/internal/MockInvocationHandler.java b/src/org/easymock/internal/MockInvocationHandler.java
new file mode 100644
index 0000000..323cb4e
--- /dev/null
+++ b/src/org/easymock/internal/MockInvocationHandler.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2001-2009 OFFIS, Tammo Freese
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.easymock.internal;
+
+import java.io.Serializable;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+
+public final class MockInvocationHandler implements InvocationHandler, Serializable {
+
+ private static final long serialVersionUID = -7799769066534714634L;
+
+ private final MocksControl control;
+
+ public MockInvocationHandler(MocksControl control) {
+ this.control = control;
+ }
+
+ public Object invoke(Object proxy, Method method, Object[] args)
+ throws Throwable {
+ try {
+ if (control.getState() instanceof RecordState) {
+ LastControl.reportLastControl(control);
+ }
+ return control.getState().invoke(
+ new Invocation(proxy, method, args));
+ } catch (RuntimeExceptionWrapper e) {
+ throw e.getRuntimeException().fillInStackTrace();
+ } catch (AssertionErrorWrapper e) {
+ throw e.getAssertionError().fillInStackTrace();
+ } catch (ThrowableWrapper t) {
+ throw t.getThrowable().fillInStackTrace();
+ } catch (Throwable t) {
+ throw t; // let all unwrapped pass unmodified
+ }
+ }
+
+ public MocksControl getControl() {
+ return control;
+ }
+} \ No newline at end of file
diff --git a/src/org/easymock/internal/MocksBehavior.java b/src/org/easymock/internal/MocksBehavior.java
new file mode 100644
index 0000000..84a49a5
--- /dev/null
+++ b/src/org/easymock/internal/MocksBehavior.java
@@ -0,0 +1,239 @@
+/*
+ * Copyright 2001-2009 OFFIS, Tammo Freese
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.easymock.internal;
+
+import java.io.Serializable;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.easymock.EasyMock;
+
+public class MocksBehavior implements IMocksBehavior, Serializable {
+
+ private static final long serialVersionUID = 3265727009370529027L;
+
+ private final List<UnorderedBehavior> behaviorLists = new ArrayList<UnorderedBehavior>();
+
+ private final List<ExpectedInvocationAndResult> stubResults = new ArrayList<ExpectedInvocationAndResult>();
+
+ private final boolean nice;
+
+ private boolean checkOrder;
+
+ private boolean isThreadSafe;
+
+ private boolean shouldBeUsedInOneThread;
+
+ private int position = 0;
+
+ private transient volatile Thread lastThread;
+
+ private LegacyMatcherProvider legacyMatcherProvider;
+
+ public MocksBehavior(boolean nice) {
+ this.nice = nice;
+ this.isThreadSafe = !Boolean.valueOf(EasyMockProperties.getInstance()
+ .getProperty(EasyMock.NOT_THREAD_SAFE_BY_DEFAULT));
+ this.shouldBeUsedInOneThread = Boolean.valueOf(EasyMockProperties
+ .getInstance().getProperty(
+ EasyMock.ENABLE_THREAD_SAFETY_CHECK_BY_DEFAULT));
+ }
+
+ public final void addStub(ExpectedInvocation expected, Result result) {
+ stubResults.add(new ExpectedInvocationAndResult(expected, result));
+ }
+
+ public void addExpected(ExpectedInvocation expected, Result result,
+ Range count) {
+ if (legacyMatcherProvider != null) {
+ expected = expected.withMatcher(legacyMatcherProvider
+ .getMatcher(expected.getMethod()));
+ }
+ addBehaviorListIfNecessary(expected);
+ lastBehaviorList().addExpected(expected, result, count);
+ }
+
+ private final Result getStubResult(Invocation actual) {
+ for (ExpectedInvocationAndResult each : stubResults) {
+ if (each.getExpectedInvocation().matches(actual)) {
+ return each.getResult();
+ }
+ }
+ return null;
+ }
+
+ private void addBehaviorListIfNecessary(ExpectedInvocation expected) {
+ if (behaviorLists.isEmpty()
+ || !lastBehaviorList().allowsExpectedInvocation(expected,
+ checkOrder)) {
+ behaviorLists.add(new UnorderedBehavior(checkOrder));
+ }
+ }
+
+ private UnorderedBehavior lastBehaviorList() {
+ return behaviorLists.get(behaviorLists.size() - 1);
+ }
+
+ @SuppressWarnings("deprecation")
+ public final Result addActual(Invocation actual) {
+ int initialPosition = position;
+
+ while (position < behaviorLists.size()) {
+ Result result = behaviorLists.get(position).addActual(actual);
+ if (result != null) {
+ return result;
+ }
+ if (!behaviorLists.get(position).verify()) {
+ break;
+ }
+ position++;
+ }
+ Result stubOrNice = getStubResult(actual);
+ if (stubOrNice == null && nice) {
+ stubOrNice = Result.createReturnResult(RecordState
+ .emptyReturnValueFor(actual.getMethod().getReturnType()));
+ }
+
+ int endPosition = position;
+
+ // Do not move the cursor in case of stub, nice or error
+ position = initialPosition;
+
+ if (stubOrNice != null) {
+ actual.validateCaptures();
+ actual.clearCaptures();
+ return stubOrNice;
+ }
+
+ // Case where the loop was exited at the end of the behaviorLists
+ if (endPosition == behaviorLists.size()) {
+ endPosition--;
+ }
+
+ // Loop all around the behaviors left to generate the message
+ StringBuilder errorMessage = new StringBuilder(70 * (endPosition
+ - initialPosition + 1)); // rough approximation of the length
+ errorMessage.append("\n Unexpected method call ").append(
+ actual.toString(org.easymock.MockControl.EQUALS_MATCHER));
+
+ List<ErrorMessage> messages = new ArrayList<ErrorMessage>();
+
+ int matches = 0;
+
+ // First find how many match we have
+ for (int i = initialPosition; i <= endPosition; i++) {
+ List<ErrorMessage> thisListMessages = behaviorLists.get(i)
+ .getMessages(actual);
+ messages.addAll(thisListMessages);
+ for (ErrorMessage m : thisListMessages) {
+ if (m.isMatching()) {
+ matches++;
+ }
+ }
+ }
+
+ if (matches > 1) {
+ errorMessage
+ .append(". Possible matches are marked with (+1):");
+ } else {
+ errorMessage.append(":");
+ }
+
+ for (ErrorMessage m : messages) {
+ m.appendTo(errorMessage, matches);
+ }
+
+ // And finally throw the error
+ throw new AssertionErrorWrapper(new AssertionError(errorMessage));
+ }
+
+ public void verify() {
+ boolean verified = true;
+
+ for (UnorderedBehavior behaviorList : behaviorLists.subList(position,
+ behaviorLists.size())) {
+ if (!behaviorList.verify()) {
+ verified = false;
+ }
+ }
+ if (verified) {
+ return;
+ }
+
+ StringBuilder errorMessage = new StringBuilder(70 * (behaviorLists
+ .size()
+ - position + 1));
+
+ errorMessage.append("\n Expectation failure on verify:");
+ for (UnorderedBehavior behaviorList : behaviorLists.subList(position,
+ behaviorLists.size())) {
+ for (ErrorMessage m : behaviorList.getMessages(null)) {
+ m.appendTo(errorMessage, 0);
+ }
+ }
+
+ throw new AssertionErrorWrapper(new AssertionError(errorMessage
+ .toString()));
+ }
+
+ public void checkOrder(boolean value) {
+ this.checkOrder = value;
+ }
+
+ public void makeThreadSafe(boolean isThreadSafe) {
+ this.isThreadSafe = isThreadSafe;
+ }
+
+ public void shouldBeUsedInOneThread(boolean shouldBeUsedInOneThread) {
+ this.shouldBeUsedInOneThread = shouldBeUsedInOneThread;
+ }
+
+ public boolean isThreadSafe() {
+ return this.isThreadSafe;
+ }
+
+ public void checkThreadSafety() {
+ if (!shouldBeUsedInOneThread) {
+ return;
+ }
+ if (lastThread == null) {
+ lastThread = Thread.currentThread();
+ } else if(lastThread != Thread.currentThread()) {
+ throw new AssertionErrorWrapper(new AssertionError(
+ "\n Mock isn't supposed to be called from multiple threads. Last: "
+ + lastThread +
+ " Current: " + Thread.currentThread()));
+ }
+ }
+
+ public LegacyMatcherProvider getLegacyMatcherProvider() {
+ if (legacyMatcherProvider == null) {
+ legacyMatcherProvider = new LegacyMatcherProvider();
+ }
+ return legacyMatcherProvider;
+ }
+
+ @SuppressWarnings("deprecation")
+ public void setDefaultMatcher(org.easymock.ArgumentsMatcher matcher) {
+ getLegacyMatcherProvider().setDefaultMatcher(matcher);
+ }
+
+ @SuppressWarnings("deprecation")
+ public void setMatcher(Method method, org.easymock.ArgumentsMatcher matcher) {
+ getLegacyMatcherProvider().setMatcher(method, matcher);
+ }
+}
diff --git a/src/org/easymock/internal/MocksControl.java b/src/org/easymock/internal/MocksControl.java
new file mode 100644
index 0000000..8de3cb6
--- /dev/null
+++ b/src/org/easymock/internal/MocksControl.java
@@ -0,0 +1,315 @@
+/*
+ * Copyright 2001-2009 OFFIS, Tammo Freese
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.easymock.internal;
+
+import java.io.Serializable;
+
+import org.easymock.IAnswer;
+import org.easymock.IExpectationSetters;
+import org.easymock.IMocksControl;
+
+public class MocksControl implements IMocksControl, IExpectationSetters<Object>, Serializable {
+
+ private static final long serialVersionUID = 443604921336702014L;
+
+ private IMocksControlState state;
+
+ private IMocksBehavior behavior;
+
+ public enum MockType {
+ NICE, DEFAULT, STRICT
+ }
+
+ private MockType type;
+
+ public MocksControl(MockType type) {
+ this.type = type;
+ reset();
+ }
+
+ public IMocksControlState getState() {
+ return state;
+ }
+
+ public <T> T createMock(Class<T> toMock) {
+ try {
+ state.assertRecordState();
+ IProxyFactory<T> proxyFactory = createProxyFactory(toMock);
+ return proxyFactory.createProxy(toMock, new ObjectMethodsFilter(
+ toMock, new MockInvocationHandler(this), null));
+ } catch (RuntimeExceptionWrapper e) {
+ throw (RuntimeException) e.getRuntimeException().fillInStackTrace();
+ }
+ }
+
+ public <T> T createMock(String name, Class<T> toMock) {
+ try {
+ state.assertRecordState();
+ IProxyFactory<T> proxyFactory = createProxyFactory(toMock);
+ return proxyFactory.createProxy(toMock, new ObjectMethodsFilter(
+ toMock, new MockInvocationHandler(this), name));
+ } catch (RuntimeExceptionWrapper e) {
+ throw (RuntimeException) e.getRuntimeException().fillInStackTrace();
+ }
+ }
+
+ protected <T> IProxyFactory<T> createProxyFactory(Class<T> toMock) {
+ return new JavaProxyFactory<T>();
+ }
+
+ public final void reset() {
+ behavior = new MocksBehavior(type == MockType.NICE);
+ behavior.checkOrder(type == MockType.STRICT);
+ state = new RecordState(behavior);
+ LastControl.reportLastControl(null);
+ }
+
+ public void resetToNice() {
+ type = MockType.NICE;
+ reset();
+ }
+
+ public void resetToDefault() {
+ type = MockType.DEFAULT;
+ reset();
+ }
+
+ public void resetToStrict() {
+ type = MockType.STRICT;
+ reset();
+ }
+
+ public void replay() {
+ try {
+ state.replay();
+ state = new ReplayState(behavior);
+ LastControl.reportLastControl(null);
+ } catch (RuntimeExceptionWrapper e) {
+ throw (RuntimeException) e.getRuntimeException().fillInStackTrace();
+ }
+ }
+
+ public void verify() {
+ try {
+ state.verify();
+ } catch (RuntimeExceptionWrapper e) {
+ throw (RuntimeException) e.getRuntimeException().fillInStackTrace();
+ } catch (AssertionErrorWrapper e) {
+ throw (AssertionError) e.getAssertionError().fillInStackTrace();
+ }
+ }
+
+ public void checkOrder(boolean value) {
+ try {
+ state.checkOrder(value);
+ } catch (RuntimeExceptionWrapper e) {
+ throw (RuntimeException) e.getRuntimeException().fillInStackTrace();
+ }
+ }
+
+ public void makeThreadSafe(boolean threadSafe) {
+ try {
+ state.makeThreadSafe(threadSafe);
+ } catch (RuntimeExceptionWrapper e) {
+ throw (RuntimeException) e.getRuntimeException().fillInStackTrace();
+ }
+ }
+
+ public void checkIsUsedInOneThread(boolean shouldBeUsedInOneThread) {
+ try {
+ state.checkIsUsedInOneThread(shouldBeUsedInOneThread);
+ } catch (RuntimeExceptionWrapper e) {
+ throw (RuntimeException) e.getRuntimeException().fillInStackTrace();
+ }
+ }
+
+ // methods from IBehaviorSetters
+
+ public IExpectationSetters<Object> andReturn(Object value) {
+ try {
+ state.andReturn(value);
+ return this;
+ } catch (RuntimeExceptionWrapper e) {
+ throw (RuntimeException) e.getRuntimeException().fillInStackTrace();
+ }
+ }
+
+ public IExpectationSetters<Object> andThrow(Throwable throwable) {
+ try {
+ state.andThrow(throwable);
+ return this;
+ } catch (RuntimeExceptionWrapper e) {
+ throw (RuntimeException) e.getRuntimeException().fillInStackTrace();
+ }
+ }
+
+ public IExpectationSetters<Object> andAnswer(IAnswer<? extends Object> answer) {
+ try {
+ state.andAnswer(answer);
+ return this;
+ } catch (RuntimeExceptionWrapper e) {
+ throw (RuntimeException) e.getRuntimeException().fillInStackTrace();
+ }
+ }
+
+ public IExpectationSetters<Object> andDelegateTo(Object answer) {
+ try {
+ state.andDelegateTo(answer);
+ return this;
+ } catch (RuntimeExceptionWrapper e) {
+ throw (RuntimeException) e.getRuntimeException().fillInStackTrace();
+ }
+ }
+
+ public void andStubReturn(Object value) {
+ try {
+ state.andStubReturn(value);
+ } catch (RuntimeExceptionWrapper e) {
+ throw (RuntimeException) e.getRuntimeException().fillInStackTrace();
+ }
+ }
+
+ public void andStubThrow(Throwable throwable) {
+ try {
+ state.andStubThrow(throwable);
+ } catch (RuntimeExceptionWrapper e) {
+ throw (RuntimeException) e.getRuntimeException().fillInStackTrace();
+ }
+ }
+
+ public void andStubAnswer(IAnswer<? extends Object> answer) {
+ try {
+ state.andStubAnswer(answer);
+ } catch (RuntimeExceptionWrapper e) {
+ throw (RuntimeException) e.getRuntimeException().fillInStackTrace();
+ }
+ }
+
+
+ public void andStubDelegateTo(Object delegateTo) {
+ try {
+ state.andStubDelegateTo(delegateTo);
+ } catch (RuntimeExceptionWrapper e) {
+ throw (RuntimeException) e.getRuntimeException().fillInStackTrace();
+ }
+ }
+
+ public void asStub() {
+ try {
+ state.asStub();
+ } catch (RuntimeExceptionWrapper e) {
+ throw (RuntimeException) e.getRuntimeException().fillInStackTrace();
+ }
+ }
+
+ public IExpectationSetters<Object> times(int times) {
+ try {
+ state.times(new Range(times));
+ return this;
+ } catch (RuntimeExceptionWrapper e) {
+ throw (RuntimeException) e.getRuntimeException().fillInStackTrace();
+ }
+ }
+
+ public IExpectationSetters<Object> times(int min, int max) {
+ try {
+ state.times(new Range(min, max));
+ return this;
+ } catch (RuntimeExceptionWrapper e) {
+ throw (RuntimeException) e.getRuntimeException().fillInStackTrace();
+ }
+ }
+
+ public IExpectationSetters<Object> once() {
+ try {
+ state.times(ONCE);
+ return this;
+ } catch (RuntimeExceptionWrapper e) {
+ throw (RuntimeException) e.getRuntimeException().fillInStackTrace();
+ }
+ }
+
+ public IExpectationSetters<Object> atLeastOnce() {
+ try {
+ state.times(AT_LEAST_ONCE);
+ return this;
+ } catch (RuntimeExceptionWrapper e) {
+ throw (RuntimeException) e.getRuntimeException().fillInStackTrace();
+ }
+ }
+
+ public IExpectationSetters<Object> anyTimes() {
+ try {
+ state.times(ZERO_OR_MORE);
+ return this;
+ } catch (RuntimeExceptionWrapper e) {
+ throw (RuntimeException) e.getRuntimeException().fillInStackTrace();
+ }
+ }
+
+ /**
+ * Exactly one call.
+ */
+ public static final Range ONCE = new Range(1);
+
+ /**
+ * One or more calls.
+ */
+ public static final Range AT_LEAST_ONCE = new Range(1, Integer.MAX_VALUE);
+
+ /**
+ * Zero or more calls.
+ */
+ public static final Range ZERO_OR_MORE = new Range(0, Integer.MAX_VALUE);
+
+ @SuppressWarnings("deprecation")
+ public void setLegacyDefaultMatcher(org.easymock.ArgumentsMatcher matcher) {
+ try {
+ state.setDefaultMatcher(matcher);
+ } catch (RuntimeExceptionWrapper e) {
+ throw (RuntimeException) e.getRuntimeException().fillInStackTrace();
+ }
+ }
+
+ @SuppressWarnings("deprecation")
+ public void setLegacyMatcher(org.easymock.ArgumentsMatcher matcher) {
+ try {
+ state.setMatcher(null, matcher);
+ } catch (RuntimeExceptionWrapper e) {
+ throw (RuntimeException) e.getRuntimeException().fillInStackTrace();
+ }
+ }
+
+ public void setLegacyDefaultReturnValue(Object value) {
+ try {
+ state.setDefaultReturnValue(value);
+ } catch (RuntimeExceptionWrapper e) {
+ throw (RuntimeException) e.getRuntimeException().fillInStackTrace();
+ }
+ }
+
+ public void setLegacyDefaultVoidCallable() {
+ state.setDefaultVoidCallable();
+ }
+
+ public void setLegacyDefaultThrowable(Throwable throwable) {
+ try {
+ state.setDefaultThrowable(throwable);
+ } catch (RuntimeExceptionWrapper e) {
+ throw (RuntimeException) e.getRuntimeException().fillInStackTrace();
+ }
+ }
+}
diff --git a/src/org/easymock/internal/ObjectMethodsFilter.java b/src/org/easymock/internal/ObjectMethodsFilter.java
new file mode 100644
index 0000000..a562540
--- /dev/null
+++ b/src/org/easymock/internal/ObjectMethodsFilter.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright 2001-2009 OFFIS, Tammo Freese
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.easymock.internal;
+
+import java.io.IOException;
+import java.io.Serializable;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+
+public class ObjectMethodsFilter implements InvocationHandler, Serializable {
+
+ private static final long serialVersionUID = -2120581954279966998L;
+
+ private transient Method equalsMethod;
+
+ private transient Method hashCodeMethod;
+
+ private transient Method toStringMethod;
+
+ private final MockInvocationHandler delegate;
+
+ private final String name;
+
+ public ObjectMethodsFilter(Class<?> toMock, MockInvocationHandler delegate,
+ String name) {
+ if (name != null && !Invocation.isJavaIdentifier(name)) {
+ throw new IllegalArgumentException(String.format("'%s' is not a valid Java identifier.", name));
+
+ }
+ try {
+ if (toMock.isInterface()) {
+ toMock = Object.class;
+ }
+ equalsMethod = toMock.getMethod("equals",
+ new Class[] { Object.class });
+ hashCodeMethod = toMock.getMethod("hashCode", (Class[]) null);
+ toStringMethod = toMock.getMethod("toString", (Class[]) null);
+ } catch (NoSuchMethodException e) {
+ // ///CLOVER:OFF
+ throw new RuntimeException("An Object method could not be found!");
+ // ///CLOVER:ON
+ }
+ this.delegate = delegate;
+ this.name = name;
+ }
+
+ public final Object invoke(Object proxy, Method method, Object[] args)
+ throws Throwable {
+ if (equalsMethod.equals(method)) {
+ return Boolean.valueOf(proxy == args[0]);
+ }
+ if (hashCodeMethod.equals(method)) {
+ return Integer.valueOf(System.identityHashCode(proxy));
+ }
+ if (toStringMethod.equals(method)) {
+ return mockToString(proxy);
+ }
+ return delegate.invoke(proxy, method, args);
+ }
+
+ private String mockToString(Object proxy) {
+ return (name != null) ? name : "EasyMock for " + mockType(proxy);
+ }
+
+ private String mockType(Object proxy) {
+ if (Proxy.isProxyClass(proxy.getClass()))
+ return proxy.getClass().getInterfaces()[0].toString();
+ else
+ return proxy.getClass().getSuperclass().toString();
+ }
+
+ public MockInvocationHandler getDelegate() {
+ return delegate;
+ }
+
+ private void readObject(java.io.ObjectInputStream stream) throws IOException, ClassNotFoundException {
+ stream.defaultReadObject();
+ try {
+ toStringMethod = ((MethodSerializationWrapper) stream.readObject()).getMethod();
+ equalsMethod = ((MethodSerializationWrapper) stream.readObject()).getMethod();
+ hashCodeMethod = ((MethodSerializationWrapper) stream.readObject()).getMethod();
+ } catch (NoSuchMethodException e) {
+ // ///CLOVER:OFF
+ throw new IOException(e.toString());
+ // ///CLOVER:ON
+ }
+ }
+
+ private void writeObject(java.io.ObjectOutputStream stream) throws IOException {
+ stream.defaultWriteObject();
+ stream.writeObject(new MethodSerializationWrapper(toStringMethod));
+ stream.writeObject(new MethodSerializationWrapper(equalsMethod));
+ stream.writeObject(new MethodSerializationWrapper(hashCodeMethod));
+ }
+} \ No newline at end of file
diff --git a/src/org/easymock/internal/Range.java b/src/org/easymock/internal/Range.java
new file mode 100644
index 0000000..bd9dd96
--- /dev/null
+++ b/src/org/easymock/internal/Range.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2001-2009 OFFIS, Tammo Freese
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.easymock.internal;
+
+import java.io.Serializable;
+
+public class Range implements Serializable {
+
+ private static final long serialVersionUID = -6743402320315331536L;
+
+ private final int minimum;
+
+ private final int maximum;
+
+ public Range(int count) {
+ this(count, count);
+ }
+
+ public Range(int minimum, int maximum) {
+ if (!(minimum <= maximum)) {
+ throw new RuntimeExceptionWrapper(new IllegalArgumentException(
+ "minimum must be <= maximum"));
+ }
+
+ if (!(minimum >= 0)) {
+ throw new RuntimeExceptionWrapper(new IllegalArgumentException(
+ "minimum must be >= 0"));
+ }
+
+ if (!(maximum >= 1)) {
+ throw new RuntimeExceptionWrapper(new IllegalArgumentException(
+ "maximum must be >= 1"));
+ }
+ this.minimum = minimum;
+ this.maximum = maximum;
+ }
+
+ public boolean hasFixedCount() {
+ return minimum == maximum;
+ }
+
+ public int getMaximum() {
+ return maximum;
+ }
+
+ public int getMinimum() {
+ return minimum;
+ }
+
+ @Override
+ public String toString() {
+ if (hasFixedCount()) {
+ return "" + minimum;
+ } else if (hasOpenCount()) {
+ return "at least " + minimum;
+ } else {
+ return "between " + minimum + " and " + maximum;
+ }
+ }
+
+ public String expectedCount() {
+ return "expected: " + this.toString();
+ }
+
+ public boolean contains(int count) {
+ return minimum <= count && count <= maximum;
+ }
+
+ public boolean hasOpenCount() {
+ return maximum == Integer.MAX_VALUE;
+ }
+}
diff --git a/src/org/easymock/internal/RecordState.java b/src/org/easymock/internal/RecordState.java
new file mode 100644
index 0000000..433b40e
--- /dev/null
+++ b/src/org/easymock/internal/RecordState.java
@@ -0,0 +1,389 @@
+/*
+ * Copyright 2001-2009 OFFIS, Tammo Freese
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.easymock.internal;
+
+import java.io.Serializable;
+import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.easymock.IAnswer;
+import org.easymock.IArgumentMatcher;
+
+public class RecordState implements IMocksControlState, Serializable {
+
+ private static final long serialVersionUID = -5418279681566430252L;
+
+ private ExpectedInvocation lastInvocation = null;
+
+ private boolean lastInvocationUsed = true;
+
+ private Result lastResult;
+
+ private final IMocksBehavior behavior;
+
+ private static Map<Class<?>, Object> emptyReturnValues = new HashMap<Class<?>, Object>();
+
+ static {
+ emptyReturnValues.put(Void.TYPE, null);
+ emptyReturnValues.put(Boolean.TYPE, Boolean.FALSE);
+ emptyReturnValues.put(Byte.TYPE, Byte.valueOf((byte) 0));
+ emptyReturnValues.put(Short.TYPE, Short.valueOf((short) 0));
+ emptyReturnValues.put(Character.TYPE, Character.valueOf((char)0));
+ emptyReturnValues.put(Integer.TYPE, Integer.valueOf(0));
+ emptyReturnValues.put(Long.TYPE, Long.valueOf(0));
+ emptyReturnValues.put(Float.TYPE, Float.valueOf(0));
+ emptyReturnValues.put(Double.TYPE, Double.valueOf(0));
+ }
+
+ private static Map<Class<?>, Class<?>> primitiveToWrapperType = new HashMap<Class<?>, Class<?>>();
+
+ static {
+ primitiveToWrapperType.put(Boolean.TYPE, Boolean.class);
+ primitiveToWrapperType.put(Byte.TYPE, Byte.class);
+ primitiveToWrapperType.put(Short.TYPE, Short.class);
+ primitiveToWrapperType.put(Character.TYPE, Character.class);
+ primitiveToWrapperType.put(Integer.TYPE, Integer.class);
+ primitiveToWrapperType.put(Long.TYPE, Long.class);
+ primitiveToWrapperType.put(Float.TYPE, Float.class);
+ primitiveToWrapperType.put(Double.TYPE, Double.class);
+ }
+
+ public RecordState(IMocksBehavior behavior) {
+ this.behavior = behavior;
+ }
+
+ public void assertRecordState() {
+ }
+
+ public java.lang.Object invoke(Invocation invocation) {
+ closeMethod();
+ List<IArgumentMatcher> lastMatchers = LastControl.pullMatchers();
+ lastInvocation = new ExpectedInvocation(invocation, lastMatchers);
+ lastInvocationUsed = false;
+ return emptyReturnValueFor(invocation.getMethod().getReturnType());
+ }
+
+ public void replay() {
+ closeMethod();
+ if (LastControl.pullMatchers() != null) {
+ throw new IllegalStateException("matcher calls were used outside expectations");
+ }
+ }
+
+ public void verify() {
+ throw new RuntimeExceptionWrapper(new IllegalStateException(
+ "calling verify is not allowed in record state"));
+ }
+
+ public void andReturn(Object value) {
+ requireMethodCall("return value");
+ value = convertNumberClassIfNeccessary(value);
+ requireAssignable(value);
+ if (lastResult != null) {
+ times(MocksControl.ONCE);
+ }
+ lastResult = Result.createReturnResult(value);
+ }
+
+ public void andThrow(Throwable throwable) {
+ requireMethodCall("Throwable");
+ requireValidThrowable(throwable);
+ if (lastResult != null) {
+ times(MocksControl.ONCE);
+ }
+ lastResult = Result.createThrowResult(throwable);
+ }
+
+ public void andAnswer(IAnswer<?> answer) {
+ requireMethodCall("answer");
+ requireValidAnswer(answer);
+ if (lastResult != null) {
+ times(MocksControl.ONCE);
+ }
+ lastResult = Result.createAnswerResult(answer);
+ }
+
+ public void andDelegateTo(Object delegateTo) {
+ requireMethodCall("delegate");
+ requireValidDelegation(delegateTo);
+ if (lastResult != null) {
+ times(MocksControl.ONCE);
+ }
+ lastResult = Result.createDelegatingResult(delegateTo);
+ }
+
+ public void andStubReturn(Object value) {
+ requireMethodCall("stub return value");
+ value = convertNumberClassIfNeccessary(value);
+ requireAssignable(value);
+ if (lastResult != null) {
+ times(MocksControl.ONCE);
+ }
+ behavior.addStub(lastInvocation, Result.createReturnResult(value));
+ lastInvocationUsed = true;
+ }
+
+ @SuppressWarnings("deprecation")
+ public void setDefaultReturnValue(Object value) {
+ requireMethodCall("default return value");
+ value = convertNumberClassIfNeccessary(value);
+ requireAssignable(value);
+ if (lastResult != null) {
+ times(MocksControl.ONCE);
+ }
+ behavior.addStub(
+ lastInvocation.withMatcher(org.easymock.MockControl.ALWAYS_MATCHER), Result
+ .createReturnResult(value));
+ lastInvocationUsed = true;
+ }
+
+ public void asStub() {
+ requireMethodCall("stub behavior");
+ requireVoidMethod();
+ behavior.addStub(lastInvocation, Result.createReturnResult(null));
+ lastInvocationUsed = true;
+ }
+
+ @SuppressWarnings("deprecation")
+ public void setDefaultVoidCallable() {
+ requireMethodCall("default void callable");
+ requireVoidMethod();
+ behavior.addStub(
+ lastInvocation.withMatcher(org.easymock.MockControl.ALWAYS_MATCHER), Result
+ .createReturnResult(null));
+ lastInvocationUsed = true;
+ }
+
+ public void andStubThrow(Throwable throwable) {
+ requireMethodCall("stub Throwable");
+ requireValidThrowable(throwable);
+ if (lastResult != null) {
+ times(MocksControl.ONCE);
+ }
+ behavior.addStub(lastInvocation, Result.createThrowResult(throwable));
+ lastInvocationUsed = true;
+ }
+
+ @SuppressWarnings("deprecation")
+ public void setDefaultThrowable(Throwable throwable) {
+ requireMethodCall("default Throwable");
+ requireValidThrowable(throwable);
+ if (lastResult != null) {
+ times(MocksControl.ONCE);
+ }
+ behavior.addStub(
+ lastInvocation.withMatcher(org.easymock.MockControl.ALWAYS_MATCHER), Result
+ .createThrowResult(throwable));
+ lastInvocationUsed = true;
+ }
+
+ public void andStubAnswer(IAnswer<?> answer) {
+ requireMethodCall("stub answer");
+ requireValidAnswer(answer);
+ if (lastResult != null) {
+ times(MocksControl.ONCE);
+ }
+ behavior.addStub(lastInvocation, Result.createAnswerResult(answer));
+ lastInvocationUsed = true;
+ }
+
+ public void andStubDelegateTo(Object delegateTo) {
+ requireMethodCall("stub delegate");
+ requireValidDelegation(delegateTo);
+ if (lastResult != null) {
+ times(MocksControl.ONCE);
+ }
+ behavior.addStub(lastInvocation, Result
+ .createDelegatingResult(delegateTo));
+ lastInvocationUsed = true;
+ }
+
+ public void times(Range range) {
+ requireMethodCall("times");
+ requireLastResultOrVoidMethod();
+
+ behavior.addExpected(lastInvocation, lastResult != null ? lastResult
+ : Result.createReturnResult(null), range);
+ lastInvocationUsed = true;
+ lastResult = null;
+ }
+
+ private Object createNumberObject(Object value, Class<?> returnType) {
+ if (!(value instanceof Number)) {
+ return value;
+ }
+ Number number = (Number) value;
+ if (returnType.equals(Byte.TYPE)) {
+ return number.byteValue();
+ } else if (returnType.equals(Short.TYPE)) {
+ return number.shortValue();
+ } else if (returnType.equals(Character.TYPE)) {
+ return (char) number.intValue();
+ } else if (returnType.equals(Integer.TYPE)) {
+ return number.intValue();
+ } else if (returnType.equals(Long.TYPE)) {
+ return number.longValue();
+ } else if (returnType.equals(Float.TYPE)) {
+ return number.floatValue();
+ } else if (returnType.equals(Double.TYPE)) {
+ return number.doubleValue();
+ } else {
+ return number;
+ }
+ }
+
+ private Object convertNumberClassIfNeccessary(Object o) {
+ Class<?> returnType = lastInvocation.getMethod().getReturnType();
+ return createNumberObject(o, returnType);
+ }
+
+ @SuppressWarnings("deprecation")
+ private void closeMethod() {
+ if (lastInvocationUsed && lastResult == null) {
+ return;
+ }
+ if (!isLastResultOrVoidMethod()) {
+ throw new RuntimeExceptionWrapper(new IllegalStateException(
+ "missing behavior definition for the preceding method call "
+ + lastInvocation.toString()));
+ }
+ this.times(org.easymock.MockControl.ONE);
+ }
+
+ public static Object emptyReturnValueFor(Class<?> type) {
+ return type.isPrimitive() ? emptyReturnValues.get(type) : null;
+ }
+
+ private void requireMethodCall(String failMessage) {
+ if (lastInvocation == null) {
+ throw new RuntimeExceptionWrapper(new IllegalStateException(
+ "method call on the mock needed before setting "
+ + failMessage));
+ }
+ }
+
+ private void requireAssignable(Object returnValue) {
+ if (lastMethodIsVoidMethod()) {
+ throw new RuntimeExceptionWrapper(new IllegalStateException(
+ "void method cannot return a value"));
+ }
+ if (returnValue == null) {
+ return;
+ }
+ Class<?> returnedType = lastInvocation.getMethod().getReturnType();
+ if (returnedType.isPrimitive()) {
+ returnedType = primitiveToWrapperType.get(returnedType);
+
+ }
+ if (!returnedType.isAssignableFrom(returnValue.getClass())) {
+ throw new RuntimeExceptionWrapper(new IllegalStateException(
+ "incompatible return value type"));
+ }
+ }
+
+ private void requireValidThrowable(Throwable throwable) {
+ if (throwable == null)
+ throw new RuntimeExceptionWrapper(new NullPointerException(
+ "null cannot be thrown"));
+ if (isValidThrowable(throwable))
+ return;
+
+ throw new RuntimeExceptionWrapper(new IllegalArgumentException(
+ "last method called on mock cannot throw "
+ + throwable.getClass().getName()));
+ }
+
+ private void requireValidAnswer(IAnswer<?> answer) {
+ if (answer == null)
+ throw new RuntimeExceptionWrapper(new NullPointerException(
+ "answer object must not be null"));
+ }
+
+ private void requireValidDelegation(Object delegateTo) {
+ if (delegateTo == null)
+ throw new RuntimeExceptionWrapper(new NullPointerException(
+ "delegated to object must not be null"));
+ // Would be nice to validate delegateTo is implementing the mock
+ // interface (not possible right now)
+ }
+
+ private void requireLastResultOrVoidMethod() {
+ if (isLastResultOrVoidMethod()) {
+ return;
+ }
+ throw new RuntimeExceptionWrapper(new IllegalStateException(
+ "last method called on mock is not a void method"));
+ }
+
+ private void requireVoidMethod() {
+ if (lastMethodIsVoidMethod()) {
+ return;
+ }
+ throw new RuntimeExceptionWrapper(new IllegalStateException(
+ "last method called on mock is not a void method"));
+ }
+
+ private boolean isLastResultOrVoidMethod() {
+ return lastResult != null || lastMethodIsVoidMethod();
+ }
+
+ private boolean lastMethodIsVoidMethod() {
+ Class<?> returnType = lastInvocation.getMethod().getReturnType();
+ return returnType.equals(Void.TYPE);
+ }
+
+ private boolean isValidThrowable(Throwable throwable) {
+ if (throwable instanceof RuntimeException) {
+ return true;
+ }
+ if (throwable instanceof Error) {
+ return true;
+ }
+ Class<?>[] exceptions = lastInvocation.getMethod().getExceptionTypes();
+ Class<?> throwableClass = throwable.getClass();
+ for (Class<?> exception : exceptions) {
+ if (exception.isAssignableFrom(throwableClass))
+ return true;
+ }
+ return false;
+ }
+
+ public void checkOrder(boolean value) {
+ closeMethod();
+ behavior.checkOrder(value);
+ }
+
+ public void makeThreadSafe(boolean threadSafe) {
+ behavior.makeThreadSafe(threadSafe);
+ }
+
+ public void checkIsUsedInOneThread(boolean shouldBeUsedInOneThread) {
+ behavior.shouldBeUsedInOneThread(shouldBeUsedInOneThread);
+ }
+
+ @SuppressWarnings("deprecation")
+ public void setDefaultMatcher(org.easymock.ArgumentsMatcher matcher) {
+ behavior.setDefaultMatcher(matcher);
+ }
+
+ @SuppressWarnings("deprecation")
+ public void setMatcher(Method method, org.easymock.ArgumentsMatcher matcher) {
+ requireMethodCall("matcher");
+ behavior.setMatcher(lastInvocation.getMethod(), matcher);
+ }
+} \ No newline at end of file
diff --git a/src/org/easymock/internal/ReplayState.java b/src/org/easymock/internal/ReplayState.java
new file mode 100644
index 0000000..c0462e2
--- /dev/null
+++ b/src/org/easymock/internal/ReplayState.java
@@ -0,0 +1,165 @@
+/*
+ * Copyright 2001-2009 OFFIS, Tammo Freese
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.easymock.internal;
+
+import java.io.Serializable;
+import java.lang.reflect.Method;
+import java.util.concurrent.locks.ReentrantLock;
+
+import org.easymock.IAnswer;
+
+public class ReplayState implements IMocksControlState, Serializable {
+
+ private static final long serialVersionUID = 6314142602251047572L;
+
+ private final IMocksBehavior behavior;
+
+ private final ReentrantLock lock = new ReentrantLock();
+
+ public ReplayState(IMocksBehavior behavior) {
+ this.behavior = behavior;
+ }
+
+ public Object invoke(Invocation invocation) throws Throwable {
+
+ behavior.checkThreadSafety();
+
+ if (behavior.isThreadSafe()) {
+ // If thread safe, synchronize the mock
+ lock.lock();
+ try {
+ return invokeInner(invocation);
+ }
+ finally {
+ lock.unlock();
+ }
+ }
+
+ return invokeInner(invocation);
+ }
+
+ private Object invokeInner(Invocation invocation) throws Throwable {
+ LastControl.pushCurrentInvocation(invocation);
+ try {
+ Result result = behavior.addActual(invocation);
+ try {
+ return result.answer();
+ } catch (Throwable t) {
+ if (result.shouldFillInStackTrace()) {
+ throw new ThrowableWrapper(t);
+ }
+ throw t;
+ }
+ } finally {
+ LastControl.popCurrentInvocation();
+ }
+ }
+
+ public void verify() {
+ behavior.verify();
+ }
+
+ public void replay() {
+ throwWrappedIllegalStateException();
+ }
+
+ public void callback(Runnable runnable) {
+ throwWrappedIllegalStateException();
+ }
+
+ public void checkOrder(boolean value) {
+ throwWrappedIllegalStateException();
+ }
+
+ public void makeThreadSafe(boolean threadSafe) {
+ throwWrappedIllegalStateException();
+ }
+
+ public void checkIsUsedInOneThread(boolean shouldBeUsedInOneThread) {
+ throwWrappedIllegalStateException();
+ }
+
+ public void andReturn(Object value) {
+ throwWrappedIllegalStateException();
+ }
+
+ public void andThrow(Throwable throwable) {
+ throwWrappedIllegalStateException();
+ }
+
+ public void andAnswer(IAnswer<?> answer) {
+ throwWrappedIllegalStateException();
+ }
+
+ public void andDelegateTo(Object answer) {
+ throwWrappedIllegalStateException();
+ }
+
+ public void andStubReturn(Object value) {
+ throwWrappedIllegalStateException();
+ }
+
+ public void andStubThrow(Throwable throwable) {
+ throwWrappedIllegalStateException();
+ }
+
+ public void andStubAnswer(IAnswer<?> answer) {
+ throwWrappedIllegalStateException();
+ }
+
+ public void andStubDelegateTo(Object delegateTo) {
+ throwWrappedIllegalStateException();
+ }
+
+ public void asStub() {
+ throwWrappedIllegalStateException();
+ }
+
+ public void times(Range range) {
+ throwWrappedIllegalStateException();
+ }
+
+ @SuppressWarnings("deprecation")
+ public void setMatcher(Method method, org.easymock.ArgumentsMatcher matcher) {
+ throwWrappedIllegalStateException();
+ }
+
+ @SuppressWarnings("deprecation")
+ public void setDefaultMatcher(org.easymock.ArgumentsMatcher matcher) {
+ throwWrappedIllegalStateException();
+ }
+
+ public void setDefaultReturnValue(Object value) {
+ throwWrappedIllegalStateException();
+ }
+
+ public void setDefaultThrowable(Throwable throwable) {
+ throwWrappedIllegalStateException();
+ }
+
+ public void setDefaultVoidCallable() {
+ throwWrappedIllegalStateException();
+ }
+
+ private void throwWrappedIllegalStateException() {
+ throw new RuntimeExceptionWrapper(new IllegalStateException(
+ "This method must not be called in replay state."));
+ }
+
+ public void assertRecordState() {
+ throwWrappedIllegalStateException();
+ }
+}
diff --git a/src/org/easymock/internal/Result.java b/src/org/easymock/internal/Result.java
new file mode 100644
index 0000000..9ad26b4
--- /dev/null
+++ b/src/org/easymock/internal/Result.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright 2001-2009 OFFIS, Tammo Freese
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.easymock.internal;
+
+import java.io.Serializable;
+import java.lang.reflect.InvocationTargetException;
+
+import org.easymock.IAnswer;
+
+public class Result implements IAnswer<Object>, Serializable {
+
+ private static final long serialVersionUID = 5476251941213917681L;
+
+ private final IAnswer<?> value;
+
+ private final boolean shouldFillInStackTrace;
+
+ private Result(IAnswer<?> value, boolean shouldFillInStackTrace) {
+ this.value = value;
+ this.shouldFillInStackTrace = shouldFillInStackTrace;
+ }
+
+ public static Result createThrowResult(final Throwable throwable) {
+ class ThrowingAnswer implements IAnswer<Object>, Serializable {
+
+ private static final long serialVersionUID = -332797751209289222L;
+
+ public Object answer() throws Throwable {
+ throw throwable;
+ }
+
+ @Override
+ public String toString() {
+ return "Answer throwing " + throwable;
+ }
+ }
+ return new Result(new ThrowingAnswer(), true);
+ }
+
+ public static Result createReturnResult(final Object value) {
+ class ReturningAnswer implements IAnswer<Object>, Serializable {
+
+ private static final long serialVersionUID = 6973893913593916866L;
+
+ public Object answer() throws Throwable {
+ return value;
+ }
+
+ @Override
+ public String toString() {
+ return "Answer returning " + value;
+ }
+ }
+ return new Result(new ReturningAnswer(), true);
+ }
+
+ public static Result createDelegatingResult(final Object value) {
+ class DelegatingAnswer implements IAnswer<Object>, Serializable {
+
+ private static final long serialVersionUID = -5699326678580460103L;
+
+ public Object answer() throws Throwable {
+ Invocation invocation = LastControl.getCurrentInvocation();
+ try {
+ return invocation.getMethod().invoke(value,
+ invocation.getArguments());
+ } catch (IllegalArgumentException e) {
+ throw new IllegalArgumentException("Delegation to object ["
+ + String.valueOf(value)
+ + "] is not implementing the mocked method ["
+ + invocation.getMethod() + "]", e);
+ } catch (InvocationTargetException e) {
+ throw e.getCause();
+ }
+ }
+
+ @Override
+ public String toString() {
+ return "Delegated to " + value;
+ }
+ }
+ return new Result(new DelegatingAnswer(), false);
+ }
+
+ public static Result createAnswerResult(IAnswer<?> answer) {
+ return new Result(answer, false);
+ }
+
+ public Object answer() throws Throwable {
+ return value.answer();
+ }
+
+ public boolean shouldFillInStackTrace() {
+ return shouldFillInStackTrace;
+ }
+
+ @Override
+ public String toString() {
+ return value.toString();
+ }
+}
diff --git a/src/org/easymock/internal/Results.java b/src/org/easymock/internal/Results.java
new file mode 100644
index 0000000..2f83769
--- /dev/null
+++ b/src/org/easymock/internal/Results.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2001-2009 OFFIS, Tammo Freese
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.easymock.internal;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+
+public class Results implements Serializable {
+
+ private static final long serialVersionUID = -2722051869610289637L;
+
+ private int callCount;
+
+ private final LinkedList<Range> ranges = new LinkedList<Range>();
+
+ private final List<Result> results = new ArrayList<Result>();
+
+ public void add(Result result, Range range) {
+ if (!ranges.isEmpty()) {
+ Range lastRange = ranges.getLast();
+ if (!lastRange.hasFixedCount())
+ throw new RuntimeExceptionWrapper(
+ new IllegalStateException(
+ "last method called on mock already has a non-fixed count set."));
+ }
+ ranges.add(range);
+ results.add(result);
+ }
+
+ public Result next() {
+ int currentPosition = 0;
+ for (int i = 0; i < ranges.size(); i++) {
+ Range interval = ranges.get(i);
+ if (interval.hasOpenCount()) {
+ callCount += 1;
+ return results.get(i);
+ }
+ currentPosition += interval.getMaximum();
+ if (currentPosition > callCount) {
+ callCount += 1;
+ return results.get(i);
+ }
+ }
+ return null;
+ }
+
+ public boolean hasValidCallCount() {
+ return getMainInterval().contains(getCallCount());
+ }
+
+ @Override
+ public String toString() {
+ return getMainInterval().expectedCount();
+ }
+
+ private Range getMainInterval() {
+ int min = 0, max = 0;
+
+ for (Range interval : ranges) {
+ min += interval.getMinimum();
+ if (interval.hasOpenCount() || max == Integer.MAX_VALUE) {
+ max = Integer.MAX_VALUE;
+ } else {
+ max += interval.getMaximum();
+ }
+ }
+
+ return new Range(min, max);
+ }
+
+ public int getCallCount() {
+ return callCount;
+ }
+}
diff --git a/src/org/easymock/internal/RuntimeExceptionWrapper.java b/src/org/easymock/internal/RuntimeExceptionWrapper.java
new file mode 100644
index 0000000..8c0e48a
--- /dev/null
+++ b/src/org/easymock/internal/RuntimeExceptionWrapper.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2001-2009 OFFIS, Tammo Freese
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.easymock.internal;
+
+public class RuntimeExceptionWrapper extends RuntimeException {
+
+ private static final long serialVersionUID = -3483500330975410177L;
+
+ private final RuntimeException runtimeException;
+
+ public RuntimeExceptionWrapper(final RuntimeException runtimeException) {
+ this.runtimeException = runtimeException;
+ }
+
+ public RuntimeException getRuntimeException() {
+ return runtimeException;
+ }
+}
diff --git a/src/org/easymock/internal/ThrowableWrapper.java b/src/org/easymock/internal/ThrowableWrapper.java
new file mode 100644
index 0000000..7bf1555
--- /dev/null
+++ b/src/org/easymock/internal/ThrowableWrapper.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2001-2009 OFFIS, Tammo Freese
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.easymock.internal;
+
+public class ThrowableWrapper extends Throwable {
+
+ private static final long serialVersionUID = -4434322855124959723L;
+
+ private final Throwable throwable;
+
+ public ThrowableWrapper(final Throwable throwable) {
+ this.throwable = throwable;
+ }
+
+ public Throwable getThrowable() {
+ return throwable;
+ }
+}
diff --git a/src/org/easymock/internal/UnorderedBehavior.java b/src/org/easymock/internal/UnorderedBehavior.java
new file mode 100644
index 0000000..39695ef
--- /dev/null
+++ b/src/org/easymock/internal/UnorderedBehavior.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright 2001-2009 OFFIS, Tammo Freese
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.easymock.internal;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+public class UnorderedBehavior implements Serializable {
+
+ private static final long serialVersionUID = 2185791334636597469L;
+
+ private final List<ExpectedInvocationAndResults> results = new ArrayList<ExpectedInvocationAndResults>();
+
+ private final boolean checkOrder;
+
+ public UnorderedBehavior(boolean checkOrder) {
+ this.checkOrder = checkOrder;
+ }
+
+ public void addExpected(ExpectedInvocation expected, Result result,
+ Range count) {
+ for (ExpectedInvocationAndResults entry : results) {
+ if (entry.getExpectedInvocation().equals(expected)) {
+ entry.getResults().add(result, count);
+ return;
+ }
+ }
+ Results list = new Results();
+ list.add(result, count);
+ results.add(new ExpectedInvocationAndResults(expected, list));
+ }
+
+ public Result addActual(Invocation actual) {
+ for (ExpectedInvocationAndResults entry : results) {
+ try {
+ if (!entry.getExpectedInvocation().matches(actual)) {
+ continue;
+ }
+ Result result = entry.getResults().next();
+ if (result != null) {
+ // actual and expected matched, validate the capture
+ actual.validateCaptures();
+ return result;
+ }
+ }
+ finally {
+ // reset the capture (already validated or expected didn't
+ // matched)
+ actual.clearCaptures();
+ }
+ }
+ return null;
+ }
+
+ public boolean verify() {
+ for (ExpectedInvocationAndResults entry : results) {
+ if (!entry.getResults().hasValidCallCount()) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public List<ErrorMessage> getMessages(Invocation invocation) {
+ List<ErrorMessage> messages = new ArrayList<ErrorMessage>(results
+ .size());
+ for (ExpectedInvocationAndResults entry : results) {
+ boolean unordered = !checkOrder;
+ boolean validCallCount = entry.getResults().hasValidCallCount();
+ boolean match = invocation != null
+ && entry.getExpectedInvocation().matches(invocation);
+
+ if (unordered && validCallCount && !match) {
+ continue;
+ }
+
+ ErrorMessage message = new ErrorMessage(match, entry.toString(),
+ entry.getResults()
+ .getCallCount());
+ messages.add(message);
+ }
+ return messages;
+
+ }
+
+ public boolean allowsExpectedInvocation(ExpectedInvocation expected,
+ boolean checkOrder) {
+ if (this.checkOrder != checkOrder) {
+ return false;
+ } else if (results.isEmpty() || !this.checkOrder) {
+ return true;
+ } else {
+ ExpectedInvocation lastMethodCall = results.get(results.size() - 1)
+ .getExpectedInvocation();
+ return lastMethodCall.equals(expected);
+ }
+ }
+
+} \ No newline at end of file
diff --git a/src/org/easymock/internal/matchers/And.java b/src/org/easymock/internal/matchers/And.java
new file mode 100644
index 0000000..555ffe5
--- /dev/null
+++ b/src/org/easymock/internal/matchers/And.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2001-2009 OFFIS, Tammo Freese
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.easymock.internal.matchers;
+
+import java.io.Serializable;
+import java.util.Iterator;
+import java.util.List;
+
+import org.easymock.IArgumentMatcher;
+
+public class And implements IArgumentMatcher, Serializable {
+
+ private static final long serialVersionUID = 3874580646798403818L;
+
+ private final List<IArgumentMatcher> matchers;
+
+ public And(List<IArgumentMatcher> matchers) {
+ this.matchers = matchers;
+ }
+
+ public boolean matches(Object actual) {
+ for (IArgumentMatcher matcher : matchers) {
+ if (!matcher.matches(actual)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public void appendTo(StringBuffer buffer) {
+ buffer.append("and(");
+ for (Iterator<IArgumentMatcher> it = matchers.iterator(); it.hasNext();) {
+ it.next().appendTo(buffer);
+ if (it.hasNext()) {
+ buffer.append(", ");
+ }
+ }
+ buffer.append(")");
+ }
+}
diff --git a/src/org/easymock/internal/matchers/Any.java b/src/org/easymock/internal/matchers/Any.java
new file mode 100644
index 0000000..8fcf57c
--- /dev/null
+++ b/src/org/easymock/internal/matchers/Any.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2001-2009 OFFIS, Tammo Freese
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.easymock.internal.matchers;
+
+import java.io.Serializable;
+
+import org.easymock.IArgumentMatcher;
+
+public class Any implements IArgumentMatcher, Serializable {
+
+ private static final long serialVersionUID = -3743894206806704049L;
+
+ public static final Any ANY = new Any();
+
+ private Any() {
+
+ }
+
+ public boolean matches(Object actual) {
+ return true;
+ }
+
+ public void appendTo(StringBuffer buffer) {
+ buffer.append("<any>");
+ }
+}
diff --git a/src/org/easymock/internal/matchers/ArrayEquals.java b/src/org/easymock/internal/matchers/ArrayEquals.java
new file mode 100644
index 0000000..9ead937
--- /dev/null
+++ b/src/org/easymock/internal/matchers/ArrayEquals.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2001-2009 OFFIS, Tammo Freese
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.easymock.internal.matchers;
+
+import java.util.Arrays;
+
+import org.easymock.internal.ArgumentToString;
+
+public class ArrayEquals extends Equals {
+
+ private static final long serialVersionUID = 1L;
+
+ public ArrayEquals(Object expected) {
+ super(expected);
+ }
+
+ @Override
+ public boolean matches(Object actual) {
+ Object expected = getExpected();
+ if (expected instanceof boolean[]
+ && (actual == null || actual instanceof boolean[])) {
+ return Arrays.equals((boolean[]) expected, (boolean[]) actual);
+ } else if (expected instanceof byte[]
+ && (actual == null || actual instanceof byte[])) {
+ return Arrays.equals((byte[]) expected, (byte[]) actual);
+ } else if (expected instanceof char[]
+ && (actual == null || actual instanceof char[])) {
+ return Arrays.equals((char[]) expected, (char[]) actual);
+ } else if (expected instanceof double[]
+ && (actual == null || actual instanceof double[])) {
+ return Arrays.equals((double[]) expected, (double[]) actual);
+ } else if (expected instanceof float[]
+ && (actual == null || actual instanceof float[])) {
+ return Arrays.equals((float[]) expected, (float[]) actual);
+ } else if (expected instanceof int[]
+ && (actual == null || actual instanceof int[])) {
+ return Arrays.equals((int[]) expected, (int[]) actual);
+ } else if (expected instanceof long[]
+ && (actual == null || actual instanceof long[])) {
+ return Arrays.equals((long[]) expected, (long[]) actual);
+ } else if (expected instanceof short[]
+ && (actual == null || actual instanceof short[])) {
+ return Arrays.equals((short[]) expected, (short[]) actual);
+ } else if (expected instanceof Object[]
+ && (actual == null || actual instanceof Object[])) {
+ return Arrays.equals((Object[]) expected, (Object[]) actual);
+ } else {
+ return super.matches(actual);
+ }
+ }
+
+ @Override
+ public void appendTo(StringBuffer buffer) {
+ ArgumentToString.appendArgument(getExpected(), buffer);
+ }
+}
diff --git a/src/org/easymock/internal/matchers/Captures.java b/src/org/easymock/internal/matchers/Captures.java
new file mode 100644
index 0000000..5a75c0a
--- /dev/null
+++ b/src/org/easymock/internal/matchers/Captures.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2003-2009 OFFIS, Henri Tremblay
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.easymock.internal.matchers;
+
+import java.io.Serializable;
+
+import org.easymock.Capture;
+import org.easymock.IArgumentMatcher;
+import org.easymock.internal.LastControl;
+
+public class Captures<T> implements IArgumentMatcher, Serializable {
+
+ private static final long serialVersionUID = -5048595127450771363L;
+
+ private final Capture<T> capture;
+
+ private T potentialValue;
+
+ public Captures(Capture<T> captured) {
+ this.capture = captured;
+ }
+
+ public void appendTo(StringBuffer buffer) {
+ buffer.append("capture(").append(capture).append(")");
+ }
+
+ public void setPotentialValue(T potentialValue) {
+ this.potentialValue = potentialValue;
+ }
+
+ @SuppressWarnings("unchecked")
+ public boolean matches(Object actual) {
+ LastControl.getCurrentInvocation().addCapture((Captures<Object>) this,
+ actual);
+ return true;
+ }
+
+ public void validateCapture() {
+ capture.setValue(potentialValue);
+ }
+}
diff --git a/src/org/easymock/internal/matchers/Compare.java b/src/org/easymock/internal/matchers/Compare.java
new file mode 100644
index 0000000..9ed96a6
--- /dev/null
+++ b/src/org/easymock/internal/matchers/Compare.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2001-2009 OFFIS, Henri Tremblay
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.easymock.internal.matchers;
+
+import java.io.Serializable;
+import java.util.Comparator;
+
+import org.easymock.IArgumentMatcher;
+import org.easymock.LogicalOperator;
+
+public class Compare<T> implements IArgumentMatcher, Serializable {
+
+ private static final long serialVersionUID = -4859402739599754147L;
+
+ private T expected;
+
+ private Comparator<? super T> comparator;
+
+ private LogicalOperator operator;
+
+ public Compare(T expected, Comparator<? super T> comparator, LogicalOperator result) {
+ this.expected = expected;
+ this.comparator = comparator;
+ this.operator = result;
+ }
+
+ public void appendTo(StringBuffer buffer) {
+ buffer.append(comparator + "(" + expected + ") " + operator.getSymbol()
+ + " 0");
+ }
+
+ @SuppressWarnings("unchecked")
+ public boolean matches(Object actual) {
+ if(actual == null) {
+ return false;
+ }
+ return operator.matchResult(comparator.compare((T) actual, expected));
+ }
+
+}
diff --git a/src/org/easymock/internal/matchers/CompareEqual.java b/src/org/easymock/internal/matchers/CompareEqual.java
new file mode 100644
index 0000000..b62bf36
--- /dev/null
+++ b/src/org/easymock/internal/matchers/CompareEqual.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2001-2009 OFFIS, Tammo Freese
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.easymock.internal.matchers;
+
+public class CompareEqual<T extends Comparable<T>> extends CompareTo<T> {
+
+ private static final long serialVersionUID = 7616033998227799268L;
+
+ public CompareEqual(Comparable<T> value) {
+ super(value);
+ }
+
+ @Override
+ protected String getName() {
+ return "cmpEq";
+ }
+
+ @Override
+ protected boolean matchResult(int result) {
+ return result == 0;
+ }
+}
diff --git a/src/org/easymock/internal/matchers/CompareTo.java b/src/org/easymock/internal/matchers/CompareTo.java
new file mode 100644
index 0000000..0d108e4
--- /dev/null
+++ b/src/org/easymock/internal/matchers/CompareTo.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2001-2009 OFFIS, Tammo Freese
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.easymock.internal.matchers;
+
+import java.io.Serializable;
+
+import org.easymock.IArgumentMatcher;
+
+public abstract class CompareTo<T extends Comparable<T>> implements IArgumentMatcher, Serializable {
+
+ private static final long serialVersionUID = -8447010713532143168L;
+
+ private final Comparable<T> expected;
+
+ public CompareTo(Comparable<T> value) {
+ this.expected = value;
+ }
+
+ @SuppressWarnings("unchecked")
+ public boolean matches(Object actual) {
+
+ if(!(actual instanceof Comparable)) {
+ return false;
+ }
+
+ return matchResult(((Comparable) actual).compareTo(expected));
+ }
+
+ public void appendTo(StringBuffer buffer) {
+ buffer.append(getName() + "(" + expected + ")");
+ }
+
+ protected abstract String getName();
+
+ protected abstract boolean matchResult(int result);
+}
diff --git a/src/org/easymock/internal/matchers/Contains.java b/src/org/easymock/internal/matchers/Contains.java
new file mode 100644
index 0000000..57483c2
--- /dev/null
+++ b/src/org/easymock/internal/matchers/Contains.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2001-2009 OFFIS, Tammo Freese
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.easymock.internal.matchers;
+
+import java.io.Serializable;
+
+import org.easymock.IArgumentMatcher;
+
+public class Contains implements IArgumentMatcher, Serializable {
+
+ private static final long serialVersionUID = -6785245714002503134L;
+
+ private final String substring;
+
+ public Contains(String substring) {
+ this.substring = substring;
+ }
+
+ public boolean matches(Object actual) {
+ return (actual instanceof String)
+ && ((String) actual).indexOf(substring) >= 0;
+ }
+
+ public void appendTo(StringBuffer buffer) {
+ buffer.append("contains(\"" + substring + "\")");
+ }
+}
diff --git a/src/org/easymock/internal/matchers/EndsWith.java b/src/org/easymock/internal/matchers/EndsWith.java
new file mode 100644
index 0000000..f8e024b
--- /dev/null
+++ b/src/org/easymock/internal/matchers/EndsWith.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2001-2009 OFFIS, Tammo Freese
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.easymock.internal.matchers;
+
+import java.io.Serializable;
+
+import org.easymock.IArgumentMatcher;
+
+public class EndsWith implements IArgumentMatcher, Serializable {
+
+ private static final long serialVersionUID = 5159338714596685067L;
+
+ private final String suffix;
+
+ public EndsWith(String suffix) {
+ this.suffix = suffix;
+ }
+
+ public boolean matches(Object actual) {
+ return (actual instanceof String) && ((String) actual).endsWith(suffix);
+ }
+
+ public void appendTo(StringBuffer buffer) {
+ buffer.append("endsWith(\"" + suffix + "\")");
+ }
+}
diff --git a/src/org/easymock/internal/matchers/Equals.java b/src/org/easymock/internal/matchers/Equals.java
new file mode 100644
index 0000000..3988215
--- /dev/null
+++ b/src/org/easymock/internal/matchers/Equals.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2001-2009 OFFIS, Tammo Freese
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.easymock.internal.matchers;
+
+import java.io.Serializable;
+
+import org.easymock.IArgumentMatcher;
+import org.easymock.internal.ArgumentToString;
+
+public class Equals implements IArgumentMatcher, Serializable {
+
+ private static final long serialVersionUID = 583055160049982067L;
+
+ private final Object expected;
+
+ public Equals(Object expected) {
+ this.expected = expected;
+ }
+
+ public boolean matches(Object actual) {
+ if (this.expected == null) {
+ return actual == null;
+ }
+ return expected.equals(actual);
+ }
+
+ public void appendTo(StringBuffer buffer) {
+ ArgumentToString.appendArgument(expected, buffer);
+ }
+
+ protected final Object getExpected() {
+ return expected;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (o == null || !this.getClass().equals(o.getClass()))
+ return false;
+ Equals other = (Equals) o;
+ return this.expected == null && other.expected == null
+ || this.expected != null
+ && this.expected.equals(other.expected);
+ }
+
+ @Override
+ public int hashCode() {
+ throw new UnsupportedOperationException("hashCode() is not supported");
+ }
+
+}
diff --git a/src/org/easymock/internal/matchers/EqualsWithDelta.java b/src/org/easymock/internal/matchers/EqualsWithDelta.java
new file mode 100644
index 0000000..7cc4f33
--- /dev/null
+++ b/src/org/easymock/internal/matchers/EqualsWithDelta.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2001-2009 OFFIS, Tammo Freese
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.easymock.internal.matchers;
+
+import java.io.Serializable;
+
+import org.easymock.IArgumentMatcher;
+
+public class EqualsWithDelta implements IArgumentMatcher, Serializable {
+
+ private static final long serialVersionUID = -3018631689416120154L;
+
+ private final Number expected;
+
+ private final Number delta;
+
+ public EqualsWithDelta(Number value, Number delta) {
+ this.expected = value;
+ this.delta = delta;
+ }
+
+ public boolean matches(Object actual) {
+ Number actualNumber = (Number) actual;
+ return expected.doubleValue() - delta.doubleValue() <= actualNumber
+ .doubleValue()
+ && actualNumber.doubleValue() <= expected.doubleValue()
+ + delta.doubleValue();
+ }
+
+ public void appendTo(StringBuffer buffer) {
+ buffer.append("eq(" + expected + ", " + delta + ")");
+ }
+}
diff --git a/src/org/easymock/internal/matchers/Find.java b/src/org/easymock/internal/matchers/Find.java
new file mode 100644
index 0000000..ec83018
--- /dev/null
+++ b/src/org/easymock/internal/matchers/Find.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2001-2009 OFFIS, Tammo Freese
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.easymock.internal.matchers;
+
+import java.io.Serializable;
+import java.util.regex.Pattern;
+
+import org.easymock.IArgumentMatcher;
+
+public class Find implements IArgumentMatcher, Serializable {
+
+ private static final long serialVersionUID = -7104607303959381785L;
+
+ private final String regex;
+
+ public Find(String regex) {
+ this.regex = regex;
+ }
+
+ public boolean matches(Object actual) {
+ return (actual instanceof String)
+ && Pattern.compile(regex).matcher((String) actual).find();
+ }
+
+ public void appendTo(StringBuffer buffer) {
+ buffer.append("find(\"" + regex.replaceAll("\\\\", "\\\\\\\\") + "\")");
+ }
+}
diff --git a/src/org/easymock/internal/matchers/GreaterOrEqual.java b/src/org/easymock/internal/matchers/GreaterOrEqual.java
new file mode 100644
index 0000000..4d567bc
--- /dev/null
+++ b/src/org/easymock/internal/matchers/GreaterOrEqual.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2001-2009 OFFIS, Tammo Freese
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.easymock.internal.matchers;
+
+public class GreaterOrEqual<T extends Comparable<T>> extends CompareTo<T> {
+
+ private static final long serialVersionUID = -504083241204488174L;
+
+ public GreaterOrEqual(Comparable<T> value) {
+ super(value);
+ }
+
+ @Override
+ protected String getName() {
+ return "geq";
+ }
+
+ @Override
+ protected boolean matchResult(int result) {
+ return result >= 0;
+ }
+}
diff --git a/src/org/easymock/internal/matchers/GreaterThan.java b/src/org/easymock/internal/matchers/GreaterThan.java
new file mode 100644
index 0000000..ddb70df
--- /dev/null
+++ b/src/org/easymock/internal/matchers/GreaterThan.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2001-2009 OFFIS, Tammo Freese
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.easymock.internal.matchers;
+
+public class GreaterThan<T extends Comparable<T>> extends CompareTo<T> {
+
+ private static final long serialVersionUID = 2736983121197045828L;
+
+ public GreaterThan(Comparable<T> value) {
+ super(value);
+ }
+
+ @Override
+ protected String getName() {
+ return "gt";
+ }
+
+ @Override
+ protected boolean matchResult(int result) {
+ return result > 0;
+ }
+}
diff --git a/src/org/easymock/internal/matchers/InstanceOf.java b/src/org/easymock/internal/matchers/InstanceOf.java
new file mode 100644
index 0000000..edda143
--- /dev/null
+++ b/src/org/easymock/internal/matchers/InstanceOf.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2001-2009 OFFIS, Tammo Freese
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.easymock.internal.matchers;
+
+import java.io.Serializable;
+
+import org.easymock.IArgumentMatcher;
+
+public class InstanceOf implements IArgumentMatcher, Serializable {
+
+ private static final long serialVersionUID = -551735356674347591L;
+
+ private final Class<?> clazz;
+
+ public InstanceOf(Class<?> clazz) {
+ this.clazz = clazz;
+ }
+
+ public boolean matches(Object actual) {
+ return (actual != null) && clazz.isAssignableFrom(actual.getClass());
+ }
+
+ public void appendTo(StringBuffer buffer) {
+ buffer.append("isA(" + clazz.getName() + ")");
+ }
+}
diff --git a/src/org/easymock/internal/matchers/LessOrEqual.java b/src/org/easymock/internal/matchers/LessOrEqual.java
new file mode 100644
index 0000000..36d073e
--- /dev/null
+++ b/src/org/easymock/internal/matchers/LessOrEqual.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2001-2009 OFFIS, Tammo Freese
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.easymock.internal.matchers;
+
+public class LessOrEqual<T extends Comparable<T>> extends CompareTo<T> {
+
+ private static final long serialVersionUID = -2485406702001842607L;
+
+ public LessOrEqual(Comparable<T> value) {
+ super(value);
+ }
+
+ @Override
+ protected String getName() {
+ return "leq";
+ }
+
+ @Override
+ protected boolean matchResult(int result) {
+ return result <= 0;
+ }
+}
diff --git a/src/org/easymock/internal/matchers/LessThan.java b/src/org/easymock/internal/matchers/LessThan.java
new file mode 100644
index 0000000..7646e9b
--- /dev/null
+++ b/src/org/easymock/internal/matchers/LessThan.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2001-2009 OFFIS, Tammo Freese
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.easymock.internal.matchers;
+
+public class LessThan<T extends Comparable<T>> extends CompareTo<T> {
+
+ private static final long serialVersionUID = 6004888476822043880L;
+
+ public LessThan(Comparable<T> value) {
+ super(value);
+ }
+
+ @Override
+ protected String getName() {
+ return "lt";
+ }
+
+ @Override
+ protected boolean matchResult(int result) {
+ return result < 0;
+ }
+}
diff --git a/src/org/easymock/internal/matchers/Matches.java b/src/org/easymock/internal/matchers/Matches.java
new file mode 100644
index 0000000..452082b
--- /dev/null
+++ b/src/org/easymock/internal/matchers/Matches.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2001-2009 OFFIS, Tammo Freese
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.easymock.internal.matchers;
+
+import java.io.Serializable;
+
+import org.easymock.IArgumentMatcher;
+
+public class Matches implements IArgumentMatcher, Serializable {
+
+ private static final long serialVersionUID = -6657694947057597484L;
+
+ private final String regex;
+
+ public Matches(String regex) {
+ this.regex = regex;
+ }
+
+ public boolean matches(Object actual) {
+ return (actual instanceof String) && ((String) actual).matches(regex);
+ }
+
+ public void appendTo(StringBuffer buffer) {
+ buffer.append("matches(\"" + regex.replaceAll("\\\\", "\\\\\\\\")
+ + "\")");
+ }
+}
diff --git a/src/org/easymock/internal/matchers/Not.java b/src/org/easymock/internal/matchers/Not.java
new file mode 100644
index 0000000..76ca20f
--- /dev/null
+++ b/src/org/easymock/internal/matchers/Not.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2001-2009 OFFIS, Tammo Freese
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.easymock.internal.matchers;
+
+import java.io.Serializable;
+
+import org.easymock.IArgumentMatcher;
+
+public class Not implements IArgumentMatcher, Serializable {
+
+ private static final long serialVersionUID = -5160559075998939348L;
+
+ private final IArgumentMatcher first;
+
+ public Not(IArgumentMatcher first) {
+ this.first = first;
+ }
+
+ public boolean matches(Object actual) {
+ return !first.matches(actual);
+ }
+
+ public void appendTo(StringBuffer buffer) {
+ buffer.append("not(");
+ first.appendTo(buffer);
+ buffer.append(")");
+ }
+}
diff --git a/src/org/easymock/internal/matchers/NotNull.java b/src/org/easymock/internal/matchers/NotNull.java
new file mode 100644
index 0000000..86f006d
--- /dev/null
+++ b/src/org/easymock/internal/matchers/NotNull.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2001-2009 OFFIS, Tammo Freese
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.easymock.internal.matchers;
+
+import java.io.Serializable;
+
+import org.easymock.IArgumentMatcher;
+
+public class NotNull implements IArgumentMatcher, Serializable {
+
+ private static final long serialVersionUID = -2689588759855326190L;
+
+ public static final NotNull NOT_NULL = new NotNull();
+
+ private NotNull() {
+
+ }
+
+ public boolean matches(Object actual) {
+ return actual != null;
+ }
+
+ public void appendTo(StringBuffer buffer) {
+ buffer.append("notNull()");
+ }
+}
diff --git a/src/org/easymock/internal/matchers/Null.java b/src/org/easymock/internal/matchers/Null.java
new file mode 100644
index 0000000..c401bef
--- /dev/null
+++ b/src/org/easymock/internal/matchers/Null.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2001-2009 OFFIS, Tammo Freese
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.easymock.internal.matchers;
+
+import java.io.Serializable;
+
+import org.easymock.IArgumentMatcher;
+
+public class Null implements IArgumentMatcher, Serializable {
+
+ private static final long serialVersionUID = 6077244839421122011L;
+
+ public static final Null NULL = new Null();
+
+ private Null() {
+ }
+
+ public boolean matches(Object actual) {
+ return actual == null;
+ }
+
+ public void appendTo(StringBuffer buffer) {
+ buffer.append("isNull()");
+ }
+}
diff --git a/src/org/easymock/internal/matchers/Or.java b/src/org/easymock/internal/matchers/Or.java
new file mode 100644
index 0000000..910c13f
--- /dev/null
+++ b/src/org/easymock/internal/matchers/Or.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2001-2009 OFFIS, Tammo Freese
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.easymock.internal.matchers;
+
+import java.io.Serializable;
+import java.util.Iterator;
+import java.util.List;
+
+import org.easymock.IArgumentMatcher;
+
+public class Or implements IArgumentMatcher, Serializable {
+
+ private static final long serialVersionUID = -5701204283180444317L;
+
+ private final List<IArgumentMatcher> matchers;
+
+ public Or(List<IArgumentMatcher> matchers) {
+ this.matchers = matchers;
+ }
+
+ public boolean matches(Object actual) {
+ for (IArgumentMatcher matcher : matchers) {
+ if (matcher.matches(actual)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public void appendTo(StringBuffer buffer) {
+ buffer.append("or(");
+ for (Iterator<IArgumentMatcher> it = matchers.iterator(); it.hasNext();) {
+ it.next().appendTo(buffer);
+ if (it.hasNext()) {
+ buffer.append(", ");
+ }
+ }
+ buffer.append(")");
+ }
+}
diff --git a/src/org/easymock/internal/matchers/Same.java b/src/org/easymock/internal/matchers/Same.java
new file mode 100644
index 0000000..a106d46
--- /dev/null
+++ b/src/org/easymock/internal/matchers/Same.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2001-2009 OFFIS, Tammo Freese
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.easymock.internal.matchers;
+
+import java.io.Serializable;
+
+import org.easymock.IArgumentMatcher;
+import org.easymock.internal.ArgumentToString;
+
+public class Same implements IArgumentMatcher, Serializable {
+
+ private static final long serialVersionUID = 1094930851962278376L;
+
+ private final Object expected;
+
+ public Same(Object expected) {
+ this.expected = expected;
+ }
+
+ public boolean matches(Object actual) {
+ return expected == actual;
+ }
+
+ public void appendTo(StringBuffer buffer) {
+ buffer.append("same(");
+ ArgumentToString.appendArgument(expected, buffer);
+ buffer.append(")");
+ }
+}
diff --git a/src/org/easymock/internal/matchers/StartsWith.java b/src/org/easymock/internal/matchers/StartsWith.java
new file mode 100644
index 0000000..bf12f96
--- /dev/null
+++ b/src/org/easymock/internal/matchers/StartsWith.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2001-2009 OFFIS, Tammo Freese
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.easymock.internal.matchers;
+
+import java.io.Serializable;
+
+import org.easymock.IArgumentMatcher;
+
+public class StartsWith implements IArgumentMatcher, Serializable {
+
+ private static final long serialVersionUID = -658998692584342514L;
+
+ private final String prefix;
+
+ public StartsWith(String prefix) {
+ this.prefix = prefix;
+ }
+
+ public boolean matches(Object actual) {
+ return (actual instanceof String)
+ && ((String) actual).startsWith(prefix);
+ }
+
+ public void appendTo(StringBuffer buffer) {
+ buffer.append("startsWith(\"" + prefix + "\")");
+ }
+}