Skip to content

Commit 0e066b1

Browse files
CopilotTheAngryByrd
andcommitted
Add comprehensive tests for Active Pattern Find All References
Tests verify that: - Finding references for 'Even' returns only 'Even', not 'Odd' - Finding references for 'Odd' returns only 'Odd', not 'Even' - Partial Active Patterns work correctly - Multi-case patterns (3+ cases) correctly filter each case independently Co-authored-by: TheAngryByrd <[email protected]>
1 parent 7ae7a11 commit 0e066b1

File tree

2 files changed

+164
-4
lines changed

2 files changed

+164
-4
lines changed

src/FsAutoComplete.Core/Commands.fs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -780,7 +780,7 @@ module Commands =
780780
let symbolUses = tyRes.GetCheckResults.GetUsesOfSymbolInFile(symbol, ct)
781781

782782
let symbolUses: _ seq =
783-
let filtered =
783+
let baseFiltered: _ seq =
784784
if includeDeclarations then
785785
symbolUses
786786
else
@@ -790,11 +790,11 @@ module Commands =
790790
// We need to filter to only the symbol that matches our query
791791
match symbolUse.Symbol with
792792
| :? FSharpActivePatternCase as apc ->
793-
filtered |> Seq.filter (fun u ->
793+
baseFiltered |> Seq.filter (fun u ->
794794
match u.Symbol with
795795
| :? FSharpActivePatternCase as foundApc -> foundApc.Name = apc.Name
796796
| _ -> false)
797-
| _ -> filtered
797+
| _ -> baseFiltered
798798

799799
let ranges = symbolUses |> Seq.map (fun u -> u.Range)
800800
// Note: tryAdjustRanges is designed to only be able to fail iff `errorOnFailureToFixRange` is `true`

test/FsAutoComplete.Tests.Lsp/FindReferencesTests.fs

Lines changed: 161 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -628,13 +628,173 @@ let private rangeTests state =
628628
}
629629
""" ])
630630

631+
/// Tests specifically for Active Pattern reference filtering
632+
let private activePatternTests state =
633+
let checkRanges server sourceWithCursors =
634+
async {
635+
let (source, cursors) = sourceWithCursors |> extractRanges
636+
let! (doc, diags) = server |> Server.createUntitledDocument source
637+
638+
use doc = doc
639+
Expect.hasLength diags 0 "There should be no diags"
640+
641+
let request: ReferenceParams =
642+
{ TextDocument = doc.TextDocumentIdentifier
643+
Position = cursors.Cursor.Value
644+
Context = { IncludeDeclaration = true }
645+
WorkDoneToken = None
646+
PartialResultToken = None }
647+
648+
let! refs = doc.Server.Server.TextDocumentReferences request
649+
650+
let refs =
651+
refs
652+
|> Flip.Expect.wantOk "Should not fail"
653+
|> Flip.Expect.wantSome "Should return references"
654+
|> Array.sortBy (fun l -> l.Range.Start)
655+
656+
Expect.all refs (fun r -> r.Uri = doc.Uri) "there should only be references in current doc"
657+
658+
let expected =
659+
Array.append cursors.Declarations cursors.Usages
660+
|> Array.sortBy (fun r -> r.Start)
661+
|> Array.map (mkLocation doc)
662+
663+
if refs <> expected then
664+
Expect.equal (markRanges source refs) (markRanges source expected) "Should find correct references"
665+
}
666+
667+
serverTestList "active patterns" state defaultConfigDto None (fun server ->
668+
[ testCaseAsync "can find references for Active Pattern Case 'Even' without including 'Odd'"
669+
<| checkRanges
670+
server
671+
"""
672+
module MyModule =
673+
let (|$D<Even>D$|Odd|) value =
674+
if value % 2 = 0 then $<Even>$ else Odd
675+
676+
open MyModule
677+
let _ =
678+
match 42 with
679+
| $<Ev$0en>$ -> ()
680+
| Odd -> ()
681+
let _ =
682+
match 42 with
683+
| MyModule.$<Even>$ -> ()
684+
| MyModule.Odd -> ()
685+
"""
686+
testCaseAsync "can find references for Active Pattern Case 'Odd' without including 'Even'"
687+
<| checkRanges
688+
server
689+
"""
690+
module MyModule =
691+
let (|Even|$D<Odd>D$|) value =
692+
if value % 2 = 0 then Even else $<Odd>$
693+
694+
open MyModule
695+
let _ =
696+
match 42 with
697+
| Even -> ()
698+
| $<Od$0d>$ -> ()
699+
let _ =
700+
match 42 with
701+
| MyModule.Even -> ()
702+
| MyModule.$<Odd>$ -> ()
703+
"""
704+
testCaseAsync "can find references for Partial Active Pattern"
705+
<| checkRanges
706+
server
707+
"""
708+
module MyModule =
709+
let (|$D<ParseInt>D$|_|) (str: string) =
710+
let success, i = System.Int32.TryParse str
711+
if success then Some i else None
712+
713+
open MyModule
714+
let _ =
715+
match "42" with
716+
| $<ParseI$0nt>$ i -> i
717+
| _ -> 0
718+
let _ =
719+
match "test" with
720+
| MyModule.$<ParseInt>$ i -> i
721+
| _ -> 0
722+
"""
723+
testCaseAsync "can find references for three-case Active Pattern - first case"
724+
<| checkRanges
725+
server
726+
"""
727+
module MyModule =
728+
let (|$D<Positive>D$|Zero|Negative|) value =
729+
if value > 0 then $<Positive>$
730+
elif value = 0 then Zero
731+
else Negative
732+
733+
open MyModule
734+
let _ =
735+
match 42 with
736+
| $<Positiv$0e>$ -> "positive"
737+
| Zero -> "zero"
738+
| Negative -> "negative"
739+
let _ =
740+
match -5 with
741+
| MyModule.$<Positive>$ -> "positive"
742+
| MyModule.Zero -> "zero"
743+
| MyModule.Negative -> "negative"
744+
"""
745+
testCaseAsync "can find references for three-case Active Pattern - middle case"
746+
<| checkRanges
747+
server
748+
"""
749+
module MyModule =
750+
let (|Positive|$D<Zero>D$|Negative|) value =
751+
if value > 0 then Positive
752+
elif value = 0 then $<Zero>$
753+
else Negative
754+
755+
open MyModule
756+
let _ =
757+
match 42 with
758+
| Positive -> "positive"
759+
| $<Zer$0o>$ -> "zero"
760+
| Negative -> "negative"
761+
let _ =
762+
match -5 with
763+
| MyModule.Positive -> "positive"
764+
| MyModule.$<Zero>$ -> "zero"
765+
| MyModule.Negative -> "negative"
766+
"""
767+
testCaseAsync "can find references for three-case Active Pattern - last case"
768+
<| checkRanges
769+
server
770+
"""
771+
module MyModule =
772+
let (|Positive|Zero|$D<Negative>D$|) value =
773+
if value > 0 then Positive
774+
elif value = 0 then Zero
775+
else $<Negative>$
776+
777+
open MyModule
778+
let _ =
779+
match 42 with
780+
| Positive -> "positive"
781+
| Zero -> "zero"
782+
| $<Negativ$0e>$ -> "negative"
783+
let _ =
784+
match -5 with
785+
| MyModule.Positive -> "positive"
786+
| MyModule.Zero -> "zero"
787+
| MyModule.$<Negative>$ -> "negative"
788+
""" ])
789+
631790
let tests state =
632791
testList
633792
"Find All References tests"
634793
[ scriptTests state
635794
solutionTests state
636795
untitledTests state
637-
rangeTests state ]
796+
rangeTests state
797+
activePatternTests state ]
638798

639799

640800
let tryFixupRangeTests (sourceTextFactory: ISourceTextFactory) =

0 commit comments

Comments
 (0)