Turn a Generator into a Test, for use with elm-test.
The API is similar to elm-test's Test.fuzz, except that instead of supplying
a fuzzer, you supply a Generator from this package.
When the test is executed, elm-test will check the expectation against every
term in the sequence, starting from the 0th term and continuing until either an
expectation fails, or the generator is exhausted.
import Exhaustive exposing (test, int)
import Test
import Expect
test int "This integer is never zero" <|
\n -> n |> Expect.notEqual 0
--: Test.TestGenerate all values of the unit type, (). There's only one!
import Exhaustive exposing (unit)
unit.nth 0
--> Just ()
unit.nth 1
--> NothingGenerate all boolean values. The 0th term is False, the 1st term is True.
import Exhaustive exposing (bool)
bool.all ()
--> [ False, True ]Generate integer values.
Since the set of all integers is infinite, we don't attempt to generate all of them. Instead, we try a small set of potentially interesting integers, which may be useful in tests:
import Exhaustive exposing (int)
int.all ()
--> [ 0, -1, 1, 2, 3, -10, 10, -100, 100 ](I am open to suggestions for more interesting integers than these!)
If you want to generate a specific list of integers, see the docs for values
instead.
Generate Float values.
Since the set of all floats is infinite, we don't attempt to generate all of them. Instead, we try a small set of potentially interesting floats, which may be useful in tests:
import Exhaustive exposing (float)
float.nth 0
--> Just 0.0(I am open to suggestions for more interesting floats than these!)
If you want to generate a specific list of floats, see the docs for values
instead.
Generate Char values.
Since the set of all Chars is infinite, we don't
attempt to generate all of them. Instead, we try a small set of potentially
interesting Chars, which may be useful in tests:
import Exhaustive exposing (char)
char.nth 0
--> Just ' '(I am open to suggestions for more interesting Chars than these!)
If you want to generate a specific list of Chars, see the docs for values
instead.
Generate String values.
Since the set of all Strings is infinite, we don't
attempt to generate all of them. Instead, we try a small set of potentially
interesting Strings, which may be useful in tests:
import Exhaustive exposing (string)
string.nth 0
--> Just ""(I am open to suggestions for more interesting Strings than these!)
If you want to generate a specific list of Strings, see the docs for values
instead.
Generate all pairs of values of given types.
import Exhaustive exposing (pair, bool)
pairBool =
pair bool bool
pairBool.all ()
--> [ ( False, False ), ( True, False ), ( False, True ), ( True, True ) ]Generate all triples of values of given types.
import Exhaustive exposing (triple, bool, unit)
tripleBoolUnitUnit =
triple bool unit unit
tripleBoolUnitUnit.all ()
--> [ ( False, (), () ), ( True, (), () ) ]Generate all Maybe values of a given type.
import Exhaustive exposing (maybe, bool)
maybeBool =
maybe bool
maybeBool.all ()
--> [ Nothing, Just False, Just True ]Generate all Result values of given error and ok types.
import Exhaustive exposing (result, unit, bool)
resultUnitBool =
result unit bool
resultUnitBool.all ()
--> [ Err (), Ok False, Ok True ]Generate all lists of values of a given type, starting with the empty list
[], and continuing up to lists of a specified length.
import Exhaustive exposing (list, bool)
listBool =
list 1 bool
listBool.all ()
--> [ [], [ False ], [ True ] ]Generate all Dicts of a given key and value type, starting with an empty
Dict and continuing up to Dicts of a specified length.
import Exhaustive exposing (dict, values, unit)
import Dict
myDict =
dict 1
(values [ "a", "b" ])
unit
myDict.all ()
--> [ Dict.fromList [], Dict.fromList [ ( "a", () ) ], Dict.fromList [ ( "b", () ) ] ]Generate all Arrays of a given type, starting with an empty Array and
continuing up to Arrays of a specified length.
import Exhaustive exposing (array, bool)
import Array
arrayBool =
array 1 bool
arrayBool.all ()
--> [ Array.fromList [], Array.fromList [ False ], Array.fromList [ True ] ]Generate all values of a record type. Use with field.
import Exhaustive exposing (record, field, bool, unit)
rec =
record (\foo bar -> { foo = foo, bar = bar })
|> field bool
|> field unit
rec.all ()
--> [ { foo = False, bar = () }, { foo = True, bar = () } ]Specify the contents of a field for a record type. Use with record.
Generate all values of a custom type . Use with variant0, variant1, etc.
import Exhaustive exposing (customType, variant0, variant1, variant2, bool, unit)
type Foo
= Foo Bool
| Bar () Bool
| Baz
foo =
customType
|> variant1 Foo bool
|> variant2 Bar unit bool
|> variant0 Baz
foo.all ()
--> [ Foo False, Foo True, Bar () False, Bar () True, Baz ]Specify a custom type variant with no arguments. Use with customType.
Specify a custom type variant with one argument. Use with customType.
Specify a custom type variant with two arguments. Use with customType.
Specify a custom type variant with three arguments. Use with customType.
Specify a custom type variant with four arguments. Use with customType.
Specify a custom type variant with five arguments. Use with customType.
A Generator that never produces any values.
import Exhaustive exposing (empty)
empty.nth 0
--> NothingA Generator that produces exactly one value.
import Exhaustive exposing (constant)
one =
constant 1
one.nth 0
--> Just 1
one.nth 1
--> NothingA Generator that produces a specific sequence of values.
import Exhaustive exposing (values)
abc =
values [ "a", "b", "c" ]
abc.nth 2
--> Just "c"
abc.nth 3
--> NothingDefine a new generator by providing an implementation for generating the nth term.
import Exhaustive exposing (new)
type Colour
= Red
| Green
| Blue
colour =
new
(\n ->
case n of
0 -> Just Red
1 -> Just Green
2 -> Just Blue
_ -> Nothing
)
colour.all ()
--> [ Red, Green, Blue ](This is a silly example. If you really had a Colour type like this, it would
be better to use the customType and variant0 functions.)
Convert a Generator of one type of value into a Generator of another
type of value.
import Exhaustive exposing (map, int)
type Id
= Id Int
id =
map Id int
id.nth 0
--> Just (Id 0)Create a Generator for values of one type based on the values produced by
a generator of another type.
import Exhaustive exposing (andThen, bool, constant, values)
oneTwoThree =
bool
|> andThen
(\b ->
case b of
False ->
values [ 1, 2 ]
True ->
constant 3
)
oneTwoThree.all ()
--> [ 1, 2, 3 ]Combine two Generators of the same type. This will first generate all the
values from the first generator, and then all the values from the second
generator.
import Exhaustive exposing (append, values)
oneTwoThreeFour =
append (values [ 1, 2 ]) (values [ 3, 4 ])
oneTwoThreeFour.all ()
--> [ 1, 2, 3, 4 ]
A
Generatorprovides a set of functions that are useful when generating values of a given type.The functions are:
count : IntThe total number of values that will be produced by the generator
nth : Int -> Maybe valueGenerate the nth value in the sequence. Sequences begin at n = 0. This function returns
Nothingif you pass an integer that is greater thancount.all : () -> List valueGenerate a list of all the values that the generator can produce, starting with n = 0 and ending with n = count. To avoid creating huge lists unnecessarily, you need to pass a
()to this function to generate the list.every : Int -> List valueGenerate a list of a subset of values, starting with the value at n = 0 and then taking values at a specified interval.
sample : Float -> List valueGenerate a list of an evenly distributed percentage of the values that the generator can produce, starting with the value at n = 0. The percentage should be specified as a
Floatbetween 0.0 and 1.0.