Testing functions returning option<T> - unit-testing

Consider unit-testing a module defining strings of constrained length as a type for representing user names:
module UserName
type T = UserName of string
let create (userName : string) =
if userName.Length >= 6 && userName.Length <= 16
then Some (UserName userName)
else None
let apply f (UserName userName) = f userName
let value userName = apply id userName
A unit test to ensure that the function returns None for an invalid input looks simple:
[<Fact>]
let ``UserName must have at least six characters`` () =
UserName.create "aaa" |> should equal None
However, a unit test for the case when the function returns Some appears to require an extra line for completeness of the match expression:
[<Fact>]
let ``Valid UserName`` () =
match UserName.create "validname" with
| Some result ->
UserName.value result |> should equal "validname"
| None -> Assert.True(false)
This does not look right to me, because my tests must define code for testing the "unhappy" path that must yield a failure anyway.
I wish I could write this instead
[<Fact>]
let ``Valid UserName`` () =
UserName.create "validname" |> should equal (Some (UserName "validname"))
but it does not compile (The value or constructor 'UserName' is not defined).
Is there a way to write a unit test of a function returning option<T> that does not require an explicit check of the "unhappy" path (e.g. | None -> Assert.True(false))? I am open to adding more types and/or functions to the UserName module to make it more testable.

Apply value to the inside of Some and then compare:
UserName.create "validname"
|> Option.map UserName.value
|> should equal (Some "validname")

Related

test haskell io for custom data type

Update: I noticed that there was a problem in the design of my code. The overall structure of my code has changed so much that any answer to this question would be more or less irrelevant to its current state. But SO says it's better not to delete an answered question, so I am keeping the question.
The problem with my code was that typeclasses were too generic for what I wanted to do. Now I concentrate on writting functions like
makeModelId :: String -> Either StringValueError ModelId
Then extend that with something like:
makeModelIdM :: (Monad m) => String -> m (Either StringValueError ModelId)
makeModelIdM astr = do
idstr <- astr
return (makeModelId idstr)
I am not sure if it is the best approach though..
I know that there are lots of similar questions to this like this or this or this, and as far I understood what I want to do can be achieved with HUnit. But I can't seem to find the exact way of doing it.
I basically have a setter typeclass which is
class StringLike2Primitive model where
fromString :: String -> model
fromText :: Text -> model
fromText aText = fromString (unpack aText)
class (StringLike2Primitive model) => StringLike2PrimitiveM model where
fromStringM :: (MonadPlus m) => String -> m model
fromTextM :: (MonadPlus m) => Text -> m model
fromStringM astr = return (fromString astr)
fromTextM aText = fromStringM (unpack aText)
And I have couple of data types which implement these typeclasses, for example:
instance StringLike2Primitive ModelId where
fromString = StringIdCons
instance StringLike2PrimitiveM ModelId where
fromStringM aStr
| null aStr = fail "empty string is not allowed as id"
| not (isAlphaNumStr aStr) = fail
"Only ascii alphanumeric strings are allowed"
| not (isAsciiStr aStr) = fail
"Only ascii alphanumeric strings are allowed"
I am not sure how can I test fromStringM function against guarded values in a unit test environment, and I think my approach to error handling is problematic. Any tips would be appreciated.
(This is more of a comment, but might be an answer as well.)
Are you sure you need a second type class? The definition of fromStringM doesn't rely on the StringLike2Primitive instance so much as it simply wraps it.
fromStringM :: (Monad m, StringLike2Primitive a) => String -> m a
fromStringM a
| null a = fail "empty string is not allowed"
| not (isAlphaNumStr aStr) = fail "Only ascii alphanumeric strings are allowed"
| not (isAsciiStr aStr) = fail "Only ascii strings are allowed"
| otherwise = return $ fromString a
and likewise for fromText.

Use meta-programming in F* for a syntactic check on a function argument

