diff --git a/src/Hedgehog/Range.fs b/src/Hedgehog/Range.fs index a3517d73..af1efef7 100644 --- a/src/Hedgehog/Range.fs +++ b/src/Hedgehog/Range.fs @@ -122,7 +122,7 @@ module Range = fromBigInt (z + diff) /// Scale an integral exponentially with the size parameter. - let inline scaleExponential (sz0 : Size) (z0 : 'a) (n0 : 'a) : 'a = + let inline scaleExponential (lo : 'a) (hi : 'a) (sz0 : Size) (z0 : 'a) (n0 : 'a) : 'a = let sz = clamp 0 99 sz0 @@ -135,7 +135,8 @@ module Range = let diff = (((float (abs (n - z) + 1I)) ** (float sz / 99.0)) - 1.0) * float (sign (n - z)) - fromBigInt (bigint (round (float z + diff))) + // https://github.com/hedgehogqa/fsharp-hedgehog/issues/185 + fromBigInt (clamp (toBigInt lo) (toBigInt hi) (bigint (round (float z + diff)))) /// Construct a range which scales the bounds relative to the size /// parameter. @@ -173,10 +174,13 @@ module Range = [] let inline exponentialFrom (z : 'a) (x : 'a) (y : 'a) : Range<'a> = Range (z, fun sz -> + let scale = + // https://github.com/hedgehogqa/fsharp-hedgehog/issues/185 + scaleExponential x y sz z let x_sized = - clamp x y (scaleExponential sz z x) + scale x let y_sized = - clamp x y (scaleExponential sz z y) + scale y x_sized, y_sized) /// Construct a range which scales the second bound exponentially relative diff --git a/tests/Hedgehog.Tests/GenTests.fs b/tests/Hedgehog.Tests/GenTests.fs index 5563d964..37f2236f 100644 --- a/tests/Hedgehog.Tests/GenTests.fs +++ b/tests/Hedgehog.Tests/GenTests.fs @@ -1,6 +1,5 @@ module Hedgehog.Tests.GenTests -open System open Hedgehog open Swensen.Unquote open Xunit @@ -66,13 +65,15 @@ let ``dateTime shrinks to correct mid-value`` () = System.DateTime (2000, 1, 1) =! result [] -let ``uint64 doesn't return any out-of-range value`` () = - let gen = Gen.uint64 <| Range.constant 1UL UInt64.MaxValue - let actual = Gen.sample 0 100 gen - test <@ actual |> List.contains 0UL |> not @> +let ``int64 can create exponentially bounded integer`` () = + Property.check <| property { + let! _ = Gen.int64 (Range.exponentialBounded ()) + return true + } [] -let ``uint32 doesn't return any out-of-range value`` () = - let gen = Gen.uint32 <| Range.constant 1ul UInt32.MaxValue - let actual = Gen.sample 0 100 gen - test <@ actual |> List.contains 0ul |> not @> +let ``uint64 can create exponentially bounded integer`` () = + Property.check <| property { + let! _ = Gen.uint64 (Range.exponentialBounded ()) + return true + } \ No newline at end of file