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 }