mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IJPL-197985: Add test for WorkspaceFileIndexListener
GitOrigin-RevId: 3ff0141d5be4e290dfc4f67f93f54be79450a099
This commit is contained in:
committed by
intellij-monorepo-bot
parent
0d9cdd3805
commit
1976bac341
+1
@@ -20,6 +20,7 @@ import com.intellij.platform.workspace.storage.instrumentation.EntityStorageInst
|
||||
import com.intellij.platform.workspace.storage.instrumentation.EntityStorageInstrumentationApi
|
||||
import com.intellij.platform.workspace.storage.instrumentation.MutableEntityStorageInstrumentation
|
||||
import com.intellij.platform.workspace.storage.metadata.model.EntityMetadata
|
||||
import com.intellij.platform.workspace.storage.url.VirtualFileUrl
|
||||
import com.intellij.util.indexing.testEntities.ChildTestEntity
|
||||
import com.intellij.util.indexing.testEntities.ParentTestEntity
|
||||
|
||||
|
||||
+3
-2
@@ -47,7 +47,8 @@ OwnPropertyMetadata(isComputable = false, isKey = false, isOpen = false, name =
|
||||
typeMetadata = EntityMetadata(fqName = "com.intellij.util.indexing.testEntities.ParentTestEntity", entityDataFqName = "com.intellij.util.indexing.testEntities.impl.ParentTestEntityData", supertypes = listOf("com.intellij.platform.workspace.storage.WorkspaceEntity"), properties = listOf(OwnPropertyMetadata(isComputable = false, isKey = false, isOpen = false, name = "entitySource", valueType = ValueTypeMetadata.SimpleType.CustomType(isNullable = false, typeMetadata = FinalClassMetadata.KnownClass(fqName = "com.intellij.platform.workspace.storage.EntitySource")), withDefault = false),
|
||||
OwnPropertyMetadata(isComputable = false, isKey = false, isOpen = false, name = "child", valueType = ValueTypeMetadata.EntityReference(connectionType = ConnectionId.ConnectionType.ONE_TO_ONE, entityFqName = "com.intellij.util.indexing.testEntities.ChildTestEntity", isChild = true, isNullable = true), withDefault = false),
|
||||
OwnPropertyMetadata(isComputable = false, isKey = false, isOpen = false, name = "secondChild", valueType = ValueTypeMetadata.EntityReference(connectionType = ConnectionId.ConnectionType.ONE_TO_ONE, entityFqName = "com.intellij.util.indexing.testEntities.SiblingEntity", isChild = true, isNullable = true), withDefault = false),
|
||||
OwnPropertyMetadata(isComputable = false, isKey = false, isOpen = false, name = "customParentProperty", valueType = primitiveTypeStringNotNullable, withDefault = false)), extProperties = listOf(), isAbstract = false)
|
||||
OwnPropertyMetadata(isComputable = false, isKey = false, isOpen = false, name = "customParentProperty", valueType = primitiveTypeStringNotNullable, withDefault = false),
|
||||
OwnPropertyMetadata(isComputable = false, isKey = false, isOpen = false, name = "parentEntityRoot", valueType = ValueTypeMetadata.SimpleType.CustomType(isNullable = false, typeMetadata = FinalClassMetadata.KnownClass(fqName = "com.intellij.platform.workspace.storage.url.VirtualFileUrl")), withDefault = false)), extProperties = listOf(), isAbstract = false)
|
||||
|
||||
addMetadata(typeMetadata)
|
||||
|
||||
@@ -63,7 +64,7 @@ OwnPropertyMetadata(isComputable = false, isKey = false, isOpen = false, name =
|
||||
addMetadataHash(typeFqn = "com.intellij.util.indexing.testEntities.IndexingTestEntity", metadataHash = -233870197)
|
||||
addMetadataHash(typeFqn = "com.intellij.util.indexing.testEntities.NonIndexableTestEntity", metadataHash = -15259978)
|
||||
addMetadataHash(typeFqn = "com.intellij.util.indexing.testEntities.NonRecursiveTestEntity", metadataHash = -55418454)
|
||||
addMetadataHash(typeFqn = "com.intellij.util.indexing.testEntities.ParentTestEntity", metadataHash = -1345180662)
|
||||
addMetadataHash(typeFqn = "com.intellij.util.indexing.testEntities.ParentTestEntity", metadataHash = 1278429366)
|
||||
addMetadataHash(typeFqn = "com.intellij.util.indexing.testEntities.SiblingEntity", metadataHash = 144691097)
|
||||
addMetadataHash(typeFqn = "com.intellij.platform.workspace.storage.EntitySource", metadataHash = 1279624819)
|
||||
addMetadataHash(typeFqn = "com.intellij.util.indexing.testEntities.TestModuleEntitySource", metadataHash = -1815413801)
|
||||
|
||||
+29
-1
@@ -20,6 +20,7 @@ import com.intellij.platform.workspace.storage.instrumentation.EntityStorageInst
|
||||
import com.intellij.platform.workspace.storage.instrumentation.EntityStorageInstrumentationApi
|
||||
import com.intellij.platform.workspace.storage.instrumentation.MutableEntityStorageInstrumentation
|
||||
import com.intellij.platform.workspace.storage.metadata.model.EntityMetadata
|
||||
import com.intellij.platform.workspace.storage.url.VirtualFileUrl
|
||||
import com.intellij.util.indexing.testEntities.ChildTestEntity
|
||||
import com.intellij.util.indexing.testEntities.ParentTestEntity
|
||||
import com.intellij.util.indexing.testEntities.SiblingEntity
|
||||
@@ -54,6 +55,12 @@ internal class ParentTestEntityImpl(private val dataSource: ParentTestEntityData
|
||||
return dataSource.customParentProperty
|
||||
}
|
||||
|
||||
override val parentEntityRoot: VirtualFileUrl
|
||||
get() {
|
||||
readField("parentEntityRoot")
|
||||
return dataSource.parentEntityRoot
|
||||
}
|
||||
|
||||
override val entitySource: EntitySource
|
||||
get() {
|
||||
readField("entitySource")
|
||||
@@ -87,6 +94,7 @@ internal class ParentTestEntityImpl(private val dataSource: ParentTestEntityData
|
||||
// Builder may switch to snapshot at any moment and lock entity data to modification
|
||||
this.currentEntityData = null
|
||||
|
||||
index(this, "parentEntityRoot", this.parentEntityRoot)
|
||||
// Process linked entities that are connected without a builder
|
||||
processLinkedEntities(builder)
|
||||
checkInitialization() // TODO uncomment and check failed tests
|
||||
@@ -100,6 +108,9 @@ internal class ParentTestEntityImpl(private val dataSource: ParentTestEntityData
|
||||
if (!getEntityData().isCustomParentPropertyInitialized()) {
|
||||
error("Field ParentTestEntity#customParentProperty should be initialized")
|
||||
}
|
||||
if (!getEntityData().isParentEntityRootInitialized()) {
|
||||
error("Field ParentTestEntity#parentEntityRoot should be initialized")
|
||||
}
|
||||
}
|
||||
|
||||
override fun connectionIdList(): List<ConnectionId> {
|
||||
@@ -111,6 +122,7 @@ internal class ParentTestEntityImpl(private val dataSource: ParentTestEntityData
|
||||
dataSource as ParentTestEntity
|
||||
if (this.entitySource != dataSource.entitySource) this.entitySource = dataSource.entitySource
|
||||
if (this.customParentProperty != dataSource.customParentProperty) this.customParentProperty = dataSource.customParentProperty
|
||||
if (this.parentEntityRoot != dataSource.parentEntityRoot) this.parentEntityRoot = dataSource.parentEntityRoot
|
||||
updateChildToParentReferences(parents)
|
||||
}
|
||||
|
||||
@@ -204,6 +216,16 @@ internal class ParentTestEntityImpl(private val dataSource: ParentTestEntityData
|
||||
changedProperty.add("customParentProperty")
|
||||
}
|
||||
|
||||
override var parentEntityRoot: VirtualFileUrl
|
||||
get() = getEntityData().parentEntityRoot
|
||||
set(value) {
|
||||
checkModificationAllowed()
|
||||
getEntityData(true).parentEntityRoot = value
|
||||
changedProperty.add("parentEntityRoot")
|
||||
val _diff = diff
|
||||
if (_diff != null) index(this, "parentEntityRoot", value)
|
||||
}
|
||||
|
||||
override fun getEntityClass(): Class<ParentTestEntity> = ParentTestEntity::class.java
|
||||
}
|
||||
}
|
||||
@@ -211,8 +233,10 @@ internal class ParentTestEntityImpl(private val dataSource: ParentTestEntityData
|
||||
@OptIn(WorkspaceEntityInternalApi::class)
|
||||
internal class ParentTestEntityData : WorkspaceEntityData<ParentTestEntity>() {
|
||||
lateinit var customParentProperty: String
|
||||
lateinit var parentEntityRoot: VirtualFileUrl
|
||||
|
||||
internal fun isCustomParentPropertyInitialized(): Boolean = ::customParentProperty.isInitialized
|
||||
internal fun isParentEntityRootInitialized(): Boolean = ::parentEntityRoot.isInitialized
|
||||
|
||||
override fun wrapAsModifiable(diff: MutableEntityStorage): WorkspaceEntity.Builder<ParentTestEntity> {
|
||||
val modifiable = ParentTestEntityImpl.Builder(null)
|
||||
@@ -241,7 +265,7 @@ internal class ParentTestEntityData : WorkspaceEntityData<ParentTestEntity>() {
|
||||
}
|
||||
|
||||
override fun createDetachedEntity(parents: List<WorkspaceEntity.Builder<*>>): WorkspaceEntity.Builder<*> {
|
||||
return ParentTestEntity(customParentProperty, entitySource) {
|
||||
return ParentTestEntity(customParentProperty, parentEntityRoot, entitySource) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -258,6 +282,7 @@ internal class ParentTestEntityData : WorkspaceEntityData<ParentTestEntity>() {
|
||||
|
||||
if (this.entitySource != other.entitySource) return false
|
||||
if (this.customParentProperty != other.customParentProperty) return false
|
||||
if (this.parentEntityRoot != other.parentEntityRoot) return false
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -268,18 +293,21 @@ internal class ParentTestEntityData : WorkspaceEntityData<ParentTestEntity>() {
|
||||
other as ParentTestEntityData
|
||||
|
||||
if (this.customParentProperty != other.customParentProperty) return false
|
||||
if (this.parentEntityRoot != other.parentEntityRoot) return false
|
||||
return true
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
var result = entitySource.hashCode()
|
||||
result = 31 * result + customParentProperty.hashCode()
|
||||
result = 31 * result + parentEntityRoot.hashCode()
|
||||
return result
|
||||
}
|
||||
|
||||
override fun hashCodeIgnoringEntitySource(): Int {
|
||||
var result = javaClass.hashCode()
|
||||
result = 31 * result + customParentProperty.hashCode()
|
||||
result = 31 * result + parentEntityRoot.hashCode()
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
+1
@@ -20,6 +20,7 @@ import com.intellij.platform.workspace.storage.instrumentation.EntityStorageInst
|
||||
import com.intellij.platform.workspace.storage.instrumentation.EntityStorageInstrumentationApi
|
||||
import com.intellij.platform.workspace.storage.instrumentation.MutableEntityStorageInstrumentation
|
||||
import com.intellij.platform.workspace.storage.metadata.model.EntityMetadata
|
||||
import com.intellij.platform.workspace.storage.url.VirtualFileUrl
|
||||
import com.intellij.util.indexing.testEntities.ParentTestEntity
|
||||
import com.intellij.util.indexing.testEntities.SiblingEntity
|
||||
|
||||
|
||||
+5
@@ -7,12 +7,14 @@ import com.intellij.platform.workspace.storage.GeneratedCodeApiVersion
|
||||
import com.intellij.platform.workspace.storage.MutableEntityStorage
|
||||
import com.intellij.platform.workspace.storage.WorkspaceEntity
|
||||
import com.intellij.platform.workspace.storage.annotations.Parent
|
||||
import com.intellij.platform.workspace.storage.url.VirtualFileUrl
|
||||
|
||||
|
||||
interface ParentTestEntity : WorkspaceEntity {
|
||||
val child: ChildTestEntity?
|
||||
val secondChild: SiblingEntity?
|
||||
val customParentProperty: String
|
||||
val parentEntityRoot: VirtualFileUrl
|
||||
|
||||
//region generated code
|
||||
@GeneratedCodeApiVersion(3)
|
||||
@@ -21,6 +23,7 @@ interface ParentTestEntity : WorkspaceEntity {
|
||||
var child: ChildTestEntity.Builder?
|
||||
var secondChild: SiblingEntity.Builder?
|
||||
var customParentProperty: String
|
||||
var parentEntityRoot: VirtualFileUrl
|
||||
}
|
||||
|
||||
companion object : EntityType<ParentTestEntity, Builder>() {
|
||||
@@ -29,11 +32,13 @@ interface ParentTestEntity : WorkspaceEntity {
|
||||
@JvmName("create")
|
||||
operator fun invoke(
|
||||
customParentProperty: String,
|
||||
parentEntityRoot: VirtualFileUrl,
|
||||
entitySource: EntitySource,
|
||||
init: (Builder.() -> Unit)? = null,
|
||||
): Builder {
|
||||
val builder = builder()
|
||||
builder.customParentProperty = customParentProperty
|
||||
builder.parentEntityRoot = parentEntityRoot
|
||||
builder.entitySource = entitySource
|
||||
init?.invoke(builder)
|
||||
return builder
|
||||
|
||||
+8
-2
@@ -7,6 +7,7 @@ import com.intellij.openapi.module.Module
|
||||
import com.intellij.openapi.roots.SkipAddingToWatchedRoots
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import com.intellij.platform.backend.workspace.WorkspaceModel
|
||||
import com.intellij.platform.backend.workspace.toVirtualFileUrl
|
||||
import com.intellij.platform.workspace.storage.EntityStorage
|
||||
import com.intellij.testFramework.junit5.TestApplication
|
||||
import com.intellij.testFramework.junit5.TestDisposable
|
||||
@@ -54,7 +55,9 @@ class WorkspaceFileIndexContributorDependenciesTest {
|
||||
runBlocking { readAction { WorkspaceFileIndex.getInstance(projectModel.project).isInWorkspace(customContentFileSetRoot) } }
|
||||
// initialize model
|
||||
val model = WorkspaceModel.getInstance(projectModel.project)
|
||||
val parent = ParentTestEntity("parent property", NonPersistentEntitySource)
|
||||
val parent = ParentTestEntity("parent property",
|
||||
customContentFileSetRoot.toVirtualFileUrl(model.getVirtualFileUrlManager()),
|
||||
NonPersistentEntitySource)
|
||||
.also { it.child = ChildTestEntity("child property", NonPersistentEntitySource) }
|
||||
.also { it.secondChild = SiblingEntity("sibling property", NonPersistentEntitySource) }
|
||||
|
||||
@@ -132,7 +135,10 @@ class WorkspaceFileIndexContributorDependenciesTest {
|
||||
@Test
|
||||
fun `child contributor should be called after its relative added`() = runBlocking {
|
||||
val model = WorkspaceModel.getInstance(projectModel.project)
|
||||
val newParentEntity = ParentTestEntity("new parent property", NonPersistentEntitySource) {
|
||||
|
||||
val newParentEntity = ParentTestEntity("new parent property",
|
||||
customContentFileSetRoot.toVirtualFileUrl(model.getVirtualFileUrlManager()),
|
||||
NonPersistentEntitySource) {
|
||||
child = ChildTestEntity("new child property", NonPersistentEntitySource)
|
||||
}
|
||||
|
||||
|
||||
+125
@@ -0,0 +1,125 @@
|
||||
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.workspaceModel.core.fileIndex
|
||||
|
||||
import com.intellij.concurrency.ConcurrentCollectionFactory
|
||||
import com.intellij.openapi.Disposable
|
||||
import com.intellij.openapi.application.readAction
|
||||
import com.intellij.openapi.module.Module
|
||||
import com.intellij.openapi.roots.SkipAddingToWatchedRoots
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import com.intellij.platform.backend.workspace.WorkspaceModel
|
||||
import com.intellij.platform.backend.workspace.toVirtualFileUrl
|
||||
import com.intellij.platform.workspace.storage.EntityStorage
|
||||
import com.intellij.testFramework.junit5.TestApplication
|
||||
import com.intellij.testFramework.junit5.TestDisposable
|
||||
import com.intellij.testFramework.rules.ProjectModelExtension
|
||||
import com.intellij.util.indexing.testEntities.ParentTestEntity
|
||||
import com.intellij.workspaceModel.core.fileIndex.impl.WorkspaceFileIndexImpl
|
||||
import com.intellij.workspaceModel.ide.NonPersistentEntitySource
|
||||
import io.kotest.common.runBlocking
|
||||
import org.junit.jupiter.api.BeforeEach
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.extension.RegisterExtension
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
@TestApplication
|
||||
class WorkspaceFileIndexListenerTest {
|
||||
|
||||
@JvmField
|
||||
@RegisterExtension
|
||||
val projectModel: ProjectModelExtension = ProjectModelExtension()
|
||||
|
||||
private val parentWorkspaceFileIndexContributor = ParentWorkspaceFileIndexContributor()
|
||||
|
||||
@TestDisposable
|
||||
private lateinit var disposable: Disposable
|
||||
private lateinit var customContentFileSetRoot: VirtualFile
|
||||
private lateinit var module: Module
|
||||
|
||||
@BeforeEach
|
||||
fun setUp() {
|
||||
WorkspaceFileIndexImpl.EP_NAME.point.registerExtension(parentWorkspaceFileIndexContributor, disposable)
|
||||
customContentFileSetRoot = projectModel.baseProjectDir.newVirtualDirectory("root")
|
||||
module = projectModel.createModule()
|
||||
|
||||
|
||||
runBlocking { readAction { WorkspaceFileIndex.getInstance(projectModel.project).isInWorkspace(customContentFileSetRoot) } }
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
fun `listener event for registered file set`() = runBlocking {
|
||||
val listener = MyWorkspaceFileIndexListener()
|
||||
projectModel.project.messageBus.connect().subscribe(WorkspaceFileIndexListener.TOPIC, listener)
|
||||
|
||||
val model = WorkspaceModel.getInstance(projectModel.project)
|
||||
|
||||
val parentEntityRoot = customContentFileSetRoot.toVirtualFileUrl(model.getVirtualFileUrlManager())
|
||||
val parent = ParentTestEntity("parent property",
|
||||
parentEntityRoot,
|
||||
NonPersistentEntitySource)
|
||||
|
||||
model.update("Add entity") {
|
||||
it.addEntity(parent)
|
||||
}
|
||||
|
||||
assertEquals(0, listener.removedRoots.size)
|
||||
assertEquals(1, listener.storedRoots.size)
|
||||
|
||||
assertEquals(parentEntityRoot,
|
||||
listener.storedRoots.first().root.toVirtualFileUrl(model.getVirtualFileUrlManager()))
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
fun `listener event for removed file set`() = runBlocking {
|
||||
val listener = MyWorkspaceFileIndexListener()
|
||||
projectModel.project.messageBus.connect().subscribe(WorkspaceFileIndexListener.TOPIC, listener)
|
||||
|
||||
val model = WorkspaceModel.getInstance(projectModel.project)
|
||||
|
||||
val parentEntityRoot = customContentFileSetRoot.toVirtualFileUrl(model.getVirtualFileUrlManager())
|
||||
val parent = ParentTestEntity("parent property",
|
||||
parentEntityRoot,
|
||||
NonPersistentEntitySource)
|
||||
|
||||
model.update("Add parent") {
|
||||
it.addEntity(parent)
|
||||
}
|
||||
assertEquals(0, listener.removedRoots.size)
|
||||
assertEquals(1, listener.storedRoots.size)
|
||||
|
||||
val parentEntity = model.currentSnapshot.entities(ParentTestEntity::class.java).first()
|
||||
|
||||
model.update("Remove entity") {storage ->
|
||||
storage.removeEntity(parentEntity)
|
||||
}
|
||||
|
||||
assertEquals(1, listener.removedRoots.size)
|
||||
assertEquals(1, listener.storedRoots.size)
|
||||
assertEquals(parentEntityRoot,
|
||||
listener.removedRoots.first().root.toVirtualFileUrl(model.getVirtualFileUrlManager()))
|
||||
|
||||
}
|
||||
|
||||
private class MyWorkspaceFileIndexListener : WorkspaceFileIndexListener {
|
||||
val storedRoots = ConcurrentCollectionFactory.createConcurrentSet<WorkspaceFileSet>()
|
||||
val removedRoots = ConcurrentCollectionFactory.createConcurrentSet<WorkspaceFileSet>()
|
||||
|
||||
override fun workspaceFileIndexChanged(event: WorkspaceFileIndexChangedEvent) {
|
||||
storedRoots.addAll(event.getStoredFileSets())
|
||||
removedRoots.addAll(event.getRemovedFileSets())
|
||||
}
|
||||
}
|
||||
|
||||
// we need SkipAddingToWatchedRoots to pass filter WorkspaceIndexingRootsBuilder.Companion.registerEntitiesFromContributors()
|
||||
private class ParentWorkspaceFileIndexContributor : WorkspaceFileIndexContributor<ParentTestEntity>, SkipAddingToWatchedRoots {
|
||||
|
||||
override val entityClass: Class<ParentTestEntity>
|
||||
get() = ParentTestEntity::class.java
|
||||
|
||||
override fun registerFileSets(entity: ParentTestEntity, registrar: WorkspaceFileSetRegistrar, storage: EntityStorage) {
|
||||
registrar.registerFileSet(entity.parentEntityRoot, WorkspaceFileKind.CONTENT, entity, null)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user