    1   package org.codehaus.groovy.classgen;
    2
    3   /*
    4    $Id: TestSupport.java,v 1.36 2005/11/13 16:42:14 blackdrag Exp $
    5
    6    Copyright 2003 (C) James Strachan and Bob Mcwhirter. All Rights Reserved.
    7
    8    Redistribution and use of this software and associated documentation
    9    ("Software"), with or without modification, are permitted provided
    10   that the following conditions are met:
    11
    12   1. Redistributions of source code must retain copyright
    13      statements and notices.  Redistributions must also contain a
    14      copy of this document.
    15
    16   2. Redistributions in binary form must reproduce the
    17      above copyright notice, this list of conditions and the
    18      following disclaimer in the documentation and/or other
    19      materials provided with the distribution.
    20
    21   3. The name "groovy" must not be used to endorse or promote
    22      products derived from this Software without prior written
    23      permission of The Codehaus.  For written permission,
    24      please contact info@codehaus.org.
    25
    26   4. Products derived from this Software may not be called "groovy"
    27      nor may "groovy" appear in their names without prior written
    28      permission of The Codehaus. "groovy" is a registered
    29      trademark of The Codehaus.
    30
    31   5. Due credit should be given to The Codehaus -
    32      http://groovy.codehaus.org/
    33
    34   THIS SOFTWARE IS PROVIDED BY THE CODEHAUS AND CONTRIBUTORS
    35   ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
    36   NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
    37   FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
    38   THE CODEHAUS OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
    39   INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
    40   (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
    41   SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
    42   HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
    43   STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
    44   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
    45   OF THE POSSIBILITY OF SUCH DAMAGE.
    46
    47   */
    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.Opcodes;
    77
    78  /***
    79   * Base class for test cases
    80   *
    81   * @author <a href="mailto:james@coredevelopers.net">James Strachan</a>
    82   * @version $Revision: 1.36 $
    83   */
    84  public class TestSupport extends GroovyTestCase implements Opcodes {
    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 new GroovyClassLoader(parentLoader);
    94      		}
    95      	});
    96      CompileUnit unit = new CompileUnit(loader, new CompilerConfiguration());
    97      ModuleNode module = new ModuleNode(unit);
    98
    99      protected Class loadClass(ClassNode classNode) {
    100         classNode.setModule(module);
    101         Class fooClass = loader.defineClass(classNode, classNode.getName() + ".groovy", "groovy.testSupport");
    102         return fooClass;
    103     }
    104
    105     protected void assertSetProperty(Object bean, String property, Object newValue) throws Exception {
    106         PropertyDescriptor descriptor = getDescriptor(bean, property);
    107         Method method = descriptor.getWriteMethod();
    108         assertTrue("has setter method", method != null);
    109
    110         Object[] args = { newValue };
    111         Object value = invokeMethod(bean, method, args);
    112
    113         assertEquals("should return null", null, value);
    114
    115         assertGetProperty(bean, property, newValue);
    116     }
    117
    118     protected void assertGetProperty(Object bean, String property, Object expected) throws Exception {
    119         PropertyDescriptor descriptor = getDescriptor(bean, property);
    120         Method method = descriptor.getReadMethod();
    121         assertTrue("has getter method", method != null);
    122
    123         Object[] args = {
    124         };
    125         Object value = invokeMethod(bean, method, args);
    126
    127         /*
    128         System.out.println("Expected: " + expected);
    129         System.out.println("Value: " + value);
    130
    131         if (expected == null) { System.out.println("Expected is null"); }
    132         if (value == null) { System.out.println("value is null"); }
    133         */
    134
    135         assertEquals("property value", expected, value);
    136     }
    137
    138     protected Object invokeMethod(Object bean, Method method, Object[] args) throws Exception {
    139         try {
    140             return method.invoke(bean, args);
    141         }
    142         catch (InvocationTargetException e) {
    143             fail("InvocationTargetException: " + e.getTargetException());
    144             return null;
    145         }
    146     }
    147
    148     protected PropertyDescriptor getDescriptor(Object bean, String property) throws Exception {
    149         BeanInfo info = Introspector.getBeanInfo(bean.getClass());
    150         PropertyDescriptor[] descriptors = info.getPropertyDescriptors();
    151         for (int i = 0; i < descriptors.length; i++) {
    152             PropertyDescriptor descriptor = descriptors[i];
    153             if (descriptor.getName().equals(property)) {
    154                 return descriptor;
    155             }
    156         }
    157         fail("Could not find property: " + property + " on bean: " + bean);
    158         return null;
    159     }
    160
    161     protected void assertField(Class aClass, String name, int modifiers, ClassNode type) throws Exception {
    162         Field field = aClass.getDeclaredField(name);
    163
    164         assertTrue("Found field called: " + name, field != null);
    165         assertEquals("Name", name, field.getName());
    166         assertEquals("Type", type.getName(), field.getType().getName());
    167         assertEquals("Modifiers", modifiers, field.getModifiers());
    168     }
    169
    170     protected ExpressionStatement createPrintlnStatement(Expression expression) throws NoSuchFieldException {
    171         return new ExpressionStatement(
    172             new MethodCallExpression(
    173                 new FieldExpression(FieldNode.newStatic(System.class, "out")),
    174                 "println",
    175                 expression));
    176     }
    177
    178     /***
    179      * Asserts that the script runs without any exceptions
    180      */
    181     protected void assertScript(String text) throws Exception {
    182         assertScript(text, getTestClassName());
    183     }
    184
    185     protected void assertScript(final String text, final String scriptName) throws Exception {
    186         log.info("About to execute script");
    187         log.info(text);
    188     	GroovyCodeSource gcs = (GroovyCodeSource) AccessController.doPrivileged(new PrivilegedAction() {
    189     		public Object run() {
    190     			return new GroovyCodeSource(text, scriptName, "/groovy/testSupport");
    191     		}
    192     	});
    193         Class groovyClass = loader.parseClass(gcs);
    194         Script script = InvokerHelper.createScript(groovyClass, new Binding());
    195         script.run();
    196     }
    197
    198     protected void assertScriptFile(String fileName) throws Exception {
    199         log.info("About to execute script: " + fileName);
    200
    201         Class groovyClass = loader.parseClass(new GroovyCodeSource(new File(fileName)));
    202         Script script = InvokerHelper.createScript(groovyClass, new Binding());
    203         script.run();
    204     }
    205
    206     protected GroovyObject compile(String fileName) throws Exception {
    207         Class groovyClass = loader.parseClass(new GroovyCodeSource(new File(fileName)));
    208
    209         GroovyObject object = (GroovyObject) groovyClass.newInstance();
    210
    211         assertTrue(object != null);
    212
    213         return object;
    214     }
    215 }