@@ -9,9 +9,11 @@ import com.intellij.openapi.application.ApplicationManager
99import com.intellij.openapi.components.serviceIfCreated
1010import com.intellij.openapi.project.Project
1111import com.intellij.openapi.vfs.VirtualFile
12+ import com.intellij.openapi.vfs.newvfs.events.VFileCopyEvent
1213import com.intellij.openapi.vfs.newvfs.events.VFileCreateEvent
1314import com.intellij.openapi.vfs.newvfs.events.VFileDeleteEvent
1415import com.intellij.openapi.vfs.newvfs.events.VFileEvent
16+ import com.intellij.openapi.vfs.newvfs.events.VFileMoveEvent
1517import com.intellij.openapi.vfs.newvfs.events.VFilePropertyChangeEvent
1618import com.intellij.util.messages.MessageBus
1719import com.intellij.util.messages.MessageBusConnection
@@ -167,6 +169,32 @@ class WorkspaceServiceHandlerTest {
167169 verify(exactly = 0 ) { mockWorkspaceService.didCreateFiles(any()) }
168170 }
169171
172+ @Test
173+ fun `test didCreateFiles with move event` () = runTest {
174+ val oldUri = URI (" file:///test/oldPath" )
175+ val newUri = URI (" file:///test/newPath" )
176+ val moveEvent = createMockVFileMoveEvent(oldUri, newUri, " test.py" )
177+
178+ sut.after(listOf (moveEvent))
179+
180+ val paramsSlot = slot<CreateFilesParams >()
181+ verify { mockWorkspaceService.didCreateFiles(capture(paramsSlot)) }
182+ assertEquals(normalizeFileUri(newUri.toString()), paramsSlot.captured.files[0 ].uri)
183+ }
184+
185+ @Test
186+ fun `test didCreateFiles with copy event` () = runTest {
187+ val originalUri = URI (" file:///test/original" )
188+ val newUri = URI (" file:///test/new" )
189+ val copyEvent = createMockVFileCopyEvent(originalUri, newUri, " test.py" )
190+
191+ sut.after(listOf (copyEvent))
192+
193+ val paramsSlot = slot<CreateFilesParams >()
194+ verify { mockWorkspaceService.didCreateFiles(capture(paramsSlot)) }
195+ assertEquals(normalizeFileUri(newUri.toString()), paramsSlot.captured.files[0 ].uri)
196+ }
197+
170198 @Test
171199 fun `test didDeleteFiles with Python file` () = runTest {
172200 val pyUri = URI (" file:///test/path" )
@@ -262,6 +290,38 @@ class WorkspaceServiceHandlerTest {
262290 assertEquals(FileChangeType .Changed , paramsSlot.captured.changes[2 ].type)
263291 }
264292
293+ @Test
294+ fun `test didChangeWatchedFiles with move event reports both delete and create` () = runTest {
295+ val oldUri = URI (" file:///test/oldPath" )
296+ val newUri = URI (" file:///test/newPath" )
297+ val moveEvent = createMockVFileMoveEvent(oldUri, newUri, " test.py" )
298+
299+ sut.after(listOf (moveEvent))
300+
301+ val paramsSlot = slot<DidChangeWatchedFilesParams >()
302+ verify { mockWorkspaceService.didChangeWatchedFiles(capture(paramsSlot)) }
303+
304+ assertEquals(2 , paramsSlot.captured.changes.size)
305+ assertEquals(normalizeFileUri(oldUri.toString()), paramsSlot.captured.changes[0 ].uri)
306+ assertEquals(FileChangeType .Deleted , paramsSlot.captured.changes[0 ].type)
307+ assertEquals(normalizeFileUri(newUri.toString()), paramsSlot.captured.changes[1 ].uri)
308+ assertEquals(FileChangeType .Created , paramsSlot.captured.changes[1 ].type)
309+ }
310+
311+ @Test
312+ fun `test didChangeWatchedFiles with copy event` () = runTest {
313+ val originalUri = URI (" file:///test/original" )
314+ val newUri = URI (" file:///test/new" )
315+ val copyEvent = createMockVFileCopyEvent(originalUri, newUri, " test.py" )
316+
317+ sut.after(listOf (copyEvent))
318+
319+ val paramsSlot = slot<DidChangeWatchedFilesParams >()
320+ verify { mockWorkspaceService.didChangeWatchedFiles(capture(paramsSlot)) }
321+ assertEquals(normalizeFileUri(newUri.toString()), paramsSlot.captured.changes[0 ].uri)
322+ assertEquals(FileChangeType .Created , paramsSlot.captured.changes[0 ].type)
323+ }
324+
265325 @Test
266326 fun `test no invoked messages when events are empty` () = runTest {
267327 // Act
@@ -510,20 +570,23 @@ class WorkspaceServiceHandlerTest {
510570 assertEquals(" folder2" , paramsSlot.captured.event.removed[0 ].name)
511571 }
512572
513- private fun createMockVFileEvent (uri : URI , type : FileChangeType = FileChangeType . Changed , isDirectory : Boolean , extension : String = "py" ): VFileEvent {
573+ private fun createMockVirtualFile (uri : URI , fileName : String , isDirectory : Boolean = false ): VirtualFile {
514574 val nioPath = mockk<Path > {
515575 every { toUri() } returns uri
516576 }
517- val virtualFile = mockk<VirtualFile > {
577+ return mockk<VirtualFile > {
518578 every { this @mockk.isDirectory } returns isDirectory
519579 every { toNioPath() } returns nioPath
520580 every { url } returns uri.path
521- every { path } returns " ${uri.path} . $extension "
581+ every { path } returns " ${uri.path} / $fileName "
522582 every { fileSystem } returns mockk {
523583 every { protocol } returns " file"
524584 }
525585 }
586+ }
526587
588+ private fun createMockVFileEvent (uri : URI , type : FileChangeType = FileChangeType .Changed , isDirectory : Boolean = false, extension : String = "py"): VFileEvent {
589+ val virtualFile = createMockVirtualFile(uri, " test.$extension " , isDirectory)
527590 return when (type) {
528591 FileChangeType .Deleted -> mockk<VFileDeleteEvent >()
529592 FileChangeType .Created -> mockk<VFileCreateEvent >()
@@ -533,49 +596,49 @@ class WorkspaceServiceHandlerTest {
533596 }
534597 }
535598
536- // for didRename events
537599 private fun createMockPropertyChangeEvent (
538600 oldName : String ,
539601 newName : String ,
540602 isDirectory : Boolean = false,
541603 ): VFilePropertyChangeEvent {
542- val parentPath = mockk<Path >()
543- val filePath = mockk<Path >()
604+ val oldUri = URI (" file:///test/$oldName " )
605+ val newUri = URI (" file:///test/$newName " )
606+ val file = createMockVirtualFile(newUri, newName, isDirectory)
607+ every { file.parent } returns createMockVirtualFile(oldUri, oldName, isDirectory)
544608
545- val parent = mockk<VirtualFile > {
546- every { toNioPath() } returns parentPath
547- every { this @mockk.isDirectory } returns isDirectory
548- every { path } returns " /test/$oldName "
549- every { url } returns " file:///test/$oldName "
550- every { fileSystem } returns mockk {
551- every { protocol } returns " file"
552- }
609+ return mockk<VFilePropertyChangeEvent >().apply {
610+ every { propertyName } returns VirtualFile .PROP_NAME
611+ every { this @apply.file } returns file
612+ every { oldValue } returns oldName
613+ every { newValue } returns newName
553614 }
615+ }
554616
555- val file = mockk<VirtualFile > {
556- every { toNioPath() } returns filePath
557- every { this @mockk.parent } returns parent
558- every { this @mockk.isDirectory } returns isDirectory
559- every { path } returns " /test/$newName "
560- every { url } returns " file:///test/$newName "
617+ private fun createMockVFileMoveEvent (oldUri : URI , newUri : URI , fileName : String ): VFileMoveEvent {
618+ val newFile = createMockVirtualFile(newUri, fileName)
619+ return mockk<VFileMoveEvent >().apply {
620+ every { file } returns newFile
621+ every { oldPath } returns oldUri.path
622+ every { oldParent } returns createMockVirtualFile(oldUri, fileName)
623+ }
624+ }
625+
626+ private fun createMockVFileCopyEvent (originalUri : URI , newUri : URI , fileName : String ): VFileCopyEvent {
627+ val newParent = mockk<VirtualFile > {
628+ every { findChild(any()) } returns createMockVirtualFile(newUri, fileName)
561629 every { fileSystem } returns mockk {
562630 every { protocol } returns " file"
563631 }
564632 }
565-
566- every { parentPath.resolve(oldName) } returns mockk {
567- every { toUri() } returns URI (" file:///test/$oldName " )
568- }
569- every { filePath.toUri() } returns URI (" file:///test/$newName " )
570-
571- return mockk<VFilePropertyChangeEvent >().apply {
572- every { propertyName } returns VirtualFile .PROP_NAME
573- every { this @apply.file } returns file
574- every { oldValue } returns oldName
575- every { newValue } returns newName
633+ return mockk<VFileCopyEvent >().apply {
634+ every { file } returns createMockVirtualFile(originalUri, fileName)
635+ every { this @apply.newParent } returns newParent
636+ every { newChildName } returns fileName
576637 }
577638 }
578639
640+
641+
579642 // for windows unit tests
580643 private fun normalizeFileUri (uri : String ): String {
581644 if (! System .getProperty(" os.name" ).lowercase().contains(" windows" )) {
0 commit comments