blob: 790bd2dd5879e6e0ddb991618129a119c460bd19 [file] [log] [blame]
/*
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
*
* 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 org.jetbrains.plugins.groovy.compiler;
import com.intellij.compiler.server.BuildManager;
import com.intellij.execution.ExecutionException;
import com.intellij.execution.Executor;
import com.intellij.execution.application.ApplicationConfiguration;
import com.intellij.execution.application.ApplicationConfigurationType;
import com.intellij.execution.configurations.RunProfile;
import com.intellij.execution.executors.DefaultRunExecutor;
import com.intellij.execution.impl.DefaultJavaProgramRunner;
import com.intellij.execution.process.*;
import com.intellij.execution.runners.ExecutionEnvironment;
import com.intellij.execution.runners.ExecutionEnvironmentBuilder;
import com.intellij.execution.runners.ProgramRunner;
import com.intellij.execution.ui.RunContentDescriptor;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.application.Result;
import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.compiler.CompilerMessage;
import com.intellij.openapi.module.ModifiableModuleModel;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleManager;
import com.intellij.openapi.module.StdModuleTypes;
import com.intellij.openapi.roots.*;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.psi.PsiFile;
import com.intellij.testFramework.CompilerTester;
import com.intellij.testFramework.IdeaTestUtil;
import com.intellij.testFramework.PlatformTestUtil;
import com.intellij.testFramework.PsiTestUtil;
import com.intellij.testFramework.builders.JavaModuleFixtureBuilder;
import com.intellij.testFramework.fixtures.JavaCodeInsightFixtureTestCase;
import com.intellij.util.concurrency.Semaphore;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.groovy.config.GroovyFacetUtil;
import org.jetbrains.plugins.groovy.runner.GroovyScriptRunConfiguration;
import org.jetbrains.plugins.groovy.runner.GroovyScriptRunConfigurationType;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;
/**
* @author aalmiray
* @author peter
*/
public abstract class GroovyCompilerTestCase extends JavaCodeInsightFixtureTestCase {
@SuppressWarnings("AbstractMethodCallInConstructor") private CompilerTester myCompilerTester;
@Override
protected void setUp() throws Exception {
super.setUp();
getProject().getComponent(GroovyCompilerLoader.class).projectOpened();
myCompilerTester = new CompilerTester(myModule);
}
@Override
protected void tuneFixture(JavaModuleFixtureBuilder moduleBuilder) throws Exception {
moduleBuilder.setLanguageLevel(LanguageLevel.JDK_1_6);
moduleBuilder.addJdk(IdeaTestUtil.getMockJdk17Path().getPath());
super.tuneFixture(moduleBuilder);
}
@Override
protected void runTest() throws Throwable {
if (PlatformTestUtil.COVERAGE_ENABLED_BUILD) return;
super.runTest();
}
protected static void addGroovyLibrary(final Module to) {
File jar = GroovyFacetUtil.getBundledGroovyJar();
PsiTestUtil.addLibrary(to, "groovy", jar.getParent(), jar.getName());
}
@Override
protected void tearDown() throws Exception {
final File systemRoot = BuildManager.getInstance().getBuildSystemDirectory();
try {
UIUtil.invokeAndWaitIfNeeded(new Runnable() {
@Override
public void run() {
try {
myCompilerTester.tearDown();
myCompilerTester = null;
GroovyCompilerTestCase.super.tearDown();
}
catch (Exception e) {
throw new RuntimeException(e);
}
}
});
}
finally {
FileUtil.delete(systemRoot);
}
}
protected void setupTestSources() {
new WriteCommandAction(getProject()) {
@Override
protected void run(Result result) throws Throwable {
final ModuleRootManager rootManager = ModuleRootManager.getInstance(myModule);
final ModifiableRootModel rootModel = rootManager.getModifiableModel();
final ContentEntry entry = rootModel.getContentEntries()[0];
entry.removeSourceFolder(entry.getSourceFolders()[0]);
entry.addSourceFolder(myFixture.getTempDirFixture().findOrCreateDir("src"), false);
entry.addSourceFolder(myFixture.getTempDirFixture().findOrCreateDir("tests"), true);
rootModel.commit();
}
}.execute();
}
protected Module addDependentModule() {
Module module = addModule("dependent", true);
ModuleRootModificationUtil.addDependency(module, myModule);
return module;
}
protected Module addModule(final String name, final boolean withSource) {
return new WriteCommandAction<Module>(getProject()) {
@Override
protected void run(Result<Module> result) throws Throwable {
final VirtualFile depRoot = myFixture.getTempDirFixture().findOrCreateDir(name);
final ModifiableModuleModel moduleModel = ModuleManager.getInstance(getProject()).getModifiableModel();
String moduleName = moduleModel.newModule(depRoot.getPath() + "/" + name + ".iml", StdModuleTypes.JAVA.getId()).getName();
moduleModel.commit();
final Module dep = ModuleManager.getInstance(getProject()).findModuleByName(moduleName);
ModuleRootModificationUtil.setModuleSdk(dep, ModuleRootManager.getInstance(myModule).getSdk());
if (withSource) {
PsiTestUtil.addSourceRoot(dep, depRoot);
} else {
PsiTestUtil.addContentRoot(dep, depRoot);
}
IdeaTestUtil.setModuleLanguageLevel(dep, LanguageLevelModuleExtension.getInstance(myModule).getLanguageLevel());
result.setResult(dep);
}
}.execute().getResultObject();
}
protected void deleteClassFile(final String className) throws IOException {
myCompilerTester.deleteClassFile(className);
}
@Nullable
protected VirtualFile findClassFile(String className) {
return findClassFile(className, myModule);
}
@Nullable
protected VirtualFile findClassFile(String className, Module module) {
return myCompilerTester.findClassFile(className, module);
}
protected void touch(VirtualFile file) throws IOException {
myCompilerTester.touch(file);
}
protected void setFileText(final PsiFile file, final String barText) throws IOException {
myCompilerTester.setFileText(file, barText);
}
protected void setFileName(final PsiFile bar, final String name) {
myCompilerTester.setFileName(bar, name);
}
protected List<CompilerMessage> make() {
return myCompilerTester.make();
}
protected List<CompilerMessage> rebuild() {
return myCompilerTester.rebuild();
}
protected List<CompilerMessage> compileModule(final Module module) {
return myCompilerTester.compileModule(module);
}
protected List<CompilerMessage> compileFiles(final VirtualFile... files) {
return myCompilerTester.compileFiles(files);
}
protected void assertOutput(String className, String output) throws ExecutionException {
assertOutput(className, output, myModule);
}
protected void assertOutput(String className, String expected, final Module module) throws ExecutionException {
final StringBuffer sb = new StringBuffer();
ProcessHandler process = runProcess(className, module, DefaultRunExecutor.class, new ProcessAdapter() {
@Override
public void onTextAvailable(ProcessEvent event, Key outputType) {
if (ProcessOutputTypes.SYSTEM != outputType) {
sb.append(event.getText());
}
}
}, ProgramRunner.PROGRAM_RUNNER_EP.findExtension(DefaultJavaProgramRunner.class));
process.waitFor();
assertEquals(expected.trim(), StringUtil.convertLineSeparators(sb.toString().trim()));
}
protected ProcessHandler runProcess(String className,
Module module,
final Class<? extends Executor> executorClass,
final ProcessListener listener, final ProgramRunner runner) throws ExecutionException {
final ApplicationConfiguration configuration = createApplicationConfiguration(className, module);
return runConfiguration(executorClass, listener, runner, configuration);
}
protected ProcessHandler runConfiguration(Class<? extends Executor> executorClass,
final ProcessListener listener,
ProgramRunner runner,
RunProfile configuration) throws ExecutionException {
final Executor executor = Executor.EXECUTOR_EXTENSION_NAME.findExtension(executorClass);
final ExecutionEnvironment environment = new ExecutionEnvironmentBuilder(getProject(), executor).runProfile(configuration).build();
final Semaphore semaphore = new Semaphore();
semaphore.down();
final AtomicReference<ProcessHandler> processHandler = new AtomicReference<ProcessHandler>();
runner.execute(environment, new ProgramRunner.Callback() {
@Override
public void processStarted(final RunContentDescriptor descriptor) {
disposeOnTearDown(new Disposable() {
@Override
public void dispose() {
Disposer.dispose(descriptor);
}
});
final ProcessHandler handler = descriptor.getProcessHandler();
assert handler != null;
handler.addProcessListener(listener);
processHandler.set(handler);
semaphore.up();
}
});
if (!semaphore.waitFor(20000)) {
fail("Process took too long");
}
return processHandler.get();
}
protected ApplicationConfiguration createApplicationConfiguration(String className, Module module) {
final ApplicationConfiguration configuration =
new ApplicationConfiguration("app", getProject(), ApplicationConfigurationType.getInstance());
configuration.setModule(module);
configuration.setMainClassName(className);
return configuration;
}
protected GroovyScriptRunConfiguration createScriptConfiguration(String scriptPath, Module module) {
final GroovyScriptRunConfiguration configuration =
new GroovyScriptRunConfiguration("app", getProject(), GroovyScriptRunConfigurationType.getInstance().getConfigurationFactories()[0]);
configuration.setModule(module);
configuration.setScriptPath(scriptPath);
return configuration;
}
}