Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I define an FSCheck generator so that it can be discovered

Tags:

f#

fscheck

I'm writing an FSCheck generator to create strings having the following properties:

  • They are non-null
  • Trimming them won't affect the length
  • They contain no spaces.

Here's my generator code:

namespace Example

open FsCheck.Arb

module public Generation = 

    let hasChars (s : string) =
        (isNull s |> not)
        && s.Length > 0

    let isTrimmed (s : string) =
        s.Trim().Length = s.Length

    let isContinuous (s : string) =
        s
        |> Seq.exists ((=) ' ')
        |> not

    [<AbstractClass; Sealed>]
    type public Generators = class end

    type public ContinuousString = ContinuousString of string with
        member x.Get = match x with ContinuousString r -> r
        override x.ToString() = x.Get

    type public Generators with

        static member ContinuousString() =
            Default.String()
            |> filter hasChars
            |> filter isTrimmed
            |> filter isContinuous
            |> convert ContinuousString string

And here's a test intended to verify the generation:

[<Property(Arbitrary=[| typeof<ContinuousString> |], MaxTest=2)>]
let ``A continuous string contains no spaces`` (s: ContinuousString) =
    s.Get.Contains " " |> not

When I run this test, I get:

System.Exception: No instances found on type Example.Generation+ContinuousString. Check that the type is public and has public static members with the right signature.

As far as I can tell looking at the FSCheck source code, the member I have defined should be found by the discovery filter, and the method seems analogous to similar built-in ones such as NonEmptyString.

What have I missed? Thanks!

like image 438
Kit Avatar asked Jan 30 '26 12:01

Kit


1 Answers

You're passing FsCheck the wrong type. You should be passing it your Generators class, not your ContinuousString DU. I.e., this:

[<Property(Arbitrary=[| typeof<ContinuousString> |], MaxTest=2)>]
let ``A continuous string contains no spaces`` (s: ContinuousString) =
    s.Get.Contains " " |> not

should have been:

[<Property(Arbitrary=[| typeof<Generators> |], MaxTest=2)>]
let ``A continuous string contains no spaces`` (s: ContinuousString) =
    s.Get.Contains " " |> not

The FsCheck error message was trying to tell you this as well:

Check that the type is public and has public static members with the right signature.

The type that you created that matches what it's looking for is Generators.

like image 99
rmunn Avatar answered Feb 02 '26 02:02

rmunn



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!