hedgehogqa / haskell-hedgehog

Release with confidence, state-of-the-art property testing for Haskell.
677 stars 107 forks source link

Automatically generating random values based on types? #135

Open saurabhnanda opened 6 years ago

saurabhnanda commented 6 years ago

(newbie alert)

Was looking around in https://hackage.haskell.org/package/hedgehog-0.5/docs/Hedgehog-Gen.html and it wasn't obvious to me how to generate random data based on the type of the value. To draw a parallel, I have used the following technique with QC:

instance Arbitrary TxnSource where
  arbitrary = genericArbitrary uniform

instance Arbitrary Nouns where
  arbitrary = genericArbitrary uniform

instance Arbitrary BookingId where
  arbitrary = genericArbitrary uniform

instance Arbitrary TLSOption where
  arbitrary = arbitraryBoundedEnum
thumphries commented 6 years ago

Hey Saurabh,

Hedgehog has no equivalent to the Arbitrary typeclass. This is intentional. Arbitrary is a lawless typeclass that inevitably leads to either orphan instances or a viral QuickCheck dependency in your production libraries. The corresponding idiom is merely to give your generators names and call them by those names.

If you really want typeclass-based overloading, you could:

Closing for now, can reopen if you have further questions or if you feel this was not adequately addressed.

saurabhnanda commented 6 years ago

I understand that hedgehog has no equivalent of the Arbitrary typeclass, but the question was more about hedgehog's equivalent of the genericArbitrary function. It "inspects" the type of the required value and automatically generates random data in that shape. Any generics or TH equivalent to do that in hedgehog?

thumphries commented 6 years ago

There's nothing like that right now - that might be a good addition or standalone library though! Sometimes you really do want totally unconstrained derived generators / fuzzers.

On Dec 5, 2017, at 5:46 PM, Saurabh Nanda notifications@github.com wrote:

I understand that hedgehog has no equivalent of the Arbitrary typeclass, but the question was more about hedgehog's equivalent of the genericArbitrary function. It "inspects" the type of the required value and automatically generates random data in that shape. Any generics or TH equivalent to do that in hedgehog?

— You are receiving this because you modified the open/close state. Reply to this email directly, view it on GitHub, or mute the thread.

dalaing commented 6 years ago

Things like this are also possible.

thumphries commented 6 years ago

@saurabhnanda sorry for misreading your original question - I was blinded by instance Arbitrary. Reopening as a feature request / suggestion

Unsure if this is better off as a Hedgehog feature, a library built on top of Hedgehog, or an entirely separate thing like Yorgey's blog post.

moodmosaic commented 6 years ago

@thumphries, @dalaing, we had a similar discussion around this with @jystic in https://github.com/hedgehogqa/fsharp-hedgehog/issues/139#issuecomment-338966392 for fsharp-hedgehog.

There, we ended up doing it in a separate library that we called fsharp-hedgehog-experimental. Perhaps we want to do something similar also here(?)

We used an approach similar to this one, but in F#, and we ended up with a generator called auto that (in F#) takes anof a and that returns a Gen a.

chessai commented 5 years ago

Hi, I've just uploaded the package hedgehog-generic (docs yet to build, because I've just uploaded a few minutes ago): http://hackage.haskell.org/package/hedgehog-generic

Perhaps this may be useful to you, @saurabhnanda? It allows you to do something like

import Hedgehog
import Hedgehog.Generic

data Foo = Foo
  { _fooX :: X
  , _fooY :: Y
  } deriving (Generic)

-- equivalent to `genFoo = Foo <$> hgen <*> hgen`
genFoo :: Gen Foo
genFoo = hgen

There is one small semantic difference in that we require a Generic instance on all fields of a type, rather than an Arbitrary instance, because of course we do not have one.