[AA] Enable test-specific configuration of write access permissions
- In general, Analysis API tests forbid write access because the Analysis API should not be used from write actions. However, in some cases we might want tests to e.g. modify PSI, which requires write access. This change allows `AnalysisApiTestConfigurator`s to enable write access for the specific test.
This commit is contained in:
committed by
Space Team
parent
6189d68c3c
commit
03a7162f37
+61
-12
@@ -24,13 +24,31 @@ import org.jetbrains.kotlin.cli.jvm.compiler.IdeaExtensionPoints.registerVersion
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.jarfs.FastJarFileSystem
|
||||
import org.jetbrains.kotlin.cli.jvm.modules.CoreJrtFileSystem
|
||||
|
||||
sealed interface KotlinCoreApplicationEnvironmentMode {
|
||||
val isWriteAccessAllowed: Boolean
|
||||
|
||||
object Production : KotlinCoreApplicationEnvironmentMode {
|
||||
override val isWriteAccessAllowed: Boolean get() = true
|
||||
}
|
||||
|
||||
class UnitTest(override val isWriteAccessAllowed: Boolean) : KotlinCoreApplicationEnvironmentMode
|
||||
|
||||
companion object {
|
||||
fun fromUnitTestModeFlag(isUnitTestMode: Boolean): KotlinCoreApplicationEnvironmentMode =
|
||||
if (isUnitTestMode) UnitTest(isWriteAccessAllowed = false) else Production
|
||||
}
|
||||
}
|
||||
|
||||
class KotlinCoreApplicationEnvironment private constructor(
|
||||
parentDisposable: Disposable, unitTestMode: Boolean
|
||||
) : JavaCoreApplicationEnvironment(parentDisposable, unitTestMode) {
|
||||
parentDisposable: Disposable,
|
||||
private val environmentMode: KotlinCoreApplicationEnvironmentMode,
|
||||
) : JavaCoreApplicationEnvironment(parentDisposable, environmentMode is KotlinCoreApplicationEnvironmentMode.UnitTest) {
|
||||
|
||||
init {
|
||||
application.initializeEnvironmentMode(environmentMode)
|
||||
|
||||
registerApplicationService(JavaFileCodeStyleFacadeFactory::class.java, DummyJavaFileCodeStyleFacadeFactory())
|
||||
registerFileType(JavaClassFileType.INSTANCE, "sig");
|
||||
registerFileType(JavaClassFileType.INSTANCE, "sig")
|
||||
}
|
||||
|
||||
override fun createJrtFileSystem(): VirtualFileSystem {
|
||||
@@ -41,15 +59,11 @@ class KotlinCoreApplicationEnvironment private constructor(
|
||||
val mock = super.createApplication(parentDisposable)
|
||||
|
||||
/**
|
||||
* We can't use just [unitTestMode] from constructor, because at this moment
|
||||
* the corresponding property is not yet initialized, so [unitTestMode] is effectively always false,
|
||||
* because this function called from super class constructor
|
||||
* We can't use [environmentMode] from the constructor to decide whether we're in unit test mode, because the corresponding property
|
||||
* is not yet initialized when this function is called from the superclass constructor.
|
||||
*/
|
||||
return if (mock.isUnitTestMode) {
|
||||
object : MockApplication(parentDisposable) {
|
||||
override fun isUnitTestMode(): Boolean = true
|
||||
override fun isWriteAccessAllowed(): Boolean = false
|
||||
}
|
||||
MockUnitTestApplication(parentDisposable)
|
||||
} else {
|
||||
mock
|
||||
}
|
||||
@@ -80,10 +94,22 @@ class KotlinCoreApplicationEnvironment private constructor(
|
||||
}
|
||||
|
||||
companion object {
|
||||
@Deprecated(
|
||||
message = "The `unitTestMode` flag is deprecated in favor of `KotlinCoreApplicationEnvironmentMode` configuration.",
|
||||
replaceWith = ReplaceWith("create(parentDisposable, KotlinCoreApplicationEnvironmentMode.fromUnitTestModeFlag(unitTestMode))"),
|
||||
)
|
||||
fun create(
|
||||
parentDisposable: Disposable, unitTestMode: Boolean
|
||||
parentDisposable: Disposable,
|
||||
unitTestMode: Boolean,
|
||||
): KotlinCoreApplicationEnvironment {
|
||||
val environment = KotlinCoreApplicationEnvironment(parentDisposable, unitTestMode)
|
||||
return create(parentDisposable, KotlinCoreApplicationEnvironmentMode.fromUnitTestModeFlag(unitTestMode))
|
||||
}
|
||||
|
||||
fun create(
|
||||
parentDisposable: Disposable,
|
||||
environmentMode: KotlinCoreApplicationEnvironmentMode,
|
||||
): KotlinCoreApplicationEnvironment {
|
||||
val environment = KotlinCoreApplicationEnvironment(parentDisposable, environmentMode)
|
||||
registerExtensionPoints()
|
||||
return environment
|
||||
}
|
||||
@@ -102,3 +128,26 @@ class KotlinCoreApplicationEnvironment private constructor(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class MockUnitTestApplication(parentDisposable: Disposable) : MockApplication(parentDisposable) {
|
||||
/**
|
||||
* We can't use [KotlinCoreApplicationEnvironment.environmentMode] in [KotlinCoreApplicationEnvironment.createApplication], because the
|
||||
* corresponding property is not yet initialized when `createApplication` is called from the superclass constructor. So we have to
|
||||
* initialize it later.
|
||||
*/
|
||||
lateinit var environmentMode: KotlinCoreApplicationEnvironmentMode
|
||||
|
||||
override fun isUnitTestMode(): Boolean = true
|
||||
|
||||
override fun isWriteAccessAllowed(): Boolean = environmentMode.isWriteAccessAllowed
|
||||
}
|
||||
|
||||
private fun MockApplication.initializeEnvironmentMode(environmentMode: KotlinCoreApplicationEnvironmentMode) {
|
||||
if (this !is MockUnitTestApplication) return
|
||||
|
||||
this.environmentMode = environmentMode
|
||||
|
||||
require(isWriteAccessAllowed == environmentMode.isWriteAccessAllowed) {
|
||||
"The mock application's `isWriteAccessAllowed` should correspond to the environment mode configuration."
|
||||
}
|
||||
}
|
||||
|
||||
+25
-12
@@ -469,7 +469,9 @@ class KotlinCoreEnvironment private constructor(
|
||||
// Tests are supposed to create a single project and dispose it right after use
|
||||
val appEnv =
|
||||
createApplicationEnvironment(
|
||||
parentDisposable, configuration, unitTestMode = true
|
||||
parentDisposable,
|
||||
configuration,
|
||||
KotlinCoreApplicationEnvironmentMode.UnitTest(isWriteAccessAllowed = false),
|
||||
)
|
||||
val projectEnv = ProjectEnvironment(parentDisposable, appEnv, configuration)
|
||||
return KotlinCoreEnvironment(projectEnv, configuration, extensionConfigs)
|
||||
@@ -499,7 +501,7 @@ class KotlinCoreEnvironment private constructor(
|
||||
val appEnv = createApplicationEnvironment(
|
||||
parentDisposable,
|
||||
configuration,
|
||||
unitTestMode = true
|
||||
KotlinCoreApplicationEnvironmentMode.UnitTest(isWriteAccessAllowed = false),
|
||||
)
|
||||
return ProjectEnvironment(parentDisposable, appEnv, configuration)
|
||||
}
|
||||
@@ -509,14 +511,25 @@ class KotlinCoreEnvironment private constructor(
|
||||
|
||||
fun getOrCreateApplicationEnvironmentForProduction(
|
||||
parentDisposable: Disposable, configuration: CompilerConfiguration
|
||||
): KotlinCoreApplicationEnvironment = getOrCreateApplicationEnvironment(parentDisposable, configuration, unitTestMode = false)
|
||||
): KotlinCoreApplicationEnvironment = getOrCreateApplicationEnvironment(
|
||||
parentDisposable,
|
||||
configuration,
|
||||
KotlinCoreApplicationEnvironmentMode.Production,
|
||||
)
|
||||
|
||||
fun getOrCreateApplicationEnvironmentForTests(
|
||||
parentDisposable: Disposable, configuration: CompilerConfiguration
|
||||
): KotlinCoreApplicationEnvironment = getOrCreateApplicationEnvironment(parentDisposable, configuration, unitTestMode = true)
|
||||
parentDisposable: Disposable,
|
||||
configuration: CompilerConfiguration,
|
||||
): KotlinCoreApplicationEnvironment = getOrCreateApplicationEnvironment(
|
||||
parentDisposable,
|
||||
configuration,
|
||||
KotlinCoreApplicationEnvironmentMode.UnitTest(isWriteAccessAllowed = false),
|
||||
)
|
||||
|
||||
private fun getOrCreateApplicationEnvironment(
|
||||
parentDisposable: Disposable, configuration: CompilerConfiguration, unitTestMode: Boolean
|
||||
fun getOrCreateApplicationEnvironment(
|
||||
parentDisposable: Disposable,
|
||||
configuration: CompilerConfiguration,
|
||||
environmentMode: KotlinCoreApplicationEnvironmentMode,
|
||||
): KotlinCoreApplicationEnvironment {
|
||||
synchronized(APPLICATION_LOCK) {
|
||||
if (ourApplicationEnvironment == null) {
|
||||
@@ -525,7 +538,7 @@ class KotlinCoreEnvironment private constructor(
|
||||
createApplicationEnvironment(
|
||||
disposable,
|
||||
configuration,
|
||||
unitTestMode
|
||||
environmentMode,
|
||||
)
|
||||
ourProjectCount = 0
|
||||
Disposer.register(disposable, Disposable {
|
||||
@@ -606,11 +619,11 @@ class KotlinCoreEnvironment private constructor(
|
||||
}
|
||||
|
||||
private fun createApplicationEnvironment(
|
||||
parentDisposable: Disposable, configuration: CompilerConfiguration, unitTestMode: Boolean
|
||||
parentDisposable: Disposable,
|
||||
configuration: CompilerConfiguration,
|
||||
environmentMode: KotlinCoreApplicationEnvironmentMode,
|
||||
): KotlinCoreApplicationEnvironment {
|
||||
val applicationEnvironment = KotlinCoreApplicationEnvironment.create(
|
||||
parentDisposable, unitTestMode
|
||||
)
|
||||
val applicationEnvironment = KotlinCoreApplicationEnvironment.create(parentDisposable, environmentMode)
|
||||
|
||||
registerApplicationExtensionPointsAndExtensionsFrom(configuration, "extensions/compiler.xml")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user