@@ -186,28 +186,6 @@ suite("CommentCompletion Test Suite", () => {
186186 ] ) ;
187187 } ) ;
188188
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-
211189 test ( "Comment completion on function with default parameter using #function" , async ( ) => {
212190 const { document, positions } = await openDocument ( `
213191 /// 1️⃣
@@ -256,9 +234,209 @@ suite("CommentCompletion Test Suite", () => {
256234/// - Returns: $3` ) ,
257235 ] ) ;
258236 } ) ;
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+ } ) ;
259405 } ) ;
260406
261407 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+
262440 test ( "Should continue a documentation comment block on new line" , async ( ) => {
263441 const { document, positions } = await openDocument ( `
264442 /// aaa
@@ -304,6 +482,141 @@ suite("CommentCompletion Test Suite", () => {
304482
305483 assert . deepEqual ( documentText , originalText , "Document text should not change" ) ;
306484 } ) ;
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+ } ) ;
307620 } ) ;
308621
309622 function expectedCompletionItem ( snippet : string ) : vscode . CompletionItem {
0 commit comments