simplify — get rid of ComponentManager.saveStore test-only extension method

This commit is contained in:
Vladimir Krivosheev
2019-01-11 17:09:00 +01:00
parent f2e17f1c69
commit 76995cb5a2
8 changed files with 100 additions and 90 deletions
@@ -57,7 +57,7 @@ class ProjectInspectionManagerTest {
val inspectionDir = Paths.get(project.stateStore.projectConfigDir, "inspectionProfiles")
val file = inspectionDir.resolve("profiles_settings.xml")
project.saveStore()
project.stateStore.save()
assertThat(file).exists()
val doNotUseProjectProfileData = """
<component name="InspectionProjectProfileManager">
@@ -97,7 +97,7 @@ class ProjectInspectionManagerTest {
assertThat(projectInspectionProfileManager.state).isEmpty()
project.saveStore()
project.stateStore.save()
assertThat(profileFile).doesNotExist()
}
@@ -118,7 +118,7 @@ class ProjectInspectionManagerTest {
assertThat(currentProfile.isProjectLevel).isTrue()
currentProfile.setToolEnabled("Convert2Diamond", false)
project.saveStore()
project.stateStore.save()
val inspectionDir = Paths.get(project.stateStore.projectConfigDir, "inspectionProfiles")
val file = inspectionDir.resolve("profiles_settings.xml")
@@ -2,6 +2,7 @@
package com.intellij.roots
import com.intellij.openapi.application.runWriteAction
import com.intellij.openapi.components.stateStore
import com.intellij.openapi.module.Module
import com.intellij.openapi.module.ModuleManager
import com.intellij.openapi.module.StdModuleTypes
@@ -14,7 +15,7 @@ import com.intellij.openapi.roots.ModuleRootModificationUtil
import com.intellij.openapi.util.Disposer
import com.intellij.openapi.util.io.FileUtil
import com.intellij.testFramework.ModuleTestCase
import com.intellij.testFramework.saveStore
import kotlinx.coroutines.runBlocking
import java.io.File
import java.util.*
@@ -22,7 +23,7 @@ import java.util.*
* @author nik
*/
class AutomaticModuleUnloaderTest : ModuleTestCase() {
fun `test unload simple module`() {
fun `test unload simple module`() = runBlocking {
createModule("a")
createModule("b")
val moduleManager = ModuleManager.getInstance(project)
@@ -35,7 +36,7 @@ class AutomaticModuleUnloaderTest : ModuleTestCase() {
ModuleTestCase.assertSameElements(moduleManager.unloadedModuleDescriptions.map { it.name }, "a", "d")
}
fun `test unload modules with dependencies between them`() {
fun `test unload modules with dependencies between them`() = runBlocking {
createModule("a")
createModule("b")
doTest("a", listOf("c", "d"), { modules ->
@@ -45,7 +46,7 @@ class AutomaticModuleUnloaderTest : ModuleTestCase() {
},"a", "c", "d")
}
fun `test do not unload module if loaded module depends on it`() {
fun `test do not unload module if loaded module depends on it`() = runBlocking {
createModule("a")
val b = createModule("b")
ModuleRootModificationUtil.updateModel(b) {
@@ -54,7 +55,7 @@ class AutomaticModuleUnloaderTest : ModuleTestCase() {
doTest("a", listOf("d"), {}, "a")
}
fun `test unload module if only unloaded module depends on it`() {
fun `test unload module if only unloaded module depends on it`() = runBlocking {
val a = createModule("a")
createModule("b")
ModuleRootModificationUtil.updateModel(a) {
@@ -63,7 +64,7 @@ class AutomaticModuleUnloaderTest : ModuleTestCase() {
doTest("a", listOf("d"), {}, "a", "d")
}
fun `test do not unload modules if loaded module depends on them transitively`() {
fun `test do not unload modules if loaded module depends on them transitively`() = runBlocking {
createModule("a")
val b = createModule("b")
ModuleRootModificationUtil.updateModel(b) {
@@ -77,7 +78,7 @@ class AutomaticModuleUnloaderTest : ModuleTestCase() {
}, "a")
}
fun `test unload module if loaded module transitively depends on it via previously unloaded module`() {
fun `test unload module if loaded module transitively depends on it via previously unloaded module`() = runBlocking {
val a = createModule("a")
val b = createModule("b")
ModuleRootModificationUtil.addDependency(a, b)
@@ -87,7 +88,7 @@ class AutomaticModuleUnloaderTest : ModuleTestCase() {
doTest("b", listOf("c"), {}, "b", "c")
}
private fun doTest(initiallyUnloaded: String,
private suspend fun doTest(initiallyUnloaded: String,
newModulesName: List<String>,
setup: (Map<String, Module>) -> Unit,
vararg expectedUnloadedModules: String) {
@@ -101,7 +102,7 @@ class AutomaticModuleUnloaderTest : ModuleTestCase() {
}
private fun createNewModuleFiles(moduleNames: List<String>, setup: (Map<String, Module>) -> Unit): List<File> {
private suspend fun createNewModuleFiles(moduleNames: List<String>, setup: (Map<String, Module>) -> Unit): List<File> {
val newModulesProjectDir = FileUtil.createTempDirectory("newModules", "")
val moduleFiles = moduleNames.map { File(newModulesProjectDir, "$it.iml") }
val projectManager = ProjectManagerEx.getInstanceEx() as ProjectManagerImpl
@@ -114,7 +115,7 @@ class AutomaticModuleUnloaderTest : ModuleTestCase() {
}
setup(ModuleManager.getInstance(project).modules.associateBy { it.name })
modules.forEach {
it.saveStore()
it.stateStore.save()
}
}
finally {
@@ -124,10 +125,10 @@ class AutomaticModuleUnloaderTest : ModuleTestCase() {
return moduleFiles
}
private fun reloadProjectWithNewModules(moduleFiles: List<File>) {
private suspend fun reloadProjectWithNewModules(moduleFiles: List<File>) {
val moduleManager = ModuleManagerImpl.getInstanceImpl(myProject)
val modulePaths = LinkedHashSet<ModulePath>()
moduleManager.modules.forEach { it.saveStore() }
moduleManager.modules.forEach { it.stateStore.save() }
moduleManager.modules.mapTo(modulePaths) { ModulePath(it.moduleFilePath, null) }
moduleManager.unloadedModuleDescriptions.mapTo(modulePaths) { (it as UnloadedModuleDescriptionImpl).modulePath }
moduleFiles.mapTo(modulePaths) { ModulePath(FileUtil.toSystemIndependentName(it.absolutePath), null) }
@@ -55,7 +55,9 @@ internal class DefaultProjectStoreTest {
private val requiredPlugins = listOf<ProjectExternalDependency>(DependencyOnPlugin("fake", "0", "1"))
private val ruleChain = RuleChain(
@JvmField
@Rule
val ruleChain = RuleChain(
tempDirManager,
WrapRule {
val app = ApplicationManagerEx.getApplicationEx()
@@ -78,8 +80,6 @@ internal class DefaultProjectStoreTest {
}
)
@Rule fun getChain() = ruleChain
@Test
fun `new project from default - file-based storage`() = runBlocking {
val externalDependenciesManager = ProjectManager.getInstance().defaultProject.service<ExternalDependenciesManager>()
@@ -115,9 +115,7 @@ internal class DefaultProjectStoreTest {
finally {
// clear state
defaultTestComponent.loadState(Element("empty"))
runInEdtAndWait {
defaultProject.saveStore()
}
defaultProject.stateStore.save()
stateStore.removeComponent(TEST_COMPONENT_NAME)
}
}
@@ -1,8 +1,12 @@
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.configurationStore
import com.intellij.ProjectTopics
import com.intellij.ide.highlighter.ModuleFileType
import com.intellij.openapi.application.AppUIExecutor
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.application.async.coroutineDispatchingContext
import com.intellij.openapi.application.async.inWriteAction
import com.intellij.openapi.application.runWriteAction
import com.intellij.openapi.components.StoragePathMacros
import com.intellij.openapi.components.stateStore
@@ -20,6 +24,8 @@ import com.intellij.util.Function
import com.intellij.util.SmartList
import com.intellij.util.io.readText
import com.intellij.util.io.systemIndependentPath
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.withContext
import org.junit.ClassRule
import org.junit.Rule
import org.junit.Test
@@ -84,7 +90,8 @@ internal class ModuleStoreRenameTest {
)
// project structure
@Test fun `rename module using model`() {
@Test
fun `rename module using model`() = runBlocking<Unit> {
saveModules()
val storage = module.storage
@@ -99,11 +106,12 @@ internal class ModuleStoreRenameTest {
}
// project view
@Test fun `rename module using rename virtual file`() {
@Test
fun `rename module using rename virtual file`() = runBlocking {
testRenameModule()
}
private fun testRenameModule() {
private suspend fun testRenameModule() {
saveModules()
val storage = module.storage
val oldFile = storage.file
@@ -111,14 +119,16 @@ internal class ModuleStoreRenameTest {
val oldName = module.name
val newName = "foo.dot"
runInEdtAndWait { runWriteAction { LocalFileSystem.getInstance().refreshAndFindFileByPath(oldFile.systemIndependentPath)!!.rename(null, "$newName${ModuleFileType.DOT_DEFAULT_EXTENSION}") } }
withContext(AppUIExecutor.onUiThread().inWriteAction().coroutineDispatchingContext()) {
LocalFileSystem.getInstance().refreshAndFindFileByPath(oldFile.systemIndependentPath)!!.rename(null, "$newName${ModuleFileType.DOT_DEFAULT_EXTENSION}")
}
assertRename(newName, oldFile)
assertThat(oldModuleNames).containsOnly(oldName)
}
// we cannot test external rename yet, because it is not supported - ModuleImpl doesn't support delete and create events (in case of external change we don't get move event, but get "delete old" and "create new")
private fun assertRename(newName: String, oldFile: Path) {
private suspend fun assertRename(newName: String, oldFile: Path) {
val newFile = module.storage.file
assertThat(newFile.fileName.toString()).isEqualTo("$newName${ModuleFileType.DOT_DEFAULT_EXTENSION}")
assertThat(oldFile)
@@ -129,13 +139,12 @@ internal class ModuleStoreRenameTest {
// ensure that macro value updated
assertThat(module.stateStore.storageManager.expandMacros(StoragePathMacros.MODULE_FILE)).isEqualTo(newFile.systemIndependentPath)
runInEdtAndWait {
dependentModule.saveStore()
}
dependentModule.stateStore.save()
assertThat(dependentModule.storage.file.readText()).contains("""<orderEntry type="module" module-name="$newName" />""")
}
@Test fun `rename module parent virtual dir`() {
@Test
fun `rename module parent virtual dir`() = runBlocking {
saveModules()
val storage = module.storage
val oldFile = storage.file
@@ -151,19 +160,21 @@ internal class ModuleStoreRenameTest {
testRenameModule()
}
finally {
runInEdtAndWait { runWriteAction { parentVirtualDir.delete(this) } }
withContext(AppUIExecutor.onUiThread().inWriteAction().coroutineDispatchingContext()) {
parentVirtualDir.delete(this)
}
}
}
@Test
@RunsInEdt
fun `rename module source root`() {
fun `rename module source root`() = runBlocking<Unit> {
saveModules()
val storage = module.storage
val parentVirtualDir = storage.virtualFile!!.parent
val src = VfsTestUtil.createDir(parentVirtualDir, "foo")
runWriteAction { PsiTestUtil.addSourceContentToRoots(module, src, false) }
module.saveStore()
module.stateStore.save()
val rootManager = module.rootManager as ModuleRootManagerComponent
val stateModificationCount = rootManager.stateModificationCount
@@ -173,10 +184,8 @@ internal class ModuleStoreRenameTest {
assertThat(stateModificationCount).isLessThan(rootManager.stateModificationCount)
}
private fun saveModules() {
runInEdtAndWait {
module.saveStore()
dependentModule.saveStore()
}
private suspend fun saveModules() {
module.stateStore.save()
dependentModule.stateStore.save()
}
}
@@ -1,4 +1,4 @@
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.configurationStore
import com.intellij.openapi.application.runWriteAction
@@ -20,6 +20,7 @@ import com.intellij.util.io.parentSystemIndependentPath
import com.intellij.util.io.readText
import com.intellij.util.io.systemIndependentPath
import gnu.trove.TObjectIntHashMap
import kotlinx.coroutines.runBlocking
import org.junit.ClassRule
import org.junit.Rule
import org.junit.Test
@@ -44,7 +45,8 @@ class ModuleStoreTest {
@Rule
val ruleChain = RuleChain(tempDirManager, EdtRule(), ActiveStoreRule(projectRule), DisposeModulesRule(projectRule))
@Test fun `set option`() {
@Test
fun `set option`() = runBlocking {
val moduleFile = runWriteAction {
VfsTestUtil.createFile(tempDirManager.newVirtualDirectory("module"), "test.iml", """
<?xml version="1.0" encoding="UTF-8"?>
@@ -55,7 +57,7 @@ class ModuleStoreTest {
assertThat(getOptionValue("foo")).isEqualTo("bar")
setOption("foo", "not bar")
saveStore()
stateStore.save()
}
projectRule.loadModule(moduleFile).useAndDispose {
@@ -63,7 +65,7 @@ class ModuleStoreTest {
setOption("foo", "not bar")
// ensure that save the same data will not lead to any problems (like "Content equals, but it must be handled not on this level")
saveStore()
stateStore.save()
}
}
@@ -77,30 +79,32 @@ class ModuleStoreTest {
}
}
@Test fun `must be empty if classpath storage`() {
@Test
fun `must be empty if classpath storage`() = runBlocking<Unit> {
// we must not use VFS here, file must not be created
val moduleFile = tempDirManager.newPath("module", refreshVfs = true).resolve("test.iml")
projectRule.createModule(moduleFile).useAndDispose {
ModuleRootModificationUtil.addContentRoot(this, moduleFile.parentSystemIndependentPath)
saveStore()
stateStore.save()
assertThat(moduleFile).isRegularFile
assertThat(moduleFile.readText()).startsWith("""
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">""".trimIndent())
ClasspathStorage.setStorageType(ModuleRootManager.getInstance(this), "eclipse")
saveStore()
stateStore.save()
assertThat(moduleFile).isEqualTo("""
<?xml version="1.0" encoding="UTF-8"?>
<module classpath="eclipse" classpath-dir="$ESCAPED_MODULE_DIR" type="JAVA_MODULE" version="4" />""")
}
}
@Test fun `one batch update session if several modules changed`() {
@Test
fun `one batch update session if several modules changed`() = runBlocking<Unit> {
val nameToCount = TObjectIntHashMap<String>()
val root = tempDirManager.newPath(refreshVfs = true)
fun Module.addContentRoot() {
suspend fun Module.addContentRoot() {
val moduleName = name
var batchUpdateCount = 0
nameToCount.put(moduleName, batchUpdateCount)
@@ -114,7 +118,7 @@ class ModuleStoreTest {
//
ModuleRootModificationUtil.addContentRoot(this, root.resolve(moduleName).systemIndependentPath)
assertThat(contentRootUrls).hasSize(1)
saveStore()
stateStore.save()
}
fun removeContentRoot(module: Module) {
@@ -78,11 +78,11 @@ internal class ProjectStoreTest {
assertThat(testComponent.state).isEqualTo(TestState("newValue"))
testComponent.state!!.value = "s".repeat(FileUtilRt.LARGE_FOR_CONTENT_LOADING + 1024)
project.saveStore()
project.stateStore.save()
// we should save twice (first call - virtual file size is not yet set)
testComponent.state!!.value = "b".repeat(FileUtilRt.LARGE_FOR_CONTENT_LOADING + 1024)
project.saveStore()
project.stateStore.save()
}
}
@@ -110,7 +110,7 @@ internal class ProjectStoreTest {
val newName = "Foo"
val oldName = project.name
(project as ProjectImpl).setProjectName(newName)
project.saveStore()
project.stateStore.save()
assertThat(store.nameFile).hasContent(newName)
project.setProjectName("clear-read-only")
@@ -119,7 +119,7 @@ internal class ProjectStoreTest {
val handler = ReadonlyStatusHandler.getInstance(project) as ReadonlyStatusHandlerImpl
try {
handler.setClearReadOnlyInTests(true)
project.saveStore()
project.stateStore.save()
}
finally {
handler.setClearReadOnlyInTests(false)
@@ -127,7 +127,7 @@ internal class ProjectStoreTest {
assertThat(store.nameFile).hasContent("clear-read-only")
project.setProjectName(oldName)
project.saveStore()
project.stateStore.save()
assertThat(store.nameFile).doesNotExist()
}
}
@@ -143,30 +143,30 @@ internal class ProjectStoreTest {
val store = project.stateStore
assertThat(store.nameFile).hasContent(name)
project.saveStore()
project.stateStore.save()
assertThat(store.nameFile).hasContent(name)
(project as ProjectImpl).setProjectName(name)
project.saveStore()
project.stateStore.save()
assertThat(store.nameFile).hasContent(name)
project.setProjectName("foo")
project.saveStore()
project.stateStore.save()
assertThat(store.nameFile).hasContent("foo")
project.setProjectName(name)
project.saveStore()
project.stateStore.save()
assertThat(store.nameFile).doesNotExist()
}
}
private fun test(project: Project): TestComponent {
private suspend fun test(project: Project): TestComponent {
val testComponent = TestComponent()
project.stateStore.initComponent(testComponent, true)
assertThat(testComponent.state).isEqualTo(TestState("customValue"))
testComponent.state!!.value = "foo"
project.saveStore()
project.stateStore.save()
val file = Paths.get(project.stateStore.storageManager.expandMacros(PROJECT_FILE))
assertThat(file).isRegularFile()
@@ -3,7 +3,10 @@ package com.intellij.openapi.externalSystem.configurationStore
import com.intellij.configurationStore.ESCAPED_MODULE_DIR
import com.intellij.configurationStore.useAndDispose
import com.intellij.openapi.application.runWriteAction
import com.intellij.openapi.application.AppUIExecutor
import com.intellij.openapi.application.async.coroutineDispatchingContext
import com.intellij.openapi.application.async.inWriteAction
import com.intellij.openapi.components.stateStore
import com.intellij.openapi.externalSystem.ExternalSystemModulePropertyManager
import com.intellij.openapi.externalSystem.service.project.manage.ExternalProjectsDataStorage
import com.intellij.openapi.externalSystem.service.project.manage.ExternalProjectsManagerImpl
@@ -13,18 +16,21 @@ import com.intellij.openapi.roots.ModuleRootManager
import com.intellij.openapi.roots.ModuleRootModificationUtil
import com.intellij.openapi.roots.impl.ModuleRootManagerImpl
import com.intellij.project.stateStore
import com.intellij.testFramework.*
import com.intellij.testFramework.ProjectRule
import com.intellij.testFramework.RunsInActiveStoreMode
import com.intellij.testFramework.TemporaryDirectory
import com.intellij.testFramework.assertions.Assertions.assertThat
import com.intellij.testFramework.createProjectAndUseInLoadComponentStateMode
import com.intellij.util.io.delete
import com.intellij.util.io.parentSystemIndependentPath
import com.intellij.util.io.systemIndependentPath
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.withContext
import org.junit.ClassRule
import org.junit.Rule
import org.junit.Test
import java.nio.file.Paths
@RunsInEdt
@RunsInActiveStoreMode
class ExternalSystemStorageTest {
companion object {
@@ -33,12 +39,9 @@ class ExternalSystemStorageTest {
val projectRule = ProjectRule()
}
private val tempDirManager = TemporaryDirectory()
@Suppress("unused")
@JvmField
@Rule
val ruleChain = RuleChain(tempDirManager, EdtRule())
val tempDirManager = TemporaryDirectory()
@Test
fun `must be empty if external system storage`() = runBlocking {
@@ -52,14 +55,17 @@ class ExternalSystemStorageTest {
// we must not use VFS here, file must not be created
val moduleFile = dotIdeaDir.parent.resolve("test.iml")
runWriteAction { ModuleManager.getInstance(project).newModule(moduleFile.systemIndependentPath, ModuleTypeId.JAVA_MODULE) }.useAndDispose {
assertThat(cacheDir).doesNotExist()
withContext(AppUIExecutor.onUiThread().inWriteAction().coroutineDispatchingContext()) {
ModuleManager.getInstance(project).newModule(moduleFile.systemIndependentPath, ModuleTypeId.JAVA_MODULE)
}
.useAndDispose {
assertThat(cacheDir).doesNotExist()
ModuleRootModificationUtil.addContentRoot(this, moduleFile.parentSystemIndependentPath)
ModuleRootModificationUtil.addContentRoot(this, moduleFile.parentSystemIndependentPath)
saveStore()
assertThat(cacheDir).doesNotExist()
assertThat(moduleFile).isEqualTo("""
stateStore.save()
assertThat(cacheDir).doesNotExist()
assertThat(moduleFile).isEqualTo("""
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
@@ -69,18 +75,18 @@ class ExternalSystemStorageTest {
</component>
</module>""")
ExternalSystemModulePropertyManager.getInstance(this).setMavenized(true)
// force re-save: this call not in the setMavenized because ExternalSystemModulePropertyManager in the API (since in production we have the only usage, it is ok for now)
(ModuleRootManager.getInstance(this) as ModuleRootManagerImpl).stateChanged()
ExternalSystemModulePropertyManager.getInstance(this).setMavenized(true)
// force re-save: this call not in the setMavenized because ExternalSystemModulePropertyManager in the API (since in production we have the only usage, it is ok for now)
(ModuleRootManager.getInstance(this) as ModuleRootManagerImpl).stateChanged()
assertThat(cacheDir).doesNotExist()
saveStore()
assertThat(cacheDir).isDirectory
assertThat(moduleFile).isEqualTo("""
assertThat(cacheDir).doesNotExist()
stateStore.save()
assertThat(cacheDir).isDirectory
assertThat(moduleFile).isEqualTo("""
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4" />""")
assertThat(cacheDir.resolve("test.xml")).isEqualTo("""
assertThat(cacheDir.resolve("test.xml")).isEqualTo("""
<module>
<component name="ExternalSystem" externalSystem="Maven" />
<component name="NewModuleRootManager" inherit-compiler-output="true">
@@ -90,8 +96,8 @@ class ExternalSystemStorageTest {
</component>
</module>""")
assertThat(dotIdeaDir.resolve("modules.xml")).doesNotExist()
}
assertThat(dotIdeaDir.resolve("modules.xml")).doesNotExist()
}
}
}
}
@@ -10,9 +10,7 @@ import com.intellij.openapi.application.async.coroutineDispatchingContext
import com.intellij.openapi.application.runUndoTransparentWriteAction
import com.intellij.openapi.command.impl.UndoManagerImpl
import com.intellij.openapi.command.undo.DocumentReferenceManager
import com.intellij.openapi.components.ComponentManager
import com.intellij.openapi.components.impl.stores.IProjectStore
import com.intellij.openapi.components.stateStore
import com.intellij.openapi.diagnostic.Logger
import com.intellij.openapi.module.Module
import com.intellij.openapi.module.ModuleManager
@@ -330,12 +328,6 @@ suspend fun createOrLoadProject(tempDirManager: TemporaryDirectory, projectCreat
}
}
fun ComponentManager.saveStore() {
runBlocking {
stateStore.save(isForceSavingAllSettings = true)
}
}
class DisposableRule : ExternalResource() {
private var _disposable = lazy { Disposer.newDisposable() }