Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Get to 100% coverage, add tests for TaskSeq.zip, mapi, iter, exactlyOne and async variants #31

Merged
merged 10 commits into from
Oct 16, 2022
Merged
2 changes: 2 additions & 0 deletions src/FSharpy.TaskSeq.Test/FSharpy.TaskSeq.Test.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
<Compile Include="TestUtils.fs" />
<Compile Include="TaskSeq.Choose.Tests.fs" />
<Compile Include="TaskSeq.Collect.Tests.fs" />
<Compile Include="TaskSeq.ExactlyOne.Tests.fs" />
<Compile Include="TaskSeq.Filter.Tests.fs" />
<Compile Include="TaskSeq.Find.Tests.fs" />
<Compile Include="TaskSeq.Fold.Tests.fs" />
Expand All @@ -22,6 +23,7 @@
<Compile Include="TaskSeq.Last.Tests.fs" />
<Compile Include="TaskSeq.Map.Tests.fs" />
<Compile Include="TaskSeq.Pick.Tests.fs" />
<Compile Include="TaskSeq.Zip.Tests.fs" />
<Compile Include="TaskSeq.ToXXX.Tests.fs" />
<Compile Include="TaskSeq.OfXXX.Tests.fs" />
<Compile Include="TaskSeq.Tests.Other.fs" />
Expand Down
9 changes: 1 addition & 8 deletions src/FSharpy.TaskSeq.Test/TaskSeq.Choose.Tests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,6 @@ open FsToolkit.ErrorHandling

open FSharpy

[<Fact>]
let ``ZHang timeout test`` () = task {
let! empty = Task.Delay 30

empty |> should be Null
}

[<Fact>]
let ``TaskSeq-choose on an empty sequence`` () = task {
let! empty =
Expand Down Expand Up @@ -50,7 +43,7 @@ let ``TaskSeq-choose can convert and filter`` () = task {
let ``TaskSeq-chooseAsync can convert and filter`` () = task {
let! alphabet =
createDummyTaskSeqWith 50L<µs> 1000L<µs> 50
|> TaskSeq.choose (fun number -> if number <= 26 then Some(char number + '@') else None)
|> TaskSeq.chooseAsync (fun number -> task { return if number <= 26 then Some(char number + '@') else None })
|> TaskSeq.toArrayAsync

String alphabet |> should equal "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
Expand Down
84 changes: 74 additions & 10 deletions src/FSharpy.TaskSeq.Test/TaskSeq.Collect.Tests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@ open FsToolkit.ErrorHandling

open FSharpy

let validateSequence sequence =
sequence
|> Seq.map string
|> String.concat ""
|> should equal "ABBCCDDEEFFGGHHIIJJK"

[<Fact>]
let ``TaskSeq-collect operates in correct order`` () = task {
let! sq =
Expand All @@ -16,10 +22,22 @@ let ``TaskSeq-collect operates in correct order`` () = task {
})
|> TaskSeq.toSeqCachedAsync

sq
|> Seq.map string
|> String.concat ""
|> should equal "ABBCCDDEEFFGGHHIIJJK"
validateSequence sq
}

[<Fact>]
let ``TaskSeq-collectAsync operates in correct order`` () = task {
let! sq =
createDummyTaskSeq 10
|> TaskSeq.collectAsync (fun item -> task {
return taskSeq {
yield char (item + 64)
yield char (item + 65)
}
})
|> TaskSeq.toSeqCachedAsync

validateSequence sq
}

[<Fact>]
Expand All @@ -32,10 +50,42 @@ let ``TaskSeq-collectSeq operates in correct order`` () = task {
})
|> TaskSeq.toSeqCachedAsync

sq
|> Seq.map string
|> String.concat ""
|> should equal "ABBCCDDEEFFGGHHIIJJK"
validateSequence sq
}

[<Fact>]
let ``TaskSeq-collectSeq with arrays operates in correct order`` () = task {
let! sq =
createDummyTaskSeq 10
|> TaskSeq.collectSeq (fun item -> [| char (item + 64); char (item + 65) |])
|> TaskSeq.toArrayAsync

validateSequence sq
}

[<Fact>]
let ``TaskSeq-collectSeqAsync operates in correct order`` () = task {
let! sq =
createDummyTaskSeq 10
|> TaskSeq.collectSeqAsync (fun item -> task {
return seq {
yield char (item + 64)
yield char (item + 65)
}
})
|> TaskSeq.toSeqCachedAsync

validateSequence sq
}

