@@ -6,7 +6,9 @@ package software.aws.toolkits.jetbrains.services.amazonq.lsp.textdocument
6
6
import com.intellij.openapi.application.writeAction
7
7
import com.intellij.openapi.editor.Document
8
8
import com.intellij.openapi.fileEditor.FileDocumentManager
9
+ import com.intellij.openapi.fileEditor.ex.FileEditorManagerEx
9
10
import com.intellij.openapi.fileTypes.FileType
11
+ import com.intellij.openapi.util.Disposer
10
12
import com.intellij.openapi.vfs.VirtualFile
11
13
import com.intellij.openapi.vfs.newvfs.events.VFileContentChangeEvent
12
14
import com.intellij.openapi.vfs.newvfs.events.VFileEvent
@@ -24,7 +26,6 @@ import io.mockk.mockkStatic
24
26
import io.mockk.slot
25
27
import io.mockk.spyk
26
28
import io.mockk.verify
27
- import kotlinx.coroutines.test.TestScope
28
29
import kotlinx.coroutines.test.advanceUntilIdle
29
30
import kotlinx.coroutines.test.runTest
30
31
import kotlinx.coroutines.withContext
@@ -35,9 +36,11 @@ import org.eclipse.lsp4j.DidOpenTextDocumentParams
35
36
import org.eclipse.lsp4j.DidSaveTextDocumentParams
36
37
import org.eclipse.lsp4j.jsonrpc.messages.ResponseMessage
37
38
import org.eclipse.lsp4j.services.TextDocumentService
39
+ import org.junit.After
38
40
import org.junit.Before
39
41
import org.junit.Rule
40
42
import org.junit.Test
43
+ import org.junit.rules.TestName
41
44
import software.aws.toolkits.jetbrains.core.coroutines.EDT
42
45
import software.aws.toolkits.jetbrains.services.amazonq.lsp.AmazonQLanguageServer
43
46
import software.aws.toolkits.jetbrains.services.amazonq.lsp.AmazonQLspService
@@ -54,9 +57,6 @@ class TextDocumentServiceHandlerTest {
54
57
private lateinit var mockTextDocumentService: TextDocumentService
55
58
private lateinit var sut: TextDocumentServiceHandler
56
59
57
- // not ideal
58
- private lateinit var testScope: TestScope
59
-
60
60
@get:Rule
61
61
val projectRule = object : CodeInsightTestFixtureRule () {
62
62
override fun createTestFixture (): CodeInsightTestFixture {
@@ -74,6 +74,9 @@ class TextDocumentServiceHandlerTest {
74
74
@get:Rule
75
75
val disposableRule = DisposableRule ()
76
76
77
+ @get:Rule
78
+ val testName = TestName ()
79
+
77
80
@Before
78
81
fun setup () {
79
82
mockTextDocumentService = mockk<TextDocumentService >()
@@ -99,13 +102,20 @@ class TextDocumentServiceHandlerTest {
99
102
every { mockTextDocumentService.didSave(any()) } returns Unit
100
103
every { mockTextDocumentService.didOpen(any()) } returns Unit
101
104
every { mockTextDocumentService.didClose(any()) } returns Unit
105
+ }
102
106
103
- testScope = TestScope ()
104
- sut = TextDocumentServiceHandler (projectRule.project, testScope)
107
+ @After
108
+ fun tearDown () {
109
+ try {
110
+ Disposer .dispose(sut)
111
+ } catch (_: Exception ) {
112
+ }
105
113
}
106
114
107
115
@Test
108
- fun `didSave runs on beforeDocumentSaving` () {
116
+ fun `didSave runs on beforeDocumentSaving` () = runTest {
117
+ sut = TextDocumentServiceHandler (projectRule.project, this )
118
+
109
119
// Create test document and file
110
120
val uri = URI .create(" file:///test/path/file.txt" )
111
121
val document = mockk<Document > {
@@ -127,7 +137,7 @@ class TextDocumentServiceHandlerTest {
127
137
sut.beforeDocumentSaving(document)
128
138
129
139
// Verify the correct LSP method was called with matching parameters
130
- testScope. advanceUntilIdle()
140
+ advanceUntilIdle()
131
141
val paramsSlot = slot<DidSaveTextDocumentParams >()
132
142
verify { mockTextDocumentService.didSave(capture(paramsSlot)) }
133
143
@@ -142,12 +152,12 @@ class TextDocumentServiceHandlerTest {
142
152
fun `didOpen runs on service init` () = runTest {
143
153
val content = " test content"
144
154
val file = withContext(EDT ) {
145
- projectRule.fixture.createFile(" name " , content).also { projectRule.fixture.openFileInEditor(it) }
155
+ projectRule.fixture.createFile(testName.methodName , content).also { projectRule.fixture.openFileInEditor(it) }
146
156
}
147
-
157
+ advanceUntilIdle()
148
158
sut = TextDocumentServiceHandler (projectRule.project, this )
149
-
150
159
advanceUntilIdle()
160
+
151
161
val paramsSlot = mutableListOf<DidOpenTextDocumentParams >()
152
162
verify { mockTextDocumentService.didOpen(capture(paramsSlot)) }
153
163
@@ -160,15 +170,14 @@ class TextDocumentServiceHandlerTest {
160
170
161
171
@Test
162
172
fun `didOpen runs on fileOpened` () = runTest {
173
+ sut = TextDocumentServiceHandler (projectRule.project, this )
174
+ advanceUntilIdle()
163
175
val content = " test content"
164
176
val file = withContext(EDT ) {
165
- projectRule.fixture.createFile(" name " , content).also { projectRule.fixture.openFileInEditor(it) }
177
+ projectRule.fixture.createFile(testName.methodName , content).also { projectRule.fixture.openFileInEditor(it) }
166
178
}
167
-
168
- sut.fileOpened(mockk(), file)
169
-
170
179
advanceUntilIdle()
171
- testScope.advanceUntilIdle()
180
+
172
181
val paramsSlot = mutableListOf<DidOpenTextDocumentParams >()
173
182
verify { mockTextDocumentService.didOpen(capture(paramsSlot)) }
174
183
@@ -181,23 +190,26 @@ class TextDocumentServiceHandlerTest {
181
190
182
191
@Test
183
192
fun `didClose runs on fileClosed` () = runTest {
184
- val uri = URI .create(" file:///test/path/file.txt" )
185
- val file = createMockVirtualFile(uri)
186
-
187
- sut.fileClosed(mockk(), file)
193
+ sut = TextDocumentServiceHandler (projectRule.project, this )
194
+ val file = withContext(EDT ) {
195
+ projectRule.fixture.createFile(testName.methodName, " " ).also {
196
+ projectRule.fixture.openFileInEditor(it)
197
+ FileEditorManagerEx .getInstanceEx(projectRule.project).closeAllFiles()
198
+ }
199
+ }
188
200
189
201
advanceUntilIdle()
190
- testScope.advanceUntilIdle()
191
202
val paramsSlot = slot<DidCloseTextDocumentParams >()
192
203
verify { mockTextDocumentService.didClose(capture(paramsSlot)) }
193
204
194
- assertThat(paramsSlot.captured.textDocument.uri).isEqualTo(normalizeFileUri(uri.toString() ))
205
+ assertThat(paramsSlot.captured.textDocument.uri).isEqualTo(file.toNioPath().toUri().toString( ))
195
206
}
196
207
197
208
@Test
198
209
fun `didChange runs on content change events` () = runTest {
210
+ sut = TextDocumentServiceHandler (projectRule.project, this )
199
211
val file = withContext(EDT ) {
200
- projectRule.fixture.createFile(" name " , " " ).also {
212
+ projectRule.fixture.createFile(testName.methodName , " " ).also {
201
213
projectRule.fixture.openFileInEditor(it)
202
214
203
215
writeAction {
@@ -208,7 +220,6 @@ class TextDocumentServiceHandlerTest {
208
220
209
221
// Verify the correct LSP method was called with matching parameters
210
222
advanceUntilIdle()
211
- testScope.advanceUntilIdle()
212
223
val paramsSlot = mutableListOf<DidChangeTextDocumentParams >()
213
224
verify { mockTextDocumentService.didChange(capture(paramsSlot)) }
214
225
@@ -220,6 +231,7 @@ class TextDocumentServiceHandlerTest {
220
231
221
232
@Test
222
233
fun `didSave does not run when URI is empty` () = runTest {
234
+ sut = TextDocumentServiceHandler (projectRule.project, this )
223
235
val document = mockk<Document >()
224
236
val file = createMockVirtualFile(URI .create(" " ))
225
237
@@ -235,14 +247,15 @@ class TextDocumentServiceHandlerTest {
235
247
236
248
sut.beforeDocumentSaving(document)
237
249
238
- testScope. advanceUntilIdle()
250
+ advanceUntilIdle()
239
251
verify(exactly = 0 ) { mockTextDocumentService.didSave(any()) }
240
252
}
241
253
}
242
254
}
243
255
244
256
@Test
245
257
fun `didSave does not run when file is null` () = runTest {
258
+ sut = TextDocumentServiceHandler (projectRule.project, this )
246
259
val document = mockk<Document >()
247
260
248
261
val fileDocumentManager = mockk<FileDocumentManager > {
@@ -254,23 +267,25 @@ class TextDocumentServiceHandlerTest {
254
267
255
268
sut.beforeDocumentSaving(document)
256
269
257
- testScope. advanceUntilIdle()
270
+ advanceUntilIdle()
258
271
verify(exactly = 0 ) { mockTextDocumentService.didSave(any()) }
259
272
}
260
273
}
261
274
262
275
@Test
263
276
fun `didChange ignores non-content change events` () = runTest {
277
+ sut = TextDocumentServiceHandler (projectRule.project, this )
264
278
val nonContentEvent = mockk<VFileEvent >() // Some other type of VFileEvent
265
279
266
280
sut.after(mutableListOf (nonContentEvent))
267
281
268
- testScope. advanceUntilIdle()
282
+ advanceUntilIdle()
269
283
verify(exactly = 0 ) { mockTextDocumentService.didChange(any()) }
270
284
}
271
285
272
286
@Test
273
287
fun `didChange skips files without cached documents` () = runTest {
288
+ sut = TextDocumentServiceHandler (projectRule.project, this )
274
289
val uri = URI .create(" file:///test/path/file.txt" )
275
290
val path = mockk<Path > {
276
291
every { toUri() } returns uri
@@ -291,7 +306,7 @@ class TextDocumentServiceHandlerTest {
291
306
292
307
sut.after(mutableListOf (changeEvent))
293
308
294
- testScope. advanceUntilIdle()
309
+ advanceUntilIdle()
295
310
verify(exactly = 0 ) { mockTextDocumentService.didChange(any()) }
296
311
}
297
312
}
0 commit comments