I would like to write a function that enforces that its argument is, syntactically, a constant string. Here's what I tried:
module Test
module R = FStar.Reflection
let is_literal (t: R.term) =
match R.inspect_ln t with
| R.Tv_Const (R.C_String _) -> true
| _ -> false
let check_literal (s: string { normalize (is_literal (`s)) }) =
()
let test () =
check_literal ""; // should work
let s = "" in
check_literal s // should not work
However, I'm pretty sure static quotations (with `) are not what I want, but instead dynamic quotations with quote. But this would put my precondition into the Tac effect. Is there any way to do what I want in the current state of things?
I don't know if you finally found a solution, but what about implicit meta arguments?
They somehow allow running Tac code at function invocation time, making quote usable.
Changing your code a bit doing so seems to work:
module Is_lit
open FStar.Tactics
let is_literal (t: term) =
match inspect_ln t with
| Tv_Const (C_String _) -> true
| _ -> false
let check_literal (s: string)
(#[(if (normalize_term (is_literal (quote s)))
then exact (`())
else fail "not a litteral")
] witness: unit)
: unit =
()
// success
let _ = check_literal "hey"
// failure
[#expect_failure]
let _ = let s = "hey" in check_literal s

F# UnitTesting function with side effect

I am C# dev that has just starting to learn F# and I have a few questions about unit testing. Let's say I want to the following code:
let input () = Console.In.ReadLine()
type MyType= {Name:string; Coordinate:Coordinate}
let readMyType =
input().Split(';')
|> fun x -> {Name=x.[1]; Coordinate = {
Longitude = float(x.[4].Replace(",","."))
Latitude =float(x.[5].Replace(",","."))
}}
As you can notice, there are a few points to take in consideration:
readMyType is calling input() with has a side effect.
readMyType assume many thing on the string read (contains ';' at least 6 columns, some columns are float with ',')
I think the way of doing this would be to:
inject the input() func as parameter
try to test what we are getting (pattern matching?)
Using NUnit as explained here
To be honest I'm just struggling to find an example that is showing me this, in order to learn the syntax and other best practices in F#. So if you could show me the path that would be very great.
Thanks in advance.
First, your function is not really a function. It's a value. The distinction between functions and values is syntactic: if you have any parameters, you're a function; otherwise - you're a value. The consequence of this distinction is very important in presence of side effects: values are computed only once, during initialization, and then never change, while functions are executed every time you call them.
For your specific example, this means that the following program:
let main _ =
readMyType
readMyType
readMyType
0
will ask the user for only one input, not three. Because readMyType is a value, it gets initialized once, at program start, and any subsequent reference to it just gets the pre-computed value, but doesn't execute the code over again.
Second, - yes, you're right: in order to test this function, you'd need to inject the input function as a parameter:
let readMyType (input: unit -> string) =
input().Split(';')
|> fun x -> {Name=x.[1]; Coordinate = {
Longitude = float(x.[4].Replace(",","."))
Latitude =float(x.[5].Replace(",","."))
}}
and then have the tests supply different inputs and check different outcomes:
let [<Test>] ``Successfully parses correctly formatted string``() =
let input() = "foo;the_name;bar;baz;1,23;4,56"
let result = readMyType input
result |> should equal { Name = "the_name"; Coordinate = { Longitude = 1.23; Latitude = 4.56 } }
let [<Test>] ``Fails when the string does not have enough parts``() =
let input() = "foo"
(fun () -> readMyType input) |> shouldFail
// etc.
Put these tests in a separate project, add reference to your main project, then add test runner to your build script.
UPDATE
From your comments, I got the impression that you were seeking not only to test the function as it is (which follows from your original question), but also asking for advice on improving the function itself, so as to make it more safe and usable.
Yes, it is definitely better to check error conditions within the function, and return appropriate result. Unlike C#, however, it is usually better to avoid exceptions as control flow mechanism. Exceptions are for exceptional situations. For such situations that you would have never expected. That is why they are exceptions. But since the whole point of your function is parsing input, it stands to reason that invalid input is one of the normal conditions for it.
In F#, instead of throwing exceptions, you would usually return a result that indicates whether the operation was successful. For your function, the following type seems appropriate:
type ErrorMessage = string
type ParseResult = Success of MyType | Error of ErrorMessage
And then modify the function accordingly:
let parseMyType (input: string) =
let parts = input.Split [|';'|]
if parts.Length < 6
then
Error "Not enough parts"
else
Success
{ Name = parts.[0]
Coordinate = { Longitude = float(parts.[4].Replace(',','.')
Latitude = float(parts.[5].Replace(',','.') }
}
This function will return us either MyType wrapped in Success or an error message wrapped in Error, and we can check this in tests:
let [<Test>] ``Successfully parses correctly formatted string``() =
let input() = "foo;the_name;bar;baz;1,23;4,56"
let result = readMyType input
result |> should equal (Success { Name = "the_name"; Coordinate = { Longitude = 1.23; Latitude = 4.56 } })
let [<Test>] ``Fails when the string does not have enough parts``() =
let input() = "foo"
let result = readMyType input
result |> should equal (Error "Not enough parts)
Note that, even though the code now checks for enough parts in the string, there are still other possible error conditions: for example, parts.[4] may be not a valid number.
I am not going to expand on this further, as that will make the answer way too long. I will only stop to mention two points:
Unlike C#, verifying all error conditions does not have to end up as a pyramid of doom. Validations can be nicely combined in a linear-looking way (see example below).
The F# 4.1 standard library already provides a type similar to ParseResult above, named Result<'t, 'e>.
For more on this approach, check out this wonderful post (and don't forget to explore all links from it, especially the video).
And here, I will leave you with an example of what your function could look like with full validation of everything (keep in mind though that this is not the cleanest version still):
let parseFloat (s: string) =
match System.Double.TryParse (s.Replace(',','.')) with
| true, x -> Ok x
| false, _ -> Error ("Not a number: " + s)
let split n (s:string) =
let parts = s.Split [|';'|]
if parts.Length < n then Error "Not enough parts"
else Ok parts
let parseMyType input =
input |> split 6 |> Result.bind (fun parts ->
parseFloat parts.[4] |> Result.bind (fun lgt ->
parseFloat parts.[5] |> Result.bind (fun lat ->
Ok { Name = parts.[1]; Coordinate = { Longitude = lgt; Latitude = lat } } )))
Usage:
> parseMyType "foo;name;bar;baz;1,23;4,56"
val it : Result<MyType,string> = Ok {Name = "name";
Coordinate = {Longitude = 1.23;
Latitude = 4.56;};}
> parseMyType "foo"
val it : Result<MyType,string> = Error "Not enough parts"
> parseMyType "foo;name;bar;baz;badnumber;4,56"
val it : Result<MyType,string> = Error "Not a number: badnumber"
This is a little follow-up to the excellent answer of #FyodorSoikin trying to explore the suggestion
keep in mind though that this is not the cleanest version still
Making the ParseResult generic
type ParseResult<'a> = Success of 'a | Error of ErrorMessage
type ResultType = ParseResult<Defibrillator> // see the Test Cases
we can define a builder
type Builder() =
member x.Bind(r :ParseResult<'a>, func : ('a -> ParseResult<'b>)) =
match r with
| Success m -> func m
| Error w -> Error w
member x.Return(value) = Success value
let builder = Builder()
so we get a concise notation:
let parse input =
builder {
let! parts = input |> split 6
let! lgt = parts.[4] |> parseFloat
let! lat = parts.[5] |> parseFloat
return { Name = parts.[1]; Coordinate = { Longitude = lgt; Latitude = lat } }
}
Test Cases
Tests are always fundamental
let [<Test>] ``3. Successfully parses correctly formatted string``() =
let input = "foo;the_name;bar;baz;1,23;4,56"
let result = parse input
result |> should equal (ResultType.Success { Name = "the_name"; Coordinate = { Longitude = 1.23; Latitude = 4.56 } })
let [<Test>] ``3. Fails when the string does not have enough parts``() =
let input = "foo"
let result = parse input
result |> should equal (ResultType.Error "Not enough parts")
let [<Test>] ``3. Fails when the string does not contain a number``() =
let input = "foo;name;bar;baz;badnumber;4,56"
let result = parse input
result |> should equal (ResultType.Error "Not a number: badnumber")
Notice the usage of a specific ParseResult from the generic one.
minor note
Double.TryParse is just enough in the following
let parseFloat (s: string) =
match Double.TryParse s with
| true, x -> Success x
| false, _ -> Error ("Not a number: " + s)

What's the difference between "let ()=" and "let _=" ;

let () = Random.self_init();;
let _ = Random.self_init ();;
│- : unit = ()
It seems "let ()" returns nothing ?
Sincerely!
let is the keyword used to define new variables, like in the following construct:
let pattern = expr
For instance
let a = 2
assigns the value 2 to the name a. (Note this is not a way to assign a value to an already existing variable, but this is another topic).
But the pattern to the left of the = sign can be more than just a name. For instance
let (a,b) = (42,"foo")
defines both a and b, to be respectively 42 and "foo".
Of course, the types on both sides must match.
Which is the case here: both sides are of type int * string.
The expressions to the right of the = sign can also be elaborated, for instance
let foo =
let temp = String.make 10 'a' in
temp.[2] <- 'b';
temp
defines foo as the string "aabaaaaaaa". (As a side note, it also ensures that temp is local to this code snippet).
Now, let's use both: on the left, a pattern matching values of type unit, and on the right, an expression of type unit:
let () = Printf.printf "Hello world!\n"
Which explains the let () = construct.
Now, about the let _, one simply needs to know that _ can be used in a pattern as a wildcard: it matches values of any type and does not bind any name. For instance
let (a,_) = (42,"foo")
defines a as 42, and discards the value "foo". _ means "I know there is something here and I explicitly say I will not use it, so I don't name it". Here _ was used to match values of type string, but it can match value of any type, like int * string:
let _ = (42,"foo")
which does not define any variable and is not very useful. Such constructs are useful when the right hand side has side effects, like this:
let _ = Printf.printf "Hello world!\n"
which explains the second part of the question.
Practical purposes
Both are used and it's rather a matter of taste whether to use one or the other.
let () = is slightly safer as it has the compiler check that the right hand side is of type unit.
A value of any other type than unit is often a bug.
let _ = is slightly shorter (I've seen this argument). (Note that with an editor that automatically closes parenthesizes, the number of keystrokes is the same ;-)
I'm not an OCaml expert, although let me share something :)
The let in OCaml can represent two things:
The way you can assign variables;
The way you can declare functions or assign functions to names;
Using examples, you can see clearly how it works:
Assigning variables:
# let ten = 10;;
val ten : int = 10
# let hello_world_string = "Hello World";;
val hello_world_string : string = "Hello World"
Declaring functions:
# let sum a b = a+b;;
val sum : int -> int -> int = <fun>
# sum 2 3;;
- : int = 5
So, answering the question the difference between let ()= and let _= is:
At first example, you are declaring a function that doesn't have name, parameters nor instructions that should output an unit. The second example, you aren't assigning to _, that is OCaml's wildcard, any value.
As we can see below, we can define a function, that will be executed immediatly because we won't be able to call it anymore:
# let () = print_string "Hello";;
Hello
Or assign to OCaml's wildcard a type and value, or a function:
# let _ = 10;;
- : int = 10
# let _ = print_string "Maybe I answered your question :) ";;
Maybe I answered your question :) - : unit = ()

F# Active Pattern List.filter or equivalent

I have a records of types
type tradeLeg = {
id : int ;
tradeId : int ;
legActivity : LegActivityType ;
actedOn : DateTime ;
estimates : legComponents ;
entryType : ShareOrDollarBased ;
confirmedPrice: DollarsPerShare option;
actuals : legComponents option ;
type trade = {
id : int ;
securityId : int ;
ricCode : string ;
tradeActivity : TradeType ;
enteredOn : DateTime ;
closedOn : DateTime ;
tradeLegs : tradeLeg list ;
}
Obviously the tradeLegs are a type off of a trade. A leg may be settled or unsettled (or unsettled but price confirmed) - thus I have defined the active pattern:
let (|LegIsSettled|LegIsConfirmed|LegIsUnsettled|) (l: tradeLeg) =
if Helper.exists l.actuals then LegIsSettled
elif Helper.exists l.confirmedPrice then LegIsConfirmed
else LegIsUnsettled
and then to determine if a trade is settled (based on all legs matching LegIsSettled pattern:
let (|TradeIsSettled|TradeIsUnsettled|) (t: trade) =
if List.exists (
fun l ->
match l with
| LegIsSettled -> false
| _ -> true) t.tradeLegs then TradeIsSettled
else TradeIsUnsettled
I can see some advantages of this use of active patterns, however i would think there is a more efficient way to see if any item of a list either matches (or doesn't) an actie pattern without having to write a lambda expression specifically for it, and using List.exist.
Question is two fold:
is there a more concise way to express this?
is there a way to abstract the functionality / expression
(fun l ->
match l with
| LegIsSettled -> false
| _ -> true)
Such that
let itemMatchesPattern pattern item =
match item with
| pattern -> true
| _ -> false
such I could write (as I am reusing this design-pattern):
let curriedItemMatchesPattern = itemMatchesPattern LegIsSettled
if List.exists curriedItemMatchesPattern t.tradeLegs then TradeIsSettled
else TradeIsUnsettled
Thoughts?
To answer your question about active patterns, let me use a simpler example:
let (|Odd|Even|) n =
if n % 2 = 0 then Even else Odd
When you declare a pattern that has multiple options using (|Odd|Even|), then the compiler understands it as a function that returns a value of type Choice<unit, unit>. So, the active pattern that you can work with is the whole combination |Odd|Even| and not just two constructs that you could use independently (such as |Odd| and |Even|).
It is possible to treat active patterns as first class functions, but if you're using patterns with multiple options, you cannot do much with it:
let pattern = (|Odd|Even|);;
val pattern : int -> Choice
You can write function that tests whether a value matches a specified pattern, but you'd need a lot of functions (because there are many Choice types overloaded by the number of type parameters):
let is1Of2 pattern item =
match pattern item with
| Choice1Of2 _ -> true
| _ -> false
> is1Of2 (|Odd|Even|) 1
val it : true
Something like this would work in your case, but it is far from being perfect.
You can do a little better job if you declare multiple partial active patterns (but then you of course loose some nice aspects of full active patterns such as completeness checking):
let (|Odd|_|) n =
if n % 2 = 0 then None else Some()
let (|Even|_|) n =
if n % 2 = 0 then Some() else None
Now you can write a function that checks whether a value matches pattern:
let matches pattern value =
match pattern value with
| Some _ -> true
| None -> false
> matches (|Odd|_|) 1;;
val it : bool = true
> matches (|Even|_|) 2;;
val it : bool = true
Summary While there may be some more or less elegant way to achieve what you need, I'd probably consider whether active patterns give you any big advantage over using standard functions. It may be a better idea to implenent the code using functions first and then decide which of the constructs would be useful as active patterns and add active patterns later. In this case, the usual code wouldn't look much worse:
type LegResult = LegIsSettled | LegIsConfirmed | LegIsUnsettled
let getLegStatus (l: tradeLeg) =
if Helper.exists l.actuals then LegIsSettled
elif Helper.exists l.confirmedPrice then LegIsConfirmed
else LegIsUnsettled
// Later in the code you would use pattern matching
match getLegStatus trade with
| LegIsSettled -> // ...
| LegIsUnSettled -> // ...
// But you can still use higher-order functions too
trades |> List.exist (fun t -> getLegStatus t = LegIsSettled)
// Which can be rewritten (if you like point-free style):
trades |> List.exist (getLegStatus >> ((=) LegIsSettled))
// Or you can write helper function (which is more readable):
let legStatusIs check trade = getLegStatus trade = check
trades |> List.exist (legStatusIs LegIsSettled)
In addition to Tomas's points on the actual details of active patterns, note that you can always shorten fun x -> match x with |... to function | ..., which will save a few keystrokes as well as the need to make up a potentially meaningless identifier.