/*******************************************************************************
* Copyright (c) 2012 VMWare, Inc.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* VMWare, Inc. - initial API and implementation
*******************************************************************************/
package org.grails.ide.eclipse.test;
import java.io.File;
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.net.URLClassLoader;
import java.util.HashSet;
import java.util.Set;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IProjectDescription;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.internal.junit.launcher.ITestFinder;
import org.eclipse.jdt.internal.junit.model.TestRunSession;
import org.eclipse.jdt.launching.JavaRuntime;
import org.grails.ide.eclipse.commands.GrailsCommand;
import org.grails.ide.eclipse.commands.GrailsCommandFactory;
import org.grails.ide.eclipse.core.junit.Grails20AwareTestFinder;
import org.grails.ide.eclipse.core.launch.SynchLaunch.ILaunchResult;
import org.grails.ide.eclipse.core.model.GrailsVersion;
import org.osgi.framework.Bundle;
import org.springsource.ide.eclipse.commons.tests.util.StsTestUtil;
import org.grails.ide.eclipse.test.util.AbstractGrailsJUnitIntegrationsTest;
import org.grails.ide.eclipse.test.util.GrailsTest;
/**
* Tests for the 'run as >> Junit test' functionality provided by JDT. We are testing here whether
* our hackery intended to make it work with Grails 2.0 actually does what it is intended to do,
* while not breaking JUnit 3 style test finding and running.
*
* @author Kris De Volder
*
* @since 2.9
*/
public class Grails20JUnitIntegrationTests extends AbstractGrailsJUnitIntegrationsTest {
public final String TEST_PROJECT_NAME = this.getClass().getSimpleName();
private IProject project;
private IJavaProject javaProject;
private String packageName; // name of the package most classes are in
private String domainClassName; // name of the single domain class present in the 'base-line' test application.
private String testDomainClassName; // name of the test class containing tests for the domain class.
private String domainClassBaseName;
private String generatedTestMethodName;
private static boolean domainClassCreated = false;
@Override
protected void setUp() throws Exception {
super.setUp();
assertTrue("This test assumes Grails 20 but most recent Grails version is "+GrailsVersion.MOST_RECENT,
GrailsVersion.MOST_RECENT.compareTo(GrailsVersion.V_2_0_0)>=0);
ensureDefaultGrailsVersion(GrailsVersion.MOST_RECENT);
setJava17Compliance();
project = ensureProject(TEST_PROJECT_NAME);
javaProject = JavaCore.create(project);
//Add a generated domain class to make the base-line test project a bit more interesting.
packageName = TEST_PROJECT_NAME.toLowerCase();
domainClassBaseName = "Song";
domainClassName = packageName + "." + domainClassBaseName;
if (!domainClassCreated) {
GrailsCommand cmd = GrailsCommandFactory.createDomainClass(project, domainClassName);
ILaunchResult result = cmd.synchExec();
System.out.println(result.getOutput());
project.refreshLocal(IResource.DEPTH_INFINITE, null);
domainClassCreated = true;
}
if (GrailsVersion.MOST_RECENT.compareTo(GrailsVersion.V_2_3_)>=0) {
testDomainClassName = domainClassName + "Spec";
generatedTestMethodName = "test something";
//Replace generated 2.3.0 spock test with a test that actually has some test code in it.
createResource(project, "test/unit/grails20junitintegrationtests/SongSpec.groovy",
"package grails20junitintegrationtests\n" +
"\n" +
"import grails.test.mixin.TestFor\n" +
"import spock.lang.Specification\n" +
"\n" +
"/**\n" +
" * See the API for {@link grails.test.mixin.domain.DomainClassUnitTestMixin} for usage instructions\n" +
" */\n" +
"@TestFor(Song)\n" +
"class SongSpec extends Specification {\n" +
"\n" +
" def setup() {\n" +
" }\n" +
"\n" +
" def cleanup() {\n" +
" }\n" +
"\n" +
" void \"test something\"() {\n" +
" expect: \"Implement me\"==\"not implemented\"\n" +
" }\n" +
"}\n"
);
//Ensure project gets built with new SongSpec class.
StsTestUtil.assertNoErrors(project);
} else {
testDomainClassName = domainClassName + "Tests";
generatedTestMethodName = "testSomething";
}
}
@Override
protected void tearDown() throws Exception {
super.tearDown();
}
public void testScaffolding() throws Exception {
StsTestUtil.assertNoErrors(project);
}
public void testOurTestFinderIsInstalled() {
ITestFinder finder = getJUnit4TestFinder();
assertTrue(finder instanceof Grails20AwareTestFinder);
}
// /**
// * For some unkown reason, JUnit 4 classpath container isn't resolving on the build server.
// * This test is trying to determine why. It does so by using a local copy of the P2Utils class
// * that is used by the JUnit support in jdt to find the junit 4 bundle and extract a jar file location from it.
// */
// public void testJUnit4BundlesAndStuff() throws Exception {
// IClasspathEntry junit4lib = BuildPathSupport.getJUnit4LibraryEntry();
// System.out.println("Junit 4 library entry = "+junit4lib);
//
// BundleInfo bundleInfo = P2Utils.findBundle("org.junit", new VersionRange("[4.7.0,5.0.0)"), false);
// System.out.println("bundleInfo = "+bundleInfo); //Example of what we expect: BundleInfo(org.junit, 4.8.2.v4_8_2_v20110321-1705, location=file:/home/kdvolder/Applications/springsource-2.9.0.M1/sts-2.9.0.M1/plugins/org.junit_4.8.2.v4_8_2_v20110321-1705/, startLevel=4, toBeStarted=false, resolved=false, id=-1,no manifest)
//
// IPath bundleLocation = P2Utils.getBundleLocationPath(bundleInfo);
// System.out.println("bundle location = "+bundleLocation);
//
// assertNotNull(bundleLocation);
//
// //What this test is printing on my machine (where the JUnit tests are passing ok)
// /*
// Junit 4 library entry = /home/kdvolder/Applications/springsource-2.9.0.M1/sts-2.9.0.M1/plugins/org.junit_4.8.2.v4_8_2_v20110321-1705/junit.jar[CPE_LIBRARY][K_BINARY][sourcePath:/home/kdvolder/Applications/springsource-2.9.0.M1/sts-2.9.0.M1/plugins/org.junit.source_4.8.2.v4_8_2_v20110321-1705.jar][isExported:false][attributes:javadoc_location=http://www.junit.org/junit/javadoc/4.5]
// bundleInfo = BundleInfo(org.junit, 4.8.2.v4_8_2_v20110321-1705, location=file:/home/kdvolder/Applications/springsource-2.9.0.M1/sts-2.9.0.M1/plugins/org.junit_4.8.2.v4_8_2_v20110321-1705/, startLevel=4, toBeStarted=false, resolved=false, id=-1,no manifest)
// /home/kdvolder/Applications/springsource-2.9.0.M1/sts-2.9.0.M1/plugins/org.junit_4.8.2.v4_8_2_v20110321-1705/
// */
// }
/**
* Test whether test finder still works for a pretty standard JDT Java project.
*/
public void testDontBreakJDT() throws Exception {
ITestFinder testFinder = getJUnit4TestFinder();
IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject("sts2312");
project.create(new NullProgressMonitor());
project.open(new NullProgressMonitor());
IProjectDescription desc = project.getDescription();
String[] natures = desc.getNatureIds();
String[] newNatures = new String[natures.length+1];
System.arraycopy(natures, 0, newNatures, 0, natures.length);
newNatures[natures.length] = JavaCore.NATURE_ID;
desc.setNatureIds(newNatures);
project.setDescription(desc, new NullProgressMonitor());
javaProject = JavaCore.create(project);
IPath outputLocation = new Path("/"+project.getName()+"/bin");
IClasspathEntry[] entries = new IClasspathEntry[] {
JavaCore.newContainerEntry(JavaRuntime.newDefaultJREContainerPath()),
getJUnit4JarEntry(),
JavaCore.newSourceEntry(new Path("/"+project.getName()+"/src")),
JavaCore.newSourceEntry(new Path("/"+project.getName()+"/test")),
};
javaProject.setRawClasspath(entries, outputLocation, new NullProgressMonitor());
createResource(project, "src/foo/Main.java",
"package foo;\n" +
"public class Main {\n" +
" public static void main(String[] args) {\n" +
" System.out.println(\"Hello\");\n" +
" }" +
"}");
createResource(project, "test/foo/Test1.java",
"package foo;\n" +
"\n" +
"import junit.framework.TestCase;\n" +
"\n" +
"public class Test1 extends TestCase {\n" +
" public void testSomething(String[] args) {\n" +
" System.out.println(\"Hello\");\n" +
" }" +
"}");
createResource(project, "src/foo/Test2.java",
"package foo;\n" +
"\n" +
"import junit.framework.TestCase;\n" +
"\n" +
"public class Test2 extends TestCase {\n" +
" public void testSomething(String[] args) {\n" +
" System.out.println(\"Hello\");\n" +
" }" +
"}");
StsTestUtil.dumpClasspathInfo(javaProject);
StsTestUtil.assertNoErrors(project);
IType test1 = javaProject.findType("foo.Test1");
IType test2 = javaProject.findType("foo.Test2");
assertNotNull(test1);
assertNotNull(test2);
assertTrue(testFinder.isTest(test1));
assertTrue(testFinder.isTest(test2));
{ // find in project
HashSet result = new HashSet();
testFinder.findTestsInContainer(javaProject, result, new NullProgressMonitor());
assertElements(result, test1, test2);
}
{ //find in type
HashSet result = new HashSet();
testFinder.findTestsInContainer(test1, result, new NullProgressMonitor());
assertElements(result, test1);
}
{ //find in type
HashSet result = new HashSet();
testFinder.findTestsInContainer(test2, result, new NullProgressMonitor());
assertElements(result, test2);
}
}
private IClasspathEntry getJUnit4JarEntry() throws IOException {
Bundle[] bundles = Platform.getBundles("org.junit", "4.7.0");
File bundleFile = FileLocator.getBundleFile(bundles[0]);
assertTrue("bundleFile doesn't exist: "+bundleFile, bundleFile.exists());
assertTrue("bundleFile isn't a directory: "+bundleFile, bundleFile.isDirectory());
for (File file : bundleFile.listFiles()) {
if (file.getName().equals("junit.jar")) {
return JavaCore.newLibraryEntry(new Path(file.toString()), null, null, true);
}
}
fail("Couldn't find Junit jar file");
return null; //unreachable code
}
/**
* Test basic function of the 'isTest' method in the test finder:
* - a domain class isn't a test
* - a class in the test/unit source folder is a test
*
* @throws Exception
*/
public void testTestFinderIsTest() throws Exception {
ITestFinder testFinder = getJUnit4TestFinder();
IType domainClass = javaProject.findType(domainClassName);
assertNotNull(domainClass);
assertFalse(testFinder.isTest(domainClass));
IType testClass = javaProject.findType(testDomainClassName);
assertNotNull(testClass);
assertTrue(testFinder.isTest(testClass));
createTmpResource(project, "test/integration/"+packageName+"/FoobarTests.groovy",
"package grails20junitintegrationtests\n" +
"\n" +
"import grails.test.mixin.*\n" +
"\n" +
"@TestFor("+domainClassBaseName+")\n" +
"class FoobarTests {\n" +
"\n" +
" void testThisAndThat() {\n" +
" assertEquals 4, 4\n" +
" }\n" +
" \n" +
"}");
StsTestUtil.waitForAutoBuild();
IType integTests = javaProject.findType(packageName+".FoobarTests");
assertNotNull(integTests);
assertTrue(testFinder.isTest(integTests));
}
/**
* Test slightly more 'advanced' cases.
* - a helper class present in the unit testing source folder shouldn't be
* recognized as a test class.
*
* @throws Exception
*/
public void testTestFinderIsTest2() throws Exception {
ITestFinder testFinder = getJUnit4TestFinder();
createTmpResource(project, "test/unit/"+packageName+"/Helper.groovy",
"package "+packageName+"\n" +
"\n" +
"class Helper {\n" +
"\n" +
" void help() {\n" +
" println 'help!'\n" +
" }\n" +
"}");
StsTestUtil.waitForAutoBuild();
IType clazz = javaProject.findType(packageName+".Helper");
assertNotNull(clazz);
assertFalse(testFinder.isTest(clazz));
}
public void testTestFinderFindTest() throws Exception {
ITestFinder testFinder = getJUnit4TestFinder();
createTmpResource(project, "test/unit/"+packageName+"/Helper.groovy",
"package "+packageName+"\n" +
"\n" +
"class Helper {\n" +
"\n" +
" void help() {\n" +
" println 'help!'\n" +
" }\n" +
"}");
StsTestUtil.waitForAutoBuild();
IType clazz = javaProject.findType(packageName+".Helper");
assertNotNull(clazz);
//1) Search in a cu that doesn't have a test class inside.
Set<Object> result = new HashSet<Object>();
testFinder.findTestsInContainer(clazz.getCompilationUnit(), result, new NullProgressMonitor());
assertEquals(0, result.size());
//2) Search in a cu that does have a test class inside
result = new HashSet<Object>();
clazz = javaProject.findType(testDomainClassName);
testFinder.findTestsInContainer(clazz.getCompilationUnit(), result, new NullProgressMonitor());
GrailsTest.assertElements(result, clazz);
//3) Search in test/unit package fragment root
result = new HashSet<Object>();
IJavaElement pfr = clazz.getAncestor(IJavaElement.PACKAGE_FRAGMENT_ROOT);
testFinder.findTestsInContainer(pfr, result, new NullProgressMonitor());
GrailsTest.assertElements(result, clazz);
//4) Same as above, but add an extra test class to see if that's also found.
createTmpResource(project, "test/unit/"+packageName+"/FoobarTests.groovy",
"package grails20junitintegrationtests\n" +
"\n" +
"import grails.test.mixin.*\n" +
"\n" +
"@TestFor("+domainClassBaseName+")\n" +
"class FoobarTests {\n" +
"\n" +
" void testThisAndThat() {\n" +
" assertEquals 4, 4\n" +
" }\n" +
" \n" +
"}");
StsTestUtil.waitForAutoBuild();
IType extraTestClass = javaProject.findType(packageName+".FoobarTests");
testFinder.findTestsInContainer(pfr, result, new NullProgressMonitor());
GrailsTest.assertElements(result, clazz, extraTestClass);
//5) One more time, now search the whole project
result = new HashSet<Object>();
testFinder.findTestsInContainer(javaProject, result, new NullProgressMonitor());
GrailsTest.assertElements(result, clazz, extraTestClass);
}
public void testTestFinderFindTestInSourceFileWithoutATestClass() throws Exception {
ITestFinder testFinder = getJUnit4TestFinder();
createTmpResource(project, "test/unit/"+packageName+"/Helper.groovy",
"package "+packageName+"\n" +
"\n" +
"class Helper {\n" +
"\n" +
" void help() {\n" +
" println 'help!'\n" +
" }\n" +
"}");
StsTestUtil.waitForAutoBuild();
IType clazz = javaProject.findType(packageName+".Helper");
assertNotNull(clazz);
Set<Object> result = new HashSet<Object>();
testFinder.findTestsInContainer(clazz.getCompilationUnit(), result, new NullProgressMonitor());
assertEquals(0, result.size());
}
@SuppressWarnings("rawtypes")
public void testThatASTTransformGotExecuted() throws Exception {
//We check this indirectly, by checking whether the TestFor annotation exists on the testMethod, as expected, in the
//byte code... We do this by creating a URLClassLoader from the projects resolved runtime classpath and then loading
//up the test class.
//This test only applies to 'regular' tests with the @TestFor annotation on the class.
// It doesn't apply to the spock test generated in Grails 2.3 so we create a old style test
// here to verify this still works.
createTmpResource(project, "test/unit/"+packageName+"/FoobarTests.groovy",
"package grails20junitintegrationtests\n" +
"\n" +
"import grails.test.mixin.*\n" +
"\n" +
"@TestFor("+domainClassBaseName+")\n" +
"class FoobarTests {\n" +
"\n" +
" void testThisAndThat() {\n" +
" assertEquals 4, 4\n" +
" }\n" +
" \n" +
"}");
//Build project is required for the new code to be compiled by Eclipse:
StsTestUtil.assertNoErrors(project);
URLClassLoader classLoader = getRuntimeClassLoader(javaProject);
Class testClass = Class.forName(packageName+".FoobarTests", false, classLoader);
Method m = getMethod(testClass, "testThisAndThat");
assertAnnotation(m, "org.junit.Test");
}
/**
* Test a simple JUnit test run, while registering a test listener to capture the results.
*
* @throws Exception
*/
public void testSimpleRun() throws Exception {
TestRunSession session = runAsJUnit(javaProject);
assertTestFailure(session, "Implement me", testDomainClassName, generatedTestMethodName);
//Also check the numbers of test run, failed etc.
assertEquals(1, session.getStartedCount());
assertEquals(0, session.getErrorCount());
assertEquals(1, session.getFailureCount());
assertEquals(1, session.getTotalCount());
}
/**
* Verify whether test finder and runner is still capable of identifying, finding and running
* JUnit 3 style test types.
*/
public void testFinderJUnit3Compatibility() throws Exception {
createTmpResource(project, "test/unit/"+packageName+"/ExtraTests.groovy",
"package "+packageName+"\n" +
"\n" +
"import grails.test.GrailsUnitTestCase;\n" +
"\n" +
"class ExtraTests extends GrailsUnitTestCase {\n" +
" \n" +
" void testSomething() {\n" +
" fail('Testing JUnit3 compatibility')\n" +
" }\n" +
"\n" +
"}"
);
StsTestUtil.waitForAutoBuild();
//Is it a test?
IType type = javaProject.findType(packageName+".ExtraTests");
ITestFinder testFinder = getJUnit4TestFinder();
assertTrue(testFinder.isTest(type));
//Can we find the test?
HashSet<Object> result = new HashSet<Object>();
testFinder.findTestsInContainer(javaProject, result, new NullProgressMonitor());
assertElements(result,
type,
javaProject.findType(testDomainClassName)
);
//Can we run the test and get expected result?
TestRunSession session = runAsJUnit(type);
assertTestFailure(session, "Testing JUnit3 compatibility",
type.getFullyQualifiedName(), "testSomething");
}
public void testDoIncludeIntegrationTestsIfJUnit3() throws Exception {
createTmpResource(project, "test/integration/"+packageName+"/ExtraTests.groovy",
"package "+packageName+"\n" +
"\n" +
"import grails.test.GrailsUnitTestCase;\n" +
"\n" +
"class ExtraTests extends GrailsUnitTestCase {\n" +
" \n" +
" void testSomething() {\n" +
" fail('Testing JUnit3 compatibility')\n" +
" }\n" +
"\n" +
"}"
);
StsTestUtil.waitForAutoBuild();
//Is it a test? (Should say YES) see https://issuetracker.springsource.com/browse/STS-2481
IType type = javaProject.findType(packageName+".ExtraTests");
ITestFinder testFinder = getJUnit4TestFinder();
assertTrue(testFinder.isTest(type));
//Can we find the test? (SHOULD) see https://issuetracker.springsource.com/browse/STS-2481
HashSet<Object> result = new HashSet<Object>();
testFinder.findTestsInContainer(javaProject, result, new NullProgressMonitor());
assertElements(result,
javaProject.findType(testDomainClassName),
type
);
}
public void testDoIncludeGrailsIntegrationTests() throws Exception {
String className = "SongITests";
createTmpResource(project, "test/integration/"+packageName+"/"+className+".groovy",
"package "+packageName+"\n" +
"\n" +
"import static org.junit.Assert.*\n" +
"import grails.test.mixin.TestFor\n" +
"\n" +
"import org.junit.*\n" +
"\n" +
"@TestFor(Song)\n" +
"class "+className+ " {\n" +
"\n" +
" void testSomething() {\n" +
" fail \"Implement me\"\n" +
" }\n" +
"}\n");
StsTestUtil.waitForAutoBuild();
//Is it a test? (Should say YES) see: https://issuetracker.springsource.com/browse/STS-2481
IType type = javaProject.findType(packageName+"."+className);
ITestFinder testFinder = getJUnit4TestFinder();
assertTrue(testFinder.isTest(type));
//Can we find the test? (SHOULD) see: https://issuetracker.springsource.com/browse/STS-2481
HashSet<Object> result = new HashSet<Object>();
testFinder.findTestsInContainer(javaProject, result, new NullProgressMonitor());
assertElements(result,
javaProject.findType(testDomainClassName),
type
);
//Run test with expected result?
TestRunSession session = runAsJUnit(javaProject);
assertTestFailure(session, "Implement me", type.getFullyQualifiedName(), "testSomething");
}
public void testDoIncludeIntegrationTestsIfJUnit4() throws Exception {
String className = "SampleIntegrationTest";
createTmpResource(project, "test/integration/"+packageName+"/"+className+".groovy",
"package "+packageName+"\n" +
"\n" +
"import org.junit.Test\n" +
"import static org.junit.Assert.*\n" +
"\n" +
"class "+className+" {\n" +
" \n" +
" @Test\n" +
" void hello() {\n" +
" assertTrue(true)\n" +
" }\n" +
"\n" +
"}\n"
);
StsTestUtil.waitForAutoBuild();
//Is it a test? (Should say YES) see: https://issuetracker.springsource.com/browse/STS-2481
IType type = javaProject.findType(packageName+"."+className);
ITestFinder testFinder = getJUnit4TestFinder();
assertTrue(testFinder.isTest(type));
//Can we find the test? (SHOULD) see: https://issuetracker.springsource.com/browse/STS-2481
HashSet<Object> result = new HashSet<Object>();
testFinder.findTestsInContainer(javaProject, result, new NullProgressMonitor());
assertElements(result,
javaProject.findType(testDomainClassName),
type
);
}
public void testOrdinaryJUNit4TestsInGrailsProject() throws Exception {
String className = "FooTest";
createTmpResource(project, "src/java/"+packageName+"/"+className+".java",
"package "+packageName+";\n" +
"\n" +
"import static org.junit.Assert.*;\n" +
"\n" +
"import org.junit.Test;\n" +
"\n" +
"public class "+className+" {\n" +
"\n" +
" @Test\n" +
" public void oneThatFails() {\n" +
" fail(\"not implemented\");\n" +
" }\n" +
"\n" +
"}\n");
StsTestUtil.waitForAutoBuild();
//Is it a test? (Should say YES) see: https://issuetracker.springsource.com/browse/STS-2481
IType type = javaProject.findType(packageName+"."+className);
ITestFinder testFinder = getJUnit4TestFinder();
assertTrue(testFinder.isTest(type));
//Can we find the test? (SHOULD) see: https://issuetracker.springsource.com/browse/STS-2481
HashSet<Object> result = new HashSet<Object>();
testFinder.findTestsInContainer(javaProject, result, new NullProgressMonitor());
assertElements(result,
javaProject.findType(testDomainClassName),
type
);
//Can we run the test and get expected result?
TestRunSession session = runAsJUnit(javaProject);
assertTestFailure(session, "not implemented", type.getFullyQualifiedName(), "oneThatFails");
}
public void testOrdinaryJUNit3TestsInGrailsProject() throws Exception {
String className = "FooTest";
createTmpResource(project, "src/java/"+packageName+"/"+className+".java",
"package grails20junitintegrationtests;\n" +
"\n" +
"import static org.junit.Assert.*;\n" +
"import junit.framework.TestCase;\n" +
"\n" +
"import org.junit.Test;\n" +
"\n" +
"public class "+className+ " extends TestCase {\n" +
" \n" +
" public void testThatFails() {\n" +
" fail(\"not implemented\");\n" +
" }\n" +
" \n" +
"}\n" +
"");
StsTestUtil.waitForAutoBuild();
//Is it a test? (Should say YES) see: https://issuetracker.springsource.com/browse/STS-2481
IType type = javaProject.findType(packageName+"."+className);
ITestFinder testFinder = getJUnit4TestFinder();
assertTrue(testFinder.isTest(type));
//Can we find the test? (SHOULD) see: https://issuetracker.springsource.com/browse/STS-2481
HashSet<Object> result = new HashSet<Object>();
testFinder.findTestsInContainer(javaProject, result, new NullProgressMonitor());
assertElements(result,
javaProject.findType(testDomainClassName),
type
);
//Can we run the test and get expected result?
TestRunSession session = runAsJUnit(javaProject);
assertTestFailure(session, "not implemented", type.getFullyQualifiedName(), "testThatFails");
}
/**
* When a Grails unit test class doesn't have the @TestFor annotation, but it has
* a name SomeDomainTests and there's a corresponding SomeDomain class, then
* it should be treated the same as if the @TestFor(SomeDomain) annotation was present.
*/
public void testNoAnnotationButCorrespondingDomainClassExists() throws Exception {
// Grails20TestSupport.DEBUG = true; //Compile will fail until Greclipse update site has newer version.
try {
tmpReplaceResource(project, "test/unit/"+packageName+"/"+domainClassBaseName+"Tests.groovy",
"package "+packageName+"\n" +
"\n" +
//@TestFor !!!!ANNOTATION REMOVED!!!!
"class "+domainClassBaseName+"Tests {\n" +
" \n" +
" void testSomething() {\n" +
" fail('Testing JUnit3 compatibility')\n" +
" }\n" +
"}"
);
StsTestUtil.waitForAutoBuild();
StsTestUtil.assertNoErrors(project);
//Using the locally created one instead of the generated one (which is a Spock test for Grails 2.3).
String testDomainClassName = packageName+"."+domainClassBaseName+"Tests";
//Is it a test?
IType type = javaProject.findType(testDomainClassName);
ITestFinder testFinder = getJUnit4TestFinder();
assertTrue(testFinder.isTest(type));
//Can we find the test?
HashSet<Object> result = new HashSet<Object>();
testFinder.findTestsInContainer(javaProject, result, new NullProgressMonitor());
int numTests;
if (GrailsVersion.MOST_RECENT.compareTo(GrailsVersion.V_2_3_)>=0) {
assertElements(result,
javaProject.findType(testDomainClassName),
javaProject.findType(this.testDomainClassName) //generated 'Spec' test in 2.3
);
numTests = 2;
} else {
numTests = 1;
assertElements(result,
javaProject.findType(testDomainClassName)
);
}
//Did the transform run?
URLClassLoader classLoader = getRuntimeClassLoader(javaProject);
Class testClass = Class.forName(testDomainClassName, false, classLoader);
Method m = getMethod(testClass, "testSomething");
assertAnnotation(m, "org.junit.Test"); //should have been added by the transform.
//Can we run the test
TestRunSession session = runAsJUnit(javaProject);
assertTestFailure(session, "Testing JUnit3 compatibility", testDomainClassName, "testSomething");
//Also check the numbers of test run, failed etc.
assertEquals(numTests, session.getStartedCount());
assertEquals(numTests, session.getFailureCount() + session.getErrorCount());
assertEquals(numTests, session.getTotalCount());
} finally {
// Grails20TestSupport.DEBUG = false;
}
}
private void assertAnnotation(Method m, String qName) {
for (Annotation a : m.getAnnotations()) {
String foundName = a.annotationType().getName();
if (foundName.equals(qName)) {
return;
}
}
fail("Annotation "+qName+" not found on "+m);
}
private Method getMethod(Class<?> clazz, String name) {
for (Method m : clazz.getMethods()) {
if (m.getName().equals(name)) {
return m;
}
}
return null;
}
}