View Javadoc

1   /*
2    $Id: GroovyTestCase.java,v 1.20 2005/02/20 15:26:20 mcspanky Exp $
3   
4    Copyright 2003 (C) James Strachan and Bob Mcwhirter. All Rights Reserved.
5   
6    Redistribution and use of this software and associated documentation
7    ("Software"), with or without modification, are permitted provided
8    that the following conditions are met:
9   
10   1. Redistributions of source code must retain copyright
11      statements and notices.  Redistributions must also contain a
12      copy of this document.
13  
14   2. Redistributions in binary form must reproduce the
15      above copyright notice, this list of conditions and the
16      following disclaimer in the documentation and/or other
17      materials provided with the distribution.
18  
19   3. The name "groovy" must not be used to endorse or promote
20      products derived from this Software without prior written
21      permission of The Codehaus.  For written permission,
22      please contact info@codehaus.org.
23  
24   4. Products derived from this Software may not be called "groovy"
25      nor may "groovy" appear in their names without prior written
26      permission of The Codehaus. "groovy" is a registered
27      trademark of The Codehaus.
28  
29   5. Due credit should be given to The Codehaus -
30      http://groovy.codehaus.org/
31  
32   THIS SOFTWARE IS PROVIDED BY THE CODEHAUS AND CONTRIBUTORS
33   ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
34   NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
35   FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
36   THE CODEHAUS OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
37   INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
38   (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
39   SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
40   HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
41   STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
42   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
43   OF THE POSSIBILITY OF SUCH DAMAGE.
44  
45   */
46  package groovy.util;
47  
48  import groovy.lang.Closure;
49  import groovy.lang.GroovyCodeSource;
50  import groovy.lang.GroovyShell;
51  
52  import java.io.File;
53  import java.io.PrintWriter;
54  import java.util.logging.Logger;
55  
56  import junit.framework.TestCase;
57  
58  import org.codehaus.groovy.runtime.DefaultGroovyMethods;
59  import org.codehaus.groovy.runtime.InvokerHelper;
60  
61  /***
62   * A default JUnit TestCase in Groovy. This provides a number of helper methods
63   * plus avoids the JUnit restriction of requiring all test* methods to be void
64   * return type.
65   *
66   * @author <a href="mailto:bob@werken.com">bob mcwhirter</a>
67   * @author <a href="mailto:james@coredevelopers.net">James Strachan</a>
68   * @version $Revision: 1.20 $
69   */
70  public class GroovyTestCase extends TestCase {
71  
72      protected Logger log = Logger.getLogger(getClass().getName());
73      private static int counter;
74      private boolean useAgileDoxNaming = false;
75  
76      public GroovyTestCase() {
77      }
78  
79      /***
80       * Overload the getName() method to make the test cases look more like AgileDox
81       * (thanks to Joe Walnes for this tip!)
82       */
83      public String getName() {
84          if (useAgileDoxNaming) {
85              return super.getName().substring(4).replaceAll("([A-Z])", " $1").toLowerCase();
86          }
87          else {
88              return super.getName();
89          }
90      }
91  
92      public String getMethodName() {
93          return super.getName();
94      }
95  
96      /***
97       * Asserts that the arrays are equivalent and contain the same values
98       *
99       * @param expected
100      * @param value
101      */
102     protected void assertArrayEquals(Object[] expected, Object[] value) {
103         String message =
104             "expected array: " + InvokerHelper.toString(expected) + " value array: " + InvokerHelper.toString(value);
105         assertNotNull(message + ": expected should not be null", expected);
106         assertNotNull(message + ": value should not be null", value);
107         assertEquals(message, expected.length, value.length);
108         for (int i = 0, size = expected.length; i < size; i++) {
109             assertEquals("value[" + i + "] when " + message, expected[i], value[i]);
110         }
111     }
112 
113     /***
114      * Asserts that the array of characters has a given length
115      *
116      * @param length expected length
117      * @param array the array
118      */
119     protected void assertLength(int length, char[] array) {
120         assertEquals(length, array.length);
121     }
122 
123     /***
124      * Asserts that the array of ints has a given length
125      *
126      * @param length expected length
127      * @param array the array
128      */
129     protected void assertLength(int length, int[] array) {
130         assertEquals(length, array.length);
131     }
132 
133     /***
134      * Asserts that the array of objects has a given length
135      *
136      * @param length expected length
137      * @param array the array
138      */
139     protected void assertLength(int length, Object[] array) {
140         assertEquals(length, array.length);
141     }
142 
143     /***
144      * Asserts that the array of characters contains a given char
145      *
146      * @param expected expected character to be found
147      * @param array the array
148      */
149     protected void assertContains(char expected, char[] array) {
150         for (int i = 0; i < array.length; ++i) {
151             if (array[i] == expected) {
152                 return;
153             }
154         }
155 
156         StringBuffer message = new StringBuffer();
157 
158         message.append(expected + " not in {");
159 
160         for (int i = 0; i < array.length; ++i) {
161             message.append("'" + array[i] + "'");
162 
163             if (i < (array.length - 1)) {
164                 message.append(", ");
165             }
166         }
167 
168         message.append(" }");
169 
170         fail(message.toString());
171     }
172 
173     /***
174      * Asserts that the array of ints contains a given int
175      *
176      * @param expected expected int
177      * @param array the array
178      */
179     protected void assertContains(int expected, int[] array) {
180         for (int i = 0; i < array.length; ++i) {
181             if (array[i] == expected) {
182                 return;
183             }
184         }
185 
186         StringBuffer message = new StringBuffer();
187 
188         message.append(expected + " not in {");
189 
190         for (int i = 0; i < array.length; ++i) {
191             message.append("'" + array[i] + "'");
192 
193             if (i < (array.length - 1)) {
194                 message.append(", ");
195             }
196         }
197 
198         message.append(" }");
199 
200         fail(message.toString());
201     }
202 
203     /***
204      * Asserts that the value of toString() on the given object matches the
205      * given text string
206      *
207      * @param value the object to be output to the console
208      * @param expected the expected String representation
209      */
210     protected void assertToString(Object value, String expected) {
211         Object console = InvokerHelper.invokeMethod(value, "toString", null);
212         assertEquals("toString() on value: " + value, expected, console);
213     }
214 
215     /***
216      * Asserts that the value of inspect() on the given object matches the
217      * given text string
218      *
219      * @param value the object to be output to the console
220      * @param expected the expected String representation
221      */
222     protected void assertInspect(Object value, String expected) {
223         Object console = InvokerHelper.invokeMethod(value, "inspect", null);
224         assertEquals("inspect() on value: " + value, expected, console);
225     }
226 
227     /***
228      * Asserts that the script runs without any exceptions
229      *
230      * @param script the script that should pass without any exception thrown
231      */
232     protected void assertScript(final String script) throws Exception {
233         log.info("About to execute script");
234         //log.info(script);
235 
236         // lets write the file to the target directory so its available
237         // to the MetaClass.getClassNode()
238         // the file is also used to determine the CodeSource if running with a security manager
239         String testClassName = getTestClassName();
240 
241         File dir = new File("target/test-script/");
242         dir.mkdirs();
243         File file = new File(dir, testClassName);
244 
245         log.info("Creating file " + file);
246 
247         DefaultGroovyMethods.withPrintWriter(file, new Closure(null) {
248             protected void doCall(PrintWriter writer) {
249                 writer.println(script);
250             }
251         });
252 
253         GroovyShell shell = new GroovyShell();
254         shell.evaluate(new GroovyCodeSource(file));
255     }
256 
257     protected String getTestClassName() {
258         return "TestScript" + getMethodName() + (counter++) + ".groovy";
259     }
260 
261     /***
262      * Asserts that the given code closure fails when it is evaluated
263      *
264      * @param code
265      */
266     protected void shouldFail(Closure code) {
267         boolean failed = false;
268         try {
269             code.call();
270         }
271         catch (Exception e) {
272             failed = true;
273             System.out.println("Worked: caught expected exception: " + e);
274         }
275         assertTrue("Closure " + code + " should have failed", failed);
276     }
277 
278     /***
279      * Asserts that the given code closure fails when it is evaluated
280      * and that a particular exception is thrown.
281      *
282      * @param clazz the class of the expected exception
283      * @param code the closure that should fail
284      */
285     protected void shouldFail(Class clazz, Closure code) {
286         boolean failed = false;
287         try {
288             code.call();
289         }
290         catch (Exception e) {
291             if (clazz.isInstance(e)) {
292                 failed = true;
293                 System.out.println("Worked: caught expected exception: " + e);
294             }
295             assertTrue("Closure " + code + " should have failed with an exception of type " + clazz.getName() + ", instead got Exception " + e, failed);
296             return;
297         }
298         assertTrue("Closure " + code + " should have failed with an exception of type " + clazz.getName(), failed);
299     }
300 
301 
302     /***
303      *  Returns a copy of a string in which all EOLs are \n.
304      */
305     protected String fixEOLs( String value )
306     {
307         return value.replaceAll( "(//r//n?)|\n", "\n" );
308     }
309 }