001    /*
002     $Id: GroovyTestCase.java,v 1.24 2005/06/09 20:20:30 glaforge Exp $
003    
004     Copyright 2003 (C) James Strachan and Bob Mcwhirter. All Rights Reserved.
005    
006     Redistribution and use of this software and associated documentation
007     ("Software"), with or without modification, are permitted provided
008     that the following conditions are met:
009    
010     1. Redistributions of source code must retain copyright
011        statements and notices.  Redistributions must also contain a
012        copy of this document.
013    
014     2. Redistributions in binary form must reproduce the
015        above copyright notice, this list of conditions and the
016        following disclaimer in the documentation and/or other
017        materials provided with the distribution.
018    
019     3. The name "groovy" must not be used to endorse or promote
020        products derived from this Software without prior written
021        permission of The Codehaus.  For written permission,
022        please contact info@codehaus.org.
023    
024     4. Products derived from this Software may not be called "groovy"
025        nor may "groovy" appear in their names without prior written
026        permission of The Codehaus. "groovy" is a registered
027        trademark of The Codehaus.
028    
029     5. Due credit should be given to The Codehaus -
030        http://groovy.codehaus.org/
031    
032     THIS SOFTWARE IS PROVIDED BY THE CODEHAUS AND CONTRIBUTORS
033     ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
034     NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
035     FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
036     THE CODEHAUS OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
037     INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
038     (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
039     SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
040     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
041     STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
042     ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
043     OF THE POSSIBILITY OF SUCH DAMAGE.
044    
045     */
046    package groovy.util;
047    
048    import groovy.lang.Closure;
049    import groovy.lang.GroovyShell;
050    
051    import java.util.logging.Logger;
052    
053    import junit.framework.TestCase;
054    
055    import org.codehaus.groovy.runtime.InvokerHelper;
056    
057    /**
058     * A default JUnit TestCase in Groovy. This provides a number of helper methods
059     * plus avoids the JUnit restriction of requiring all test* methods to be void
060     * return type.
061     *
062     * @author <a href="mailto:bob@werken.com">bob mcwhirter</a>
063     * @author <a href="mailto:james@coredevelopers.net">James Strachan</a>
064     * @version $Revision: 1.24 $
065     */
066    public class GroovyTestCase extends TestCase {
067    
068        protected Logger log = Logger.getLogger(getClass().getName());
069        private static int counter;
070        private boolean useAgileDoxNaming = false;
071    
072        public GroovyTestCase() {
073        }
074    
075        /**
076         * Overload the getName() method to make the test cases look more like AgileDox
077         * (thanks to Joe Walnes for this tip!)
078         */
079        public String getName() {
080            if (useAgileDoxNaming) {
081                return super.getName().substring(4).replaceAll("([A-Z])", " $1").toLowerCase();
082            }
083            else {
084                return super.getName();
085            }
086        }
087    
088        public String getMethodName() {
089            return super.getName();
090        }
091    
092        /**
093         * Asserts that the arrays are equivalent and contain the same values
094         *
095         * @param expected
096         * @param value
097         */
098        protected void assertArrayEquals(Object[] expected, Object[] value) {
099            String message =
100                "expected array: " + InvokerHelper.toString(expected) + " value array: " + InvokerHelper.toString(value);
101            assertNotNull(message + ": expected should not be null", expected);
102            assertNotNull(message + ": value should not be null", value);
103            assertEquals(message, expected.length, value.length);
104            for (int i = 0, size = expected.length; i < size; i++) {
105                assertEquals("value[" + i + "] when " + message, expected[i], value[i]);
106            }
107        }
108    
109        /**
110         * Asserts that the array of characters has a given length
111         *
112         * @param length expected length
113         * @param array the array
114         */
115        protected void assertLength(int length, char[] array) {
116            assertEquals(length, array.length);
117        }
118    
119        /**
120         * Asserts that the array of ints has a given length
121         *
122         * @param length expected length
123         * @param array the array
124         */
125        protected void assertLength(int length, int[] array) {
126            assertEquals(length, array.length);
127        }
128    
129        /**
130         * Asserts that the array of objects has a given length
131         *
132         * @param length expected length
133         * @param array the array
134         */
135        protected void assertLength(int length, Object[] array) {
136            assertEquals(length, array.length);
137        }
138    
139        /**
140         * Asserts that the array of characters contains a given char
141         *
142         * @param expected expected character to be found
143         * @param array the array
144         */
145        protected void assertContains(char expected, char[] array) {
146            for (int i = 0; i < array.length; ++i) {
147                if (array[i] == expected) {
148                    return;
149                }
150            }
151    
152            StringBuffer message = new StringBuffer();
153    
154            message.append(expected + " not in {");
155    
156            for (int i = 0; i < array.length; ++i) {
157                message.append("'" + array[i] + "'");
158    
159                if (i < (array.length - 1)) {
160                    message.append(", ");
161                }
162            }
163    
164            message.append(" }");
165    
166            fail(message.toString());
167        }
168    
169        /**
170         * Asserts that the array of ints contains a given int
171         *
172         * @param expected expected int
173         * @param array the array
174         */
175        protected void assertContains(int expected, int[] array) {
176            for (int i = 0; i < array.length; ++i) {
177                if (array[i] == expected) {
178                    return;
179                }
180            }
181    
182            StringBuffer message = new StringBuffer();
183    
184            message.append(expected + " not in {");
185    
186            for (int i = 0; i < array.length; ++i) {
187                message.append("'" + array[i] + "'");
188    
189                if (i < (array.length - 1)) {
190                    message.append(", ");
191                }
192            }
193    
194            message.append(" }");
195    
196            fail(message.toString());
197        }
198    
199        /**
200         * Asserts that the value of toString() on the given object matches the
201         * given text string
202         *
203         * @param value the object to be output to the console
204         * @param expected the expected String representation
205         */
206        protected void assertToString(Object value, String expected) {
207            Object console = InvokerHelper.invokeMethod(value, "toString", null);
208            assertEquals("toString() on value: " + value, expected, console);
209        }
210    
211        /**
212         * Asserts that the value of inspect() on the given object matches the
213         * given text string
214         *
215         * @param value the object to be output to the console
216         * @param expected the expected String representation
217         */
218        protected void assertInspect(Object value, String expected) {
219            Object console = InvokerHelper.invokeMethod(value, "inspect", null);
220            assertEquals("inspect() on value: " + value, expected, console);
221        }
222    
223        /**
224         * Asserts that the script runs without any exceptions
225         *
226         * @param script the script that should pass without any exception thrown
227         */
228        protected void assertScript(final String script) throws Exception {
229            GroovyShell shell = new GroovyShell();
230            shell.evaluate(script, getTestClassName());
231        }
232    
233        protected String getTestClassName() {
234            return "TestScript" + getMethodName() + (counter++) + ".groovy";
235        }
236    
237        /**
238         * Asserts that the given code closure fails when it is evaluated
239         *
240         * @param code
241         */
242        protected void shouldFail(Closure code) {
243            boolean failed = false;
244            try {
245                code.call();
246            }
247            catch (Exception e) {
248                failed = true;
249            }
250            assertTrue("Closure " + code + " should have failed", failed);
251        }
252    
253        /**
254         * Asserts that the given code closure fails when it is evaluated
255         * and that a particular exception is thrown.
256         *
257         * @param clazz the class of the expected exception
258         * @param code the closure that should fail
259         */
260        protected void shouldFail(Class clazz, Closure code) {
261            boolean failed = false;
262            try {
263                code.call();
264            }
265            catch (Exception e) {
266                if (clazz.isInstance(e)) {
267                    failed = true;
268                }
269                assertTrue("Closure " + code + " should have failed with an exception of type " + clazz.getName() + ", instead got Exception " + e, failed);
270                return;
271            }
272            assertTrue("Closure " + code + " should have failed with an exception of type " + clazz.getName(), failed);
273        }
274    
275    
276        /**
277         *  Returns a copy of a string in which all EOLs are \n.
278         */
279        protected String fixEOLs( String value )
280        {
281            return value.replaceAll( "(\\r\\n?)|\n", "\n" );
282        }
283    }