/* * Copyright 2010-2015 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.kotlin.idea.configuration; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.PathMacros; import com.intellij.openapi.module.Module; import com.intellij.openapi.module.ModuleManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.projectRoots.Sdk; import com.intellij.openapi.roots.ModuleRootManager; import com.intellij.openapi.roots.libraries.Library; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.io.FileUtilRt; import com.intellij.testFramework.PlatformTestCase; import org.jetbrains.annotations.NotNull; import org.jetbrains.kotlin.idea.versions.LibraryJarDescriptor; import org.jetbrains.kotlin.utils.PathUtil; import java.io.File; import java.io.IOException; import java.util.Collections; import java.util.List; import static org.jetbrains.kotlin.idea.configuration.KotlinWithLibraryConfigurator.FileState; public abstract class AbstractConfigureKotlinTest extends PlatformTestCase { private static final String BASE_PATH = "idea/testData/configuration/"; private static final String TEMP_DIR_MACRO_KEY = "TEMP_TEST_DIR"; protected static final KotlinJavaModuleConfigurator JAVA_CONFIGURATOR = new KotlinJavaModuleConfigurator() { @Override protected String getDefaultPathToJarFile(@NotNull Project project) { return getPathRelativeToTemp("default_jvm_lib"); } }; protected static final KotlinJsModuleConfigurator JS_CONFIGURATOR = new KotlinJsModuleConfigurator() { @Override protected String getDefaultPathToJarFile(@NotNull Project project) { return getPathRelativeToTemp("default_js_lib"); } }; private static void configure( @NotNull List<Module> modules, @NotNull FileState runtimeState, @NotNull KotlinWithLibraryConfigurator configurator, @NotNull String jarFromDist, @NotNull String jarFromTemp ) { Project project = modules.iterator().next().getProject(); NotificationMessageCollector collector = NotificationMessageCollectorKt.createConfigureKotlinNotificationCollector(project); for (Module module : modules) { Library library = configurator.getKotlinLibrary(module); if (library == null) { library = configurator.createNewLibrary(project, collector); } String pathToJar = getPathToJar(runtimeState, jarFromDist, jarFromTemp); Sdk sdk = ModuleRootManager.getInstance(module).getSdk(); Library.ModifiableModel model = library.getModifiableModel(); for (LibraryJarDescriptor descriptor : configurator.getLibraryJarDescriptors(sdk)) { configurator.configureLibraryJar(model, runtimeState, pathToJar, descriptor, collector); } ApplicationManager.getApplication().runWriteAction(model::commit); configurator.addLibraryToModuleIfNeeded(module, library, collector); } collector.showNotification(); } @NotNull private static String getPathToJar(@NotNull FileState runtimeState, @NotNull String jarFromDist, @NotNull String jarFromTemp) { switch (runtimeState) { case EXISTS: return jarFromDist; case COPY: return jarFromTemp; case DO_NOT_COPY: return jarFromDist; } return jarFromDist; } protected static void configure(@NotNull Module module, @NotNull FileState jarState, @NotNull KotlinProjectConfigurator configurator) { if (configurator instanceof KotlinJavaModuleConfigurator) { configure(Collections.singletonList(module), jarState, (KotlinWithLibraryConfigurator) configurator, getPathToExistentRuntimeJar(), getPathToNonexistentRuntimeJar()); } if (configurator instanceof KotlinJsModuleConfigurator) { configure(Collections.singletonList(module), jarState, (KotlinWithLibraryConfigurator) configurator, getPathToExistentJsJar(), getPathToNonexistentJsJar()); } } private static String getPathToNonexistentRuntimeJar() { String pathToTempKotlinRuntimeJar = FileUtil.getTempDirectory() + "/" + PathUtil.KOTLIN_JAVA_RUNTIME_JAR; myFilesToDelete.add(new File(pathToTempKotlinRuntimeJar)); return pathToTempKotlinRuntimeJar; } private static String getPathToNonexistentJsJar() { String pathToTempKotlinRuntimeJar = FileUtil.getTempDirectory() + "/" + PathUtil.JS_LIB_JAR_NAME; myFilesToDelete.add(new File(pathToTempKotlinRuntimeJar)); return pathToTempKotlinRuntimeJar; } private static String getPathToExistentRuntimeJar() { return PathUtil.getKotlinPathsForDistDirectory().getStdlibPath().getParent(); } private static String getPathToExistentJsJar() { return PathUtil.getKotlinPathsForDistDirectory().getJsStdLibJarPath().getParent(); } protected static void assertNotConfigured(Module module, KotlinWithLibraryConfigurator configurator) { assertFalse( String.format("Module %s should not be configured as %s Module", module.getName(), configurator.getPresentableText()), configurator.isConfigured(module)); } protected static void assertConfigured(Module module, KotlinWithLibraryConfigurator configurator) { assertTrue(String.format("Module %s should be configured with configurator '%s'", module.getName(), configurator.getPresentableText()), configurator.isConfigured(module)); } protected static void assertProperlyConfigured(Module module, KotlinWithLibraryConfigurator configurator) { assertConfigured(module, configurator); assertNotConfigured(module, getOppositeConfigurator(configurator)); } private static KotlinWithLibraryConfigurator getOppositeConfigurator(KotlinWithLibraryConfigurator configurator) { if (configurator == JAVA_CONFIGURATOR) return JS_CONFIGURATOR; if (configurator == JS_CONFIGURATOR) return JAVA_CONFIGURATOR; throw new IllegalArgumentException("Only JS_CONFIGURATOR and JAVA_CONFIGURATOR are supported"); } private static String getPathRelativeToTemp(String relativePath) { String tempPath = PathMacros.getInstance().getValue(TEMP_DIR_MACRO_KEY); return tempPath + '/' + relativePath; } @Override protected void tearDown() throws Exception { PathMacros.getInstance().removeMacro(TEMP_DIR_MACRO_KEY); super.tearDown(); } @Override protected void initApplication() throws Exception { super.initApplication(); File tempLibDir = FileUtil.createTempDirectory("temp", null); PathMacros.getInstance().setMacro(TEMP_DIR_MACRO_KEY, FileUtilRt.toSystemDependentName(tempLibDir.getAbsolutePath())); } protected void doTestConfigureModulesWithNonDefaultSetup(KotlinWithLibraryConfigurator configurator) { assertNoFilesInDefaultPaths(); Module[] modules = getModules(); for (Module module : modules) { assertNotConfigured(module, configurator); } configurator.configure(myProject, Collections.<Module>emptyList()); assertNoFilesInDefaultPaths(); for (Module module : modules) { assertProperlyConfigured(module, configurator); } } protected void doTestOneJavaModule(@NotNull FileState jarState) { doTestOneModule(jarState, JAVA_CONFIGURATOR); } protected void doTestOneJsModule(@NotNull FileState jarState) { doTestOneModule(jarState, JS_CONFIGURATOR); } private void doTestOneModule(@NotNull FileState jarState, @NotNull KotlinWithLibraryConfigurator configurator) { Module module = getModule(); assertNotConfigured(module, configurator); configure(module, jarState, configurator); assertProperlyConfigured(module, configurator); } @Override public Module getModule() { Module[] modules = ModuleManager.getInstance(myProject).getModules(); assert modules.length == 1 : "One module should be loaded " + modules.length; myModule = modules[0]; return super.getModule(); } public Module[] getModules() { return ModuleManager.getInstance(myProject).getModules(); } @Override protected File getIprFile() throws IOException { String projectFilePath = getProjectRoot() + "/projectFile.ipr"; assertTrue("Project file should exists " + projectFilePath, new File(projectFilePath).exists()); return new File(projectFilePath); } @Override protected Project doCreateProject(@NotNull File projectFile) throws Exception { return myProjectManager.loadProject(projectFile.getPath()); } private String getProjectName() { String testName = getTestName(true); if (testName.contains("_")) { return testName.substring(0, testName.indexOf("_")); } return testName; } protected String getProjectRoot() { return BASE_PATH + getProjectName(); } @Override protected void setUpModule() { } private void assertNoFilesInDefaultPaths() { assertDoesntExist(new File(JAVA_CONFIGURATOR.getDefaultPathToJarFile(getProject()))); assertDoesntExist(new File(JS_CONFIGURATOR.getDefaultPathToJarFile(getProject()))); } }