@@ -186,28 +186,6 @@ suite("CommentCompletion Test Suite", () => {
186
186
] ) ;
187
187
} ) ;
188
188
189
- test ( "Comment Insertion" , async ( ) => {
190
- const { document, positions } = await openDocument ( `
191
- /// 1️⃣
192
- func foo(bar: Int, baz: String) -> Data throws { return Data() }` ) ;
193
- const position = positions [ "1️⃣" ] ;
194
-
195
- const editor = await vscode . window . showTextDocument ( document ) ;
196
- await provider . insert ( editor , position . line + 1 ) ;
197
-
198
- assert . deepEqual (
199
- editor . document . getText ( ) ,
200
- `
201
- /// !
202
- /// !
203
- /// - Parameters:
204
- /// - bar: !
205
- /// - baz: !
206
- /// - Returns: !
207
- func foo(bar: Int, baz: String) -> Data throws { return Data() }` . replace ( / ! / g, "" )
208
- ) ; // ! ensures trailing white space is not trimmed when this file is formatted.
209
- } ) ;
210
-
211
189
test ( "Comment completion on function with default parameter using #function" , async ( ) => {
212
190
const { document, positions } = await openDocument ( `
213
191
/// 1️⃣
@@ -256,9 +234,209 @@ suite("CommentCompletion Test Suite", () => {
256
234
/// - Returns: $3` ) ,
257
235
] ) ;
258
236
} ) ;
237
+
238
+ test ( "Comment insertion" , async ( ) => {
239
+ const { document, positions } = await openDocument ( `
240
+ /// 1️⃣
241
+ func foo(bar: Int, baz: String) -> Data throws { return Data() }` ) ;
242
+ const position = positions [ "1️⃣" ] ;
243
+
244
+ const editor = await vscode . window . showTextDocument ( document ) ;
245
+ await provider . insert ( editor , position . line + 1 ) ;
246
+
247
+ assert . deepEqual (
248
+ editor . document . getText ( ) ,
249
+ `
250
+ /// !
251
+ /// !
252
+ /// - Parameters:
253
+ /// - bar: !
254
+ /// - baz: !
255
+ /// - Returns: !
256
+ func foo(bar: Int, baz: String) -> Data throws { return Data() }` . replace ( / ! / g, "" )
257
+ ) ; // ! ensures trailing white space is not trimmed when this file is formatted.
258
+ } ) ;
259
+
260
+ suite ( "Function Comment Completion - Edge Cases" , ( ) => {
261
+ test ( "Comment completion on generic function" , async ( ) => {
262
+ const { document, positions } = await openDocument ( `
263
+ /// 1️⃣
264
+ func foo<T>(bar: T) -> T { return bar }` ) ;
265
+ const position = positions [ "1️⃣" ] ;
266
+
267
+ const items = await provider . functionCommentCompletion . provideCompletionItems (
268
+ document ,
269
+ position
270
+ ) ;
271
+ assert . deepEqual ( items , [
272
+ expectedCompletionItem ( ` $1
273
+ /// - Parameter bar: $2
274
+ /// - Returns: $3` ) ,
275
+ ] ) ;
276
+ } ) ;
277
+
278
+ test ( "Comment completion on generic function with multiple type parameters" , async ( ) => {
279
+ const { document, positions } = await openDocument ( `
280
+ /// 1️⃣
281
+ func foo<T, U>(bar: T, baz: U) -> T { return bar }` ) ;
282
+ const position = positions [ "1️⃣" ] ;
283
+
284
+ const items = await provider . functionCommentCompletion . provideCompletionItems (
285
+ document ,
286
+ position
287
+ ) ;
288
+ assert . deepEqual ( items , [
289
+ expectedCompletionItem ( ` $1
290
+ /// - Parameters:
291
+ /// - bar: $2
292
+ /// - baz: $3
293
+ /// - Returns: $4` ) ,
294
+ ] ) ;
295
+ } ) ;
296
+
297
+ test ( "Comment completion on generic function with constraints" , async ( ) => {
298
+ const { document, positions } = await openDocument ( `
299
+ /// 1️⃣
300
+ func foo<T: Equatable>(bar: T) -> T { return bar }` ) ;
301
+ const position = positions [ "1️⃣" ] ;
302
+
303
+ const items = await provider . functionCommentCompletion . provideCompletionItems (
304
+ document ,
305
+ position
306
+ ) ;
307
+ assert . deepEqual ( items , [
308
+ expectedCompletionItem ( ` $1
309
+ /// - Parameter bar: $2
310
+ /// - Returns: $3` ) ,
311
+ ] ) ;
312
+ } ) ;
313
+
314
+ test ( "Comment completion on malformed function - no function name" , async ( ) => {
315
+ const { document, positions } = await openDocument ( `
316
+ /// 1️⃣
317
+ func (bar: Int) {}` ) ;
318
+ const position = positions [ "1️⃣" ] ;
319
+
320
+ const items = await provider . functionCommentCompletion . provideCompletionItems (
321
+ document ,
322
+ position
323
+ ) ;
324
+ assert . deepEqual ( items , [
325
+ expectedCompletionItem ( ` $1
326
+ /// - Parameter bar: $2` ) ,
327
+ ] ) ;
328
+ } ) ;
329
+
330
+ test ( "Comment completion on malformed function - no parameter name" , async ( ) => {
331
+ const { document, positions } = await openDocument ( `
332
+ /// 1️⃣
333
+ func foo(: Int) {}` ) ;
334
+ const position = positions [ "1️⃣" ] ;
335
+
336
+ const items = await provider . functionCommentCompletion . provideCompletionItems (
337
+ document ,
338
+ position
339
+ ) ;
340
+ assert . deepEqual ( items , [
341
+ expectedCompletionItem ( ` $1
342
+ /// - Parameter : $2` ) ,
343
+ ] ) ;
344
+ } ) ;
345
+
346
+ test ( "Comment completion on malformed function - unclosed parameter list" , async ( ) => {
347
+ const { document, positions } = await openDocument ( `
348
+ /// 1️⃣
349
+ func foo(bar: Int` ) ;
350
+ const position = positions [ "1️⃣" ] ;
351
+
352
+ const items = await provider . functionCommentCompletion . provideCompletionItems (
353
+ document ,
354
+ position
355
+ ) ;
356
+ assert . deepEqual ( items , undefined ) ;
357
+ } ) ;
358
+
359
+ test ( "Comment completion on malformed generic function - unclosed generic list" , async ( ) => {
360
+ const { document, positions } = await openDocument ( `
361
+ /// 1️⃣
362
+ func foo<T(bar: Int) {}` ) ;
363
+ const position = positions [ "1️⃣" ] ;
364
+
365
+ const items = await provider . functionCommentCompletion . provideCompletionItems (
366
+ document ,
367
+ position
368
+ ) ;
369
+ assert . deepEqual ( items , undefined ) ;
370
+ } ) ;
371
+
372
+ test ( "Comment completion on init method" , async ( ) => {
373
+ const { document, positions } = await openDocument ( `
374
+ /// 1️⃣
375
+ init(bar: Int) {}` ) ;
376
+ const position = positions [ "1️⃣" ] ;
377
+
378
+ const items = await provider . functionCommentCompletion . provideCompletionItems (
379
+ document ,
380
+ position
381
+ ) ;
382
+ assert . deepEqual ( items , [
383
+ expectedCompletionItem ( ` $1
384
+ /// - Parameter bar: $2` ) ,
385
+ ] ) ;
386
+ } ) ;
387
+
388
+ test ( "Comment completion on throwing init method" , async ( ) => {
389
+ const { document, positions } = await openDocument ( `
390
+ /// 1️⃣
391
+ init(bar: Int) throws {}` ) ;
392
+ const position = positions [ "1️⃣" ] ;
393
+
394
+ const items = await provider . functionCommentCompletion . provideCompletionItems (
395
+ document ,
396
+ position
397
+ ) ;
398
+ assert . deepEqual ( items , [
399
+ expectedCompletionItem ( ` $1
400
+ /// - Parameter bar: $2
401
+ /// - Throws: $3` ) ,
402
+ ] ) ;
403
+ } ) ;
404
+ } ) ;
259
405
} ) ;
260
406
261
407
suite ( "Document Comment Completion" , ( ) => {
408
+ test ( "Should not provide completions on first line" , async ( ) => {
409
+ const { document, positions } = await openDocument ( `1️⃣
410
+ public func foo() {}` ) ;
411
+
412
+ const position = positions [ "1️⃣" ] ;
413
+ const items = await provider . docCommentCompletion . provideCompletionItems (
414
+ document ,
415
+ position
416
+ ) ;
417
+
418
+ assert . strictEqual ( items , undefined , "Should not provide completions on first line" ) ;
419
+ } ) ;
420
+
421
+ test ( "Should not provide completions when previous line is not a comment" , async ( ) => {
422
+ const { document, positions } = await openDocument ( `
423
+ public func bar() {}
424
+ 1️⃣
425
+ public func foo() {}` ) ;
426
+
427
+ const position = positions [ "1️⃣" ] ;
428
+ const items = await provider . docCommentCompletion . provideCompletionItems (
429
+ document ,
430
+ position
431
+ ) ;
432
+
433
+ assert . strictEqual (
434
+ items ,
435
+ undefined ,
436
+ "Should not provide completions when previous line is not a comment"
437
+ ) ;
438
+ } ) ;
439
+
262
440
test ( "Should continue a documentation comment block on new line" , async ( ) => {
263
441
const { document, positions } = await openDocument ( `
264
442
/// aaa
@@ -304,6 +482,141 @@ suite("CommentCompletion Test Suite", () => {
304
482
305
483
assert . deepEqual ( documentText , originalText , "Document text should not change" ) ;
306
484
} ) ;
485
+
486
+ test ( "Should handle case when no active text editor" , async ( ) => {
487
+ const { document, positions } = await openDocument ( `
488
+ /// aaa
489
+ 1️⃣
490
+ public func foo() {}` ) ;
491
+
492
+ const position = positions [ "1️⃣" ] ;
493
+
494
+ // Close all editors to simulate no active text editor
495
+ await vscode . commands . executeCommand ( Workbench . ACTION_CLOSEALLEDITORS ) ;
496
+
497
+ // This should not throw an error
498
+ const items = await provider . docCommentCompletion . provideCompletionItems (
499
+ document ,
500
+ position
501
+ ) ;
502
+
503
+ assert . equal (
504
+ items ,
505
+ undefined ,
506
+ "Should not provide completions when no active text editor"
507
+ ) ;
508
+ } ) ;
509
+
510
+ test ( "Should specifically test continueExistingDocCommentBlock with no active editor" , async ( ) => {
511
+ const { document, positions } = await openDocument ( `
512
+ /// aaa
513
+ 1️⃣
514
+ public func foo() {}` ) ;
515
+
516
+ const position = positions [ "1️⃣" ] ;
517
+
518
+ // Close all editors to simulate no active text editor
519
+ await vscode . commands . executeCommand ( Workbench . ACTION_CLOSEALLEDITORS ) ;
520
+
521
+ // Store original activeTextEditor property
522
+ const originalActiveTextEditor = Object . getOwnPropertyDescriptor (
523
+ vscode . window ,
524
+ "activeTextEditor"
525
+ ) ;
526
+
527
+ // Mock the activeTextEditor to be null for the specific method call
528
+ Object . defineProperty ( vscode . window , "activeTextEditor" , {
529
+ get : ( ) => null ,
530
+ configurable : true ,
531
+ } ) ;
532
+
533
+ try {
534
+ // Call the method directly to ensure the branch is covered
535
+ await provider . docCommentCompletion [ "continueExistingDocCommentBlock" ] (
536
+ document ,
537
+ position
538
+ ) ;
539
+
540
+ // If we get here, the method didn't throw an error, which is what we want
541
+ assert . ok ( true , "Method should not throw when there's no active editor" ) ;
542
+ } finally {
543
+ // Restore the original activeTextEditor property
544
+ if ( originalActiveTextEditor ) {
545
+ Object . defineProperty (
546
+ vscode . window ,
547
+ "activeTextEditor" ,
548
+ originalActiveTextEditor
549
+ ) ;
550
+ }
551
+ }
552
+ } ) ;
553
+
554
+ test ( "Should handle when previous line has // but not ///" , async ( ) => {
555
+ const { document, positions } = await openDocument ( `
556
+ // aaa
557
+ 1️⃣
558
+ public func foo() {}` ) ;
559
+
560
+ const position = positions [ "1️⃣" ] ;
561
+ const items = await provider . docCommentCompletion . provideCompletionItems (
562
+ document ,
563
+ position
564
+ ) ;
565
+
566
+ assert . strictEqual (
567
+ items ,
568
+ undefined ,
569
+ "Should not provide completions when previous line is not a doc comment"
570
+ ) ;
571
+ } ) ;
572
+
573
+ test ( "Should handle when line has content after //" , async ( ) => {
574
+ const { document, positions } = await openDocument ( `
575
+ /// aaa
576
+ 1️⃣// bbb
577
+ public func foo() {}` ) ;
578
+
579
+ const position = positions [ "1️⃣" ] ;
580
+
581
+ // Show the document to ensure there's an active editor
582
+ await vscode . window . showTextDocument ( document ) ;
583
+
584
+ const items = await provider . docCommentCompletion . provideCompletionItems (
585
+ document ,
586
+ position
587
+ ) ;
588
+
589
+ // Check that the line was modified
590
+ const lineText = document . lineAt ( position . line ) . text ;
591
+ assert . strictEqual ( lineText . trim ( ) , "/// bbb" , "Should convert // to ///" ) ;
592
+
593
+ assert . ok ( items , "Should provide completions" ) ;
594
+ assert . strictEqual ( items . length , 1 , "Should provide one completion" ) ;
595
+ } ) ;
596
+
597
+ test ( "Should handle when line has no match for comment continuation" , async ( ) => {
598
+ const { document, positions } = await openDocument ( `
599
+ /// aaa
600
+ 1️⃣let x = 1
601
+ public func foo() {}` ) ;
602
+
603
+ const position = positions [ "1️⃣" ] ;
604
+
605
+ // Show the document to ensure there's an active editor
606
+ await vscode . window . showTextDocument ( document ) ;
607
+
608
+ const originalText = document . getText ( ) ;
609
+ const items = await provider . docCommentCompletion . provideCompletionItems (
610
+ document ,
611
+ position
612
+ ) ;
613
+
614
+ // Document should not be modified
615
+ assert . strictEqual ( document . getText ( ) , originalText , "Document should not be modified" ) ;
616
+
617
+ assert . ok ( items , "Should provide completions" ) ;
618
+ assert . strictEqual ( items . length , 1 , "Should provide one completion" ) ;
619
+ } ) ;
307
620
} ) ;
308
621
309
622
function expectedCompletionItem ( snippet : string ) : vscode . CompletionItem {
0 commit comments