File tree Expand file tree Collapse file tree 5 files changed +75
-3
lines changed
src/FsToolkit.ErrorHandling
tests/FsToolkit.ErrorHandling.Tests Expand file tree Collapse file tree 5 files changed +75
-3
lines changed Original file line number Diff line number Diff line change 31
31
<Compile Include =" AsyncOptionCE.fs" />
32
32
<Compile Include =" AsyncOptionOp.fs" />
33
33
<Compile Include =" List.fs" />
34
+ <Compile Include =" Seq.fs" />
34
35
<None Include =" Script.fsx" />
35
36
</ItemGroup >
36
37
39
40
<Content Include =" *.fsproj; **\*.fs" PackagePath =" fable\" />
40
41
</ItemGroup >
41
42
42
-
43
+
43
44
<Import Project =" ..\..\.paket\Paket.Restore.targets" />
44
45
</Project >
Original file line number Diff line number Diff line change
1
+ namespace FsToolkit.ErrorHandling
2
+
3
+ [<RequireQualifiedAccess>]
4
+ module Seq =
5
+
6
+ let sequenceResultM ( xs : seq < Result < 't , 'e >>) : Result < 't list , 'e > =
7
+ let rec loop xs ts =
8
+ match Seq.tryHead xs with
9
+ | Some x ->
10
+ x
11
+ |> Result.bind ( fun t ->
12
+ loop ( Seq.tail xs) ( t :: ts))
13
+ | None ->
14
+ Ok ( List.rev ts)
15
+
16
+ // Seq.cache prevents double evaluation in Seq.tail
17
+ loop ( Seq.cache xs) []
Original file line number Diff line number Diff line change 23
23
<Compile Include =" AsyncOption.fs" />
24
24
<Compile Include =" AsyncOptionCE.fs" />
25
25
<Compile Include =" List.fs" />
26
+ <Compile Include =" Seq.fs" />
26
27
<Compile Include =" AsyncResult.fs" />
27
28
<Compile Include =" AsyncResultCE.fs" />
28
29
<Compile Include =" AsyncResultOption.fs" />
29
30
<Compile Include =" Validation.fs" />
30
31
<Compile Include =" ValidationCE.fs" />
31
32
<Compile Include =" Main.fs" />
32
33
</ItemGroup >
33
-
34
+
34
35
<Import Project =" ..\..\.paket\Paket.Restore.targets" />
35
36
</Project >
Original file line number Diff line number Diff line change @@ -15,6 +15,7 @@ let allTests = testList "All Tests" [
15
15
AsyncOptionTests.allTests
16
16
AsyncOptionCETests.allTests
17
17
ListTests.allTests
18
+ SeqTests.allTests
18
19
AsyncResultTests.allTests
19
20
AsyncResultCETests.allTests
20
21
AsyncResultOptionTests.allTests
@@ -27,5 +28,5 @@ let main argv =
27
28
#if FABLE_ COMPILER
28
29
Mocha.runTests allTests
29
30
#else
30
- Tests.runTestsWithArgs defaultConfig argv allTests
31
+ Tests.runTestsWithArgs defaultConfig argv allTests
31
32
#endif
Original file line number Diff line number Diff line change
1
+ module SeqTests
2
+
3
+
4
+ #if FABLE_ COMPILER
5
+ open Fable.Mocha
6
+ #else
7
+ open Expecto
8
+ #endif
9
+ open SampleDomain
10
+ open TestData
11
+ open TestHelpers
12
+ open System
13
+ open FsToolkit.ErrorHandling
14
+
15
+
16
+
17
+ let sequenceResultMTests =
18
+ testList " Seq.sequenceResultM Tests" [
19
+ testCase " traverseResult with an empty sequence" <| fun _ ->
20
+ let tweets = []
21
+ let expected = Ok []
22
+ let actual = Seq.sequenceResultM ( Seq.map Tweet.TryCreate tweets)
23
+ Expect.equal actual expected " Should have an empty list of valid tweets"
24
+
25
+ testCase " traverseResult with a sequence of valid data" <| fun _ ->
26
+ let tweets = [ " Hi" ; " Hello" ; " Hola" ]
27
+ let expected = List.map tweet tweets |> Ok
28
+ let actual = Seq.sequenceResultM ( Seq.map Tweet.TryCreate tweets)
29
+ Expect.equal actual expected " Should have a list of valid tweets"
30
+
31
+ testCase " sequenceResultM with few invalid data" <| fun _ ->
32
+ let tweets = [ " " ; " Hello" ; aLongerInvalidTweet] :> seq<_>
33
+ let actual = Seq.sequenceResultM ( Seq.map Tweet.TryCreate tweets)
34
+ Expect.equal actual ( Error emptyTweetErrMsg) " traverse the sequence and return the first error"
35
+
36
+ testCase " sequenceResultM stops after first invalid data" <| fun _ ->
37
+ let mutable counter = 0
38
+ let tweets = seq {
39
+ " Hi"
40
+ " Hello"
41
+ " Hola"
42
+ aLongerInvalidTweet
43
+ counter <- counter + 1
44
+ }
45
+ let actual = Seq.sequenceResultM ( Seq.map Tweet.TryCreate tweets)
46
+ Expect.equal actual ( Error longerTweetErrMsg) " traverse the sequence and return the first error"
47
+ Expect.equal counter 0 " evaluation of the sequence stops at the first error"
48
+ ]
49
+
50
+ let allTests = testList " Seq Tests" [
51
+ sequenceResultMTests
52
+ ]
You can’t perform that action at this time.
0 commit comments