From 7f5d912654d8b3c3ed682f69cc6283a9f684ee79 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Thu, 12 Mar 2026 01:00:39 +0000 Subject: [PATCH 1/5] test: add coverage for Seq.span, catOptions, choice1s/2s, partitionChoices, groupNeighboursBy, equalsWith; fix ptest for Seq.tail - Activate the long-pending ptest for Seq.tail on empty input: the test was broken because `Seq.tail []` returns a lazy seq and `|> ignore` never enumerates it. Fix by calling `|> Seq.toList |> ignore` so the ArgumentException is actually raised. - Add 11 new deterministic tests covering previously-untested Seq functions: Seq.span, Seq.groupNeighboursBy, Seq.catOptions, Seq.choice1s, Seq.choice2s, Seq.partitionChoices, and Seq.equalsWith. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- tests/FSharpx.Collections.Tests/SeqTests.fs | 92 ++++++++++++++++++++- 1 file changed, 90 insertions(+), 2 deletions(-) diff --git a/tests/FSharpx.Collections.Tests/SeqTests.fs b/tests/FSharpx.Collections.Tests/SeqTests.fs index 1d334e63..a9a31e8f 100644 --- a/tests/FSharpx.Collections.Tests/SeqTests.fs +++ b/tests/FSharpx.Collections.Tests/SeqTests.fs @@ -156,7 +156,9 @@ module SeqTests = |> Expect.sequenceEqual "tail" (List.toSeq [ 2; 3; 4 ]) } - ptest "I should not be able to get the tail of a empty sequence" { Expect.throwsT<_> "empty tail" (fun () -> Seq.tail [] |> ignore) } + test "I should not be able to get the tail of an empty sequence" { + Expect.throwsT "empty tail" (fun () -> Seq.tail [] |> Seq.toList |> ignore) + } test "I should be able to get the tail of a empty sequence without a fail" { Seq.tailNoFail [] |> Expect.sequenceEqual "tailNoFail" Seq.empty @@ -244,4 +246,90 @@ module SeqTests = Expect.sequenceEqual "" a (a |> Seq.intersperse ',') } - testPropertyWithConfig config10k "I should interperse always 2n-1 elements" intersperse ] + testPropertyWithConfig config10k "I should interperse always 2n-1 elements" intersperse + + test "span should split sequence at predicate boundary" { + let before, after = Seq.span (fun x -> x < 5.0) data + Expect.sequenceEqual "before" [ 1.; 2.; 3.; 4. ] (before |> Seq.toList) + Expect.sequenceEqual "after" [ 5.; 6.; 7.; 8.; 9.; 10. ] (after |> Seq.toList) + } + + test "span on empty sequence yields two empty sequences" { + let before, after = Seq.span (fun (x: float) -> x < 5.0) Seq.empty + Expect.sequenceEqual "before" [] (before |> Seq.toList) + Expect.sequenceEqual "after" [] (after |> Seq.toList) + } + + test "span where predicate is always true returns whole sequence and empty" { + let before, after = Seq.span (fun x -> x < 100.0) data + Expect.sequenceEqual "before" data (before |> Seq.toList) + Expect.sequenceEqual "after" [] (after |> Seq.toList) + } + + test "groupNeighboursBy groups consecutive equal elements" { + let input = [ 1; 1; 2; 2; 2; 1; 3 ] + let groups = Seq.groupNeighboursBy id input |> Seq.toList + let keys = groups |> List.map fst + let values = groups |> List.map(snd >> Seq.toList) + Expect.equal "keys" [ 1; 2; 1; 3 ] keys + Expect.equal "groups" [ [ 1; 1 ]; [ 2; 2; 2 ]; [ 1 ]; [ 3 ] ] values + } + + test "groupNeighboursBy on empty sequence returns empty" { + let groups = Seq.groupNeighboursBy id (Seq.empty) |> Seq.toList + Expect.equal "empty groups" [] groups + } + + test "groupNeighboursBy with projection" { + let input = [ "a1"; "a2"; "b1"; "b2"; "a3" ] + + let groups = Seq.groupNeighboursBy (fun (s: string) -> s.[0]) input |> Seq.toList + + let keys = groups |> List.map fst + Expect.equal "keys" [ 'a'; 'b'; 'a' ] keys + } + + test "catOptions returns only Some values" { + let input = [ Some 1; None; Some 2; None; Some 3 ] + let result = Seq.catOptions input |> Seq.toList + Expect.equal "catOptions" [ 1; 2; 3 ] result + } + + test "catOptions on all None returns empty" { + let input = [ None; None; None ] + let result = Seq.catOptions input |> Seq.toList + Expect.equal "catOptions all None" [] result + } + + test "choice1s extracts Choice1Of2 values" { + let input: Choice list = + [ Choice1Of2 1; Choice2Of2 "a"; Choice1Of2 2; Choice2Of2 "b" ] + + let result = Seq.choice1s input |> Seq.toList + Expect.equal "choice1s" [ 1; 2 ] result + } + + test "choice2s extracts Choice2Of2 values" { + let input: Choice list = + [ Choice1Of2 1; Choice2Of2 "a"; Choice1Of2 2; Choice2Of2 "b" ] + + let result = Seq.choice2s input |> Seq.toList + Expect.equal "choice2s" [ "a"; "b" ] result + } + + test "partitionChoices splits into two sequences" { + let input: Choice list = + [ Choice1Of2 1; Choice2Of2 "a"; Choice1Of2 2; Choice2Of2 "b" ] + + let lefts, rights = Seq.partitionChoices input + Expect.equal "lefts" [ 1; 2 ] (lefts |> Seq.toList) + Expect.equal "rights" [ "a"; "b" ] (rights |> Seq.toList) + } + + test "equalsWith returns true for equal sequences" { Expect.isTrue "equalsWith" (Seq.equalsWith (=) [ 1; 2; 3 ] [ 1; 2; 3 ]) } + + test "equalsWith returns false for different sequences" { Expect.isFalse "equalsWith" (Seq.equalsWith (=) [ 1; 2; 3 ] [ 1; 2; 4 ]) } + + test "equalsWith returns false for sequences of different lengths" { + Expect.isFalse "equalsWith" (Seq.equalsWith (=) [ 1; 2 ] [ 1; 2; 3 ]) + } ] From c4c092117ed480f53b05c726645c5e273760ef24 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Thu, 12 Mar 2026 01:07:41 +0000 Subject: [PATCH 2/5] ci: trigger checks From 7bd2c39d5f2f1b770457387f036d4478397f85a2 Mon Sep 17 00:00:00 2001 From: Grzegorz Dziadkiewicz Date: Sat, 14 Mar 2026 15:40:36 +0100 Subject: [PATCH 3/5] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- tests/FSharpx.Collections.Tests/SeqTests.fs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/FSharpx.Collections.Tests/SeqTests.fs b/tests/FSharpx.Collections.Tests/SeqTests.fs index a9a31e8f..c606e7a5 100644 --- a/tests/FSharpx.Collections.Tests/SeqTests.fs +++ b/tests/FSharpx.Collections.Tests/SeqTests.fs @@ -286,7 +286,9 @@ module SeqTests = let groups = Seq.groupNeighboursBy (fun (s: string) -> s.[0]) input |> Seq.toList let keys = groups |> List.map fst + let values = groups |> List.map (snd >> Seq.toList) Expect.equal "keys" [ 'a'; 'b'; 'a' ] keys + Expect.equal "groups" [ [ "a1"; "a2" ]; [ "b1"; "b2" ]; [ "a3" ] ] values } test "catOptions returns only Some values" { From 3234f772ae0099c78bd7ba588ee3bea6684dd310 Mon Sep 17 00:00:00 2001 From: Grzegorz Dziadkiewicz Date: Sat, 14 Mar 2026 17:03:10 +0100 Subject: [PATCH 4/5] Apply suggestions from code review Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- tests/FSharpx.Collections.Tests/SeqTests.fs | 31 ++++++--------------- 1 file changed, 8 insertions(+), 23 deletions(-) diff --git a/tests/FSharpx.Collections.Tests/SeqTests.fs b/tests/FSharpx.Collections.Tests/SeqTests.fs index 0fab0c46..aaf60375 100644 --- a/tests/FSharpx.Collections.Tests/SeqTests.fs +++ b/tests/FSharpx.Collections.Tests/SeqTests.fs @@ -291,19 +291,7 @@ module SeqTests = Expect.equal "groups" [ [ "a1"; "a2" ]; [ "b1"; "b2" ]; [ "a3" ] ] values } - test "catOptions returns only Some values" { - let input = [ Some 1; None; Some 2; None; Some 3 ] - let result = Seq.catOptions input |> Seq.toList - Expect.equal "catOptions" [ 1; 2; 3 ] result - } - - test "catOptions on all None returns empty" { - let input = [ None; None; None ] - let result = Seq.catOptions input |> Seq.toList - Expect.equal "catOptions all None" [] result - } - - test "choice1s extracts Choice1Of2 values" { + test "choice1s extracts only Choice1Of2 values" { let input: Choice list = [ Choice1Of2 1; Choice2Of2 "a"; Choice1Of2 2; Choice2Of2 "b" ] @@ -311,7 +299,7 @@ module SeqTests = Expect.equal "choice1s" [ 1; 2 ] result } - test "choice2s extracts Choice2Of2 values" { + test "choice2s extracts Choice2Of2 values from sequence" { let input: Choice list = [ Choice1Of2 1; Choice2Of2 "a"; Choice1Of2 2; Choice2Of2 "b" ] @@ -319,21 +307,18 @@ module SeqTests = Expect.equal "choice2s" [ "a"; "b" ] result } - test "partitionChoices splits into two sequences" { - let input: Choice list = - [ Choice1Of2 1; Choice2Of2 "a"; Choice1Of2 2; Choice2Of2 "b" ] + test "partitionChoices with empty input returns empty sequences" { + let input: Choice list = [] let lefts, rights = Seq.partitionChoices input - Expect.equal "lefts" [ 1; 2 ] (lefts |> Seq.toList) - Expect.equal "rights" [ "a"; "b" ] (rights |> Seq.toList) + Expect.equal "lefts empty" [] (lefts |> Seq.toList) + Expect.equal "rights empty" [] (rights |> Seq.toList) } - test "equalsWith returns true for equal sequences" { Expect.isTrue "equalsWith" (Seq.equalsWith (=) [ 1; 2; 3 ] [ 1; 2; 3 ]) } - - test "equalsWith returns false for different sequences" { Expect.isFalse "equalsWith" (Seq.equalsWith (=) [ 1; 2; 3 ] [ 1; 2; 4 ]) } - test "equalsWith returns false for sequences of different lengths" { Expect.isFalse "equalsWith" (Seq.equalsWith (=) [ 1; 2 ] [ 1; 2; 3 ]) + } + test "cons prepends an element to a seq" { Seq.cons 0 [ 1; 2; 3 ] |> Expect.sequenceEqual "cons" (List.toSeq [ 0; 1; 2; 3 ]) From 0490b949cb85e6db69ddd77716c62abe42530484 Mon Sep 17 00:00:00 2001 From: Grzegorz Dziadkiewicz Date: Sun, 15 Mar 2026 16:05:33 +0100 Subject: [PATCH 5/5] Format code --- tests/FSharpx.Collections.Tests/SeqTests.fs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/FSharpx.Collections.Tests/SeqTests.fs b/tests/FSharpx.Collections.Tests/SeqTests.fs index aaf60375..45ce65be 100644 --- a/tests/FSharpx.Collections.Tests/SeqTests.fs +++ b/tests/FSharpx.Collections.Tests/SeqTests.fs @@ -286,7 +286,7 @@ module SeqTests = let groups = Seq.groupNeighboursBy (fun (s: string) -> s.[0]) input |> Seq.toList let keys = groups |> List.map fst - let values = groups |> List.map (snd >> Seq.toList) + let values = groups |> List.map(snd >> Seq.toList) Expect.equal "keys" [ 'a'; 'b'; 'a' ] keys Expect.equal "groups" [ [ "a1"; "a2" ]; [ "b1"; "b2" ]; [ "a3" ] ] values }