Search code examples
f#fscheckproperty-based-testingexpecto

Expecto FsCheck getting stack overflow exception when generating string


I'm trying to learn how to use FsCheck properly, and integrating it with Expecto at the moment. I can get property tests to run if I'm using the default FsCheck config, but when I try to use my own Generator, it causes a stack overflow exception.

Here is my generator

type NameGen() =
    static member Name() =
        Arb.generate<string * string>
        |> Gen.where (fun (firstName, lastName) ->
            firstName.Length > 0 && lastName.Length > 0
        )
        |> Gen.map (fun (first, last) -> sprintf "%s %s" first last)
        |> Arb.fromGen
        |> Arb.convert string id

And I'm trying to use it like this:

let config = { FsCheckConfig.defaultConfig with arbitrary = [typeof<NameGen>] }

let propertyTests input =
    let output = toInitials input
    output.EndsWith(".")

testPropertyWithConfig config "Must end with period" propertyTests

The exception is thrown before it even gets into the Gen.where function

What am I doing wrong? Thanks


Solution

  • You are trying to use FsCheck's generator of strings to redefine how its generator of strings work, but when you do that, it'll recursively call itself until it runs out of stack space. It's a known issue: https://github.com/fscheck/FsCheck/issues/109

    Does this alternative work?

    type NameGen =
        static member Name () =
            Arb.Default.NonEmptyString().Generator
            |> Gen.map (fun (NonEmptyString s) -> s)
            |> Gen.two
            |> Gen.map (fun (first, last) -> sprintf "%s %s" first last)
            |> Arb.fromGen