@@ -389,6 +389,185 @@ defmodule ElixirLS.LanguageServer.Providers.ExecuteCommand.LlmDocsAggregatorTest
389
389
assert String . contains? ( type_result . documentation , "An example type" )
390
390
end
391
391
392
+ test "handles macro documentation with specs" do
393
+ modules = [ "ElixirSenseExample.ModuleWithDocs.some_macro/2" ]
394
+
395
+ assert { :ok , result } = LlmDocsAggregator . execute ( [ modules ] , % { } )
396
+
397
+ assert Map . has_key? ( result , :results )
398
+ assert length ( result . results ) == 1
399
+
400
+ macro_result = hd ( result . results )
401
+ assert macro_result . module == "ElixirSenseExample.ModuleWithDocs"
402
+ assert macro_result . function == "some_macro"
403
+ assert macro_result . arity == 2
404
+ assert macro_result . documentation =~ "An example macro"
405
+
406
+ # Check that metadata is included (since: "1.1.0")
407
+ assert macro_result . documentation =~ "Since"
408
+ assert macro_result . documentation =~ "1.1.0"
409
+ end
410
+
411
+ test "handles macro documentation without arity" do
412
+ modules = [ "ElixirSenseExample.ModuleWithDocs.some_macro" ]
413
+
414
+ assert { :ok , result } = LlmDocsAggregator . execute ( [ modules ] , % { } )
415
+
416
+ assert Map . has_key? ( result , :results )
417
+ # Should find at least the some_macro/2 (from the fixture)
418
+ assert length ( result . results ) >= 1
419
+
420
+ macro_result = result . results |> Enum . find ( & ( & 1 . arity == 2 ) )
421
+ assert macro_result . module == "ElixirSenseExample.ModuleWithDocs"
422
+ assert macro_result . function == "some_macro"
423
+ assert macro_result . arity == 2
424
+ assert macro_result . documentation =~ "An example macro"
425
+ end
426
+
427
+ test "handles macrocallback documentation with arity" do
428
+ modules = [ "ElixirSenseExample.ModuleWithDocs.some_macrocallback/1" ]
429
+
430
+ assert { :ok , result } = LlmDocsAggregator . execute ( [ modules ] , % { } )
431
+
432
+ assert Map . has_key? ( result , :results )
433
+ assert length ( result . results ) == 1
434
+
435
+ macrocallback_result = hd ( result . results )
436
+ assert macrocallback_result . module == "ElixirSenseExample.ModuleWithDocs"
437
+ assert macrocallback_result . callback == "some_macrocallback"
438
+ assert macrocallback_result . arity == 1
439
+ assert macrocallback_result . documentation =~ "An example callback"
440
+
441
+ # Check that we got the documentation (metadata may be formatted differently for callbacks)
442
+ assert macrocallback_result . documentation
443
+ end
444
+
445
+ test "handles macrocallback documentation without arity" do
446
+ modules = [ "ElixirSenseExample.ModuleWithDocs.some_macrocallback" ]
447
+
448
+ assert { :ok , result } = LlmDocsAggregator . execute ( [ modules ] , % { } )
449
+
450
+ assert Map . has_key? ( result , :results )
451
+ assert length ( result . results ) >= 1
452
+
453
+ macrocallback_result = result . results |> Enum . find ( & ( & 1 . arity == 1 ) )
454
+ assert macrocallback_result . module == "ElixirSenseExample.ModuleWithDocs"
455
+ assert macrocallback_result . callback == "some_macrocallback"
456
+ assert macrocallback_result . arity == 1
457
+ assert macrocallback_result . documentation =~ "An example callback"
458
+ end
459
+
460
+ test "verifies macro and macrocallback specs are included" do
461
+ # Test callback spec
462
+ assert { :ok , result } = LlmDocsAggregator . execute ( [ [ "ElixirSenseExample.ModuleWithDocs.some_callback/1" ] ] , % { } )
463
+ assert Map . has_key? ( result , :results )
464
+ assert length ( result . results ) == 1
465
+
466
+ callback_result = hd ( result . results )
467
+ assert Map . has_key? ( callback_result , :spec )
468
+ assert Map . has_key? ( callback_result , :kind )
469
+ assert Map . has_key? ( callback_result , :metadata )
470
+ assert callback_result . spec == "@callback some_callback(integer()) :: atom()"
471
+ assert callback_result . kind == :callback
472
+ assert callback_result . metadata . since == "1.1.0"
473
+
474
+ # Test macrocallback spec
475
+ assert { :ok , result } = LlmDocsAggregator . execute ( [ [ "ElixirSenseExample.ModuleWithDocs.some_macrocallback/1" ] ] , % { } )
476
+ assert Map . has_key? ( result , :results )
477
+ assert length ( result . results ) == 1
478
+
479
+ macrocallback_result = hd ( result . results )
480
+ assert Map . has_key? ( macrocallback_result , :spec )
481
+ assert Map . has_key? ( macrocallback_result , :kind )
482
+ assert Map . has_key? ( macrocallback_result , :metadata )
483
+ assert macrocallback_result . spec == "@macrocallback some_macrocallback(integer()) :: atom()"
484
+ assert macrocallback_result . kind == :macrocallback
485
+ assert macrocallback_result . metadata . since == "1.1.0"
486
+ end
487
+
488
+ test "verifies function documentation contains specs" do
489
+ # Test with ElixirSenseExample.ModuleWithDocs.some_fun/2 which has a @spec
490
+ modules = [ "ElixirSenseExample.ModuleWithDocs.some_fun/2" ]
491
+
492
+ assert { :ok , result } = LlmDocsAggregator . execute ( [ modules ] , % { } )
493
+
494
+ assert Map . has_key? ( result , :results )
495
+ assert length ( result . results ) == 1
496
+
497
+ func_result = hd ( result . results )
498
+ assert func_result . module == "ElixirSenseExample.ModuleWithDocs"
499
+ assert func_result . function == "some_fun"
500
+ assert func_result . arity == 2
501
+ assert func_result . documentation =~ "An example fun"
502
+
503
+ # Verify that specs are included in the documentation
504
+ assert func_result . documentation =~ "**Specs:**"
505
+ assert func_result . documentation =~ "@spec some_fun"
506
+ assert func_result . documentation =~ "```elixir"
507
+ assert func_result . documentation =~ "integer()"
508
+ end
509
+
510
+ test "verifies macro documentation contains specs" do
511
+ # Test with ElixirSenseExample.ModuleWithDocs.some_macro/2 which has a @spec
512
+ modules = [ "ElixirSenseExample.ModuleWithDocs.some_macro/2" ]
513
+
514
+ assert { :ok , result } = LlmDocsAggregator . execute ( [ modules ] , % { } )
515
+
516
+ assert Map . has_key? ( result , :results )
517
+ assert length ( result . results ) == 1
518
+
519
+ macro_result = hd ( result . results )
520
+ assert macro_result . module == "ElixirSenseExample.ModuleWithDocs"
521
+ assert macro_result . function == "some_macro"
522
+ assert macro_result . arity == 2
523
+ assert macro_result . documentation =~ "An example macro"
524
+
525
+ # Verify that specs are included in the macro documentation
526
+ assert macro_result . documentation =~ "**Specs:**"
527
+ assert macro_result . documentation =~ "@spec some_macro"
528
+ assert macro_result . documentation =~ "```elixir"
529
+ assert macro_result . documentation =~ "Macro.t()"
530
+ end
531
+
532
+ test "verifies function specs are properly formatted" do
533
+ # Test function without arity to get all arities
534
+ modules = [ "ElixirSenseExample.ModuleWithDocs.some_fun" ]
535
+
536
+ assert { :ok , result } = LlmDocsAggregator . execute ( [ modules ] , % { } )
537
+
538
+ assert Map . has_key? ( result , :results )
539
+ assert length ( result . results ) >= 1
540
+
541
+ # Find the result with arity 2 (which has specs)
542
+ func_result = Enum . find ( result . results , & ( & 1 . arity == 2 ) )
543
+ assert func_result
544
+
545
+ # Verify spec formatting
546
+ assert func_result . documentation =~ "**Specs:**"
547
+ assert func_result . documentation =~ "```elixir"
548
+ assert func_result . documentation =~ "@spec some_fun(integer(), integer() | nil) :: integer()"
549
+ end
550
+
551
+ test "verifies macro specs are properly formatted" do
552
+ # Test macro without arity to get all arities
553
+ modules = [ "ElixirSenseExample.ModuleWithDocs.some_macro" ]
554
+
555
+ assert { :ok , result } = LlmDocsAggregator . execute ( [ modules ] , % { } )
556
+
557
+ assert Map . has_key? ( result , :results )
558
+ assert length ( result . results ) >= 1
559
+
560
+ # Find the result with arity 2 (which has specs)
561
+ macro_result = Enum . find ( result . results , & ( & 1 . arity == 2 ) )
562
+ assert macro_result
563
+
564
+ # Verify spec formatting for macro
565
+ assert macro_result . documentation =~ "**Specs:**"
566
+ assert macro_result . documentation =~ "```elixir"
567
+ assert macro_result . documentation =~ "@spec some_macro(Macro.t(), Macro.t() | nil) :: Macro.t()"
568
+ end
569
+
570
+
392
571
test "returns error for invalid arguments" do
393
572
# Test with non-list argument
394
573
assert { :ok , result } = LlmDocsAggregator . execute ( "String" , % { } )
0 commit comments