Skip to content

Commit 753ac30

Browse files
committed
tests for applyWorkspaceEdit
1 parent 2d59143 commit 753ac30

File tree

1 file changed

+213
-0
lines changed
  • plugins/amazonq/shared/jetbrains-community/tst/software/aws/toolkits/jetbrains/services/amazonq/lsp/util

1 file changed

+213
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,213 @@
1+
// Copyright 2025 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
package software.aws.toolkits.jetbrains.services.amazonq.lsp.util
5+
6+
import com.intellij.openapi.command.WriteCommandAction
7+
import com.intellij.openapi.editor.Document
8+
import com.intellij.openapi.editor.Editor
9+
import com.intellij.openapi.editor.LogicalPosition
10+
import com.intellij.openapi.fileEditor.FileDocumentManager
11+
import com.intellij.openapi.fileEditor.FileEditorManager
12+
import com.intellij.openapi.fileEditor.TextEditor
13+
import com.intellij.openapi.project.Project
14+
import com.intellij.openapi.vfs.VirtualFile
15+
import com.intellij.openapi.vfs.VirtualFileManager
16+
import com.intellij.testFramework.ApplicationExtension
17+
import io.mockk.every
18+
import io.mockk.mockk
19+
import io.mockk.mockkStatic
20+
import io.mockk.slot
21+
import io.mockk.verify
22+
import org.eclipse.lsp4j.Position
23+
import org.eclipse.lsp4j.Range
24+
import org.eclipse.lsp4j.TextDocumentEdit
25+
import org.eclipse.lsp4j.TextEdit
26+
import org.eclipse.lsp4j.VersionedTextDocumentIdentifier
27+
import org.eclipse.lsp4j.WorkspaceEdit
28+
import org.eclipse.lsp4j.jsonrpc.messages.Either
29+
import org.junit.jupiter.api.BeforeEach
30+
import org.junit.jupiter.api.Test
31+
import org.junit.jupiter.api.extension.ExtendWith
32+
33+
@ExtendWith(ApplicationExtension::class)
34+
class ApplyWorkspaceEditTest {
35+
36+
private lateinit var project: Project
37+
private lateinit var virtualFileManager: VirtualFileManager
38+
private lateinit var fileDocumentManager: FileDocumentManager
39+
private lateinit var fileEditorManager: FileEditorManager
40+
41+
@BeforeEach
42+
fun setUp() {
43+
virtualFileManager = mockk(relaxed = true)
44+
fileDocumentManager = mockk(relaxed = true)
45+
fileEditorManager = mockk(relaxed = true)
46+
project = mockk(relaxed = true)
47+
48+
mockkStatic(WriteCommandAction::class)
49+
every { WriteCommandAction.runWriteCommandAction(any(), any<Runnable>()) } answers {
50+
secondArg<Runnable>().run()
51+
}
52+
53+
mockkStatic(VirtualFileManager::getInstance)
54+
every { VirtualFileManager.getInstance() } returns virtualFileManager
55+
56+
mockkStatic(FileDocumentManager::getInstance)
57+
every { FileDocumentManager.getInstance() } returns fileDocumentManager
58+
59+
mockkStatic(FileEditorManager::getInstance)
60+
every { FileEditorManager.getInstance(any()) } returns fileEditorManager
61+
}
62+
63+
@Test
64+
fun `test applyWorkspaceEdit with changes`() {
65+
val uri = "file:///test.kt"
66+
val document = mockk<Document>(relaxed = true)
67+
val file = mockk<VirtualFile>()
68+
val textEdit = TextEdit(Range(Position(0, 0), Position(0, 5)), "newText")
69+
70+
every { virtualFileManager.findFileByUrl(uri) } returns file
71+
every { fileDocumentManager.getDocument(file) } returns document
72+
every { document.getLineStartOffset(0) } returns 0
73+
74+
val workspaceEdit = WorkspaceEdit().apply {
75+
changes = mapOf(uri to listOf(textEdit))
76+
}
77+
78+
LspEditorUtil.applyWorkspaceEdit(project, workspaceEdit)
79+
80+
verify { document.replaceString(0, 5, "newText") }
81+
}
82+
83+
@Test
84+
fun `test applyWorkspaceEdit with documentChanges`() {
85+
val uri = "file:///test.kt"
86+
val document = mockk<Document>(relaxed = true)
87+
val file = mockk<VirtualFile>()
88+
val textEdit = TextEdit(Range(Position(0, 0), Position(0, 5)), "newText")
89+
90+
every { virtualFileManager.findFileByUrl(uri) } returns file
91+
every { fileDocumentManager.getDocument(file) } returns document
92+
every { document.getLineStartOffset(0) } returns 0
93+
94+
val versionedIdentifier = VersionedTextDocumentIdentifier(uri, 1)
95+
val textDocumentEdit = TextDocumentEdit(versionedIdentifier, listOf(textEdit))
96+
val workspaceEdit = WorkspaceEdit().apply {
97+
documentChanges = listOf(Either.forLeft(textDocumentEdit))
98+
}
99+
100+
LspEditorUtil.applyWorkspaceEdit(project, workspaceEdit)
101+
102+
verify { document.replaceString(0, 5, "newText") }
103+
}
104+
105+
@Test
106+
fun `test applyWorkspaceEdit with editor`() {
107+
val uri = "file:///test.kt"
108+
val document = mockk<Document>(relaxed = true)
109+
val file = mockk<VirtualFile>()
110+
val editor = mockk<Editor>()
111+
val textEditor = mockk<TextEditor>()
112+
113+
every { virtualFileManager.findFileByUrl(uri) } returns file
114+
every { fileDocumentManager.getDocument(file) } returns document
115+
every { fileEditorManager.getSelectedEditor(file) } returns textEditor
116+
every { textEditor.editor } returns editor
117+
118+
val positionSlot = slot<LogicalPosition>()
119+
every { editor.logicalPositionToOffset(capture(positionSlot)) } answers {
120+
if (positionSlot.captured.line == 0 && positionSlot.captured.column == 0) 0 else 5
121+
}
122+
123+
val textEdit = TextEdit(Range(Position(0, 0), Position(0, 5)), "newText")
124+
val workspaceEdit = WorkspaceEdit().apply {
125+
changes = mapOf(uri to listOf(textEdit))
126+
}
127+
128+
LspEditorUtil.applyWorkspaceEdit(project, workspaceEdit)
129+
130+
verify { document.replaceString(0, 5, "newText") }
131+
}
132+
133+
@Test
134+
fun `test applyWorkspaceEdit with both changes and documentChanges`() {
135+
val uri1 = "file:///test1.kt"
136+
val uri2 = "file:///test2.kt"
137+
val document1 = mockk<Document>(relaxed = true)
138+
val document2 = mockk<Document>(relaxed = true)
139+
val file1 = mockk<VirtualFile>()
140+
val file2 = mockk<VirtualFile>()
141+
142+
val textEdit1 = TextEdit(Range(Position(0, 0), Position(0, 5)), "newText1")
143+
val textEdit2 = TextEdit(Range(Position(1, 0), Position(1, 10)), "newText2")
144+
145+
every { virtualFileManager.findFileByUrl(uri1) } returns file1
146+
every { virtualFileManager.findFileByUrl(uri2) } returns file2
147+
every { fileDocumentManager.getDocument(file1) } returns document1
148+
every { fileDocumentManager.getDocument(file2) } returns document2
149+
every { document1.getLineStartOffset(0) } returns 0
150+
every { document2.getLineStartOffset(1) } returns 100
151+
152+
val versionedIdentifier = VersionedTextDocumentIdentifier(uri1, 1)
153+
val textDocumentEdit = TextDocumentEdit(versionedIdentifier, listOf(textEdit1))
154+
155+
val workspaceEdit = WorkspaceEdit().apply {
156+
documentChanges = listOf(Either.forLeft(textDocumentEdit))
157+
changes = mapOf(uri2 to listOf(textEdit2))
158+
}
159+
160+
LspEditorUtil.applyWorkspaceEdit(project, workspaceEdit)
161+
162+
verify { document1.replaceString(0, 5, "newText1") }
163+
verify { document2.replaceString(100, 110, "newText2") }
164+
}
165+
166+
@Test
167+
fun `test applyWorkspaceEdit with multiple edits to same file`() {
168+
val uri = "file:///test.kt"
169+
val document = mockk<Document>(relaxed = true)
170+
val file = mockk<VirtualFile>()
171+
172+
val textEdit1 = TextEdit(Range(Position(0, 0), Position(0, 5)), "newText1")
173+
val textEdit2 = TextEdit(Range(Position(1, 0), Position(1, 10)), "newText2")
174+
175+
every { virtualFileManager.findFileByUrl(uri) } returns file
176+
every { fileDocumentManager.getDocument(file) } returns document
177+
every { document.getLineStartOffset(0) } returns 0
178+
every { document.getLineStartOffset(1) } returns 100
179+
180+
val workspaceEdit = WorkspaceEdit().apply {
181+
changes = mapOf(uri to listOf(textEdit1, textEdit2))
182+
}
183+
184+
LspEditorUtil.applyWorkspaceEdit(project, workspaceEdit)
185+
186+
verify { document.replaceString(0, 5, "newText1") }
187+
verify { document.replaceString(100, 110, "newText2") }
188+
}
189+
190+
@Test
191+
fun `test applyWorkspaceEdit with empty edits`() {
192+
val workspaceEdit = WorkspaceEdit()
193+
LspEditorUtil.applyWorkspaceEdit(project, workspaceEdit)
194+
195+
// No verification needed - just ensuring no exceptions
196+
}
197+
198+
199+
@Test
200+
fun `test applyWorkspaceEdit with invalid file`() {
201+
val uri = "file:///nonexistent.kt"
202+
val textEdit = TextEdit(Range(Position(0, 0), Position(0, 5)), "newText")
203+
204+
every { virtualFileManager.findFileByUrl(uri) } returns null
205+
206+
val workspaceEdit = WorkspaceEdit().apply {
207+
changes = mapOf(uri to listOf(textEdit))
208+
}
209+
210+
// Execute - should not throw exception
211+
LspEditorUtil.applyWorkspaceEdit(project, workspaceEdit)
212+
}
213+
}

0 commit comments

Comments
 (0)