/* * Copyright (c) 2013, the Dart project authors. * * Licensed under the Eclipse Public License v1.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.eclipse.org/legal/epl-v10.html * * 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 com.google.dart.tools.core; import com.google.dart.engine.utilities.io.PrintStringWriter; import junit.framework.TestCase; import java.util.ArrayList; /** * Used by tests to track calls made to mocked objects. */ public class CallList { public static class Call { protected final Object target; protected final String methodName; protected final Object[] args; public Call(Object target, String methodName, Object... args) { this.target = target; this.methodName = methodName; this.args = args; } @Override public boolean equals(Object obj) { if (obj instanceof Call) { Call call = (Call) obj; return equalTarget(call.target) && equalMethodName(call.methodName) && equalArguments(call.args); } else { return false; } } @Override public String toString() { PrintStringWriter writer = new PrintStringWriter(); writer.print("Call["); print(writer, ""); writer.print("]"); return writer.toString(); } protected boolean equalArgument(int index, Object arg1, Object arg2) { if (arg1 == arg2) { return true; } if (arg1 == null) { return arg2 == null; } return arg1.equals(arg2); } protected boolean equalArguments(Object[] otherArgs) { if (args.length != otherArgs.length) { return false; } for (int index = 0; index < args.length; index++) { if (!equalArgument(index, args[index], otherArgs[index])) { return false; } } return true; } protected boolean equalMethodName(String otherMethodName) { if (methodName == null) { return otherMethodName == null; } return methodName.equals(otherMethodName); } protected boolean equalTarget(Object otherTarget) { if (target == otherTarget) { return true; } if (target == null) { return otherTarget == null; } return target.equals(otherTarget); } protected void print(PrintStringWriter writer, String indent) { printTarget(writer, indent, target); printMethodName(writer, indent + " "); printArguments(writer, indent + " ", args); } protected void printArgument(PrintStringWriter writer, String indent, Object arg) { writer.print(indent); writer.println(arg != null ? arg.toString() : "null"); } protected void printArguments(PrintStringWriter writer, String indent, Object[] args) { for (Object arg : args) { printArgument(writer, indent, arg); } } protected void printMethodName(PrintStringWriter writer, String indent) { writer.print(indent); writer.println(methodName); } protected void printTarget(PrintStringWriter writer, String indent, Object target) { writer.print(indent); writer.println(target != null ? target.toString() : "null"); } } private final ArrayList<Call> calls = new ArrayList<Call>(); /** * Add a call to the list of calls * * @param call the call that was added (not {@code null}) */ public void add(Call call) { if (call == null) { throw new IllegalArgumentException(); } calls.add(call); } /** * Add a call to the list of calls * * @param target the call target (not {@code null}) * @param methodName the method that was called on the target (not {@code null}) * @param args zero or more arguments for the call */ public void add(Object target, String methodName, Object... args) { add(new Call(target, methodName, args)); } /** * Assert that the list contains the specified call, and remove that call from the list. * * @param call the call (not {@code null}) */ public void assertCall(Call call) { if (!calls.remove(call)) { fail(call); } } /** * Assert that the list contains the specified call, and remove that call from the list. * * @param target the call target (not {@code null}) * @param methodName the method name (not {@code null}) * @param args zero or more call arguments */ public void assertCall(Object target, String methodName, Object... args) { assertCall(new Call(target, methodName, args)); } /** * Assert that the list contains the specified call or not depending upon whether it was expected. * * @param expected {@code true} if the call is expected, else {@code false} * @param call the call (not {@code null}) */ public void assertExpectedCall(boolean expected, Call call) { if (expected) { assertCall(call); } else { assertNoCall(call); } } /** * Assert that the list contains the specified call or not depending upon whether it was expected. * * @param expected {@code true} if the call is expected, else {@code false} * @param target the call target (not {@code null}) * @param methodName the method name (not {@code null}) * @param args zero or more call arguments */ public void assertExpectedCall(boolean expected, Object target, String methodName, Object... args) { assertExpectedCall(expected, new Call(target, methodName, args)); } /** * Assert that the list does NOT contain the specified call. * * @param call the call (not {@code null}) */ public void assertNoCall(Call call) { if (calls.contains(call)) { PrintStringWriter writer = new PrintStringWriter(); writer.println("Did NOT expect:"); call.print(writer, " "); TestCase.fail(writer.toString().trim()); } } /** * Assert that the list does NOT contain the specified call. * * @param target the call target (not {@code null}) * @param methodName the method name (not {@code null}) * @param args zero or more call arguments */ public void assertNoCall(Object target, String methodName, Object... args) { assertNoCall(new Call(target, methodName, args)); } /** * Assert that there are no more calls in the list */ public void assertNoCalls() { if (calls.size() > 0) { fail("No more calls"); } } /** * Assert that there are one or more matching calls. * * @param call the call (not {@code null}) */ public void assertOneOrMoreCalls(Call call) { boolean atLeastOne = false; for (int index = calls.size() - 1; index >= 0; index--) { if (calls.get(index).equals(call)) { calls.remove(index); atLeastOne = true; } } if (!atLeastOne) { fail(call); } } public void clear() { calls.clear(); } private void fail(Object expected) { PrintStringWriter writer = new PrintStringWriter(); writer.println("Expected:"); if (expected instanceof Call) { ((Call) expected).print(writer, " "); } else { writer.println(expected != null ? expected.toString() : "null"); } writer.println("Actual:"); for (Call call : calls) { call.print(writer, " "); } TestCase.fail(writer.toString().trim()); } }