hedgehogqa / hedgehogqa/fsharp-hedgehog
Unifying `Property<unit>` and `Property<bool>`
- Dominant language
- F#
- Stars
- 284
- Forks
- 31
- PR merge metrics
- No merged PRs in 30d
Description
I've been looking through Haskell Hedgehog recently, and I noticed that their `Property` type is not polymorphic. I'd like to get the F# version in line with this, and I have some ideas on how this might be done, though I'm very open to ideas/suggestions here.
```fsi
module Property =
/// Turns a generator into a property, verifying that the condition always holds.
val always : ('a -> bool) -> Gen<'a> -> Property
/// Turns a bool generator into a property, verifying that the generator always generates `true`.
val alwaysTrue : Gen -> Property
/// Turns a bool generator into a property, verifying that the generator always generates `false`.
val alwaysFalse : Gen -> Property
/// Turns a `Result` generator into a property, verifying that the generator always generates `Ok`.
val alwaysOk : Gen> -> Property
/// Turns a `Result` generator into a property, verifying that the generator always generates `Error`.
val alwaysError : Gen> -> Property
/// Turns a unit generator into a property, verifying that the generator always throws a specific exception.
/// This could resolve `#128`.
val alwaysThrowsExact<'exn :> exn> : Gen -> Property
/// Turns a unit generator into a property, verifying that the generator always throws an exception.
val alwaysThrows : Gen -> Property
/// Turns a unit generator into a property, verifying that the generator never throws an exception.
/// Alias for Property.forAll?
val neverThrows : Gen -> Property
```
This API would be used like so:
```fsharp
gen {
let! x = Gen.bool
Expect.equal x x "x = x"
}
|> Property.neverThrows
|> Property.check
gen {
let! x = Gen.bool
return x = x
}
|> Property.alwaysTrue
|> Property.check
gen {
raise (NotImplementedException())
}
|> Property.alwaysThrowsExact
|> Property.check
gen {
let! z = Gen.int32 (Range.constantBounded ())
return z
}
|> Property.always (fun x -> x <> 0)
|> Property.check
```
I'm still unsure how we would support `counterexample` and maybe another function or two with this, mostly because I haven't dug into them yet.
Contributor guide
Research direction
Start by reading the existing Property API and comparing the current Property and Property behavior. Resolve the proposed polymorphic shape and how counterexample support fits, then define the completion criteria for the always, alwaysTrue, alwaysFalse, Result, and exception helpers before implementing or testing the API.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- fsharp
- Domain
- testing
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 20/100