View Javadoc

1   // Copyright (C) 2004 - 2009 Philip Aston
2   // All rights reserved.
3   //
4   // This file is part of The Grinder software distribution. Refer to
5   // the file LICENSE which is part of The Grinder distribution for
6   // licensing details. The Grinder distribution is available on the
7   // Internet at http://grinder.sourceforge.net/
8   //
9   // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
10  // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
11  // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
12  // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
13  // COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
14  // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
15  // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
16  // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
17  // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
18  // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
19  // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
20  // OF THE POSSIBILITY OF SUCH DAMAGE.
21  
22  package net.grinder.testutility;
23  
24  import java.lang.reflect.Method;
25  import java.util.Arrays;
26  
27  import junit.framework.Assert;
28  
29  
30  /**
31   *  Method call data.
32   *
33   * @author    Philip Aston
34   */
35  public final class CallData extends Assert implements CallAssertions {
36    private final Method m_method;
37    private final Object[] m_parameters;
38    private final Object m_result;
39    private final Throwable m_throwable;
40  
41    public CallData(Method method, Object result, Object... parameters) {
42      m_method = method;
43      m_parameters = parameters;
44      m_result = result;
45      m_throwable = null;
46    }
47  
48    public CallData(Method method, Throwable throwable, Object... parameters) {
49      m_method = method;
50      m_parameters = parameters;
51      m_result = null;
52      m_throwable = throwable;
53    }
54  
55    public Method getMethod() {
56      return m_method;
57    }
58  
59    public String getMethodName() {
60      return getMethod().getName();
61    }
62  
63    public Object[] getParameters() {
64      return m_parameters;
65    }
66  
67    public Class<?>[] getParameterTypes() {
68      if (m_parameters == null) {
69        return new Class[0];
70      }
71  
72      final Class<?>[] types = new Class<?>[m_parameters.length];
73  
74      for (int i=0; i<types.length; ++i) {
75        if (m_parameters[i] == null) {
76          types[i] = ANY_TYPE.class;
77        }
78        else {
79          types[i] = m_parameters[i].getClass();
80        }
81      }
82  
83      return types;
84    }
85  
86    /**
87     * Class that represents a parameter that is compatible with any type.
88     */
89    public static class ANY_TYPE { }
90  
91    public Object getResult() {
92      assertNull(m_throwable);
93      return m_result;
94    }
95  
96    public Throwable getThrowable() {
97      return m_throwable;
98    }
99  
100   /**
101    *  Check the given method was called.
102    */
103   public final CallData assertSuccess(String methodName, Object... parameters) {
104     assertCalled(methodName, parameters);
105     assertNull(getThrowable());
106     return this;
107   }
108 
109   public final CallData assertSuccess(String methodName,
110                                       Class<?>... parameterTypes) {
111     assertCalled(methodName, parameterTypes);
112     assertNull(getThrowable());
113     return this;
114   }
115 
116   public final CallData assertSuccess(String methodName) {
117     return assertSuccess(methodName, new Class[0]);
118   }
119 
120   public final CallData assertException(String methodName,
121                                         Throwable throwable,
122                                         Object... parameters) {
123     assertCalled(methodName, parameters);
124     assertEquals(throwable, getThrowable());
125     return this;
126   }
127 
128   public final CallData assertException(String methodName,
129                                         Throwable throwable,
130                                         Class<?>... parameterTypes) {
131     assertCalled(methodName, parameterTypes);
132     assertEquals(throwable, getThrowable());
133     return this;
134   }
135 
136   public final CallData assertException(String methodName,
137                                         Class<?> throwableType,
138                                         Object... parameters) {
139     assertCalled(methodName, parameters);
140     assertTrue(throwableType.isAssignableFrom(getThrowable().getClass()));
141     return this;
142   }
143 
144   public final CallData assertException(String methodName,
145                                         Class<?> throwableType,
146                                         Class<?>... parameterTypes) {
147     assertCalled(methodName, parameterTypes);
148     assertNotNull(getThrowable());
149     assertTrue(throwableType.isAssignableFrom(getThrowable().getClass()));
150     return this;
151   }
152 
153   private void assertCalled(String methodName, Object... parameters) {
154     if (parameters.length == 0) {
155       parameters = null;
156     }
157 
158     // Just check method names match. Don't worry about modifiers
159     // etc., or even which class the method belongs to.
160     assertEquals(methodName, getMethodName());
161 
162     AssertUtilities. assertArraysEqual(
163       "Expected " + parametersToString(parameters) +
164       " but was " + parametersToString(getParameters()),
165       parameters, getParameters());
166   }
167 
168   private void assertCalled(String methodName, Class<?>... parameterTypes) {
169 
170     // Just check method names match. Don't worry about modifiers
171     // etc., or even which class the method belongs to.
172     assertEquals(methodName, getMethodName());
173 
174     final Class<?>[] actualParameterTypes = getParameterTypes();
175 
176     if (parameterTypes != null || actualParameterTypes != null) {
177       assertNotNull(parameterTypes);
178       assertNotNull(actualParameterTypes);
179 
180       // If statement is to shut up eclipse null warning.
181       if (parameterTypes != null && actualParameterTypes != null) {
182         assertEquals("Called with the correct number of parameters",
183                      parameterTypes.length,
184                      actualParameterTypes.length);
185 
186         for (int i = 0; i < parameterTypes.length; ++i) {
187           if (!(actualParameterTypes[i].equals(ANY_TYPE.class))) {
188             assertTrue("Parameter  " + i + " is instance of  " +
189                        actualParameterTypes[i].getName() +
190                        " which supports the interfaces " +
191                        Arrays.asList(actualParameterTypes[i].getInterfaces()) +
192                        " and is not assignable from " +
193                        parameterTypes[i].getName(),
194                        parameterTypes[i].isAssignableFrom(
195                          actualParameterTypes[i]));
196           }
197         }
198       }
199     }
200   }
201 
202   public String toString() {
203     final StringBuffer result = new StringBuffer();
204 
205     result.append(getMethodName());
206     result.append(parametersToString(getParameters()));
207 
208     final Throwable throwable = getThrowable();
209 
210     if (throwable != null) {
211       result.append(" threw " + throwable);
212     }
213     else {
214       result.append(" returned " + getResult());
215     }
216 
217     return result.toString();
218   }
219 
220   private static final String parametersToString(Object[] parameters) {
221 
222     final StringBuffer result = new StringBuffer();
223 
224     result.append('(');
225 
226     if (parameters != null) {
227       for (int i = 0; i < parameters.length; ++i) {
228         if (i != 0) {
229           result.append(", ");
230         }
231 
232         if (parameters[i] != null &&
233             !parameters[i].getClass().isPrimitive() &&
234             !parameters[i].getClass().isArray()) {
235           result.append("\"");
236           result.append(parameters[i]);
237           result.append("\"");
238         }
239         else {
240           result.append(parameters[i]);
241         }
242       }
243     }
244 
245     result.append(')');
246 
247     return result.toString();
248   }
249 }