How to force any decimal value (be it part of a type or not) generated with fscheck to be within a certain range?

40 Views Asked by At

I'm using fscheck to write some unite tests and I would like to narrow down the range of decimal automatically generated and that regardless of the parameter I'm passing. What I mean by that is that let's say I have the types below:

  • decimal
  • DecimalHolder
  • Nested records containing decimal fields
  • DU with cases with decimal fields

Without having something to define an arbitrary for each single type, just that down the line in the generation if there a decimal it must say be between 0 and 300,000.

module Tests

open Xunit
open FsCheck.Xunit
open Swensen.Unquote


let addDecimals a b: decimal =
   a + b

[<Property>]
let ``test adding two decimals`` a b =
    let actual = addDecimals a b
    let expected = a + b
    test<@ actual = expected @>

type DecimalHolder =
    { Value: decimal }

let addDecimalHolders a b =
    { Value = a.Value + b.Value }

[<Property>]
let ``test adding two decimal holders`` a b =
    let actual = addDecimalHolders a b
    let expected = { Value = a.Value + b.Value }
    test<@ actual = expected @>

type DecimalStuff =
    | Value of decimal
    | Holder of DecimalHolder
    | Holders of DecimalHolder list
    // Whatever

etc.

How can I achieve that?

1

There are 1 best solutions below

0
Natalie Perret On BEST ANSWER

Ok actually the Arbitrary definition works recursively across parameters types was enough:

module Tests

open Xunit
open FsCheck.Xunit
open Swensen.Unquote

type NotBigPositiveDecimalArbitrary =

    static member NotBigPositiveDecimal() =
        Gen.choose (1, 500)
        |> Gen.map (fun x -> decimal x)
        |> Arb.fromGen

let addDecimals a b: decimal =
   a + b

[<Property(Arbitrary = [| typeof<NotBigPositiveDecimalArbitrary> |])>]
let ``test adding two decimals`` a b =
    let actual = addDecimals a b
    let expected = a + b
    test<@ actual = expected @>

type DecimalHolder =
    { Value: decimal }

let addDecimalHolders a b =
    { Value = a.Value + b.Value }

[<Property(Arbitrary = [| typeof<NotBigPositiveDecimalArbitrary> |])>]
let ``test adding two decimal holders`` a b =
    let actual = addDecimalHolders a b
    let expected = { Value = a.Value + b.Value }
    test<@ actual = expected @>

Related Questions in F#