/* * Copyright (C) 2009 The Android Open Source Project * * Licensed under the Eclipse Public License, Version 1.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.eclipse.org/org/documents/epl-v10.php * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.ide.eclipse.tests.groovytests; import org.codehaus.groovy.control.CompilationFailedException; import org.eclipse.swt.graphics.Rectangle; import groovy.lang.GroovyClassLoader; import java.io.FileNotFoundException; import java.io.InputStream; import junit.framework.TestCase; /** * Tests we can invoke a groovy script that implements a given interface. */ public class TestGroovy extends TestCase { @Override protected void setUp() throws Exception { super.setUp(); } /** * This is the interface that we want our Groovy script to implement. */ public static interface AdtTestInterface { /** Method that returns a boolean. */ public boolean acceptDrag(String xmlName); /** Method that returns an SWT Rectangle. */ public Rectangle acceptDrop(String xmlName); /** Method that returns some Groovy object (opaque for us). */ public Object returnGroovyObject(); /** Method that accepts the Groovy object back. */ public boolean testGroovyObject(Object o); } /** * Loads a groovy script that defines one class that implements the {@link AdtTestInterface}. * * @param filename The name of the script to load, that must be located in this Java package. * @return A non-null instance of the groovy class on success. * @throws CompilationFailedException if the groovy script failed to compile (e.g. syntax * errors or it doesn't completely implement the interface.) * @throws ClassCastException if the groovy script does not implement our interface. * @throws FileNotFoundException if the groovy script does not exist. * @throws InstantiationException * @throws IllegalAccessException */ @SuppressWarnings("unchecked") private AdtTestInterface loadScript(String filename) throws CompilationFailedException, ClassCastException, InstantiationException, IllegalAccessException, FileNotFoundException { // Get the input source from the sources or the JAR. InputStream myGroovyStream = getClass().getResourceAsStream(filename); // The stream is null if the file does not exists. if (myGroovyStream == null) { throw new FileNotFoundException(filename); } // Create a groovy class from it. Can fail to compile. ClassLoader cl = getClass().getClassLoader(); GroovyClassLoader gcl = new GroovyClassLoader(cl); Class gClass = gcl.parseClass(myGroovyStream, filename); // Get an instance. This might throw ClassCastException. return (AdtTestInterface) gClass.newInstance(); } /** * Tests that a {@link FileNotFoundException} is thrown if when trying * to load a missing script. */ public void testMissingScript() throws Exception { try { @SuppressWarnings("unused") AdtTestInterface instance = loadScript("not_an_existing_script.groovy"); fail("loadScript should not succeed, FileNotFoundException expected."); } catch (FileNotFoundException e) { assertEquals("not_an_existing_script.groovy", e.getMessage()); return; // succeed } fail("Script failed to throw an exception on missing groovy file."); } /** * Tests that a {@link ClassCastException} is thrown if the script does not * implement our interface. */ public void testInvalidInterface() throws Exception { try { @SuppressWarnings("unused") AdtTestInterface instance = loadScript("invalid_interface.groovy"); fail("loadScript should not succeed, ClassCastException expected."); } catch(ClassCastException e) { // This has to fail because the script does not implement our interface // The message explains why but we're not harcoding the message in the test. assertNotNull(e.getMessage()); return; // succeed } fail("Script failed to throw a ClassCastException."); } /** * Tests that a {@link CompilationFailedException} is thrown if the script * is not valid. */ public void testCompilationError() throws Exception { try { @SuppressWarnings("unused") AdtTestInterface instance = loadScript("compile_error.groovy"); fail("loadScript should not succeed, CompilationFailedException expected."); } catch (CompilationFailedException e) { // This script does not compile, the message explains why but we're not // harcoding the message in the test. assertNotNull(e.getMessage()); return; // succeed } fail("Script failed to throw a compilation error."); } /** * Tests a valid script scenario with only some basic methods */ public void testSimpleMethods() throws Exception { AdtTestInterface instance = loadScript("simple_test.groovy"); assertTrue(instance.acceptDrag("LinearLayout")); assertFalse(instance.acceptDrag("RelativeLayout")); assertNull(instance.acceptDrop("none")); Rectangle r = instance.acceptDrop("LinearLayout"); assertNotNull(r); assertEquals(new Rectangle(1, 2, 3, 4), r); } /** * Tests a valid script scenario with some methods providing some callbacks. */ public void testCallback() throws Exception { AdtTestInterface instance = loadScript("simple_test.groovy"); // The groovy method returns an object. We should treat it as an opaque object // which purpose is just to give it back to groovy later. Object o = instance.returnGroovyObject(); assertNotNull(o); // Let the groovy script get back the object and play with it assertTrue(instance.testGroovyObject(o)); } }