-
Notifications
You must be signed in to change notification settings - Fork 60
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Adds AsyncOption, TaskOption, JobOption helpers
* TaskOption Working on #77 -> AsyncOption.map * TaskOption Wirking on #77 -> AsyncOption.Bind * TaskOption Working on #77 -> AsyncOption.apply * TaskOption Working on #77 -> AsyncOption.retn * TaskOption Working on #77 -> AsyncOption basic Operators * TaskOption Working on #77 -> TaskOption basic Functions * TaskOption Fixes #77 -> JobOption * TaskOption Fixes #77 -> Add AsyncOption Tests to execution
- Loading branch information
Showing
19 changed files
with
495 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
namespace FsToolkit.ErrorHandling | ||
|
||
open Hopac | ||
open Hopac.Infixes | ||
|
||
[<RequireQualifiedAccess>] | ||
module JobOption = | ||
|
||
let inline map f ar = | ||
Job.map (Option.map f) ar | ||
|
||
let bind f (ar: Job<_>) = job { | ||
let! opt = ar | ||
let t = | ||
match opt with | ||
| Some x -> f x | ||
| None -> job { return None } | ||
return! t | ||
} | ||
|
||
let retn x = | ||
job { return Some x } | ||
|
||
let apply f x = | ||
bind (fun f' -> | ||
bind (fun x' -> retn (f' x')) x) f |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
namespace FsToolkit.ErrorHandling.Operator.JobOption | ||
|
||
open FsToolkit.ErrorHandling | ||
|
||
[<AutoOpen>] | ||
module JobOption = | ||
|
||
let inline (<!>) f x = JobOption.map f x | ||
let inline (<*>) f x = JobOption.apply f x | ||
let inline (>>=) x f = JobOption.bind f x |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
namespace FsToolkit.ErrorHandling | ||
|
||
open System.Threading.Tasks | ||
open FSharp.Control.Tasks.V2.ContextInsensitive | ||
|
||
[<RequireQualifiedAccess>] | ||
module TaskOption = | ||
|
||
let inline map f ar = | ||
Task.map (Option.map f) ar | ||
|
||
let bind f (ar: Task<_>) = | ||
task { | ||
let! opt = ar | ||
let t = | ||
match opt with | ||
| Some x -> f x | ||
| None -> task { return None } | ||
return! t | ||
} | ||
|
||
let retn x = | ||
task { return Some x } | ||
|
||
let apply f x = | ||
bind (fun f' -> | ||
bind (fun x' -> retn (f' x')) x) f |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
namespace FsToolkit.ErrorHandling.Operator.TaskOption | ||
|
||
open FsToolkit.ErrorHandling | ||
|
||
[<AutoOpen>] | ||
module TaskOption = | ||
|
||
let inline (<!>) f x = TaskOption.map f x | ||
let inline (<*>) f x = TaskOption.apply f x | ||
let inline (>>=) x f = TaskOption.bind f x |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
namespace FsToolkit.ErrorHandling | ||
|
||
open System.Threading.Tasks | ||
|
||
[<RequireQualifiedAccess>] | ||
module AsyncOption = | ||
|
||
let inline map f ar = | ||
Async.map (Option.map f) ar | ||
|
||
let bind f ar = async { | ||
let! opt = ar | ||
let t = | ||
match opt with | ||
| Some x -> f x | ||
| None -> async { return None } | ||
return! t | ||
} | ||
|
||
let retn x = | ||
async { return Some x } | ||
|
||
let apply f x = | ||
bind (fun f' -> | ||
bind (fun x' -> retn (f' x')) x) f |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
namespace FsToolkit.ErrorHandling.Operator.AsyncOption | ||
|
||
open FsToolkit.ErrorHandling | ||
|
||
[<AutoOpen>] | ||
module AsyncOption = | ||
|
||
let inline (<!>) f x = AsyncOption.map f x | ||
let inline (<*>) f x = AsyncOption.apply f x | ||
let inline (>>=) x f = AsyncOption.bind f x |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
21 changes: 21 additions & 0 deletions
21
tests/FsToolkit.ErrorHandling.JobResult.Tests/Expect.JobOption.fs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
namespace Expects.JobOption | ||
|
||
module Expect = | ||
open Expecto | ||
open Hopac | ||
|
||
let hasJobValue v jobX = | ||
let x = run jobX | ||
if v = x then | ||
() | ||
else Tests.failtestf "Expected %A, was %A." v x | ||
|
||
|
||
let hasJobSomeValue v jobX = | ||
let x = run jobX | ||
TestHelpers.Expect.hasSomeValue v x | ||
|
||
|
||
let hasJobNoneValue jobX = | ||
let x = run jobX | ||
TestHelpers.Expect.hasNoneValue x |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
100 changes: 100 additions & 0 deletions
100
tests/FsToolkit.ErrorHandling.JobResult.Tests/JobOption.fs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
module JobOptionTests | ||
|
||
|
||
open Expecto | ||
open Expects.JobOption | ||
open SampleDomain | ||
open TestData | ||
open TestHelpers | ||
open FsToolkit.ErrorHandling | ||
open FsToolkit.ErrorHandling.Operator.JobOption | ||
open System | ||
open Hopac | ||
|
||
let runJobSync = run | ||
let createPostSome = createPostSome >> Job.fromAsync | ||
let getFollowersSome = getFollowersSome >> Job.fromAsync | ||
let allowedToPostOptional = allowedToPostOptional >> Job.fromAsync | ||
|
||
let mapTests = | ||
testList "JobOption.map Tests" [ | ||
testCase "map with Job(Some x)" <| fun _ -> | ||
Job.singleton (Some validTweet) | ||
|> JobOption.map remainingCharacters | ||
|> Expect.hasJobSomeValue 267 | ||
|
||
testCase "map with Job(None)" <| fun _ -> | ||
Job.singleton (None) | ||
|> JobOption.map remainingCharacters | ||
|> Expect.hasJobNoneValue | ||
] | ||
|
||
let bindTests = | ||
testList "JobOption.bind tests" [ | ||
testCase "bind with Job(Some x)" <| fun _ -> | ||
allowedToPostOptional sampleUserId | ||
|> JobOption.bind (fun isAllowed -> job { | ||
if isAllowed then | ||
return! createPostSome validCreatePostRequest | ||
else | ||
return None }) | ||
|> Expect.hasJobSomeValue (PostId newPostId) | ||
|
||
testCase "bind with Job(None)" <| fun _ -> | ||
allowedToPostOptional (UserId (Guid.NewGuid())) | ||
|> JobOption.bind (fun isAllowed -> job {return Some isAllowed}) | ||
|> Expect.hasJobNoneValue | ||
|
||
testCase "bind with Job(Ok x) that returns Job (None)" <| fun _ -> | ||
allowedToPostOptional sampleUserId | ||
|> JobOption.bind (fun _ -> job { | ||
return None | ||
}) | ||
|> Expect.hasJobNoneValue | ||
] | ||
|
||
let applyTests = | ||
testList "JobOption.apply Tests" [ | ||
testCase "apply with Job(Some x)" <| fun _ -> | ||
Job.singleton (Some validTweet) | ||
|> JobOption.apply (Job.singleton (Some remainingCharacters)) | ||
|> Expect.hasJobSomeValue (267) | ||
|
||
testCase "apply with Job(None)" <| fun _ -> | ||
Job.singleton None | ||
|> JobOption.apply (Job.singleton (Some remainingCharacters)) | ||
|> Expect.hasJobNoneValue | ||
] | ||
|
||
let retnTests = | ||
testList "JobOption.retn Tests" [ | ||
testCase "retn with x" <| fun _ -> | ||
JobOption.retn 267 | ||
|> Expect.hasJobSomeValue (267) | ||
] | ||
|
||
let jobOptionOperatorTests = | ||
testList "JobOption Operators Tests" [ | ||
testCase "map & apply operators" <| fun _ -> | ||
let getFollowersResult = getFollowersSome sampleUserId | ||
let createPostResult = createPostSome validCreatePostRequest | ||
newPostRequest <!> getFollowersResult <*> createPostResult | ||
|> Expect.hasJobSomeValue {NewPostId = PostId newPostId; UserIds = followerIds} | ||
|
||
testCase "bind operator" <| fun _ -> | ||
allowedToPostOptional sampleUserId | ||
>>= (fun isAllowed -> | ||
if isAllowed then | ||
createPostSome validCreatePostRequest | ||
else | ||
Job.singleton None) | ||
|> Expect.hasJobSomeValue (PostId newPostId) | ||
] | ||
|
||
let allTests = testList "Job Option Tests" [ | ||
mapTests | ||
bindTests | ||
applyTests | ||
retnTests | ||
jobOptionOperatorTests | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.