Rework TestlibTest, use JUnit console runner instead of manual suite
The problem with the manually created suite was that it was created in setUp() and so a lot of the hard work (compilation, test case lookup) was happening in setUp(). If any exception is thrown in setUp(), tearDown() is not called, leaving the application (~9000+ subsequent tests) in the inconsistent state. Support JUnit 4 tests via JUnit4TestAdapter. Previously only a small number of test classes were actually run because this test was looking only for JUnit 3 testcases. Delete FilesTest#relativePath because it was testing a deprecated function and was failing if run from the project root
This commit is contained in:
@@ -16,12 +16,11 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.codegen;
|
package org.jetbrains.kotlin.codegen;
|
||||||
|
|
||||||
import com.intellij.testFramework.UsefulTestCase;
|
import com.intellij.testFramework.TestRunnerUtil;
|
||||||
import junit.extensions.TestSetup;
|
import junit.framework.*;
|
||||||
import junit.framework.Test;
|
import junit.textui.TestRunner;
|
||||||
import junit.framework.TestCase;
|
|
||||||
import junit.framework.TestSuite;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys;
|
import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys;
|
||||||
import org.jetbrains.kotlin.cli.common.messages.PrintingMessageCollector;
|
import org.jetbrains.kotlin.cli.common.messages.PrintingMessageCollector;
|
||||||
import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles;
|
import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles;
|
||||||
@@ -30,7 +29,6 @@ import org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler;
|
|||||||
import org.jetbrains.kotlin.cli.jvm.config.JvmContentRootsKt;
|
import org.jetbrains.kotlin.cli.jvm.config.JvmContentRootsKt;
|
||||||
import org.jetbrains.kotlin.codegen.forTestCompile.ForTestCompileRuntime;
|
import org.jetbrains.kotlin.codegen.forTestCompile.ForTestCompileRuntime;
|
||||||
import org.jetbrains.kotlin.codegen.state.GenerationState;
|
import org.jetbrains.kotlin.codegen.state.GenerationState;
|
||||||
import org.jetbrains.kotlin.codegen.state.JetTypeMapper;
|
|
||||||
import org.jetbrains.kotlin.config.CompilerConfiguration;
|
import org.jetbrains.kotlin.config.CompilerConfiguration;
|
||||||
import org.jetbrains.kotlin.config.ContentRootsKt;
|
import org.jetbrains.kotlin.config.ContentRootsKt;
|
||||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor;
|
import org.jetbrains.kotlin.descriptors.ClassDescriptor;
|
||||||
@@ -39,53 +37,20 @@ import org.jetbrains.kotlin.psi.KtDeclaration;
|
|||||||
import org.jetbrains.kotlin.psi.KtFile;
|
import org.jetbrains.kotlin.psi.KtFile;
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext;
|
import org.jetbrains.kotlin.resolve.BindingContext;
|
||||||
import org.jetbrains.kotlin.resolve.BindingContextUtils;
|
import org.jetbrains.kotlin.resolve.BindingContextUtils;
|
||||||
|
import org.jetbrains.kotlin.resolve.lazy.KotlinTestWithEnvironment;
|
||||||
import org.jetbrains.kotlin.test.ConfigurationKind;
|
import org.jetbrains.kotlin.test.ConfigurationKind;
|
||||||
import org.jetbrains.kotlin.test.KotlinTestUtils;
|
import org.jetbrains.kotlin.test.KotlinTestUtils;
|
||||||
import org.jetbrains.kotlin.test.TestJdkKind;
|
import org.jetbrains.kotlin.test.TestJdkKind;
|
||||||
import org.jetbrains.kotlin.types.KotlinType;
|
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.lang.reflect.Modifier;
|
import java.lang.reflect.Modifier;
|
||||||
|
|
||||||
import static org.jetbrains.kotlin.types.TypeUtils.getAllSupertypes;
|
public class TestlibTest extends KotlinTestWithEnvironment {
|
||||||
|
|
||||||
@SuppressWarnings("JUnitTestCaseWithNoTests")
|
|
||||||
public class TestlibTest extends UsefulTestCase {
|
|
||||||
public static Test suite() {
|
|
||||||
return new TestlibTest().buildTestSuite();
|
|
||||||
}
|
|
||||||
|
|
||||||
private TestSuite suite;
|
|
||||||
private File junitJar;
|
|
||||||
private GeneratedClassLoader classLoader;
|
|
||||||
private JetTypeMapper typeMapper;
|
|
||||||
private GenerationState generationState;
|
|
||||||
private KotlinCoreEnvironment myEnvironment;
|
|
||||||
|
|
||||||
private Test buildTestSuite() {
|
|
||||||
suite = new TestSuite("stdlib_test");
|
|
||||||
|
|
||||||
return new TestSetup(suite) {
|
|
||||||
@Override
|
|
||||||
protected void setUp() throws Exception {
|
|
||||||
TestlibTest.this.setUp();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void tearDown() throws Exception {
|
|
||||||
TestlibTest.this.tearDown();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setUp() throws Exception {
|
protected KotlinCoreEnvironment createEnvironment() {
|
||||||
super.setUp();
|
|
||||||
|
|
||||||
CompilerConfiguration configuration = KotlinTestUtils.compilerConfigurationForTests(ConfigurationKind.ALL, TestJdkKind.FULL_JDK);
|
CompilerConfiguration configuration = KotlinTestUtils.compilerConfigurationForTests(ConfigurationKind.ALL, TestJdkKind.FULL_JDK);
|
||||||
JvmContentRootsKt.addJvmClasspathRoot(configuration, KotlinTestUtils.getAnnotationsJar());
|
|
||||||
|
|
||||||
junitJar = new File("libraries/lib/junit-4.11.jar");
|
File junitJar = new File("libraries/lib/junit-4.11.jar");
|
||||||
assertTrue(junitJar.exists());
|
assertTrue(junitJar.exists());
|
||||||
JvmContentRootsKt.addJvmClasspathRoot(configuration, junitJar);
|
JvmContentRootsKt.addJvmClasspathRoot(configuration, junitJar);
|
||||||
|
|
||||||
@@ -93,74 +58,73 @@ public class TestlibTest extends UsefulTestCase {
|
|||||||
ContentRootsKt.addKotlinSourceRoot(configuration, KotlinTestUtils.getHomeDirectory() + "/libraries/kunit/src");
|
ContentRootsKt.addKotlinSourceRoot(configuration, KotlinTestUtils.getHomeDirectory() + "/libraries/kunit/src");
|
||||||
configuration.put(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY, PrintingMessageCollector.PLAIN_TEXT_TO_SYSTEM_ERR);
|
configuration.put(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY, PrintingMessageCollector.PLAIN_TEXT_TO_SYSTEM_ERR);
|
||||||
|
|
||||||
myEnvironment = KotlinCoreEnvironment.createForTests(getTestRootDisposable(), configuration, EnvironmentConfigFiles.JVM_CONFIG_FILES);
|
return KotlinCoreEnvironment.createForTests(getTestRootDisposable(), configuration, EnvironmentConfigFiles.JVM_CONFIG_FILES);
|
||||||
|
}
|
||||||
|
|
||||||
generationState = KotlinToJVMBytecodeCompiler.analyzeAndGenerate(myEnvironment);
|
public void testStdlib() throws ClassNotFoundException {
|
||||||
if (generationState == null) {
|
GenerationState state = KotlinToJVMBytecodeCompiler.analyzeAndGenerate(getEnvironment());
|
||||||
throw new RuntimeException("There were compilation errors");
|
if (state == null) {
|
||||||
|
fail("There were compilation errors");
|
||||||
}
|
}
|
||||||
|
|
||||||
classLoader = new GeneratedClassLoader(generationState.getFactory(), ForTestCompileRuntime.runtimeAndReflectJarClassLoader()) {
|
GeneratedClassLoader classLoader = new GeneratedClassLoader(
|
||||||
|
state.getFactory(), ForTestCompileRuntime.runtimeAndReflectJarClassLoader()
|
||||||
|
) {
|
||||||
@Override
|
@Override
|
||||||
public Class<?> loadClass(@NotNull String name) throws ClassNotFoundException {
|
public Class<?> loadClass(@NotNull String name) throws ClassNotFoundException {
|
||||||
if (name.startsWith("junit.") || name.startsWith("org.junit.")) {
|
if (name.startsWith("junit.") || name.startsWith("org.junit.")) {
|
||||||
//In other way we don't find any test cause will have two different TestCase classes!
|
|
||||||
return TestlibTest.class.getClassLoader().loadClass(name);
|
return TestlibTest.class.getClassLoader().loadClass(name);
|
||||||
}
|
}
|
||||||
return super.loadClass(name);
|
return super.loadClass(name);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
typeMapper = generationState.getTypeMapper();
|
TestSuite tests = new TestSuite("Standard Library Tests");
|
||||||
|
|
||||||
for (KtFile jetFile : myEnvironment.getSourceFiles()) {
|
for (KtFile file : getEnvironment().getSourceFiles()) {
|
||||||
for (KtDeclaration declaration : jetFile.getDeclarations()) {
|
// Skip JS tests
|
||||||
|
if (file.getVirtualFile().getPath().contains("/js/")) continue;
|
||||||
|
|
||||||
|
for (KtDeclaration declaration : file.getDeclarations()) {
|
||||||
if (!(declaration instanceof KtClass)) continue;
|
if (!(declaration instanceof KtClass)) continue;
|
||||||
|
|
||||||
ClassDescriptor descriptor = (ClassDescriptor) BindingContextUtils.getNotNull(generationState.getBindingContext(),
|
ClassDescriptor descriptor = (ClassDescriptor) BindingContextUtils.getNotNull(
|
||||||
BindingContext.DECLARATION_TO_DESCRIPTOR,
|
state.getBindingContext(), BindingContext.DECLARATION_TO_DESCRIPTOR, declaration
|
||||||
declaration);
|
);
|
||||||
|
|
||||||
for (KotlinType superType : getAllSupertypes(descriptor.getDefaultType())) {
|
Test test = createTest(classLoader, state.getTypeMapper().mapClass(descriptor).getClassName());
|
||||||
if (!"junit/framework/Test".equals(typeMapper.mapType(superType).getInternalName())) continue;
|
|
||||||
|
|
||||||
String name = typeMapper.mapClass(descriptor).getInternalName();
|
if (test != null) {
|
||||||
|
tests.addTest(test);
|
||||||
System.out.println(name);
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
Class<TestCase> aClass = (Class<TestCase>) classLoader.loadClass(name.replace('/', '.'));
|
|
||||||
|
|
||||||
if (!Modifier.isAbstract(aClass.getModifiers()) && Modifier.isPublic(aClass.getModifiers())) {
|
|
||||||
try {
|
|
||||||
if (Modifier.isPublic(aClass.getConstructor().getModifiers())) {
|
|
||||||
suite.addTestSuite(aClass);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (NoSuchMethodException e) {
|
|
||||||
// Ignore test classes we can't instantiate
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TestResult result = new TestRunner(System.err).doRun(tests);
|
||||||
|
if (!result.wasSuccessful()) {
|
||||||
|
fail("Some stdlib tests failed, see stderr for details");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Nullable
|
||||||
protected void tearDown() throws Exception {
|
private static Test createTest(@NotNull ClassLoader classLoader, @NotNull String className) {
|
||||||
typeMapper = null;
|
try {
|
||||||
|
Class<?> aClass = classLoader.loadClass(className);
|
||||||
|
if (Modifier.isAbstract(aClass.getModifiers()) ||
|
||||||
|
!Modifier.isPublic(aClass.getModifiers()) ||
|
||||||
|
!Modifier.isPublic(aClass.getConstructor().getModifiers())) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
classLoader.dispose();
|
return TestCase.class.isAssignableFrom(aClass) ? new TestSuite(aClass) :
|
||||||
classLoader = null;
|
TestRunnerUtil.isJUnit4TestClass(aClass) ? new JUnit4TestAdapter(aClass) : null;
|
||||||
|
}
|
||||||
generationState = null;
|
catch (NoSuchMethodException e) {
|
||||||
|
// Ignore test classes we can't instantiate
|
||||||
myEnvironment = null;
|
return null;
|
||||||
|
}
|
||||||
junitJar = null;
|
catch (ClassNotFoundException e) {
|
||||||
|
return null;
|
||||||
super.tearDown();
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -588,16 +588,6 @@ class FilesTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@test fun relativePath() {
|
|
||||||
val file1 = File("src")
|
|
||||||
val file2 = File(file1, "kotlin")
|
|
||||||
val file3 = File("test")
|
|
||||||
|
|
||||||
assertEquals("kotlin", file1.relativePath(file2))
|
|
||||||
assertEquals("", file1.relativePath(file1))
|
|
||||||
assertEquals(file3.canonicalPath, file1.relativePath(file3))
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun checkFileElements(f: File, root: File?, elements: List<String>) {
|
private fun checkFileElements(f: File, root: File?, elements: List<String>) {
|
||||||
var i = 0
|
var i = 0
|
||||||
assertEquals(root, f.root)
|
assertEquals(root, f.root)
|
||||||
|
|||||||
Reference in New Issue
Block a user