diff --git a/.idea/compiler.xml b/.idea/compiler.xml index d9076ec..2f83f0d 100644 --- a/.idea/compiler.xml +++ b/.idea/compiler.xml @@ -5,6 +5,8 @@ + + - \ No newline at end of file + diff --git a/.idea/gradle.xml b/.idea/gradle.xml index 247e294..d6bfecb 100644 --- a/.idea/gradle.xml +++ b/.idea/gradle.xml @@ -20,6 +20,16 @@ diff --git a/.idea/kotlinc.xml b/.idea/kotlinc.xml index c224ad5..c41c613 100644 --- a/.idea/kotlinc.xml +++ b/.idea/kotlinc.xml @@ -1,6 +1,6 @@ - - \ No newline at end of file + diff --git a/api/src/main/kotlin/org/modelix/mps/api/IModelixMpsApi.kt b/api/src/main/kotlin/org/modelix/mps/api/IModelixMpsApi.kt index 49f0187..7e9ff69 100644 --- a/api/src/main/kotlin/org/modelix/mps/api/IModelixMpsApi.kt +++ b/api/src/main/kotlin/org/modelix/mps/api/IModelixMpsApi.kt @@ -1,7 +1,7 @@ package org.modelix.mps.api -import jetbrains.mps.project.Project import org.jetbrains.mps.openapi.module.SModule +import org.jetbrains.mps.openapi.project.Project interface IModelixMpsApi { fun getMPSProjects(): List diff --git a/build.gradle.kts b/build.gradle.kts index 776e55f..12e95a8 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,5 +1,3 @@ -import org.gradle.kotlin.dsl.configure -import org.gradle.kotlin.dsl.withType import org.jetbrains.kotlin.gradle.dsl.KotlinJvmProjectExtension import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformJvmPlugin @@ -49,6 +47,13 @@ for ((majorVersion, fullVersion) in mpsVersions) { into(mpsDir) } } + // The build number of a local IDE is expected to contain a product code, otherwise an exception is thrown. + val buildTxt = mpsDir.get().asFile.resolve("build.txt") + val buildNumber = buildTxt.readText() + val prefix = "MPS-" + if (!buildNumber.startsWith(prefix)) { + buildTxt.writeText("$prefix$buildNumber") + } dependencies { "implementation"(project(":api")) diff --git a/gradle.properties b/gradle.properties index f7ee5d3..70da221 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,4 @@ -org.gradle.configuration-cache=true +org.gradle.configuration-cache=false org.gradle.parallel=true org.gradle.caching=true kotlin.daemon.jvmargs=-Xmx2g diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index e6a780f..64ee9e9 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -9,3 +9,5 @@ kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version = "2.1.10" } shadow = { id = "com.gradleup.shadow", version = "9.0.0-beta6" } binaryCompatibility = { id ="org.jetbrains.kotlinx.binary-compatibility-validator", version = "0.17.0" } +intellij = { id = "org.jetbrains.intellij", version = "1.17.4" } +intellij2 = { id = "org.jetbrains.intellij.platform", version = "2.2.1" } diff --git a/impl203/src/main/kotlin/org/modelix/mps/api/ModelixMpsApiImpl203.kt b/impl203/src/main/kotlin/org/modelix/mps/api/ModelixMpsApiImpl203.kt index 33f24a3..9951f30 100644 --- a/impl203/src/main/kotlin/org/modelix/mps/api/ModelixMpsApiImpl203.kt +++ b/impl203/src/main/kotlin/org/modelix/mps/api/ModelixMpsApiImpl203.kt @@ -2,9 +2,9 @@ package org.modelix.mps.api import jetbrains.mps.lang.migration.runtime.base.VersionFixer import jetbrains.mps.project.MPSProject -import jetbrains.mps.project.Project import jetbrains.mps.project.ProjectManager import org.jetbrains.mps.openapi.module.SModule +import org.jetbrains.mps.openapi.project.Project open class ModelixMpsApiImpl203 : IModelixMpsApi { override fun getMPSProjects(): List { @@ -19,6 +19,6 @@ open class ModelixMpsApiImpl203 : IModelixMpsApi { } override fun fixVersions(project: Project, module: SModule) { - VersionFixer(project, module, true).updateImportVersions() + VersionFixer(project as jetbrains.mps.project.Project, module, true).updateImportVersions() } } diff --git a/impl211/src/main/kotlin/org/modelix/mps/api/ModelixMpsApiImpl211.kt b/impl211/src/main/kotlin/org/modelix/mps/api/ModelixMpsApiImpl211.kt index 6510691..b18ff77 100644 --- a/impl211/src/main/kotlin/org/modelix/mps/api/ModelixMpsApiImpl211.kt +++ b/impl211/src/main/kotlin/org/modelix/mps/api/ModelixMpsApiImpl211.kt @@ -1,9 +1,9 @@ package org.modelix.mps.api -import jetbrains.mps.project.Project import jetbrains.mps.smodel.ModuleDependencyVersions import jetbrains.mps.smodel.language.LanguageRegistry import org.jetbrains.mps.openapi.module.SModule +import org.jetbrains.mps.openapi.project.Project open class ModelixMpsApiImpl211 : ModelixMpsApiImpl203() { override fun fixVersions(project: Project, module: SModule) { diff --git a/impl222/src/main/kotlin/org/modelix/mps/api/ModelixMpsApiImpl222.kt b/impl222/src/main/kotlin/org/modelix/mps/api/ModelixMpsApiImpl222.kt index c2be93e..71214f2 100644 --- a/impl222/src/main/kotlin/org/modelix/mps/api/ModelixMpsApiImpl222.kt +++ b/impl222/src/main/kotlin/org/modelix/mps/api/ModelixMpsApiImpl222.kt @@ -1,8 +1,8 @@ package org.modelix.mps.api import jetbrains.mps.project.MPSProject -import jetbrains.mps.project.Project import org.jetbrains.mps.openapi.module.SModule +import org.jetbrains.mps.openapi.project.Project open class ModelixMpsApiImpl222 : ModelixMpsApiImpl213() { override fun getVirtualFolder( diff --git a/impl243/src/main/kotlin/org/modelix/mps/api/ModelixMpsApiImpl243.kt b/impl243/src/main/kotlin/org/modelix/mps/api/ModelixMpsApiImpl243.kt index 0b2eaef..d77029b 100644 --- a/impl243/src/main/kotlin/org/modelix/mps/api/ModelixMpsApiImpl243.kt +++ b/impl243/src/main/kotlin/org/modelix/mps/api/ModelixMpsApiImpl243.kt @@ -1,8 +1,8 @@ package org.modelix.mps.api import jetbrains.mps.ide.MPSCoreComponents -import jetbrains.mps.project.Project import jetbrains.mps.project.ProjectManager +import org.jetbrains.mps.openapi.project.Project open class ModelixMpsApiImpl243 : ModelixMpsApiImpl241() { override fun getMPSProjects(): List { diff --git a/lib/api/lib.api b/lib/api/lib.api index 400b6b0..d118234 100644 --- a/lib/api/lib.api +++ b/lib/api/lib.api @@ -1,9 +1,9 @@ public final class org/modelix/mps/api/ModelixMpsApi : org/modelix/mps/api/IModelixMpsApi { public static final field INSTANCE Lorg/modelix/mps/api/ModelixMpsApi; - public fun fixVersions (Ljetbrains/mps/project/Project;Lorg/jetbrains/mps/openapi/module/SModule;)V + public fun fixVersions (Lorg/jetbrains/mps/openapi/project/Project;Lorg/jetbrains/mps/openapi/module/SModule;)V public fun getMPSProjects ()Ljava/util/List; - public fun getVirtualFolder (Ljetbrains/mps/project/Project;Lorg/jetbrains/mps/openapi/module/SModule;)Ljava/lang/String; public fun getVirtualFolder (Lorg/jetbrains/mps/openapi/module/SModule;)Ljava/lang/String; + public fun getVirtualFolder (Lorg/jetbrains/mps/openapi/project/Project;Lorg/jetbrains/mps/openapi/module/SModule;)Ljava/lang/String; public fun getVirtualFolders (Lorg/jetbrains/mps/openapi/module/SModule;)Ljava/util/List; } diff --git a/lib/src/main/kotlin/org/modelix/mps/api/ModelixMpsApi.kt b/lib/src/main/kotlin/org/modelix/mps/api/ModelixMpsApi.kt index e27ab6d..c34e9d7 100644 --- a/lib/src/main/kotlin/org/modelix/mps/api/ModelixMpsApi.kt +++ b/lib/src/main/kotlin/org/modelix/mps/api/ModelixMpsApi.kt @@ -4,7 +4,7 @@ import com.intellij.openapi.application.ApplicationInfo private fun detectMpsVersion(): Int { val info = ApplicationInfo.getInstance() - return info.majorVersion.toInt() - 2000 + info.minorVersionMainPart.toInt() + return (info.majorVersion.toInt() - 2000) * 10 + info.minorVersionMainPart.toInt() } private fun resolveInstance(): IModelixMpsApi { diff --git a/settings.gradle.kts b/settings.gradle.kts index 2682d4e..5cc9cde 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -6,6 +6,7 @@ plugins { rootProject.name = "modelix.mps-api" include("api") include("lib") +include("test") // https://artifacts.itemis.cloud/service/rest/repository/browse/maven-mps/com/jetbrains/mps/ val mpsVersions = mapOf( @@ -23,4 +24,7 @@ val mpsVersions = mapOf( for (majorVersion in mpsVersions.keys) { include("impl$majorVersion") + if (majorVersion < 242) { // MPS is not yet compatible to the new intellij plugin + include(":test:$majorVersion") + } } diff --git a/test/203/build.gradle.kts b/test/203/build.gradle.kts new file mode 100644 index 0000000..08c2c8e --- /dev/null +++ b/test/203/build.gradle.kts @@ -0,0 +1,19 @@ +plugins { + alias(libs.plugins.intellij) + alias(libs.plugins.kotlin.jvm) +} + +intellij { + localPath = project(":impl203").layout.buildDirectory.dir("mps").map { it.asFile.absolutePath } + instrumentCode = false +} + +tasks { + buildSearchableOptions { + enabled = false + } +} + +dependencies { + testImplementation(project(":lib")) +} diff --git a/test/203/src/test/kotlin/TestBase.kt b/test/203/src/test/kotlin/TestBase.kt new file mode 100644 index 0000000..b784d0b --- /dev/null +++ b/test/203/src/test/kotlin/TestBase.kt @@ -0,0 +1,103 @@ +import com.intellij.ide.impl.OpenProjectTask +import com.intellij.openapi.Disposable +import com.intellij.openapi.application.ApplicationManager +import com.intellij.openapi.project.Project +import com.intellij.openapi.project.ProjectManager +import com.intellij.openapi.project.ex.ProjectManagerEx +import com.intellij.openapi.util.Disposer +import com.intellij.testFramework.TestApplicationManager +import com.intellij.testFramework.UsefulTestCase +import com.intellij.util.io.delete +import jetbrains.mps.ide.ThreadUtils +import jetbrains.mps.ide.project.ProjectHelper +import jetbrains.mps.project.MPSProject +import java.io.File +import java.nio.file.Files +import java.nio.file.Path + +/** + * Based on org.jetbrains.uast.test.env.AbstractLargeProjectTest + */ +@Suppress("removal") +abstract class TestBase(val testDataName: String?) : UsefulTestCase() { + init { + // workaround for MPS 2023.3 failing to start in test mode + System.setProperty("intellij.platform.load.app.info.from.resources", "true") + } + + protected lateinit var project: Project + + override fun runInDispatchThread() = false + + override fun setUp() { + super.setUp() + TestApplicationManager.getInstance() + project = openTestProject() + } + + override fun tearDown() { + super.tearDown() + } + + private fun openTestProject(): Project { + val projectDirParent = Path.of("build", "test-projects").toAbsolutePath() + projectDirParent.toFile().mkdirs() + val projectDir = Files.createTempDirectory(projectDirParent, "mps-project") + projectDir.delete(recursively = true) + projectDir.toFile().mkdirs() + projectDir.toFile().deleteOnExit() + val project = if (testDataName != null) { + val sourceDir = File("testdata/$testDataName") + sourceDir.copyRecursively(projectDir.toFile(), overwrite = true) + ProjectManagerEx.getInstanceEx().openProject(projectDir, OpenProjectTask())!! + } else { + ProjectManagerEx.getInstanceEx().newProject(projectDir, OpenProjectTask())!! + } + + disposeOnTearDownInEdt { runCatching { ProjectManager.getInstance().closeAndDispose(project) } } + + ApplicationManager.getApplication().invokeAndWait { + // empty - openTestProject executed not in EDT, so, invokeAndWait just forces + // processing of all events that were queued during project opening + } + + return project + } + + private fun disposeOnTearDownInEdt(runnable: Runnable) { + Disposer.register( + testRootDisposable, + Disposable { + ApplicationManager.getApplication().invokeAndWait(runnable) + }, + ) + } + + protected val mpsProject: MPSProject get() { + return checkNotNull(ProjectHelper.fromIdeaProject(project)) { "MPS project not loaded" } + } + + protected fun writeAction(body: () -> R): R { + return mpsProject.modelAccess.computeWriteAction(body) + } + + protected fun writeActionOnEdt(body: () -> R): R { + return onEdt { writeAction { body() } } + } + + protected fun onEdt(body: () -> R): R { + var result: R? = null + ThreadUtils.runInUIThreadAndWait { + result = body() + } + return result as R + } + + protected fun readAction(body: () -> R): R { + var result: R? = null + mpsProject.modelAccess.runReadAction { + result = body() + } + return result as R + } +} diff --git a/test/203/src/test/kotlin/VirtualFolderTests203.kt b/test/203/src/test/kotlin/VirtualFolderTests203.kt new file mode 100644 index 0000000..8f4d4a7 --- /dev/null +++ b/test/203/src/test/kotlin/VirtualFolderTests203.kt @@ -0,0 +1,10 @@ +import org.modelix.mps.api.ModelixMpsApi + +class VirtualFolderTests203 : TestBase("SimpleProject") { + + fun `test getVirtualFolder`() { + val module = ModelixMpsApi.getMPSProjects().single().projectModules.single() + val folder = ModelixMpsApi.getVirtualFolder(module) + assertEquals("myFolder", folder) + } +} diff --git a/test/203/testdata/SimpleProject/.mps/modules.xml b/test/203/testdata/SimpleProject/.mps/modules.xml new file mode 100644 index 0000000..6b0fa61 --- /dev/null +++ b/test/203/testdata/SimpleProject/.mps/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/test/203/testdata/SimpleProject/solutions/Solution1/Solution1.msd b/test/203/testdata/SimpleProject/solutions/Solution1/Solution1.msd new file mode 100644 index 0000000..f015948 --- /dev/null +++ b/test/203/testdata/SimpleProject/solutions/Solution1/Solution1.msd @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/203/testdata/SimpleProject/solutions/Solution1/models/Solution1.model1.mps b/test/203/testdata/SimpleProject/solutions/Solution1/models/Solution1.model1.mps new file mode 100644 index 0000000..64b0724 --- /dev/null +++ b/test/203/testdata/SimpleProject/solutions/Solution1/models/Solution1.model1.mps @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/211/build.gradle.kts b/test/211/build.gradle.kts new file mode 100644 index 0000000..ebcba97 --- /dev/null +++ b/test/211/build.gradle.kts @@ -0,0 +1,19 @@ +plugins { + alias(libs.plugins.intellij) + alias(libs.plugins.kotlin.jvm) +} + +intellij { + localPath = project(":impl211").layout.buildDirectory.dir("mps").map { it.asFile.absolutePath } + instrumentCode = false +} + +tasks { + buildSearchableOptions { + enabled = false + } +} + +dependencies { + testImplementation(project(":lib")) +} diff --git a/test/211/src/test/kotlin/TestBase.kt b/test/211/src/test/kotlin/TestBase.kt new file mode 100644 index 0000000..b784d0b --- /dev/null +++ b/test/211/src/test/kotlin/TestBase.kt @@ -0,0 +1,103 @@ +import com.intellij.ide.impl.OpenProjectTask +import com.intellij.openapi.Disposable +import com.intellij.openapi.application.ApplicationManager +import com.intellij.openapi.project.Project +import com.intellij.openapi.project.ProjectManager +import com.intellij.openapi.project.ex.ProjectManagerEx +import com.intellij.openapi.util.Disposer +import com.intellij.testFramework.TestApplicationManager +import com.intellij.testFramework.UsefulTestCase +import com.intellij.util.io.delete +import jetbrains.mps.ide.ThreadUtils +import jetbrains.mps.ide.project.ProjectHelper +import jetbrains.mps.project.MPSProject +import java.io.File +import java.nio.file.Files +import java.nio.file.Path + +/** + * Based on org.jetbrains.uast.test.env.AbstractLargeProjectTest + */ +@Suppress("removal") +abstract class TestBase(val testDataName: String?) : UsefulTestCase() { + init { + // workaround for MPS 2023.3 failing to start in test mode + System.setProperty("intellij.platform.load.app.info.from.resources", "true") + } + + protected lateinit var project: Project + + override fun runInDispatchThread() = false + + override fun setUp() { + super.setUp() + TestApplicationManager.getInstance() + project = openTestProject() + } + + override fun tearDown() { + super.tearDown() + } + + private fun openTestProject(): Project { + val projectDirParent = Path.of("build", "test-projects").toAbsolutePath() + projectDirParent.toFile().mkdirs() + val projectDir = Files.createTempDirectory(projectDirParent, "mps-project") + projectDir.delete(recursively = true) + projectDir.toFile().mkdirs() + projectDir.toFile().deleteOnExit() + val project = if (testDataName != null) { + val sourceDir = File("testdata/$testDataName") + sourceDir.copyRecursively(projectDir.toFile(), overwrite = true) + ProjectManagerEx.getInstanceEx().openProject(projectDir, OpenProjectTask())!! + } else { + ProjectManagerEx.getInstanceEx().newProject(projectDir, OpenProjectTask())!! + } + + disposeOnTearDownInEdt { runCatching { ProjectManager.getInstance().closeAndDispose(project) } } + + ApplicationManager.getApplication().invokeAndWait { + // empty - openTestProject executed not in EDT, so, invokeAndWait just forces + // processing of all events that were queued during project opening + } + + return project + } + + private fun disposeOnTearDownInEdt(runnable: Runnable) { + Disposer.register( + testRootDisposable, + Disposable { + ApplicationManager.getApplication().invokeAndWait(runnable) + }, + ) + } + + protected val mpsProject: MPSProject get() { + return checkNotNull(ProjectHelper.fromIdeaProject(project)) { "MPS project not loaded" } + } + + protected fun writeAction(body: () -> R): R { + return mpsProject.modelAccess.computeWriteAction(body) + } + + protected fun writeActionOnEdt(body: () -> R): R { + return onEdt { writeAction { body() } } + } + + protected fun onEdt(body: () -> R): R { + var result: R? = null + ThreadUtils.runInUIThreadAndWait { + result = body() + } + return result as R + } + + protected fun readAction(body: () -> R): R { + var result: R? = null + mpsProject.modelAccess.runReadAction { + result = body() + } + return result as R + } +} diff --git a/test/211/src/test/kotlin/VirtualFolderTests211.kt b/test/211/src/test/kotlin/VirtualFolderTests211.kt new file mode 100644 index 0000000..c3fab10 --- /dev/null +++ b/test/211/src/test/kotlin/VirtualFolderTests211.kt @@ -0,0 +1,10 @@ +import org.modelix.mps.api.ModelixMpsApi + +class VirtualFolderTests211 : TestBase("SimpleProject") { + + fun `test getVirtualFolder`() { + val module = ModelixMpsApi.getMPSProjects().single().projectModules.single() + val folder = ModelixMpsApi.getVirtualFolder(module) + assertEquals("myFolder", folder) + } +} diff --git a/test/211/testdata/SimpleProject/.mps/modules.xml b/test/211/testdata/SimpleProject/.mps/modules.xml new file mode 100644 index 0000000..6b0fa61 --- /dev/null +++ b/test/211/testdata/SimpleProject/.mps/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/test/211/testdata/SimpleProject/solutions/Solution1/Solution1.msd b/test/211/testdata/SimpleProject/solutions/Solution1/Solution1.msd new file mode 100644 index 0000000..f015948 --- /dev/null +++ b/test/211/testdata/SimpleProject/solutions/Solution1/Solution1.msd @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/211/testdata/SimpleProject/solutions/Solution1/models/Solution1.model1.mps b/test/211/testdata/SimpleProject/solutions/Solution1/models/Solution1.model1.mps new file mode 100644 index 0000000..64b0724 --- /dev/null +++ b/test/211/testdata/SimpleProject/solutions/Solution1/models/Solution1.model1.mps @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/212/build.gradle.kts b/test/212/build.gradle.kts new file mode 100644 index 0000000..807db89 --- /dev/null +++ b/test/212/build.gradle.kts @@ -0,0 +1,19 @@ +plugins { + alias(libs.plugins.intellij) + alias(libs.plugins.kotlin.jvm) +} + +intellij { + localPath = project(":impl212").layout.buildDirectory.dir("mps").map { it.asFile.absolutePath } + instrumentCode = false +} + +tasks { + buildSearchableOptions { + enabled = false + } +} + +dependencies { + testImplementation(project(":lib")) +} diff --git a/test/212/src/test/kotlin/TestBase.kt b/test/212/src/test/kotlin/TestBase.kt new file mode 100644 index 0000000..b784d0b --- /dev/null +++ b/test/212/src/test/kotlin/TestBase.kt @@ -0,0 +1,103 @@ +import com.intellij.ide.impl.OpenProjectTask +import com.intellij.openapi.Disposable +import com.intellij.openapi.application.ApplicationManager +import com.intellij.openapi.project.Project +import com.intellij.openapi.project.ProjectManager +import com.intellij.openapi.project.ex.ProjectManagerEx +import com.intellij.openapi.util.Disposer +import com.intellij.testFramework.TestApplicationManager +import com.intellij.testFramework.UsefulTestCase +import com.intellij.util.io.delete +import jetbrains.mps.ide.ThreadUtils +import jetbrains.mps.ide.project.ProjectHelper +import jetbrains.mps.project.MPSProject +import java.io.File +import java.nio.file.Files +import java.nio.file.Path + +/** + * Based on org.jetbrains.uast.test.env.AbstractLargeProjectTest + */ +@Suppress("removal") +abstract class TestBase(val testDataName: String?) : UsefulTestCase() { + init { + // workaround for MPS 2023.3 failing to start in test mode + System.setProperty("intellij.platform.load.app.info.from.resources", "true") + } + + protected lateinit var project: Project + + override fun runInDispatchThread() = false + + override fun setUp() { + super.setUp() + TestApplicationManager.getInstance() + project = openTestProject() + } + + override fun tearDown() { + super.tearDown() + } + + private fun openTestProject(): Project { + val projectDirParent = Path.of("build", "test-projects").toAbsolutePath() + projectDirParent.toFile().mkdirs() + val projectDir = Files.createTempDirectory(projectDirParent, "mps-project") + projectDir.delete(recursively = true) + projectDir.toFile().mkdirs() + projectDir.toFile().deleteOnExit() + val project = if (testDataName != null) { + val sourceDir = File("testdata/$testDataName") + sourceDir.copyRecursively(projectDir.toFile(), overwrite = true) + ProjectManagerEx.getInstanceEx().openProject(projectDir, OpenProjectTask())!! + } else { + ProjectManagerEx.getInstanceEx().newProject(projectDir, OpenProjectTask())!! + } + + disposeOnTearDownInEdt { runCatching { ProjectManager.getInstance().closeAndDispose(project) } } + + ApplicationManager.getApplication().invokeAndWait { + // empty - openTestProject executed not in EDT, so, invokeAndWait just forces + // processing of all events that were queued during project opening + } + + return project + } + + private fun disposeOnTearDownInEdt(runnable: Runnable) { + Disposer.register( + testRootDisposable, + Disposable { + ApplicationManager.getApplication().invokeAndWait(runnable) + }, + ) + } + + protected val mpsProject: MPSProject get() { + return checkNotNull(ProjectHelper.fromIdeaProject(project)) { "MPS project not loaded" } + } + + protected fun writeAction(body: () -> R): R { + return mpsProject.modelAccess.computeWriteAction(body) + } + + protected fun writeActionOnEdt(body: () -> R): R { + return onEdt { writeAction { body() } } + } + + protected fun onEdt(body: () -> R): R { + var result: R? = null + ThreadUtils.runInUIThreadAndWait { + result = body() + } + return result as R + } + + protected fun readAction(body: () -> R): R { + var result: R? = null + mpsProject.modelAccess.runReadAction { + result = body() + } + return result as R + } +} diff --git a/test/212/src/test/kotlin/VirtualFolderTests212.kt b/test/212/src/test/kotlin/VirtualFolderTests212.kt new file mode 100644 index 0000000..7293f9b --- /dev/null +++ b/test/212/src/test/kotlin/VirtualFolderTests212.kt @@ -0,0 +1,10 @@ +import org.modelix.mps.api.ModelixMpsApi + +class VirtualFolderTests212 : TestBase("SimpleProject") { + + fun `test getVirtualFolder`() { + val module = ModelixMpsApi.getMPSProjects().single().projectModules.single() + val folder = ModelixMpsApi.getVirtualFolder(module) + assertEquals("myFolder", folder) + } +} diff --git a/test/212/testdata/SimpleProject/.mps/modules.xml b/test/212/testdata/SimpleProject/.mps/modules.xml new file mode 100644 index 0000000..6b0fa61 --- /dev/null +++ b/test/212/testdata/SimpleProject/.mps/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/test/212/testdata/SimpleProject/solutions/Solution1/Solution1.msd b/test/212/testdata/SimpleProject/solutions/Solution1/Solution1.msd new file mode 100644 index 0000000..f015948 --- /dev/null +++ b/test/212/testdata/SimpleProject/solutions/Solution1/Solution1.msd @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/212/testdata/SimpleProject/solutions/Solution1/models/Solution1.model1.mps b/test/212/testdata/SimpleProject/solutions/Solution1/models/Solution1.model1.mps new file mode 100644 index 0000000..64b0724 --- /dev/null +++ b/test/212/testdata/SimpleProject/solutions/Solution1/models/Solution1.model1.mps @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/213/build.gradle.kts b/test/213/build.gradle.kts new file mode 100644 index 0000000..2b99c0f --- /dev/null +++ b/test/213/build.gradle.kts @@ -0,0 +1,19 @@ +plugins { + alias(libs.plugins.intellij) + alias(libs.plugins.kotlin.jvm) +} + +intellij { + localPath = project(":impl213").layout.buildDirectory.dir("mps").map { it.asFile.absolutePath } + instrumentCode = false +} + +tasks { + buildSearchableOptions { + enabled = false + } +} + +dependencies { + testImplementation(project(":lib")) +} diff --git a/test/213/src/test/kotlin/TestBase.kt b/test/213/src/test/kotlin/TestBase.kt new file mode 100644 index 0000000..b784d0b --- /dev/null +++ b/test/213/src/test/kotlin/TestBase.kt @@ -0,0 +1,103 @@ +import com.intellij.ide.impl.OpenProjectTask +import com.intellij.openapi.Disposable +import com.intellij.openapi.application.ApplicationManager +import com.intellij.openapi.project.Project +import com.intellij.openapi.project.ProjectManager +import com.intellij.openapi.project.ex.ProjectManagerEx +import com.intellij.openapi.util.Disposer +import com.intellij.testFramework.TestApplicationManager +import com.intellij.testFramework.UsefulTestCase +import com.intellij.util.io.delete +import jetbrains.mps.ide.ThreadUtils +import jetbrains.mps.ide.project.ProjectHelper +import jetbrains.mps.project.MPSProject +import java.io.File +import java.nio.file.Files +import java.nio.file.Path + +/** + * Based on org.jetbrains.uast.test.env.AbstractLargeProjectTest + */ +@Suppress("removal") +abstract class TestBase(val testDataName: String?) : UsefulTestCase() { + init { + // workaround for MPS 2023.3 failing to start in test mode + System.setProperty("intellij.platform.load.app.info.from.resources", "true") + } + + protected lateinit var project: Project + + override fun runInDispatchThread() = false + + override fun setUp() { + super.setUp() + TestApplicationManager.getInstance() + project = openTestProject() + } + + override fun tearDown() { + super.tearDown() + } + + private fun openTestProject(): Project { + val projectDirParent = Path.of("build", "test-projects").toAbsolutePath() + projectDirParent.toFile().mkdirs() + val projectDir = Files.createTempDirectory(projectDirParent, "mps-project") + projectDir.delete(recursively = true) + projectDir.toFile().mkdirs() + projectDir.toFile().deleteOnExit() + val project = if (testDataName != null) { + val sourceDir = File("testdata/$testDataName") + sourceDir.copyRecursively(projectDir.toFile(), overwrite = true) + ProjectManagerEx.getInstanceEx().openProject(projectDir, OpenProjectTask())!! + } else { + ProjectManagerEx.getInstanceEx().newProject(projectDir, OpenProjectTask())!! + } + + disposeOnTearDownInEdt { runCatching { ProjectManager.getInstance().closeAndDispose(project) } } + + ApplicationManager.getApplication().invokeAndWait { + // empty - openTestProject executed not in EDT, so, invokeAndWait just forces + // processing of all events that were queued during project opening + } + + return project + } + + private fun disposeOnTearDownInEdt(runnable: Runnable) { + Disposer.register( + testRootDisposable, + Disposable { + ApplicationManager.getApplication().invokeAndWait(runnable) + }, + ) + } + + protected val mpsProject: MPSProject get() { + return checkNotNull(ProjectHelper.fromIdeaProject(project)) { "MPS project not loaded" } + } + + protected fun writeAction(body: () -> R): R { + return mpsProject.modelAccess.computeWriteAction(body) + } + + protected fun writeActionOnEdt(body: () -> R): R { + return onEdt { writeAction { body() } } + } + + protected fun onEdt(body: () -> R): R { + var result: R? = null + ThreadUtils.runInUIThreadAndWait { + result = body() + } + return result as R + } + + protected fun readAction(body: () -> R): R { + var result: R? = null + mpsProject.modelAccess.runReadAction { + result = body() + } + return result as R + } +} diff --git a/test/213/src/test/kotlin/VirtualFolderTests213.kt b/test/213/src/test/kotlin/VirtualFolderTests213.kt new file mode 100644 index 0000000..38d98ab --- /dev/null +++ b/test/213/src/test/kotlin/VirtualFolderTests213.kt @@ -0,0 +1,10 @@ +import org.modelix.mps.api.ModelixMpsApi + +class VirtualFolderTests213 : TestBase("SimpleProject") { + + fun `test getVirtualFolder`() { + val module = ModelixMpsApi.getMPSProjects().single().projectModules.single() + val folder = ModelixMpsApi.getVirtualFolder(module) + assertEquals("myFolder", folder) + } +} diff --git a/test/213/testdata/SimpleProject/.mps/modules.xml b/test/213/testdata/SimpleProject/.mps/modules.xml new file mode 100644 index 0000000..6b0fa61 --- /dev/null +++ b/test/213/testdata/SimpleProject/.mps/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/test/213/testdata/SimpleProject/solutions/Solution1/Solution1.msd b/test/213/testdata/SimpleProject/solutions/Solution1/Solution1.msd new file mode 100644 index 0000000..f015948 --- /dev/null +++ b/test/213/testdata/SimpleProject/solutions/Solution1/Solution1.msd @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/213/testdata/SimpleProject/solutions/Solution1/models/Solution1.model1.mps b/test/213/testdata/SimpleProject/solutions/Solution1/models/Solution1.model1.mps new file mode 100644 index 0000000..64b0724 --- /dev/null +++ b/test/213/testdata/SimpleProject/solutions/Solution1/models/Solution1.model1.mps @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/222/build.gradle.kts b/test/222/build.gradle.kts new file mode 100644 index 0000000..d3f9bea --- /dev/null +++ b/test/222/build.gradle.kts @@ -0,0 +1,19 @@ +plugins { + alias(libs.plugins.intellij) + alias(libs.plugins.kotlin.jvm) +} + +intellij { + localPath = project(":impl222").layout.buildDirectory.dir("mps").map { it.asFile.absolutePath } + instrumentCode = false +} + +tasks { + buildSearchableOptions { + enabled = false + } +} + +dependencies { + testImplementation(project(":lib")) +} diff --git a/test/222/src/test/kotlin/TestBase.kt b/test/222/src/test/kotlin/TestBase.kt new file mode 100644 index 0000000..b784d0b --- /dev/null +++ b/test/222/src/test/kotlin/TestBase.kt @@ -0,0 +1,103 @@ +import com.intellij.ide.impl.OpenProjectTask +import com.intellij.openapi.Disposable +import com.intellij.openapi.application.ApplicationManager +import com.intellij.openapi.project.Project +import com.intellij.openapi.project.ProjectManager +import com.intellij.openapi.project.ex.ProjectManagerEx +import com.intellij.openapi.util.Disposer +import com.intellij.testFramework.TestApplicationManager +import com.intellij.testFramework.UsefulTestCase +import com.intellij.util.io.delete +import jetbrains.mps.ide.ThreadUtils +import jetbrains.mps.ide.project.ProjectHelper +import jetbrains.mps.project.MPSProject +import java.io.File +import java.nio.file.Files +import java.nio.file.Path + +/** + * Based on org.jetbrains.uast.test.env.AbstractLargeProjectTest + */ +@Suppress("removal") +abstract class TestBase(val testDataName: String?) : UsefulTestCase() { + init { + // workaround for MPS 2023.3 failing to start in test mode + System.setProperty("intellij.platform.load.app.info.from.resources", "true") + } + + protected lateinit var project: Project + + override fun runInDispatchThread() = false + + override fun setUp() { + super.setUp() + TestApplicationManager.getInstance() + project = openTestProject() + } + + override fun tearDown() { + super.tearDown() + } + + private fun openTestProject(): Project { + val projectDirParent = Path.of("build", "test-projects").toAbsolutePath() + projectDirParent.toFile().mkdirs() + val projectDir = Files.createTempDirectory(projectDirParent, "mps-project") + projectDir.delete(recursively = true) + projectDir.toFile().mkdirs() + projectDir.toFile().deleteOnExit() + val project = if (testDataName != null) { + val sourceDir = File("testdata/$testDataName") + sourceDir.copyRecursively(projectDir.toFile(), overwrite = true) + ProjectManagerEx.getInstanceEx().openProject(projectDir, OpenProjectTask())!! + } else { + ProjectManagerEx.getInstanceEx().newProject(projectDir, OpenProjectTask())!! + } + + disposeOnTearDownInEdt { runCatching { ProjectManager.getInstance().closeAndDispose(project) } } + + ApplicationManager.getApplication().invokeAndWait { + // empty - openTestProject executed not in EDT, so, invokeAndWait just forces + // processing of all events that were queued during project opening + } + + return project + } + + private fun disposeOnTearDownInEdt(runnable: Runnable) { + Disposer.register( + testRootDisposable, + Disposable { + ApplicationManager.getApplication().invokeAndWait(runnable) + }, + ) + } + + protected val mpsProject: MPSProject get() { + return checkNotNull(ProjectHelper.fromIdeaProject(project)) { "MPS project not loaded" } + } + + protected fun writeAction(body: () -> R): R { + return mpsProject.modelAccess.computeWriteAction(body) + } + + protected fun writeActionOnEdt(body: () -> R): R { + return onEdt { writeAction { body() } } + } + + protected fun onEdt(body: () -> R): R { + var result: R? = null + ThreadUtils.runInUIThreadAndWait { + result = body() + } + return result as R + } + + protected fun readAction(body: () -> R): R { + var result: R? = null + mpsProject.modelAccess.runReadAction { + result = body() + } + return result as R + } +} diff --git a/test/222/src/test/kotlin/VirtualFolderTests222.kt b/test/222/src/test/kotlin/VirtualFolderTests222.kt new file mode 100644 index 0000000..6677125 --- /dev/null +++ b/test/222/src/test/kotlin/VirtualFolderTests222.kt @@ -0,0 +1,10 @@ +import org.modelix.mps.api.ModelixMpsApi + +class VirtualFolderTests222 : TestBase("SimpleProject") { + + fun `test getVirtualFolder`() { + val module = ModelixMpsApi.getMPSProjects().single().projectModules.single() + val folder = ModelixMpsApi.getVirtualFolder(module) + assertEquals("myFolder", folder) + } +} diff --git a/test/222/testdata/SimpleProject/.mps/modules.xml b/test/222/testdata/SimpleProject/.mps/modules.xml new file mode 100644 index 0000000..6b0fa61 --- /dev/null +++ b/test/222/testdata/SimpleProject/.mps/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/test/222/testdata/SimpleProject/solutions/Solution1/Solution1.msd b/test/222/testdata/SimpleProject/solutions/Solution1/Solution1.msd new file mode 100644 index 0000000..f015948 --- /dev/null +++ b/test/222/testdata/SimpleProject/solutions/Solution1/Solution1.msd @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/222/testdata/SimpleProject/solutions/Solution1/models/Solution1.model1.mps b/test/222/testdata/SimpleProject/solutions/Solution1/models/Solution1.model1.mps new file mode 100644 index 0000000..64b0724 --- /dev/null +++ b/test/222/testdata/SimpleProject/solutions/Solution1/models/Solution1.model1.mps @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/223/build.gradle.kts b/test/223/build.gradle.kts new file mode 100644 index 0000000..2a79527 --- /dev/null +++ b/test/223/build.gradle.kts @@ -0,0 +1,19 @@ +plugins { + alias(libs.plugins.intellij) + alias(libs.plugins.kotlin.jvm) +} + +intellij { + localPath = project(":impl223").layout.buildDirectory.dir("mps").map { it.asFile.absolutePath } + instrumentCode = false +} + +tasks { + buildSearchableOptions { + enabled = false + } +} + +dependencies { + testImplementation(project(":lib")) +} diff --git a/test/223/src/test/kotlin/TestBase.kt b/test/223/src/test/kotlin/TestBase.kt new file mode 100644 index 0000000..b784d0b --- /dev/null +++ b/test/223/src/test/kotlin/TestBase.kt @@ -0,0 +1,103 @@ +import com.intellij.ide.impl.OpenProjectTask +import com.intellij.openapi.Disposable +import com.intellij.openapi.application.ApplicationManager +import com.intellij.openapi.project.Project +import com.intellij.openapi.project.ProjectManager +import com.intellij.openapi.project.ex.ProjectManagerEx +import com.intellij.openapi.util.Disposer +import com.intellij.testFramework.TestApplicationManager +import com.intellij.testFramework.UsefulTestCase +import com.intellij.util.io.delete +import jetbrains.mps.ide.ThreadUtils +import jetbrains.mps.ide.project.ProjectHelper +import jetbrains.mps.project.MPSProject +import java.io.File +import java.nio.file.Files +import java.nio.file.Path + +/** + * Based on org.jetbrains.uast.test.env.AbstractLargeProjectTest + */ +@Suppress("removal") +abstract class TestBase(val testDataName: String?) : UsefulTestCase() { + init { + // workaround for MPS 2023.3 failing to start in test mode + System.setProperty("intellij.platform.load.app.info.from.resources", "true") + } + + protected lateinit var project: Project + + override fun runInDispatchThread() = false + + override fun setUp() { + super.setUp() + TestApplicationManager.getInstance() + project = openTestProject() + } + + override fun tearDown() { + super.tearDown() + } + + private fun openTestProject(): Project { + val projectDirParent = Path.of("build", "test-projects").toAbsolutePath() + projectDirParent.toFile().mkdirs() + val projectDir = Files.createTempDirectory(projectDirParent, "mps-project") + projectDir.delete(recursively = true) + projectDir.toFile().mkdirs() + projectDir.toFile().deleteOnExit() + val project = if (testDataName != null) { + val sourceDir = File("testdata/$testDataName") + sourceDir.copyRecursively(projectDir.toFile(), overwrite = true) + ProjectManagerEx.getInstanceEx().openProject(projectDir, OpenProjectTask())!! + } else { + ProjectManagerEx.getInstanceEx().newProject(projectDir, OpenProjectTask())!! + } + + disposeOnTearDownInEdt { runCatching { ProjectManager.getInstance().closeAndDispose(project) } } + + ApplicationManager.getApplication().invokeAndWait { + // empty - openTestProject executed not in EDT, so, invokeAndWait just forces + // processing of all events that were queued during project opening + } + + return project + } + + private fun disposeOnTearDownInEdt(runnable: Runnable) { + Disposer.register( + testRootDisposable, + Disposable { + ApplicationManager.getApplication().invokeAndWait(runnable) + }, + ) + } + + protected val mpsProject: MPSProject get() { + return checkNotNull(ProjectHelper.fromIdeaProject(project)) { "MPS project not loaded" } + } + + protected fun writeAction(body: () -> R): R { + return mpsProject.modelAccess.computeWriteAction(body) + } + + protected fun writeActionOnEdt(body: () -> R): R { + return onEdt { writeAction { body() } } + } + + protected fun onEdt(body: () -> R): R { + var result: R? = null + ThreadUtils.runInUIThreadAndWait { + result = body() + } + return result as R + } + + protected fun readAction(body: () -> R): R { + var result: R? = null + mpsProject.modelAccess.runReadAction { + result = body() + } + return result as R + } +} diff --git a/test/223/src/test/kotlin/VirtualFolderTests223.kt b/test/223/src/test/kotlin/VirtualFolderTests223.kt new file mode 100644 index 0000000..086d16f --- /dev/null +++ b/test/223/src/test/kotlin/VirtualFolderTests223.kt @@ -0,0 +1,10 @@ +import org.modelix.mps.api.ModelixMpsApi + +class VirtualFolderTests223 : TestBase("SimpleProject") { + + fun `test getVirtualFolder`() { + val module = ModelixMpsApi.getMPSProjects().single().projectModules.single() + val folder = ModelixMpsApi.getVirtualFolder(module) + assertEquals("myFolder", folder) + } +} diff --git a/test/223/testdata/SimpleProject/.mps/modules.xml b/test/223/testdata/SimpleProject/.mps/modules.xml new file mode 100644 index 0000000..6b0fa61 --- /dev/null +++ b/test/223/testdata/SimpleProject/.mps/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/test/223/testdata/SimpleProject/solutions/Solution1/Solution1.msd b/test/223/testdata/SimpleProject/solutions/Solution1/Solution1.msd new file mode 100644 index 0000000..f015948 --- /dev/null +++ b/test/223/testdata/SimpleProject/solutions/Solution1/Solution1.msd @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/223/testdata/SimpleProject/solutions/Solution1/models/Solution1.model1.mps b/test/223/testdata/SimpleProject/solutions/Solution1/models/Solution1.model1.mps new file mode 100644 index 0000000..64b0724 --- /dev/null +++ b/test/223/testdata/SimpleProject/solutions/Solution1/models/Solution1.model1.mps @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/232/build.gradle.kts b/test/232/build.gradle.kts new file mode 100644 index 0000000..e320508 --- /dev/null +++ b/test/232/build.gradle.kts @@ -0,0 +1,19 @@ +plugins { + alias(libs.plugins.intellij) + alias(libs.plugins.kotlin.jvm) +} + +intellij { + localPath = project(":impl232").layout.buildDirectory.dir("mps").map { it.asFile.absolutePath } + instrumentCode = false +} + +tasks { + buildSearchableOptions { + enabled = false + } +} + +dependencies { + testImplementation(project(":lib")) +} diff --git a/test/232/src/test/kotlin/TestBase.kt b/test/232/src/test/kotlin/TestBase.kt new file mode 100644 index 0000000..b784d0b --- /dev/null +++ b/test/232/src/test/kotlin/TestBase.kt @@ -0,0 +1,103 @@ +import com.intellij.ide.impl.OpenProjectTask +import com.intellij.openapi.Disposable +import com.intellij.openapi.application.ApplicationManager +import com.intellij.openapi.project.Project +import com.intellij.openapi.project.ProjectManager +import com.intellij.openapi.project.ex.ProjectManagerEx +import com.intellij.openapi.util.Disposer +import com.intellij.testFramework.TestApplicationManager +import com.intellij.testFramework.UsefulTestCase +import com.intellij.util.io.delete +import jetbrains.mps.ide.ThreadUtils +import jetbrains.mps.ide.project.ProjectHelper +import jetbrains.mps.project.MPSProject +import java.io.File +import java.nio.file.Files +import java.nio.file.Path + +/** + * Based on org.jetbrains.uast.test.env.AbstractLargeProjectTest + */ +@Suppress("removal") +abstract class TestBase(val testDataName: String?) : UsefulTestCase() { + init { + // workaround for MPS 2023.3 failing to start in test mode + System.setProperty("intellij.platform.load.app.info.from.resources", "true") + } + + protected lateinit var project: Project + + override fun runInDispatchThread() = false + + override fun setUp() { + super.setUp() + TestApplicationManager.getInstance() + project = openTestProject() + } + + override fun tearDown() { + super.tearDown() + } + + private fun openTestProject(): Project { + val projectDirParent = Path.of("build", "test-projects").toAbsolutePath() + projectDirParent.toFile().mkdirs() + val projectDir = Files.createTempDirectory(projectDirParent, "mps-project") + projectDir.delete(recursively = true) + projectDir.toFile().mkdirs() + projectDir.toFile().deleteOnExit() + val project = if (testDataName != null) { + val sourceDir = File("testdata/$testDataName") + sourceDir.copyRecursively(projectDir.toFile(), overwrite = true) + ProjectManagerEx.getInstanceEx().openProject(projectDir, OpenProjectTask())!! + } else { + ProjectManagerEx.getInstanceEx().newProject(projectDir, OpenProjectTask())!! + } + + disposeOnTearDownInEdt { runCatching { ProjectManager.getInstance().closeAndDispose(project) } } + + ApplicationManager.getApplication().invokeAndWait { + // empty - openTestProject executed not in EDT, so, invokeAndWait just forces + // processing of all events that were queued during project opening + } + + return project + } + + private fun disposeOnTearDownInEdt(runnable: Runnable) { + Disposer.register( + testRootDisposable, + Disposable { + ApplicationManager.getApplication().invokeAndWait(runnable) + }, + ) + } + + protected val mpsProject: MPSProject get() { + return checkNotNull(ProjectHelper.fromIdeaProject(project)) { "MPS project not loaded" } + } + + protected fun writeAction(body: () -> R): R { + return mpsProject.modelAccess.computeWriteAction(body) + } + + protected fun writeActionOnEdt(body: () -> R): R { + return onEdt { writeAction { body() } } + } + + protected fun onEdt(body: () -> R): R { + var result: R? = null + ThreadUtils.runInUIThreadAndWait { + result = body() + } + return result as R + } + + protected fun readAction(body: () -> R): R { + var result: R? = null + mpsProject.modelAccess.runReadAction { + result = body() + } + return result as R + } +} diff --git a/test/232/src/test/kotlin/VirtualFolderTests232.kt b/test/232/src/test/kotlin/VirtualFolderTests232.kt new file mode 100644 index 0000000..71ab34b --- /dev/null +++ b/test/232/src/test/kotlin/VirtualFolderTests232.kt @@ -0,0 +1,10 @@ +import org.modelix.mps.api.ModelixMpsApi + +class VirtualFolderTests232 : TestBase("SimpleProject") { + + fun `test getVirtualFolder`() { + val module = ModelixMpsApi.getMPSProjects().single().projectModules.single() + val folder = ModelixMpsApi.getVirtualFolder(module) + assertEquals("myFolder", folder) + } +} diff --git a/test/232/testdata/SimpleProject/.mps/modules.xml b/test/232/testdata/SimpleProject/.mps/modules.xml new file mode 100644 index 0000000..6b0fa61 --- /dev/null +++ b/test/232/testdata/SimpleProject/.mps/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/test/232/testdata/SimpleProject/solutions/Solution1/Solution1.msd b/test/232/testdata/SimpleProject/solutions/Solution1/Solution1.msd new file mode 100644 index 0000000..f015948 --- /dev/null +++ b/test/232/testdata/SimpleProject/solutions/Solution1/Solution1.msd @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/232/testdata/SimpleProject/solutions/Solution1/models/Solution1.model1.mps b/test/232/testdata/SimpleProject/solutions/Solution1/models/Solution1.model1.mps new file mode 100644 index 0000000..64b0724 --- /dev/null +++ b/test/232/testdata/SimpleProject/solutions/Solution1/models/Solution1.model1.mps @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/233/build.gradle.kts b/test/233/build.gradle.kts new file mode 100644 index 0000000..b9d7817 --- /dev/null +++ b/test/233/build.gradle.kts @@ -0,0 +1,19 @@ +plugins { + alias(libs.plugins.intellij) + alias(libs.plugins.kotlin.jvm) +} + +intellij { + localPath = project(":impl233").layout.buildDirectory.dir("mps").map { it.asFile.absolutePath } + instrumentCode = false +} + +tasks { + buildSearchableOptions { + enabled = false + } +} + +dependencies { + testImplementation(project(":lib")) +} diff --git a/test/233/src/test/kotlin/TestBase.kt b/test/233/src/test/kotlin/TestBase.kt new file mode 100644 index 0000000..b784d0b --- /dev/null +++ b/test/233/src/test/kotlin/TestBase.kt @@ -0,0 +1,103 @@ +import com.intellij.ide.impl.OpenProjectTask +import com.intellij.openapi.Disposable +import com.intellij.openapi.application.ApplicationManager +import com.intellij.openapi.project.Project +import com.intellij.openapi.project.ProjectManager +import com.intellij.openapi.project.ex.ProjectManagerEx +import com.intellij.openapi.util.Disposer +import com.intellij.testFramework.TestApplicationManager +import com.intellij.testFramework.UsefulTestCase +import com.intellij.util.io.delete +import jetbrains.mps.ide.ThreadUtils +import jetbrains.mps.ide.project.ProjectHelper +import jetbrains.mps.project.MPSProject +import java.io.File +import java.nio.file.Files +import java.nio.file.Path + +/** + * Based on org.jetbrains.uast.test.env.AbstractLargeProjectTest + */ +@Suppress("removal") +abstract class TestBase(val testDataName: String?) : UsefulTestCase() { + init { + // workaround for MPS 2023.3 failing to start in test mode + System.setProperty("intellij.platform.load.app.info.from.resources", "true") + } + + protected lateinit var project: Project + + override fun runInDispatchThread() = false + + override fun setUp() { + super.setUp() + TestApplicationManager.getInstance() + project = openTestProject() + } + + override fun tearDown() { + super.tearDown() + } + + private fun openTestProject(): Project { + val projectDirParent = Path.of("build", "test-projects").toAbsolutePath() + projectDirParent.toFile().mkdirs() + val projectDir = Files.createTempDirectory(projectDirParent, "mps-project") + projectDir.delete(recursively = true) + projectDir.toFile().mkdirs() + projectDir.toFile().deleteOnExit() + val project = if (testDataName != null) { + val sourceDir = File("testdata/$testDataName") + sourceDir.copyRecursively(projectDir.toFile(), overwrite = true) + ProjectManagerEx.getInstanceEx().openProject(projectDir, OpenProjectTask())!! + } else { + ProjectManagerEx.getInstanceEx().newProject(projectDir, OpenProjectTask())!! + } + + disposeOnTearDownInEdt { runCatching { ProjectManager.getInstance().closeAndDispose(project) } } + + ApplicationManager.getApplication().invokeAndWait { + // empty - openTestProject executed not in EDT, so, invokeAndWait just forces + // processing of all events that were queued during project opening + } + + return project + } + + private fun disposeOnTearDownInEdt(runnable: Runnable) { + Disposer.register( + testRootDisposable, + Disposable { + ApplicationManager.getApplication().invokeAndWait(runnable) + }, + ) + } + + protected val mpsProject: MPSProject get() { + return checkNotNull(ProjectHelper.fromIdeaProject(project)) { "MPS project not loaded" } + } + + protected fun writeAction(body: () -> R): R { + return mpsProject.modelAccess.computeWriteAction(body) + } + + protected fun writeActionOnEdt(body: () -> R): R { + return onEdt { writeAction { body() } } + } + + protected fun onEdt(body: () -> R): R { + var result: R? = null + ThreadUtils.runInUIThreadAndWait { + result = body() + } + return result as R + } + + protected fun readAction(body: () -> R): R { + var result: R? = null + mpsProject.modelAccess.runReadAction { + result = body() + } + return result as R + } +} diff --git a/test/233/src/test/kotlin/VirtualFolderTests233.kt b/test/233/src/test/kotlin/VirtualFolderTests233.kt new file mode 100644 index 0000000..2d46a62 --- /dev/null +++ b/test/233/src/test/kotlin/VirtualFolderTests233.kt @@ -0,0 +1,10 @@ +import org.modelix.mps.api.ModelixMpsApi + +class VirtualFolderTests233 : TestBase("SimpleProject") { + + fun `test getVirtualFolder`() { + val module = ModelixMpsApi.getMPSProjects().single().projectModules.single() + val folder = ModelixMpsApi.getVirtualFolder(module) + assertEquals("myFolder", folder) + } +} diff --git a/test/233/testdata/SimpleProject/.mps/modules.xml b/test/233/testdata/SimpleProject/.mps/modules.xml new file mode 100644 index 0000000..6b0fa61 --- /dev/null +++ b/test/233/testdata/SimpleProject/.mps/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/test/233/testdata/SimpleProject/solutions/Solution1/Solution1.msd b/test/233/testdata/SimpleProject/solutions/Solution1/Solution1.msd new file mode 100644 index 0000000..f015948 --- /dev/null +++ b/test/233/testdata/SimpleProject/solutions/Solution1/Solution1.msd @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/233/testdata/SimpleProject/solutions/Solution1/models/Solution1.model1.mps b/test/233/testdata/SimpleProject/solutions/Solution1/models/Solution1.model1.mps new file mode 100644 index 0000000..64b0724 --- /dev/null +++ b/test/233/testdata/SimpleProject/solutions/Solution1/models/Solution1.model1.mps @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/241/build.gradle.kts b/test/241/build.gradle.kts new file mode 100644 index 0000000..3329d34 --- /dev/null +++ b/test/241/build.gradle.kts @@ -0,0 +1,19 @@ +plugins { + alias(libs.plugins.intellij) + alias(libs.plugins.kotlin.jvm) +} + +intellij { + localPath = project(":impl241").layout.buildDirectory.dir("mps").map { it.asFile.absolutePath } + instrumentCode = false +} + +tasks { + buildSearchableOptions { + enabled = false + } +} + +dependencies { + testImplementation(project(":lib")) +} diff --git a/test/241/src/test/kotlin/TestBase.kt b/test/241/src/test/kotlin/TestBase.kt new file mode 100644 index 0000000..b784d0b --- /dev/null +++ b/test/241/src/test/kotlin/TestBase.kt @@ -0,0 +1,103 @@ +import com.intellij.ide.impl.OpenProjectTask +import com.intellij.openapi.Disposable +import com.intellij.openapi.application.ApplicationManager +import com.intellij.openapi.project.Project +import com.intellij.openapi.project.ProjectManager +import com.intellij.openapi.project.ex.ProjectManagerEx +import com.intellij.openapi.util.Disposer +import com.intellij.testFramework.TestApplicationManager +import com.intellij.testFramework.UsefulTestCase +import com.intellij.util.io.delete +import jetbrains.mps.ide.ThreadUtils +import jetbrains.mps.ide.project.ProjectHelper +import jetbrains.mps.project.MPSProject +import java.io.File +import java.nio.file.Files +import java.nio.file.Path + +/** + * Based on org.jetbrains.uast.test.env.AbstractLargeProjectTest + */ +@Suppress("removal") +abstract class TestBase(val testDataName: String?) : UsefulTestCase() { + init { + // workaround for MPS 2023.3 failing to start in test mode + System.setProperty("intellij.platform.load.app.info.from.resources", "true") + } + + protected lateinit var project: Project + + override fun runInDispatchThread() = false + + override fun setUp() { + super.setUp() + TestApplicationManager.getInstance() + project = openTestProject() + } + + override fun tearDown() { + super.tearDown() + } + + private fun openTestProject(): Project { + val projectDirParent = Path.of("build", "test-projects").toAbsolutePath() + projectDirParent.toFile().mkdirs() + val projectDir = Files.createTempDirectory(projectDirParent, "mps-project") + projectDir.delete(recursively = true) + projectDir.toFile().mkdirs() + projectDir.toFile().deleteOnExit() + val project = if (testDataName != null) { + val sourceDir = File("testdata/$testDataName") + sourceDir.copyRecursively(projectDir.toFile(), overwrite = true) + ProjectManagerEx.getInstanceEx().openProject(projectDir, OpenProjectTask())!! + } else { + ProjectManagerEx.getInstanceEx().newProject(projectDir, OpenProjectTask())!! + } + + disposeOnTearDownInEdt { runCatching { ProjectManager.getInstance().closeAndDispose(project) } } + + ApplicationManager.getApplication().invokeAndWait { + // empty - openTestProject executed not in EDT, so, invokeAndWait just forces + // processing of all events that were queued during project opening + } + + return project + } + + private fun disposeOnTearDownInEdt(runnable: Runnable) { + Disposer.register( + testRootDisposable, + Disposable { + ApplicationManager.getApplication().invokeAndWait(runnable) + }, + ) + } + + protected val mpsProject: MPSProject get() { + return checkNotNull(ProjectHelper.fromIdeaProject(project)) { "MPS project not loaded" } + } + + protected fun writeAction(body: () -> R): R { + return mpsProject.modelAccess.computeWriteAction(body) + } + + protected fun writeActionOnEdt(body: () -> R): R { + return onEdt { writeAction { body() } } + } + + protected fun onEdt(body: () -> R): R { + var result: R? = null + ThreadUtils.runInUIThreadAndWait { + result = body() + } + return result as R + } + + protected fun readAction(body: () -> R): R { + var result: R? = null + mpsProject.modelAccess.runReadAction { + result = body() + } + return result as R + } +} diff --git a/test/241/src/test/kotlin/VirtualFolderTests241.kt b/test/241/src/test/kotlin/VirtualFolderTests241.kt new file mode 100644 index 0000000..8154d2a --- /dev/null +++ b/test/241/src/test/kotlin/VirtualFolderTests241.kt @@ -0,0 +1,10 @@ +import org.modelix.mps.api.ModelixMpsApi + +class VirtualFolderTests241 : TestBase("SimpleProject") { + + fun `test getVirtualFolder`() { + val module = ModelixMpsApi.getMPSProjects().single().projectModules.single() + val folder = ModelixMpsApi.getVirtualFolder(module) + assertEquals("myFolder", folder) + } +} diff --git a/test/241/testdata/SimpleProject/.mps/modules.xml b/test/241/testdata/SimpleProject/.mps/modules.xml new file mode 100644 index 0000000..6b0fa61 --- /dev/null +++ b/test/241/testdata/SimpleProject/.mps/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/test/241/testdata/SimpleProject/solutions/Solution1/Solution1.msd b/test/241/testdata/SimpleProject/solutions/Solution1/Solution1.msd new file mode 100644 index 0000000..f015948 --- /dev/null +++ b/test/241/testdata/SimpleProject/solutions/Solution1/Solution1.msd @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/241/testdata/SimpleProject/solutions/Solution1/models/Solution1.model1.mps b/test/241/testdata/SimpleProject/solutions/Solution1/models/Solution1.model1.mps new file mode 100644 index 0000000..64b0724 --- /dev/null +++ b/test/241/testdata/SimpleProject/solutions/Solution1/models/Solution1.model1.mps @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/243/build.gradle.kts b/test/243/build.gradle.kts new file mode 100644 index 0000000..65221a6 --- /dev/null +++ b/test/243/build.gradle.kts @@ -0,0 +1,31 @@ +import org.apache.tools.ant.taskdefs.condition.Os +import org.jetbrains.intellij.platform.gradle.TestFrameworkType + +plugins { + alias(libs.plugins.intellij2) + alias(libs.plugins.kotlin.jvm) +} + +repositories { + intellijPlatform { + defaultRepositories() + localPlatformArtifacts() + } +} + +intellijPlatform { +} + +dependencies { + intellijPlatform { + if (Os.isOs(Os.FAMILY_MAC, null, "aarch64", null)) { + local(System.getProperty("user.home") + "/Applications/MPS 2024.3.app/Contents") + } else { + local(project.project(":impl243").layout.buildDirectory.dir("mps").map { it.asFile.absolutePath }.get()) + } + // intellijIdeaCommunity("2024.3") + testFramework(TestFrameworkType.Platform) + } + testImplementation(project(":lib")) + testImplementation("junit:junit:4.13.2") +} diff --git a/test/243/src/test/kotlin/TestBase.kt b/test/243/src/test/kotlin/TestBase.kt new file mode 100644 index 0000000..b784d0b --- /dev/null +++ b/test/243/src/test/kotlin/TestBase.kt @@ -0,0 +1,103 @@ +import com.intellij.ide.impl.OpenProjectTask +import com.intellij.openapi.Disposable +import com.intellij.openapi.application.ApplicationManager +import com.intellij.openapi.project.Project +import com.intellij.openapi.project.ProjectManager +import com.intellij.openapi.project.ex.ProjectManagerEx +import com.intellij.openapi.util.Disposer +import com.intellij.testFramework.TestApplicationManager +import com.intellij.testFramework.UsefulTestCase +import com.intellij.util.io.delete +import jetbrains.mps.ide.ThreadUtils +import jetbrains.mps.ide.project.ProjectHelper +import jetbrains.mps.project.MPSProject +import java.io.File +import java.nio.file.Files +import java.nio.file.Path + +/** + * Based on org.jetbrains.uast.test.env.AbstractLargeProjectTest + */ +@Suppress("removal") +abstract class TestBase(val testDataName: String?) : UsefulTestCase() { + init { + // workaround for MPS 2023.3 failing to start in test mode + System.setProperty("intellij.platform.load.app.info.from.resources", "true") + } + + protected lateinit var project: Project + + override fun runInDispatchThread() = false + + override fun setUp() { + super.setUp() + TestApplicationManager.getInstance() + project = openTestProject() + } + + override fun tearDown() { + super.tearDown() + } + + private fun openTestProject(): Project { + val projectDirParent = Path.of("build", "test-projects").toAbsolutePath() + projectDirParent.toFile().mkdirs() + val projectDir = Files.createTempDirectory(projectDirParent, "mps-project") + projectDir.delete(recursively = true) + projectDir.toFile().mkdirs() + projectDir.toFile().deleteOnExit() + val project = if (testDataName != null) { + val sourceDir = File("testdata/$testDataName") + sourceDir.copyRecursively(projectDir.toFile(), overwrite = true) + ProjectManagerEx.getInstanceEx().openProject(projectDir, OpenProjectTask())!! + } else { + ProjectManagerEx.getInstanceEx().newProject(projectDir, OpenProjectTask())!! + } + + disposeOnTearDownInEdt { runCatching { ProjectManager.getInstance().closeAndDispose(project) } } + + ApplicationManager.getApplication().invokeAndWait { + // empty - openTestProject executed not in EDT, so, invokeAndWait just forces + // processing of all events that were queued during project opening + } + + return project + } + + private fun disposeOnTearDownInEdt(runnable: Runnable) { + Disposer.register( + testRootDisposable, + Disposable { + ApplicationManager.getApplication().invokeAndWait(runnable) + }, + ) + } + + protected val mpsProject: MPSProject get() { + return checkNotNull(ProjectHelper.fromIdeaProject(project)) { "MPS project not loaded" } + } + + protected fun writeAction(body: () -> R): R { + return mpsProject.modelAccess.computeWriteAction(body) + } + + protected fun writeActionOnEdt(body: () -> R): R { + return onEdt { writeAction { body() } } + } + + protected fun onEdt(body: () -> R): R { + var result: R? = null + ThreadUtils.runInUIThreadAndWait { + result = body() + } + return result as R + } + + protected fun readAction(body: () -> R): R { + var result: R? = null + mpsProject.modelAccess.runReadAction { + result = body() + } + return result as R + } +} diff --git a/test/243/src/test/kotlin/VirtualFolderTests243.kt b/test/243/src/test/kotlin/VirtualFolderTests243.kt new file mode 100644 index 0000000..c561848 --- /dev/null +++ b/test/243/src/test/kotlin/VirtualFolderTests243.kt @@ -0,0 +1,10 @@ +import org.modelix.mps.api.ModelixMpsApi + +class VirtualFolderTests243 : TestBase("SimpleProject") { + + fun `test getVirtualFolder`() { + val module = ModelixMpsApi.getMPSProjects().single().projectModules.single() + val folder = ModelixMpsApi.getVirtualFolder(module) + assertEquals("myFolder", folder) + } +} diff --git a/test/243/testdata/SimpleProject/.mps/modules.xml b/test/243/testdata/SimpleProject/.mps/modules.xml new file mode 100644 index 0000000..6b0fa61 --- /dev/null +++ b/test/243/testdata/SimpleProject/.mps/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/test/243/testdata/SimpleProject/solutions/Solution1/Solution1.msd b/test/243/testdata/SimpleProject/solutions/Solution1/Solution1.msd new file mode 100644 index 0000000..f015948 --- /dev/null +++ b/test/243/testdata/SimpleProject/solutions/Solution1/Solution1.msd @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/243/testdata/SimpleProject/solutions/Solution1/models/Solution1.model1.mps b/test/243/testdata/SimpleProject/solutions/Solution1/models/Solution1.model1.mps new file mode 100644 index 0000000..64b0724 --- /dev/null +++ b/test/243/testdata/SimpleProject/solutions/Solution1/models/Solution1.model1.mps @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +