module QCheck:`sig`

..`end`

The library takes inspiration from Haskell's QuickCheck library. The rough idea is that the programer describes invariants that values of a certain type need to satisfy ("properties"), as functions from this type to bool. She also needs to desribe how to generate random values of the type, so that the property is tried and checked on a number of random instances.

This explains the organization of this module:

`'a arbitrary`

is used to describe how to generate random values, shrink them (make counter-examples as small as possible), print them, etc. Auxiliary modules such as`QCheck.Gen`

,`QCheck.Print`

, and`QCheck.Shrink`

can be used along with`QCheck.make`

to build one's own arbitrary instances.

`QCheck.Test`

is used to describe a single test, that is, a property of type`'a -> bool`

combined with an`'a arbitrary`

that is used to generate the test cases for this property. Optional parameters allow to specify the random generator state, number of instances to generate and test, etc.

- List.rev is involutive:

```
let test =
QCheck.(Test.make ~count:1000
(list int) (fun l -> List.rev (List.rev l) = l));;
QCheck.Test.run_exn test;;
```

- Not all lists are sorted (false property that will fail. The 15 smallest counter-example lists will be printed):

```
let test = QCheck.(
Test.make
~count:10_000 ~max_fail:3
(list small_int)
(fun l -> l = List.sort compare l));;
QCheck.Test.check_exn test;;
```

- generate 20 random trees using
`Arbitrary.fix`

:

```
type tree = Leaf of int | Node of tree * tree
let leaf x = Leaf x
let node x y = Node (x,y)
let g = QCheck.Gen.(sized @@ fix
(fun self n -> match n with
| 0 -> map leaf nat
| n ->
frequency
[1, map leaf nat;
2, map2 node (self (n/2)) (self (n/2))]
))
Gen.generate ~n:20 g;;
```

More complex and powerful combinators can be found in Gabriel Scherer's
`Generator`

module. Its documentation can be found
here.

`val (==>) : ``bool -> bool -> bool`

`b1 ==> b2`

is the logical implication `b1 => b2`

ie `not b1 || b2`

(except that it is strict and will interact
better with `QCheck.Test.check_exn`

and the likes, because they will know
the precondition was not satisfied.).module Gen:`sig`

..`end`

Generate Random Values

module Print:`sig`

..`end`

Show Values

module Iter:`sig`

..`end`

Iterators

module Shrink:`sig`

..`end`

Shrink Values

A value of type `'a arbitrary`

glues together a random generator,
and optional functions for shrinking, printing, computing the size,
etc. It is the "normal" way of describing how to generate
values of a given type, to be then used in tests (see `QCheck.Test`

)

`type ``'a`

