diff --git a/tests/FSharp.Control.AsyncSeq.Tests/AsyncSeqTests.fs b/tests/FSharp.Control.AsyncSeq.Tests/AsyncSeqTests.fs index 83379f41..f12c5279 100644 --- a/tests/FSharp.Control.AsyncSeq.Tests/AsyncSeqTests.fs +++ b/tests/FSharp.Control.AsyncSeq.Tests/AsyncSeqTests.fs @@ -2113,3 +2113,114 @@ let ``Seq.ofAsyncSeq with exception should propagate``() = #endif +// ---------------------------------------------------------------------------- +// Additional Coverage Tests targeting uncovered edge cases and branches + +[] +let ``AsyncSeq.bufferByCount with size 1 should work`` () = + let source = asyncSeq { yield 1; yield 2; yield 3 } + let result = AsyncSeq.bufferByCount 1 source |> AsyncSeq.toListSynchronously + Assert.AreEqual([[|1|]; [|2|]; [|3|]], result) + +[] +let ``AsyncSeq.bufferByCount with empty sequence should return empty`` () = + let result = AsyncSeq.bufferByCount 2 AsyncSeq.empty |> AsyncSeq.toListSynchronously + Assert.AreEqual([], result) + +[] +let ``AsyncSeq.bufferByCount with size larger than sequence should return partial`` () = + let source = asyncSeq { yield 1; yield 2 } + let result = AsyncSeq.bufferByCount 5 source |> AsyncSeq.toListSynchronously + Assert.AreEqual([[|1; 2|]], result) + +[] +let ``AsyncSeq.pairwise with empty sequence should return empty`` () = + let result = AsyncSeq.pairwise AsyncSeq.empty |> AsyncSeq.toListSynchronously + Assert.AreEqual([], result) + +[] +let ``AsyncSeq.pairwise with single element should return empty`` () = + let source = asyncSeq { yield 42 } + let result = AsyncSeq.pairwise source |> AsyncSeq.toListSynchronously + Assert.AreEqual([], result) + +[] +let ``AsyncSeq.pairwise with three elements should produce two pairs`` () = + let source = asyncSeq { yield 1; yield 2; yield 3 } + let result = AsyncSeq.pairwise source |> AsyncSeq.toListSynchronously + Assert.AreEqual([(1, 2); (2, 3)], result) + +[] +let ``AsyncSeq.distinctUntilChangedWith should work with custom equality`` () = + let source = asyncSeq { yield "a"; yield "A"; yield "B"; yield "b"; yield "c" } + let customEq (x: string) (y: string) = x.ToLower() = y.ToLower() + let result = AsyncSeq.distinctUntilChangedWith customEq source |> AsyncSeq.toListSynchronously + Assert.AreEqual(["a"; "B"; "c"], result) + +[] +let ``AsyncSeq.distinctUntilChangedWith with all same elements should return single`` () = + let source = asyncSeq { yield 1; yield 1; yield 1 } + let result = AsyncSeq.distinctUntilChangedWith (=) source |> AsyncSeq.toListSynchronously + Assert.AreEqual([1], result) + +[] +let ``AsyncSeq.append with both sequences having exceptions should propagate first`` () = + async { + let seq1 = asyncSeq { yield 1; failwith "error1" } + let seq2 = asyncSeq { yield 2; failwith "error2" } + let combined = AsyncSeq.append seq1 seq2 + + try + let! _ = AsyncSeq.toListAsync combined + Assert.Fail("Expected exception to be thrown") + with + | ex when ex.Message = "error1" -> + () // Expected - first sequence's error should be thrown + | ex -> + Assert.Fail($"Unexpected exception: {ex.Message}") + } |> Async.RunSynchronously + +[] +let ``AsyncSeq.concat with nested exceptions should propagate properly`` () = + async { + let nested = asyncSeq { + yield asyncSeq { yield 1; yield 2 } + yield asyncSeq { failwith "nested error" } + yield asyncSeq { yield 3 } + } + let flattened = AsyncSeq.concat nested + + try + let! result = AsyncSeq.toListAsync flattened + Assert.Fail("Expected exception to be thrown") + with + | ex when ex.Message = "nested error" -> + () // Expected + | ex -> + Assert.Fail($"Unexpected exception: {ex.Message}") + } |> Async.RunSynchronously + +[] +let ``AsyncSeq.choose with all None should return empty`` () = + let source = asyncSeq { yield 1; yield 2; yield 3 } + let result = AsyncSeq.choose (fun _ -> None) source |> AsyncSeq.toListSynchronously + Assert.AreEqual([], result) + +[] +let ``AsyncSeq.choose with mixed Some and None should filter correctly`` () = + let source = asyncSeq { yield 1; yield 2; yield 3; yield 4 } + let chooser x = if x % 2 = 0 then Some (x * 2) else None + let result = AsyncSeq.choose chooser source |> AsyncSeq.toListSynchronously + Assert.AreEqual([4; 8], result) + +[] +let ``AsyncSeq.chooseAsync with async transformation should work`` () = + async { + let source = asyncSeq { yield 1; yield 2; yield 3; yield 4 } + let chooserAsync x = async { + if x % 2 = 0 then return Some (x * 3) else return None + } + let! result = AsyncSeq.chooseAsync chooserAsync source |> AsyncSeq.toListAsync + Assert.AreEqual([6; 12], result) + } |> Async.RunSynchronously +