1

I can't seem to get the FSCheck shrinker to work. Say I have this

    let arb_chars =
        Arb.fromGenShrink(
            Arb.generate<char[]>,
            fun cs -> seq {
                printfn "shrinking..."
                for i in 0..(cs.Length) do
                    printfn "  shrink %d" i
                    yield [| cs.[0] |]
            })

    let prop_len() = gen {
        //let! a = Arb.generate<char[]> // this doesn't work either...
        let! a = arb_chars.Generator
        let len = a.Length
        printfn "a.Length = %A" len
        return (len <> 5)
    }
    :
    Check.One(config, prop_len)

When I run it, I always get 0 shrinks. Here's a typical run:

a.Length = 0
a.Length = 4
a.Length = 1
a.Length = 0
a.Length = 4
a.Length = 7
a.Length = 6
a.Length = 7
a.Length = 19
a.Length = 18
a.Length = 5
Falsifiable, after 11 tests (0 shrinks) (StdGen (19971972,296557937)):
Original:
<null>
Ray
  • 2,974
  • 20
  • 26
  • How is `prop_len` used? It looks like a generator for bool values, but the naming suggests it's a property you'd like to test? In any case, my guess would be that creating a new generator using `gen { }` computation expression makes FsCheck not be able to use `arb_chars`' shrinker, because it doesn't know `arb_chars` is being used at all - the `prop_len` generator can have any implementation and doesn't define a shrinker of its own – Honza Brestan Feb 10 '19 at 01:55
  • @Honza I just use `Check.One(config, prop_len)`. I've updated the example. – Ray Feb 10 '19 at 19:08

1 Answers1

3

Use Prop.forAll to define your property and use the custom generator/shrinker. Something like this (sorry typing from memory but should be close)

let prop_len = Prop.forAll (arb_chars) 
    (fun a ->
        let len = a.Length
        printfn "a.Length = %A" len
        return (len <> 5)
    )
Alberto Zaccagni
  • 30,779
  • 11
  • 72
  • 106
Kurt Schelfthout
  • 8,880
  • 1
  • 30
  • 48