@@ -1882,6 +1882,86 @@ let ``Seq.ofAsyncSeq with exception`` () =
18821882 Seq.ofAsyncSeq asyncSeqWithError |> Seq.toList |> ignore
18831883 ) |> ignore
18841884
1885+ [<Test>]
1886+ let ``AsyncSeq.intervalMs should generate sequence with timestamps`` () =
1887+ let result =
1888+ AsyncSeq.intervalMs 50
1889+ |> AsyncSeq.take 3
1890+ |> AsyncSeq.toListAsync
1891+ |> AsyncOps.timeoutMs 1000
1892+ |> Async.RunSynchronously
1893+
1894+ Assert.AreEqual( 3 , result.Length)
1895+ // Verify timestamps are increasing
1896+ Assert.IsTrue( result.[ 1 ] > result.[ 0 ])
1897+ Assert.IsTrue( result.[ 2 ] > result.[ 1 ])
1898+
1899+ [<Test>]
1900+ let ``AsyncSeq.intervalMs with zero period should work`` () =
1901+ let result =
1902+ AsyncSeq.intervalMs 0
1903+ |> AsyncSeq.take 2
1904+ |> AsyncSeq.toListAsync
1905+ |> AsyncOps.timeoutMs 500
1906+ |> Async.RunSynchronously
1907+
1908+ Assert.AreEqual( 2 , result.Length)
1909+
1910+ [<Test>]
1911+ let ``AsyncSeq.take with negative count should throw ArgumentException`` () =
1912+ Assert.Throws< System.ArgumentException>( fun () ->
1913+ AsyncSeq.ofSeq [ 1 ; 2 ; 3 ]
1914+ |> AsyncSeq.take - 1
1915+ |> AsyncSeq.toListAsync
1916+ |> Async.RunSynchronously
1917+ |> ignore
1918+ ) |> ignore
1919+
1920+ [<Test>]
1921+ let ``AsyncSeq.skip with negative count should throw ArgumentException`` () =
1922+ Assert.Throws< System.ArgumentException>( fun () ->
1923+ AsyncSeq.ofSeq [ 1 ; 2 ; 3 ]
1924+ |> AsyncSeq.skip - 1
1925+ |> AsyncSeq.toListAsync
1926+ |> Async.RunSynchronously
1927+ |> ignore
1928+ ) |> ignore
1929+
1930+ [<Test>]
1931+ let ``AsyncSeq.take zero should return empty sequence`` () =
1932+ let expected = []
1933+ let actual =
1934+ AsyncSeq.ofSeq [ 1 ; 2 ; 3 ]
1935+ |> AsyncSeq.take 0
1936+ |> AsyncSeq.toListAsync
1937+ |> Async.RunSynchronously
1938+
1939+ Assert.AreEqual( expected, actual)
1940+
1941+ [<Test>]
1942+ let ``AsyncSeq.skip zero should return original sequence`` () =
1943+ let expected = [ 1 ; 2 ; 3 ]
1944+ let actual =
1945+ AsyncSeq.ofSeq [ 1 ; 2 ; 3 ]
1946+ |> AsyncSeq.skip 0
1947+ |> AsyncSeq.toListAsync
1948+ |> Async.RunSynchronously
1949+
1950+ Assert.AreEqual( expected, actual)
1951+
1952+ [<Test>]
1953+ let ``AsyncSeq.replicateInfinite with exception should propagate exception`` () =
1954+ let exceptionMsg = " test exception"
1955+ let expected = System.ArgumentException( exceptionMsg)
1956+
1957+ Assert.Throws< System.ArgumentException>( fun () ->
1958+ AsyncSeq.replicateInfinite ( raise expected)
1959+ |> AsyncSeq.take 2
1960+ |> AsyncSeq.toListAsync
1961+ |> Async.RunSynchronously
1962+ |> ignore
1963+ ) |> ignore
1964+
18851965#if ( NETSTANDARD2_ 1 || NETCOREAPP3_ 0)
18861966[<Test>]
18871967let ``AsyncSeq.ofAsyncEnum should roundtrip successfully`` () =
@@ -2102,3 +2182,115 @@ let ``AsyncSeq.mapAsyncParallel with exception should propagate``() =
21022182 Assert.Throws< System.Exception>( fun () ->
21032183 exceptionSeq |> AsyncSeq.toListSynchronously |> ignore
21042184 ) |> ignore
2185+
2186+ // ----------------------------------------------------------------------------
2187+ // Additional Coverage Tests targeting uncovered edge cases and branches
2188+
2189+ [<Test>]
2190+ let ``AsyncSeq.bufferByCount with size 1 should work`` () =
2191+ let source = asyncSeq { yield 1 ; yield 2 ; yield 3 }
2192+ let result = AsyncSeq.bufferByCount 1 source |> AsyncSeq.toListSynchronously
2193+ Assert.AreEqual([[| 1 |]; [| 2 |]; [| 3 |]], result)
2194+
2195+ [<Test>]
2196+ let ``AsyncSeq.bufferByCount with empty sequence should return empty`` () =
2197+ let result = AsyncSeq.bufferByCount 2 AsyncSeq.empty |> AsyncSeq.toListSynchronously
2198+ Assert.AreEqual([], result)
2199+
2200+ [<Test>]
2201+ let ``AsyncSeq.bufferByCount with size larger than sequence should return partial`` () =
2202+ let source = asyncSeq { yield 1 ; yield 2 }
2203+ let result = AsyncSeq.bufferByCount 5 source |> AsyncSeq.toListSynchronously
2204+ Assert.AreEqual([[| 1 ; 2 |]], result)
2205+
2206+ [<Test>]
2207+ let ``AsyncSeq.pairwise with empty sequence should return empty`` () =
2208+ let result = AsyncSeq.pairwise AsyncSeq.empty |> AsyncSeq.toListSynchronously
2209+ Assert.AreEqual([], result)
2210+
2211+ [<Test>]
2212+ let ``AsyncSeq.pairwise with single element should return empty`` () =
2213+ let source = asyncSeq { yield 42 }
2214+ let result = AsyncSeq.pairwise source |> AsyncSeq.toListSynchronously
2215+ Assert.AreEqual([], result)
2216+
2217+ [<Test>]
2218+ let ``AsyncSeq.pairwise with three elements should produce two pairs`` () =
2219+ let source = asyncSeq { yield 1 ; yield 2 ; yield 3 }
2220+ let result = AsyncSeq.pairwise source |> AsyncSeq.toListSynchronously
2221+ Assert.AreEqual([( 1 , 2 ); ( 2 , 3 )], result)
2222+
2223+ [<Test>]
2224+ let ``AsyncSeq.distinctUntilChangedWith should work with custom equality`` () =
2225+ let source = asyncSeq { yield " a" ; yield " A" ; yield " B" ; yield " b" ; yield " c" }
2226+ let customEq ( x : string ) ( y : string ) = x.ToLower() = y.ToLower()
2227+ let result = AsyncSeq.distinctUntilChangedWith customEq source |> AsyncSeq.toListSynchronously
2228+ Assert.AreEqual([ " a" ; " B" ; " c" ], result)
2229+
2230+ [<Test>]
2231+ let ``AsyncSeq.distinctUntilChangedWith with all same elements should return single`` () =
2232+ let source = asyncSeq { yield 1 ; yield 1 ; yield 1 }
2233+ let result = AsyncSeq.distinctUntilChangedWith (=) source |> AsyncSeq.toListSynchronously
2234+ Assert.AreEqual([ 1 ], result)
2235+
2236+ [<Test>]
2237+ let ``AsyncSeq.append with both sequences having exceptions should propagate first`` () =
2238+ async {
2239+ let seq1 = asyncSeq { yield 1 ; failwith " error1" }
2240+ let seq2 = asyncSeq { yield 2 ; failwith " error2" }
2241+ let combined = AsyncSeq.append seq1 seq2
2242+
2243+ try
2244+ let! _ = AsyncSeq.toListAsync combined
2245+ Assert.Fail( " Expected exception to be thrown" )
2246+ with
2247+ | ex when ex.Message = " error1" ->
2248+ () // Expected - first sequence's error should be thrown
2249+ | ex ->
2250+ Assert.Fail( $" Unexpected exception: {ex.Message}" )
2251+ } |> Async.RunSynchronously
2252+
2253+ [<Test>]
2254+ let ``AsyncSeq.concat with nested exceptions should propagate properly`` () =
2255+ async {
2256+ let nested = asyncSeq {
2257+ yield asyncSeq { yield 1 ; yield 2 }
2258+ yield asyncSeq { failwith " nested error" }
2259+ yield asyncSeq { yield 3 }
2260+ }
2261+ let flattened = AsyncSeq.concat nested
2262+
2263+ try
2264+ let! result = AsyncSeq.toListAsync flattened
2265+ Assert.Fail( " Expected exception to be thrown" )
2266+ with
2267+ | ex when ex.Message = " nested error" ->
2268+ () // Expected
2269+ | ex ->
2270+ Assert.Fail( $" Unexpected exception: {ex.Message}" )
2271+ } |> Async.RunSynchronously
2272+
2273+ [<Test>]
2274+ let ``AsyncSeq.choose with all None should return empty`` () =
2275+ let source = asyncSeq { yield 1 ; yield 2 ; yield 3 }
2276+ let result = AsyncSeq.choose ( fun _ -> None) source |> AsyncSeq.toListSynchronously
2277+ Assert.AreEqual([], result)
2278+
2279+ [<Test>]
2280+ let ``AsyncSeq.choose with mixed Some and None should filter correctly`` () =
2281+ let source = asyncSeq { yield 1 ; yield 2 ; yield 3 ; yield 4 }
2282+ let chooser x = if x % 2 = 0 then Some ( x * 2 ) else None
2283+ let result = AsyncSeq.choose chooser source |> AsyncSeq.toListSynchronously
2284+ Assert.AreEqual([ 4 ; 8 ], result)
2285+
2286+ [<Test>]
2287+ let ``AsyncSeq.chooseAsync with async transformation should work`` () =
2288+ async {
2289+ let source = asyncSeq { yield 1 ; yield 2 ; yield 3 ; yield 4 }
2290+ let chooserAsync x = async {
2291+ if x % 2 = 0 then return Some ( x * 3 ) else return None
2292+ }
2293+ let! result = AsyncSeq.chooseAsync chooserAsync source |> AsyncSeq.toListAsync
2294+ Assert.AreEqual([ 6 ; 12 ], result)
2295+ } |> Async.RunSynchronously
2296+
0 commit comments