arbitrary = {

` ` |
`gen : ` |
|||

` ` |
`print : ` |
`(*` |
print values
| `*)` |

` ` |
`small : ` |
`(*` |
size of example
| `*)` |

` ` |
`shrink : ` |
`(*` |
shrink to smaller examples
| `*)` |

` ` |
`collect : ` |
`(*` |
map value to tag, and group by tag
| `*)` |

a value of type

`'a arbitrary`

is an object with a method for generating random
values of type `'a`

, and additional methods to compute the size of values,
print them, and possibly shrink them into smaller counterexamples
**NOTE** the collect field is unstable and might be removed, or
moved into `QCheck.Test`

.

`val make : ``?print:'a Print.t ->`

?small:('a -> int) ->

?shrink:'a Shrink.t ->

?collect:('a -> string) -> 'a Gen.t -> 'a arbitrary

Builder for arbitrary. Default is to only have a generator, but other
arguments can be added

`val set_print : ``'a Print.t -> 'a arbitrary -> 'a arbitrary`

`val set_small : ``('a -> int) -> 'a arbitrary -> 'a arbitrary`

`val set_shrink : ``'a Shrink.t -> 'a arbitrary -> 'a arbitrary`

`val set_collect : ``('a -> string) -> 'a arbitrary -> 'a arbitrary`

`val choose : ``'a arbitrary list -> 'a arbitrary`

Choose among the given list of generators. The list must not
be empty; if it is Invalid_argument is raised.

`val unit : ``unit arbitrary`

always generates

`()`

, obviously.`val bool : ``bool arbitrary`

uniform boolean generator

`val float : ``float arbitrary`

generates regular floats (no nan and no infinities)

`val pos_float : ``float arbitrary`

positive float generator (no nan and no infinities)

`val neg_float : ``float arbitrary`

negative float generator (no nan and no infinities)

`val int : ``int arbitrary`

int generator. Uniformly distributed

`val int_bound : ``int -> int arbitrary`

`int_bound n`

is uniform between `0`

and `n`

included`val int_range : ``int -> int -> int arbitrary`

`int_range a b`

is uniform between `a`

and `b`

included. `b`

must be
larger than `a`

.`val (--) : ``int -> int -> int arbitrary`

Synonym to

`QCheck.int_range`

`val int32 : ``int32 arbitrary`

int32 generator. Uniformly distributed

`val int64 : ``int64 arbitrary`

int generator. Uniformly distributed

`val pos_int : ``int arbitrary`

positive int generator. Uniformly distributed

`val small_int : ``int arbitrary`

positive int generator. The probability that a number is chosen
is roughly an exponentially decreasing function of the number.

`val small_int_corners : ``unit -> int arbitrary`

As

`small_int`

, but each newly created generator starts with
a list of corner cases before falling back on random generation.`val neg_int : ``int arbitrary`

negative int generator. The distribution is similar to that of

`small_int`

, not of `pos_int`

.`val char : ``char arbitrary`

Uniformly distributed on all the chars (not just ascii or
valid latin-1)

`val printable_char : ``char arbitrary`

uniformly distributed over a subset of chars

`val numeral_char : ``char arbitrary`

uniformy distributed over

`'0'..'9'`

`val string_gen_of_size : ``int Gen.t -> char Gen.t -> string arbitrary`

`val string_gen : ``char Gen.t -> string arbitrary`

generates strings with a distribution of length of

`small_int`

`val string : ``string arbitrary`

generates strings with a distribution of length of

`small_int`

and distribution of characters of `char`

`val small_string : ``string arbitrary`

`val string_of_size : ``int Gen.t -> string arbitrary`

generates strings with distribution of characters if

`char`

`val printable_string : ``string arbitrary`

generates strings with a distribution of length of

`small_int`

and distribution of characters of `printable_char`

`val printable_string_of_size : ``int Gen.t -> string arbitrary`

generates strings with distribution of characters of

`printable_char`

`val small_printable_string : ``string arbitrary`

`val numeral_string : ``string arbitrary`

generates strings with a distribution of length of

`small_int`

and distribution of characters of `numeral_char`

`val numeral_string_of_size : ``int Gen.t -> string arbitrary`

generates strings with a distribution of characters of

`numeral_char`

`val list : ``'a arbitrary -> 'a list arbitrary`

generates lists with length generated by

`small_int`

`val list_of_size : ``int Gen.t -> 'a arbitrary -> 'a list arbitrary`

generates lists with length from the given distribution

`val array : ``'a arbitrary -> 'a array arbitrary`

generates arrays with length generated by

`small_int`

`val array_of_size : ``int Gen.t -> 'a arbitrary -> 'a array arbitrary`

generates arrays with length from the given distribution

`val pair : ``'a arbitrary -> 'b arbitrary -> ('a * 'b) arbitrary`

combines two generators into a generator of pairs

`val triple : ``'a arbitrary ->`

'b arbitrary -> 'c arbitrary -> ('a * 'b * 'c) arbitrary

combines three generators into a generator of 3-uples

`val option : ``'a arbitrary -> 'a option arbitrary`

choose between returning Some random value, or None

`val fun1 : ``'a arbitrary -> 'b arbitrary -> ('a -> 'b) arbitrary`

generator of functions of arity 1.
The functions are always pure and total functions:

- when given the same argument (as decided by Pervasives.(=)), it returns the same value
- it never does side effects, like printing or never raise exceptions etc. The functions generated are really printable.

`val fun2 : ``'a arbitrary ->`

'b arbitrary ->

'c arbitrary -> ('a -> 'b -> 'c) arbitrary

generator of functions of arity 2. The remark about

`fun1`

also apply
here.`val oneofl : ``?print:'a Print.t ->`

?collect:('a -> string) -> 'a list -> 'a arbitrary

Pick an element randomly in the list

`val oneofa : ``?print:'a Print.t ->`

?collect:('a -> string) -> 'a array -> 'a arbitrary

Pick an element randomly in the array

`val oneof : ``'a arbitrary list -> 'a arbitrary`

Pick a generator among the list, randomly

`val always : ``?print:'a Print.t -> 'a -> 'a arbitrary`

Always return the same element

`val frequency : ``?print:'a Print.t ->`

?small:('a -> int) ->

?shrink:'a Shrink.t ->

?collect:('a -> string) ->

(int * 'a arbitrary) list -> 'a arbitrary

Similar to

`QCheck.oneof`

but with frequencies`val frequencyl : ``?print:'a Print.t ->`

?small:('a -> int) -> (int * 'a) list -> 'a arbitrary

Same as

`QCheck.oneofl`

, but each element is paired with its frequency in
the probability distribution (the higher, the more likely)`val frequencya : ``?print:'a Print.t ->`

?small:('a -> int) -> (int * 'a) array -> 'a arbitrary

Same as

`QCheck.frequencyl`

, but with an array`val map : ``?rev:('b -> 'a) -> ('a -> 'b) -> 'a arbitrary -> 'b arbitrary`

`map f a`

returns a new arbitrary instance that generates values using
`a#gen`

and then transforms them through `f`

.`rev`

: if provided, maps values back to type `'a`

so that the printer,
shrinker, etc. of `a`

can be used. We assume `f`

is monotonic in
this case (that is, smaller inputs are transformed into smaller outputs).`val map_same_type : ``('a -> 'a) -> 'a arbitrary -> 'a arbitrary`

Specialization of

`map`

when the transformation preserves the type, which
makes shrinker, printer, etc. still relevant`val map_keep_input : ``?print:'b Print.t ->`

?small:('b -> int) ->

('a -> 'b) -> 'a arbitrary -> ('a * 'b) arbitrary

`map_keep_input f a`

generates random values from `a`

, and maps them into
values of type `'b`

using the function `f`

, but it also keeps the
original value.
For shrinking, it is assumed that `f`

is monotonic and that smaller input
values will map into smaller values`print`

: optional printer for the `f`

's outputmodule TestResult:`sig`

..`end`

module Test:`sig`

..`end`