qcheck icon indicating copy to clipboard operation
qcheck copied to clipboard

Add [without_shrinker] to [QCheck2.Gen]

Open vch9 opened this issue 3 years ago • 4 comments

Closes #232.

I don't know if that's the most convenient solution, but it seems to work. If you have any suggestion to improve this function, I'd be happy to implement it.

vch9 avatar Jul 11 '22 20:07 vch9

Thanks for this! :pray:

In QCheck(1) there's:

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

meaning you can achieve something like this with set_shrink Shrink.nil some_gen.

Perhaps we should rename and generalize slightly, so that the QCheck2 operation takes a shrinker function as an argument?

  val set_shrink: ('a -> 'a Seq.t) -> 'a Gen.t -> 'a Gen.t

That way

  • we continue to keep the interfaces close, in an effort to make QCheck->QCheck2 porting easy
  • you should be able to achieve the same functionality with set_shrink (fun -> Seq.empty) some_gen (we could also include a binding Shrink.nil for the function argument)

jmid avatar Jul 12 '22 06:07 jmid

Thanks for this! pray

In QCheck(1) there's:

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

meaning you can achieve something like this with set_shrink Shrink.nil some_gen.

Perhaps we should rename and generalize slightly, so that the QCheck2 operation takes a shrinker function as an argument?

  val set_shrink: ('a -> 'a Seq.t) -> 'a Gen.t -> 'a Gen.t

That way

* we continue to keep the interfaces close, in an effort to make QCheck->QCheck2 porting easy

* you should be able to achieve the same functionality with `set_shrink (fun -> Seq.empty) some_gen` (we could also include a binding `Shrink.nil` for the function argument)

Yep, that's a good idea. Pushed a new commit with set_shrink.

vch9 avatar Jul 12 '22 08:07 vch9

Looks good!

Three minor/bike-shed'dy things:

  • ~~We should probably add a small test of set_shrink too?~~
  • Regarding documentation a reader could misunderstand this comment to be side-effecting (if they do not look at the type signature). One possibility is to adapt it to say returns a generator using [gen] but with shrinking disabled (or something like that):
    val without_shrinker : 'a t -> 'a t
    (** [without_shrinker gen] removes the shrinker from [gen]. *)
    
  • I was thinking about the naming. Looking at names related to shrinking, the last one stands out a bit (only entry using shrinker). Furthermore it is a short-hand for something that can be achieved with set_shrink - but it is a relatively long identifier. One option could be to use no_shrink instead (same form of 'shrink' + short) - I'm open to other proposals though
    val add_shrink_invariant : ('a -> bool) -> 'a t -> 'a t
    val set_shrink : ('a -> 'a Seq.t) -> 'a t -> 'a t
    val without_shrinker : 'a t -> 'a t
    

jmid avatar Jul 13 '22 07:07 jmid

Sorry, I take back the suggestion of adding a test of set_shrink, since you're already using it to implement without_shrinker/no_shrink and hence testing it as part of that... (I blame the work injury from having written too many tests of QCheck previously... :sweat_smile:)

jmid avatar Jul 15 '22 11:07 jmid

Hi! Sorry for the huge delay.

Pushed a rebased branch:

  1. Used your suggestion for the documentation
  2. Went fo no_shrink, I like the name, explicit enough and fits well with set_shrink
  3. Fixed the changelog I think? The # 0.20 was missing. I don't know if that was intended

vch9 avatar Oct 13 '22 09:10 vch9

Looks good to me, thanks!

jmid avatar Oct 25 '22 15:10 jmid