Practical Persimmon.Dried
Arbitray
You can use arbitraries flexibly: there are various arbitraries for basic types like Arb.int
, Arb.byte
and Arb.string
, and for collection types like Arb.list Arb.int
, Arb.array Arb.float
and Arb.map Arb.int Arb.string
.
You can also use arbitraries for functions or System.Func
:
1: 2: 3: 4: 5: 6: 7: 8: 9: |
|
A module CoArb
represents the module of “arbitraries for functions (which are arbitraries)”.
If you want to treat arbitraries of collection types as non-empty or non-null, you can:
1: 2: 3: 4: 5: 6: 7: 8: 9: |
|
Arbitrary and Gen
When you use Persimmon.Dried, you may want to generate arguments as well as you think. You can make another arbitrary from the present one.
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: |
|
The basic arbitraries are F# records which have 3 values (labels), Gen
, Shrinker
and PrettyPrinter
. In these labels, Gen
: Gen<'T>
takes charge of generating values, so controling it makes the result better.
Gen
module has a lot of useful functions fo Gen<'T> values. There are examples in the following subsections.
oneOf
oneOf
function takes a sequence of Gen<'T> then returns one of elements in it.
1: 2: 3: 4: 5: 6: 7: 8: 9: |
|
suchThat
suchThat
function takes Gen<'T> value and a condition function, then returns Gen<'T> to generate values which satisfy the condition.
1: 2: 3: 4: 5: 6: 7: 8: |
|
listOfLength
listOfLength
function takes a length number N and Gen<'T>, then returns Gen<'T list> which generates N-length ‘T list.
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: |
|
There are similar functions such as listOfMaxLength
which generates lists less than or equal to length N, and listOfMinLength
which generates lists greater than or equal to length N.
If you want to know more about Gen, let’s read the source code.
Properties
In Prop
module, there are useful functions and operators to write properties.
And / Or operator
The And operator .&.
succeeds if both of properties succeed, otherwise fails.
1: 2: 3: 4: 5: 6: |
|
On the other hand, the Or operator .|.
succeeds if either property succeeds, fails if both fail.
1: 2: 3: 4: 5: 6: |
|
If you execute each 2 properties, and operator will fail and or operator will succeed.
|@
and @|
you see in the code snipets above are the labeling operators. You can use them as p |@ s or s @| p, then label p s.
Conditional property
==>
operator checks a right hand side property only if a left hand side property succeeds.
1: 2: 3: 4: 5: |
|
This snipet checks whether the length of i :: ls is greater than 6 or not if the input list ls has greater length than 5.
Note that the binary operators which take both properties, same as .&.
or .|.
, must take its right hand side property as lazy
. This restriction is for the reason that F# mainly uses eager evaluation. In the case of rasing an exception when the right property is evaluated, the exception is occurred at the time of passing both properties to the operator, then the check fails.
1: 2: 3: 4: |
|
Classify properties
classify
function is similar to the labeling operators in the way of naming properties. Moreover, it can classify them by any conditions.
1: 2: 3: 4: 5: 6: 7: |
|
When you execute the snipet above, it may show you as follows:
1:
|
|
|
You can get the ratio of failing arguments from here.
Full name: Practice.prms
Full name: Practice.( function as parameter )
val int : value:'T -> int (requires member op_Explicit)
Full name: Microsoft.FSharp.Core.Operators.int
--------------------
type int = int32
Full name: Microsoft.FSharp.Core.int
--------------------
type int<'Measure> = int
Full name: Microsoft.FSharp.Core.int<_>
Full name: Practice.( System.Func as parameter )
val string : value:'T -> string
Full name: Microsoft.FSharp.Core.Operators.string
--------------------
type string = System.String
Full name: Microsoft.FSharp.Core.string
Full name: Practice.( non empty list )
Full name: Microsoft.FSharp.Collections.list<_>
module List
from Microsoft.FSharp.Collections
--------------------
Full name: Practice.( non null array )
Full name: Microsoft.FSharp.Core.array<_>
from Microsoft.FSharp.Collections
Full name: Microsoft.FSharp.Collections.Array.length
Full name: Practice.arbLs
Full name: Practice.( list of max length 3 )
Full name: Practice.arbOneOf
Full name: Practice.( get one of prime numbers )
Full name: Practice.arbEven
Full name: Practice.( only even number )
Full name: Practice.arbList3
Full name: Practice.arbList5
Full name: Practice.( list of length )
Full name: Practice.( and operator )
Full name: Practice.( or operator )
Full name: Practice.( conditional property )
Full name: Practice.( right hand side executes... what? )
Full name: Practice.( classifying test case )