Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
111 changes: 111 additions & 0 deletions tests/FSharp.Control.AsyncSeq.Tests/AsyncSeqTests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -2113,3 +2113,114 @@ let ``Seq.ofAsyncSeq with exception should propagate``() =

#endif

// ----------------------------------------------------------------------------
// Additional Coverage Tests targeting uncovered edge cases and branches

[<Test>]
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)

[<Test>]
let ``AsyncSeq.bufferByCount with empty sequence should return empty`` () =
let result = AsyncSeq.bufferByCount 2 AsyncSeq.empty |> AsyncSeq.toListSynchronously
Assert.AreEqual([], result)

[<Test>]
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)

[<Test>]
let ``AsyncSeq.pairwise with empty sequence should return empty`` () =
let result = AsyncSeq.pairwise AsyncSeq.empty |> AsyncSeq.toListSynchronously
Assert.AreEqual([], result)

[<Test>]
let ``AsyncSeq.pairwise with single element should return empty`` () =
let source = asyncSeq { yield 42 }
let result = AsyncSeq.pairwise source |> AsyncSeq.toListSynchronously
Assert.AreEqual([], result)

[<Test>]
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)

[<Test>]
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)

[<Test>]
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)

[<Test>]
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

[<Test>]
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

[<Test>]
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)

[<Test>]
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)

[<Test>]
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