MPP wizard test: add project import (KT-27492)

This commit is contained in:
Mikhail Glukhikh
2018-10-12 18:14:04 +03:00
parent 43c8c44441
commit 855e2707e3
2 changed files with 158 additions and 17 deletions
@@ -9,29 +9,74 @@ import com.intellij.ide.projectWizard.NewProjectWizard
import com.intellij.ide.projectWizard.ProjectTypeStep import com.intellij.ide.projectWizard.ProjectTypeStep
import com.intellij.ide.projectWizard.ProjectWizardTestCase import com.intellij.ide.projectWizard.ProjectWizardTestCase
import com.intellij.ide.util.newProjectWizard.AbstractProjectWizard import com.intellij.ide.util.newProjectWizard.AbstractProjectWizard
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.application.Result
import com.intellij.openapi.application.WriteAction
import com.intellij.openapi.components.ServiceManager
import com.intellij.openapi.diagnostic.Logger import com.intellij.openapi.diagnostic.Logger
import com.intellij.openapi.externalSystem.importing.ImportSpecBuilder
import com.intellij.openapi.externalSystem.model.DataNode
import com.intellij.openapi.externalSystem.model.project.ProjectData
import com.intellij.openapi.externalSystem.service.execution.ProgressExecutionMode
import com.intellij.openapi.externalSystem.service.project.ExternalProjectRefreshCallback
import com.intellij.openapi.externalSystem.service.project.ProjectDataManager
import com.intellij.openapi.externalSystem.settings.ExternalProjectSettings
import com.intellij.openapi.externalSystem.settings.ExternalSystemSettingsListenerAdapter
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil
import com.intellij.openapi.externalSystem.util.ExternalSystemUtil
import com.intellij.openapi.module.ModuleManager import com.intellij.openapi.module.ModuleManager
import com.intellij.openapi.project.Project import com.intellij.openapi.project.Project
import com.intellij.openapi.projectRoots.ProjectJdkTable
import com.intellij.openapi.projectRoots.SimpleJavaSdkType
import com.intellij.openapi.roots.ModuleRootManager import com.intellij.openapi.roots.ModuleRootManager
import com.intellij.openapi.roots.ProjectRootManager import com.intellij.openapi.roots.ProjectRootManager
import com.intellij.openapi.roots.ui.configuration.ModulesProvider import com.intellij.openapi.roots.ui.configuration.ModulesProvider
import com.intellij.openapi.util.Couple
import com.intellij.openapi.util.Ref
import com.intellij.openapi.util.io.FileUtil
import com.intellij.openapi.util.text.StringUtil import com.intellij.openapi.util.text.StringUtil
import com.intellij.openapi.vfs.LocalFileSystem
import com.intellij.openapi.vfs.VfsUtilCore import com.intellij.openapi.vfs.VfsUtilCore
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.testFramework.IdeaTestUtil
import com.intellij.testFramework.UsefulTestCase import com.intellij.testFramework.UsefulTestCase
import com.intellij.util.containers.ContainerUtil
import com.intellij.util.containers.ContainerUtilRt
import junit.framework.TestCase import junit.framework.TestCase
import org.jetbrains.kotlin.ide.konan.gradle.KotlinGradleNativeMultiplatformModuleBuilder import org.jetbrains.kotlin.ide.konan.gradle.KotlinGradleNativeMultiplatformModuleBuilder
import org.jetbrains.kotlin.idea.codeInsight.gradle.GradleImportingTestCase
import org.jetbrains.kotlin.idea.configuration.* import org.jetbrains.kotlin.idea.configuration.*
import org.jetbrains.kotlin.utils.PrintingLogger import org.jetbrains.kotlin.utils.PrintingLogger
import org.jetbrains.plugins.gradle.service.project.wizard.GradleModuleBuilder import org.jetbrains.plugins.gradle.settings.DistributionType
import org.jetbrains.plugins.gradle.settings.GradleProjectSettings
import org.jetbrains.plugins.gradle.settings.GradleSettings
import org.jetbrains.plugins.gradle.util.GradleConstants
import org.junit.Test import org.junit.Test
import java.io.File import java.io.File
import java.io.IOException
import java.util.*
class GradleMultiplatformWizardTest : ProjectWizardTestCase<AbstractProjectWizard>() { class GradleMultiplatformWizardTest : ProjectWizardTestCase<AbstractProjectWizard>() {
private val pluginVersion = "1.3.0-rc-146"
override fun createWizard(project: Project?, directory: File): AbstractProjectWizard { override fun createWizard(project: Project?, directory: File): AbstractProjectWizard {
return NewProjectWizard(project, ModulesProvider.EMPTY_MODULES_PROVIDER, directory.path) return NewProjectWizard(project, ModulesProvider.EMPTY_MODULES_PROVIDER, directory.path)
} }
private fun Project.reconfigureGradleSettings(f: GradleProjectSettings.() -> Unit) {
val systemSettings = ExternalSystemApiUtil.getSettings(
this,
externalSystemId
)
val projectSettings = GradleProjectSettings()
projectSettings.f()
val projects = ContainerUtilRt.newHashSet<Any>(systemSettings.getLinkedProjectsSettings())
projects.remove(projectSettings)
projects.add(projectSettings)
systemSettings.setLinkedProjectsSettings(projects)
}
private fun testImportFromBuilder( private fun testImportFromBuilder(
builder: KotlinGradleAbstractMultiplatformModuleBuilder, nameRoot: String, metadataInside: Boolean = false builder: KotlinGradleAbstractMultiplatformModuleBuilder, nameRoot: String, metadataInside: Boolean = false
) { ) {
@@ -52,7 +97,14 @@ class GradleMultiplatformWizardTest : ProjectWizardTestCase<AbstractProjectWizar
TestCase.assertEquals(4, steps.size) TestCase.assertEquals(4, steps.size)
val projectBuilder = myWizard.projectBuilder val projectBuilder = myWizard.projectBuilder
UsefulTestCase.assertInstanceOf(projectBuilder, builder::class.java) UsefulTestCase.assertInstanceOf(projectBuilder, builder::class.java)
(projectBuilder as GradleModuleBuilder).name = projectName with(projectBuilder as KotlinGradleAbstractMultiplatformModuleBuilder) {
name = projectName
explicitPluginVersion = pluginVersion
}
myProject.reconfigureGradleSettings {
distributionType = DistributionType.DEFAULT_WRAPPED
}
} }
} }
@@ -64,29 +116,102 @@ class GradleMultiplatformWizardTest : ProjectWizardTestCase<AbstractProjectWizar
TestCase.assertEquals(projectName, module.name) TestCase.assertEquals(projectName, module.name)
val root = ProjectRootManager.getInstance(project).contentRoots[0] val root = ProjectRootManager.getInstance(project).contentRoots[0]
val settingsScript = VfsUtilCore.findRelativeFile("settings.gradle", root) val settingsScript = VfsUtilCore.findRelativeFile("settings.gradle", root)
TestCase.assertNotNull(settingsScript) TestCase.assertNotNull(settingsScript)
TestCase.assertEquals( val settingsScriptText = StringUtil.convertLineSeparators(VfsUtilCore.loadText(settingsScript!!))
String.format("rootProject.name = '%s'\n\n", projectName) + TestCase.assertTrue(String.format("rootProject.name = '%s'\n\n", projectName) in settingsScriptText)
if (metadataInside) "\nenableFeaturePreview('GRADLE_METADATA')\n" else "", if (metadataInside) {
StringUtil.convertLineSeparators(VfsUtilCore.loadText(settingsScript!!)) TestCase.assertTrue("enableFeaturePreview('GRADLE_METADATA')" in settingsScriptText)
) }
val buildScript = VfsUtilCore.findRelativeFile("build.gradle", root)!! val buildScript = VfsUtilCore.findRelativeFile("build.gradle", root)!!
println(StringUtil.convertLineSeparators(VfsUtilCore.loadText(buildScript))) val buildScriptText = StringUtil.convertLineSeparators(VfsUtilCore.loadText(buildScript))
println(buildScriptText)
doImportProject(project)
} }
@Throws(Exception::class) @Throws(IOException::class)
override fun setUp() { private fun Project.createProjectSubFile(relativePath: String): VirtualFile {
super.setUp() val f = File(basePath!!, relativePath)
configureJdk() FileUtil.ensureExists(f.parentFile)
FileUtil.ensureCanCreateFile(f)
val created = f.createNewFile()
if (!created) {
throw AssertionError("Unable to create the project sub file: " + f.absolutePath)
}
return LocalFileSystem.getInstance().refreshAndFindFileByIoFile(f)!!
} }
@Test private fun runWrite(f: () -> Unit) {
fun testMobile() { object : WriteAction<Any>() {
testImportFromBuilder(KotlinGradleMobileMultiplatformModuleBuilder(), "Mobile") override fun run(result: Result<Any>) {
f()
}
}.execute()
} }
private fun doImportProject(project: Project) {
ExternalSystemApiUtil.subscribe(
project,
GradleConstants.SYSTEM_ID,
object : ExternalSystemSettingsListenerAdapter<ExternalProjectSettings>() {
override fun onProjectsLinked(settings: Collection<ExternalProjectSettings>) {
val item = ContainerUtil.getFirstItem<Any>(settings)
if (item is GradleProjectSettings) {
item.gradleJvm = DEFAULT_SDK
}
}
})
GradleSettings.getInstance(project).gradleVmOptions = "-Xmx128m -XX:MaxPermSize=64m"
val wrapperJarFrom = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(GradleImportingTestCase.wrapperJar())!!
val wrapperJarFromTo = project.createProjectSubFile("gradle/wrapper/gradle-wrapper.jar")
runWrite {
wrapperJarFromTo.setBinaryContent(wrapperJarFrom.contentsToByteArray())
}
project.reconfigureGradleSettings {
distributionType = DistributionType.DEFAULT_WRAPPED
externalProjectPath = project.basePath!!
gradleJvm = DEFAULT_SDK
}
val error = Ref.create<Couple<String>>()
ExternalSystemUtil.refreshProjects(
ImportSpecBuilder(project, externalSystemId)
.use(ProgressExecutionMode.MODAL_SYNC)
.callback(object : ExternalProjectRefreshCallback {
override fun onSuccess(externalProject: DataNode<ProjectData>?) {
if (externalProject == null) {
val errorMessage = "Got null External project after import"
System.err.println(errorMessage)
error.set(Couple.of(errorMessage, null))
return
}
ServiceManager.getService(ProjectDataManager::class.java).importData(externalProject, project, true)
println("External project was successfully imported")
}
override fun onFailure(errorMessage: String, errorDetails: String?) {
error.set(Couple.of(errorMessage, errorDetails))
}
})
.forceWhenUptodate()
)
if (!error.isNull) {
var failureMsg = "Import failed: " + error.get().first
if (StringUtil.isNotEmpty(error.get().second)) {
failureMsg += "\nError details: \n" + error.get().second
}
TestCase.fail(failureMsg)
}
}
// TODO: add testMobile when we will be able to locate Android SDK automatically
@Test @Test
fun testMobileShared() { fun testMobileShared() {
testImportFromBuilder(KotlinGradleMobileSharedMultiplatformModuleBuilder(), "MobileShared", metadataInside = true) testImportFromBuilder(KotlinGradleMobileSharedMultiplatformModuleBuilder(), "MobileShared", metadataInside = true)
@@ -106,4 +231,20 @@ class GradleMultiplatformWizardTest : ProjectWizardTestCase<AbstractProjectWizar
fun testWeb() { fun testWeb() {
testImportFromBuilder(KotlinGradleWebMultiplatformModuleBuilder(), "Web") testImportFromBuilder(KotlinGradleWebMultiplatformModuleBuilder(), "Web")
} }
override fun setUp() {
super.setUp()
val javaHome = IdeaTestUtil.requireRealJdkHome()
ApplicationManager.getApplication().runWriteAction {
addSdk(SimpleJavaSdkType().createJdk(DEFAULT_SDK, javaHome))
addSdk(SimpleJavaSdkType().createJdk("_other", javaHome))
println("ProjectWizardTestCase.configureJdk:")
println(Arrays.asList(*ProjectJdkTable.getInstance().allJdks))
}
}
companion object {
val externalSystemId = GradleConstants.SYSTEM_ID
}
} }
@@ -224,7 +224,7 @@ abstract class GradleImportingTestCase : ExternalSystemImportingTestCase() {
} }
companion object { companion object {
private const val GRADLE_JDK_NAME = "Gradle JDK" const val GRADLE_JDK_NAME = "Gradle JDK"
private const val GRADLE_DAEMON_TTL_MS = 10000 private const val GRADLE_DAEMON_TTL_MS = 10000
@JvmStatic @JvmStatic
@@ -236,7 +236,7 @@ abstract class GradleImportingTestCase : ExternalSystemImportingTestCase() {
return Arrays.asList(*AbstractModelBuilderTest.SUPPORTED_GRADLE_VERSIONS) return Arrays.asList(*AbstractModelBuilderTest.SUPPORTED_GRADLE_VERSIONS)
} }
private fun wrapperJar(): File { fun wrapperJar(): File {
return File(PathUtil.getJarPathForClass(GradleWrapperMain::class.java)) return File(PathUtil.getJarPathForClass(GradleWrapperMain::class.java))
} }
} }