tests
This commit is contained in:
parent
4917139553
commit
c3e1d26ab3
4 changed files with 104 additions and 13 deletions
|
@ -1,12 +1,86 @@
|
|||
module Pentole.Result
|
||||
namespace Pentole
|
||||
|
||||
type Result<'o, 'e> with
|
||||
|
||||
module Result =
|
||||
|
||||
let inline protect ([<InlineIfLambda>]f) x =
|
||||
try
|
||||
Ok (f x)
|
||||
with e -> Error e
|
||||
|
||||
let inline pairwise_map fun_ (x: 'a, y: 'a) =
|
||||
match fun_ x with
|
||||
| Error e -> Error e
|
||||
| Ok o ->
|
||||
match fun_ y with | Ok o' -> Ok (o, o') | Error e -> Error e
|
||||
|
||||
let of_option = function | Some s -> Ok s | None -> Error ()
|
||||
|
||||
let zip a b =
|
||||
match (a, b) with
|
||||
| Ok a, Ok b -> Ok (a, b)
|
||||
| Error e, _ -> Error e
|
||||
| _, Error e -> Error e
|
||||
|
||||
module Unsafe =
|
||||
/// <summary>
|
||||
/// `o` if `Ok o` else throw
|
||||
/// </summary>
|
||||
/// <param name="result"></param>
|
||||
let inline get r =
|
||||
match r with
|
||||
| Ok o -> o
|
||||
| Error e ->
|
||||
$"Tried to access value from Result r, error={e}"
|
||||
|> System.ArgumentException
|
||||
|> raise
|
||||
|
||||
/// Module to operate on lists
|
||||
module ResultList =
|
||||
/// <summary>
|
||||
/// `o` if `Ok o` else throw
|
||||
/// Transforms a sequence by applying a function that returns a Result, collecting successful results or short-circuiting on the first error.
|
||||
/// </summary>
|
||||
/// <param name="result"></param>
|
||||
static member get (result: Result<'o, 'e>) =
|
||||
match result with
|
||||
| Ok o -> o
|
||||
| Error e -> failwith $"Can't unwrap Error {e}"
|
||||
///
|
||||
/// <param name="lambda">A function that transforms each element and returns a Result</param>
|
||||
/// <param name="seq_">The input sequence to transform</param>
|
||||
/// <returns>
|
||||
/// <list>
|
||||
/// - Ok of a list containing all successfully transformed elements if all transformations succeed
|
||||
/// </list>
|
||||
/// <list>
|
||||
/// - Error with the first encountered error if any transformation fails
|
||||
/// </list>
|
||||
/// </returns>
|
||||
/// <example>
|
||||
/// Basic usage:
|
||||
///
|
||||
/// <code>
|
||||
/// let parseInts = ResultList.collect int "123,456,789".Split(',')
|
||||
/// // Returns Ok [123; 456; 789]
|
||||
/// </code>
|
||||
///
|
||||
///
|
||||
/// Error handling:
|
||||
/// <code>
|
||||
/// let parseInts = ResultList.collect (Result.protect int) ["123"; "abc"; "456"]
|
||||
/// // Returns Error (FormatException "The input string 'abc' was not in a correct format.")
|
||||
/// </code>
|
||||
///
|
||||
///
|
||||
/// Custom transformation:
|
||||
///
|
||||
/// <code>
|
||||
/// let validatePositive x =
|
||||
/// if x > 0 then Ok x else Error "Negative value"
|
||||
/// let result = ResultList.collect validatePositive [1; 2; -3; 4]
|
||||
/// // Returns Error "Negative value"
|
||||
/// </code>
|
||||
/// </example>
|
||||
let collect (lambda: 'a -> Result<'ok, 'err>) (seq_: 'a seq) =
|
||||
let rec iter_ acc seq_ =
|
||||
match Seq.tryHead seq_ with
|
||||
| None -> Ok acc
|
||||
| Some x ->
|
||||
match lambda x with
|
||||
| Error e -> Error e
|
||||
| Ok o -> iter_ (o::acc) (Seq.tail seq_)
|
||||
iter_ [] seq_
|
||||
|
|
|
@ -2,9 +2,9 @@ module Tests.Path
|
|||
|
||||
open NUnit.Framework
|
||||
|
||||
open Pentole
|
||||
open Pentole.TestsExtensions
|
||||
open Pentole.Path
|
||||
open Pentole.Result
|
||||
|
||||
[<Test>]
|
||||
let constructor_test () =
|
||||
|
@ -42,8 +42,8 @@ let resolve_test () =
|
|||
s
|
||||
|> Path.of_string
|
||||
|> Result.map FileSystem.resolve
|
||||
|> Result.get
|
||||
let p (n: string ) = Path.of_string n |> Result.get
|
||||
|> Result.Unsafe.get
|
||||
let p (n: string ) = Path.of_string n |> Result.Unsafe.get
|
||||
|
||||
"/" |> test |> Assert.ok_is_equal (p "/")
|
||||
"/etc/../" |> test |> Assert.ok_is_equal (p "/")
|
||||
|
@ -51,7 +51,7 @@ let resolve_test () =
|
|||
|
||||
[<Test>]
|
||||
let equality_test () =
|
||||
let p (n: string ) = Path.of_string n |> Result.get
|
||||
let p (n: string ) = Path.of_string n |> Result.Unsafe.get
|
||||
Assert.are_equal (p "/etc") (p "/etc/")
|
||||
(*
|
||||
[<Test>]
|
||||
|
|
16
tests/result_tests.fs
Normal file
16
tests/result_tests.fs
Normal file
|
@ -0,0 +1,16 @@
|
|||
module Tests.Result
|
||||
|
||||
open NUnit.Framework
|
||||
|
||||
open Pentole.TestsExtensions
|
||||
|
||||
open Pentole
|
||||
|
||||
[<Test>]
|
||||
let err_test () =
|
||||
let got = ResultList.collect (Result.protect int) ["123"; "abc"; "456"]
|
||||
let msg = "The input string 'abc' was not in a correct format."
|
||||
|
||||
match got with
|
||||
| Ok _ -> Assert.Fail "Expected an error"
|
||||
| Error exn -> Assert.are_equal exn.Message msg
|
|
@ -10,6 +10,7 @@
|
|||
|
||||
<ItemGroup>
|
||||
<Compile Include="bytes_tests.fs" />
|
||||
<Compile Include="result_tests.fs" />
|
||||
<Compile Include="string_tests.fs" />
|
||||
<Compile Include="path_tests.fs" />
|
||||
<Compile Include="Program.fs" />
|
||||
|
|
Loading…
Reference in a new issue