[<Fact>]
let ``TaskSeq-collectSeqAsync with arrays operates in correct order`` () = task {
let! sq =
createDummyTaskSeq 10
|> TaskSeq.collectSeqAsync (fun item -> task { return [| char (item + 64); char (item + 65) |] })
|> TaskSeq.toArrayAsync

validateSequence sq
}

[<Fact>]
Expand All @@ -48,6 +98,16 @@ let ``TaskSeq-collect with empty task sequences`` () = task {
Seq.isEmpty sq |> should be True
}

[<Fact>]
let ``TaskSeq-collectAsync with empty task sequences`` () = task {
let! sq =
createDummyTaskSeq 10
|> TaskSeq.collectAsync (fun _ -> task { return TaskSeq.empty<string> })
|> TaskSeq.toSeqCachedAsync

Seq.isEmpty sq |> should be True
}

[<Fact>]
let ``TaskSeq-collectSeq with empty sequences`` () = task {
let! sq =
Expand All @@ -59,7 +119,11 @@ let ``TaskSeq-collectSeq with empty sequences`` () = task {
}

[<Fact>]
let ``TaskSeq-empty is empty`` () = task {
let! sq = TaskSeq.empty<string> |> TaskSeq.toSeqCachedAsync
let ``TaskSeq-collectSeqAsync with empty sequences`` () = task {
let! sq =
createDummyTaskSeq 10
|> TaskSeq.collectSeqAsync (fun _ -> task { return Array.empty<int> })
|> TaskSeq.toSeqCachedAsync

Seq.isEmpty sq |> should be True
}
57 changes: 57 additions & 0 deletions src/FSharpy.TaskSeq.Test/TaskSeq.ExactlyOne.Tests.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
module FSharpy.Tests.Head

open System
open Xunit
open FsUnit.Xunit
open FsToolkit.ErrorHandling

open FSharpy


[<Fact>]
let ``TaskSeq-head throws on empty sequences`` () = task {
fun () -> TaskSeq.empty<string> |> TaskSeq.head |> Task.ignore
|> should throwAsyncExact typeof<ArgumentException>
}

[<Fact>]
let ``TaskSeq-head throws on empty sequences - variant`` () = task {
fun () -> taskSeq { do () } |> TaskSeq.head |> Task.ignore
|> should throwAsyncExact typeof<ArgumentException>
}

[<Fact>]
let ``TaskSeq-tryHead returns None on empty sequences`` () = task {
let! nothing = TaskSeq.empty<string> |> TaskSeq.tryHead
nothing |> should be None'
}

[<Fact>]
let ``TaskSeq-head gets the first item in a longer sequence`` () = task {
let! head = createDummyTaskSeqWith 50L<µs> 1000L<µs> 50 |> TaskSeq.head

head |> should equal 1
}

[<Fact>]
let ``TaskSeq-head gets the only item in a singleton sequence`` () = task {
let! head = taskSeq { yield 10 } |> TaskSeq.head
head |> should equal 10
}

[<Fact>]
let ``TaskSeq-tryHead gets the first item in a longer sequence`` () = task {
let! head =
createDummyTaskSeqWith 50L<µs> 1000L<µs> 50
|> TaskSeq.tryHead

head |> should be Some'
head |> should equal (Some 1)
}

[<Fact>]
let ``TaskSeq-tryHead gets the only item in a singleton sequence`` () = task {
let! head = taskSeq { yield 10 } |> TaskSeq.tryHead
head |> should be Some'
head |> should equal (Some 10)
}
88 changes: 65 additions & 23 deletions src/FSharpy.TaskSeq.Test/TaskSeq.Head.Tests.fs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
module FSharpy.Tests.Head
module FSharpy.Tests.ExactlyOne

open System
open Xunit
Expand All @@ -9,49 +9,91 @@ open FSharpy


[<Fact>]
let ``TaskSeq-head throws on empty sequences`` () = task {
fun () -> TaskSeq.empty<string> |> TaskSeq.head |> Task.ignore
let ``TaskSeq-exactlyOne throws on empty sequences`` () = task {
fun () -> TaskSeq.empty<string> |> TaskSeq.exactlyOne |> Task.ignore
|> should throwAsyncExact typeof<ArgumentException>
}

[<Fact>]
let ``TaskSeq-head throws on empty sequences - variant`` () = task {
fun () -> taskSeq { do () } |> TaskSeq.head |> Task.ignore
let ``TaskSeq-exactlyOne throws on empty sequences - variant`` () = task {
fun () -> taskSeq { do () } |> TaskSeq.exactlyOne |> Task.ignore
|> should throwAsyncExact typeof<ArgumentException>
}

[<Fact>]
let ``TaskSeq-tryHead returns None on empty sequences`` () = task {
let! nothing = TaskSeq.empty<string> |> TaskSeq.tryHead
let ``TaskSeq-tryExactlyOne returns None on empty sequences`` () = task {
let! nothing = TaskSeq.empty<string> |> TaskSeq.tryExactlyOne
nothing |> should be None'
}

[<Fact>]
let ``TaskSeq-head gets the first item in a longer sequence`` () = task {
let! head = createDummyTaskSeqWith 50L<µs> 1000L<µs> 50 |> TaskSeq.head
let ``TaskSeq-exactlyOne throws for a sequence of length = two`` () = task {
fun () ->
taskSeq {
yield 1
yield 2
}
|> TaskSeq.exactlyOne
|> Task.ignore
|> should throwAsyncExact typeof<ArgumentException>
}

[<Fact>]
let ``TaskSeq-exactlyOne throws for a sequence of length = two - variant`` () = task {
fun () ->
createDummyTaskSeqWith 50L<µs> 1000L<µs> 2
|> TaskSeq.exactlyOne
|> Task.ignore
|> should throwAsyncExact typeof<ArgumentException>
}


[<Fact>]
let ``TaskSeq-exactlyOne throws with a larger sequence`` () = task {
fun () ->
createDummyTaskSeqWith 50L<µs> 300L<µs> 200
|> TaskSeq.exactlyOne
|> Task.ignore
|> should throwAsyncExact typeof<ArgumentException>
}

head |> should equal 1
[<Fact>]
let ``TaskSeq-tryExactlyOne returns None with a larger sequence`` () = task {
let! nothing =
createDummyTaskSeqWith 50L<µs> 300L<µs> 20
|> TaskSeq.tryExactlyOne

nothing |> should be None'
}

[<Fact>]
let ``TaskSeq-head gets the only item in a singleton sequence`` () = task {
let! head = taskSeq { yield 10 } |> TaskSeq.head
head |> should equal 10
let ``TaskSeq-exactlyOne gets the only item in a singleton sequence`` () = task {
let! exactlyOne = taskSeq { yield 10 } |> TaskSeq.exactlyOne
exactlyOne |> should equal 10
}

[<Fact>]
let ``TaskSeq-tryHead gets the first item in a longer sequence`` () = task {
let! head =
createDummyTaskSeqWith 50L<µs> 1000L<µs> 50
|> TaskSeq.tryHead
let ``TaskSeq-tryExactlyOne gets the only item in a singleton sequence`` () = task {
let! exactlyOne = taskSeq { yield 10 } |> TaskSeq.tryExactlyOne
exactlyOne |> should be Some'
exactlyOne |> should equal (Some 10)
}

[<Fact>]
let ``TaskSeq-exactlyOne gets the only item in a singleton sequence - variant`` () = task {
let! exactlyOne =
createLongerDummyTaskSeq 50<ms> 300<ms> 1
|> TaskSeq.exactlyOne

head |> should be Some'
head |> should equal (Some 1)
exactlyOne |> should equal 1
}

[<Fact>]
let ``TaskSeq-tryHead gets the only item in a singleton sequence`` () = task {
let! head = taskSeq { yield 10 } |> TaskSeq.tryHead
head |> should be Some'
head |> should equal (Some 10)
let ``TaskSeq-tryExactlyOne gets the only item in a singleton sequence - variant`` () = task {
let! exactlyOne =
createLongerDummyTaskSeq 50<ms> 300<ms> 1
|> TaskSeq.tryExactlyOne

exactlyOne |> should be Some'
exactlyOne |> should equal (Some 1)
}
16 changes: 15 additions & 1 deletion src/FSharpy.TaskSeq.Test/TaskSeq.Iter.Tests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,24 @@ module FSharpy.Tests.Iter

open Xunit
open FsUnit.Xunit
open FsToolkit.ErrorHandling

open FSharpy

[<Fact>]
let ``TaskSeq-iteri does nothing on empty sequences`` () = task {
let tq = createDummyTaskSeq 10
let mutable sum = -1
do! TaskSeq.empty |> TaskSeq.iteri (fun i _ -> sum <- sum + i)
sum |> should equal -1
}

[<Fact>]
let ``TaskSeq-iter does nothing on empty sequences`` () = task {
let tq = createDummyTaskSeq 10
let mutable sum = -1
do! TaskSeq.empty |> TaskSeq.iter (fun i -> sum <- sum + i)
sum |> should equal -1
}

[<Fact>]
let ``TaskSeq-iteri should go over all items`` () = task {
Expand Down
Loading