[LL] CleanableSoftValueCache: Add non-concurrent tests for value cleanup
- The non-concurrent `CleanableSoftValueCacheTest` ensures that deterministic cleanup behaves correctly. A Lincheck test can only discover differences between the single-threaded and concurrent executions of a test scenario, so it cannot find correctness issues with deterministic cleanup on its own. ^KT-61222
This commit is contained in:
committed by
Space Team
parent
53e545aa3f
commit
5207940f0b
+27
@@ -5,8 +5,10 @@
|
||||
|
||||
package org.jetbrains.kotlin.analysis.test.framework.utils
|
||||
|
||||
import com.intellij.mock.MockApplication
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.util.Computable
|
||||
import com.intellij.openapi.util.Disposer
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiReference
|
||||
import com.intellij.psi.impl.source.resolve.reference.impl.PsiMultiReference
|
||||
@@ -16,6 +18,7 @@ import org.jetbrains.kotlin.idea.references.KtReference
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.test.directives.model.Directive
|
||||
import org.jetbrains.kotlin.test.directives.model.RegisteredDirectives
|
||||
import org.jetbrains.kotlin.test.testFramework.resetApplicationToNull
|
||||
|
||||
inline fun <T> runReadAction(crossinline runnable: () -> T): T {
|
||||
return ApplicationManager.getApplication().runReadAction(Computable { runnable() })
|
||||
@@ -24,6 +27,30 @@ inline fun <T> runReadAction(crossinline runnable: () -> T): T {
|
||||
fun <R> executeOnPooledThreadInReadAction(action: () -> R): R =
|
||||
ApplicationManager.getApplication().executeOnPooledThread<R> { runReadAction(action) }.get()
|
||||
|
||||
/**
|
||||
* Executes [action] with a dummy application available via [ApplicationManager.getApplication]. This function should **only** be used if
|
||||
* an application is needed to avoid null pointer exceptions from [ApplicationManager.getApplication] when used in simple situations. Do not
|
||||
* use this function if you need a properly set up application and project.
|
||||
*/
|
||||
fun <R> withDummyApplication(action: () -> R): R {
|
||||
val previousApplication = ApplicationManager.getApplication()
|
||||
val disposable = Disposer.newDisposable("Application disposable for dummy application from Analysis API test framework")
|
||||
try {
|
||||
MockApplication.setUp(disposable)
|
||||
return action()
|
||||
} finally {
|
||||
Disposer.dispose(disposable)
|
||||
|
||||
// If there is a previous application, disposal of `disposable` will reset the application manager to that application, so we won't
|
||||
// need to nor should we reset its application to `null`. This is handled by the application argument in `resetApplicationToNull`.
|
||||
resetApplicationToNull(previousApplication)
|
||||
|
||||
require(ApplicationManager.getApplication() === previousApplication) {
|
||||
"The managed application should have been reset to the previous application or `null`."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun PsiElement?.position(): String {
|
||||
if (this == null) return "(unknown)"
|
||||
return offsetToLineAndColumn(containingFile.viewProvider.document, textRange.startOffset).toString()
|
||||
|
||||
Reference in New Issue
Block a user