    1   /*
    2    $Id: TestSupport.java,v 1.32 2004/04/19 07:29:46 cpoirier 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
    47  package org.codehaus.groovy.classgen;
    48
    49  import groovy.lang.Binding;
    50  import groovy.lang.GroovyClassLoader;
    51  import groovy.lang.GroovyCodeSource;
    52  import groovy.lang.GroovyObject;
    53  import groovy.lang.Script;
    54  import groovy.util.GroovyTestCase;
    55
    56  import java.beans.BeanInfo;
    57  import java.beans.Introspector;
    58  import java.beans.PropertyDescriptor;
    59  import java.io.File;
    60  import java.lang.reflect.Field;
    61  import java.lang.reflect.InvocationTargetException;
    62  import java.lang.reflect.Method;
    63  import java.security.AccessController;
    64  import java.security.PrivilegedAction;
    65
    66  import org.codehaus.groovy.ast.ClassNode;
    67  import org.codehaus.groovy.ast.CompileUnit;
    68  import org.codehaus.groovy.ast.FieldNode;
    69  import org.codehaus.groovy.ast.ModuleNode;
    70  import org.codehaus.groovy.ast.expr.Expression;
    71  import org.codehaus.groovy.ast.expr.FieldExpression;
    72  import org.codehaus.groovy.ast.expr.MethodCallExpression;
    73  import org.codehaus.groovy.ast.stmt.ExpressionStatement;
    74  import org.codehaus.groovy.control.CompilerConfiguration;
    75  import org.codehaus.groovy.runtime.InvokerHelper;
    76  import org.objectweb.asm.Constants;
    77
    78  /***
    79   * Base class for test cases
    80   *
    81   * @author <a href="mailto:james@coredevelopers.net">James Strachan</a>
    82   * @version $Revision: 1.32 $
    83   */
    84  public class TestSupport extends GroovyTestCase implements Constants {
    85
    86      protected static boolean DUMP_CLASS = false;
    87
    88      // ClassLoader parentLoader = Thread.currentThread().getContextClassLoader();
    89      ClassLoader parentLoader = getClass().getClassLoader();
    90      protected GroovyClassLoader loader =
    91      	(GroovyClassLoader) AccessController.doPrivileged(new PrivilegedAction() {
    92      		public Object run() {
    93      			return (DUMP_CLASS)
    94  					? new DumpingClassLoader(parentLoader)
    95  					: new GroovyClassLoader(parentLoader);
    96      		}
    97      	});
    98      CompileUnit unit = new CompileUnit(parentLoader, new CompilerConfiguration());
    99      ModuleNode module = new ModuleNode(unit);
    100
    101     protected Class loadClass(ClassNode classNode) {
    102         classNode.setModule(module);
    103         Class fooClass = loader.defineClass(classNode, classNode.getName() + ".groovy", "groovy.testSupport");
    104         return fooClass;
    105     }
    106
    107     protected void assertSetProperty(Object bean, String property, Object newValue) throws Exception {
    108         PropertyDescriptor descriptor = getDescriptor(bean, property);
    109         Method method = descriptor.getWriteMethod();
    110         assertTrue("has setter method", method != null);
    111
    112         Object[] args = { newValue };
    113         Object value = invokeMethod(bean, method, args);
    114
    115         assertEquals("should return null", null, value);
    116
    117         assertGetProperty(bean, property, newValue);
    118     }
    119
    120     protected void assertGetProperty(Object bean, String property, Object expected) throws Exception {
    121         PropertyDescriptor descriptor = getDescriptor(bean, property);
    122         Method method = descriptor.getReadMethod();
    123         assertTrue("has getter method", method != null);
    124
    125         Object[] args = {
    126         };
    127         Object value = invokeMethod(bean, method, args);
    128
    129         /*
    130         System.out.println("Expected: " + expected);
    131         System.out.println("Value: " + value);
    132
    133         if (expected == null) { System.out.println("Expected is null"); }
    134         if (value == null) { System.out.println("value is null"); }
    135         */
    136
    137         assertEquals("property value", expected, value);
    138     }
    139
    140     protected Object invokeMethod(Object bean, Method method, Object[] args) throws Exception {
    141         try {
    142             return method.invoke(bean, args);
    143         }
    144         catch (InvocationTargetException e) {
    145             fail("InvocationTargetException: " + e.getTargetException());
    146             return null;
    147         }
    148     }
    149
    150     protected PropertyDescriptor getDescriptor(Object bean, String property) throws Exception {
    151         BeanInfo info = Introspector.getBeanInfo(bean.getClass());
    152         PropertyDescriptor[] descriptors = info.getPropertyDescriptors();
    153         for (int i = 0; i < descriptors.length; i++) {
    154             PropertyDescriptor descriptor = descriptors[i];
    155             if (descriptor.getName().equals(property)) {
    156                 return descriptor;
    157             }
    158         }
    159         fail("Could not find property: " + property + " on bean: " + bean);
    160         return null;
    161     }
    162
    163     protected void assertField(Class aClass, String name, int modifiers, String typeName) throws Exception {
    164         Field field = aClass.getDeclaredField(name);
    165
    166         assertTrue("Found field called: " + name, field != null);
    167         assertEquals("Name", name, field.getName());
    168         assertEquals("Type", typeName, field.getType().getName());
    169         assertEquals("Modifiers", modifiers, field.getModifiers());
    170     }
    171
    172     protected ExpressionStatement createPrintlnStatement(Expression expression) throws NoSuchFieldException {
    173         return new ExpressionStatement(
    174             new MethodCallExpression(
    175                 new FieldExpression(FieldNode.newStatic(System.class, "out")),
    176                 "println",
    177                 expression));
    178     }
    179
    180     /***
    181      * Asserts that the script runs without any exceptions
    182      * @param script
    183      */
    184     protected void assertScript(String text) throws Exception {
    185         assertScript(text, getTestClassName());
    186     }
    187
    188     protected void assertScript(final String text, final String scriptName) throws Exception {
    189         log.info("About to execute script");
    190         log.info(text);
    191     	GroovyCodeSource gcs = (GroovyCodeSource) AccessController.doPrivileged(new PrivilegedAction() {
    192     		public Object run() {
    193     			return new GroovyCodeSource(text, scriptName, "/groovy/testSupport");
    194     		}
    195     	});
    196         Class groovyClass = loader.parseClass(gcs);
    197         Script script = InvokerHelper.createScript(groovyClass, new Binding());
    198         script.run();
    199     }
    200
    201     protected void assertScriptFile(String fileName) throws Exception {
    202         log.info("About to execute script: " + fileName);
    203
    204         Class groovyClass = loader.parseClass(new GroovyCodeSource(new File(fileName)));
    205         Script script = InvokerHelper.createScript(groovyClass, new Binding());
    206         script.run();
    207     }
    208
    209     protected GroovyObject compile(String fileName) throws Exception {
    210         Class groovyClass = loader.parseClass(new GroovyCodeSource(new File(fileName)));
    211
    212         GroovyObject object = (GroovyObject) groovyClass.newInstance();
    213
    214         assertTrue(object != null);
    215
    216         return object;
    217     }
    218 }