From 1ad0e777bee13e68bef41a7fa908a8061654ff27 Mon Sep 17 00:00:00 2001 From: Alex Date: Sat, 23 Jan 2021 20:10:56 -0600 Subject: [PATCH] Added maxShrinks --- src/Hedgehog/Linq/Property.fs | 18 +++++++++ src/Hedgehog/Property.fs | 57 ++++++++++++++++++++--------- tests/Hedgehog.Tests/ShrinkTests.fs | 15 ++++++++ 3 files changed, 73 insertions(+), 17 deletions(-) diff --git a/src/Hedgehog/Linq/Property.fs b/src/Hedgehog/Linq/Property.fs index 155ad0ae..979acdec 100644 --- a/src/Hedgehog/Linq/Property.fs +++ b/src/Hedgehog/Linq/Property.fs @@ -74,6 +74,11 @@ type PropertyExtensions private () = let (Property property) = property Property.report property + [] + static member Report (property : Property, tests : int, maxShrinks : int) : Report = + let (Property property) = property + Property.report'' tests maxShrinks property + [] static member Report (property : Property, tests : int) : Report = let (Property property) = property @@ -87,11 +92,20 @@ type PropertyExtensions private () = static member Report (property : Property, tests : int) : Report = Property.reportBool' tests property + [] + static member Report (property : Property, tests : int, maxShrinks : int) : Report = + Property.reportBool'' tests maxShrinks property + [] static member Check (property : Property) : unit = let (Property property) = property Property.check property + [] + static member Check (property : Property, tests : int, maxShrinks : int) : unit = + let (Property property) = property + Property.check'' tests maxShrinks property + [] static member Check (property : Property, tests : int) : unit = let (Property property) = property @@ -105,6 +119,10 @@ type PropertyExtensions private () = static member Check (property : Property, tests : int) : unit = Property.checkBool' tests property + [] + static member Check (property : Property, tests : int, maxShrinks : int) : unit = + Property.checkBool'' tests maxShrinks property + [] static member Recheck (property : Property, size : Size, seed : Seed) : unit = let (Property property) = property diff --git a/src/Hedgehog/Property.fs b/src/Hedgehog/Property.fs index 818ab366..6604a557 100644 --- a/src/Hedgehog/Property.fs +++ b/src/Hedgehog/Property.fs @@ -100,26 +100,34 @@ module Property = (size : Size) (seed : Seed) (Node ((journal, x), xs) : Tree>) - (nshrinks : int) : Status = + (nshrinks : int) + (maxShrinks : int Option) : Status = + let failed = + Failed { + Size = size + Seed = seed + Shrinks = nshrinks + Journal = journal + RenderRecheck = renderRecheck + } + let takeSmallest tree = takeSmallest renderRecheck size seed tree (nshrinks + 1) maxShrinks match x with | Failure -> match Seq.tryFind (Outcome.isFailure << snd << Tree.outcome) xs with - | None -> - Failed { - Size = size - Seed = seed - Shrinks = nshrinks - Journal = journal - RenderRecheck = renderRecheck - } + | None -> failed | Some tree -> - takeSmallest renderRecheck size seed tree (nshrinks + 1) + match maxShrinks with + | None -> takeSmallest tree + | Some maxShrinks' -> + if nshrinks < maxShrinks' then + takeSmallest tree + else failed | Discard -> GaveUp | Success _ -> OK - let private reportWith' (renderRecheck : bool) (size0 : Size) (seed : Seed) (n : int) (p : Property) : Report = + let private reportWith' (renderRecheck : bool) (size0 : Size) (seed : Seed) (n : int) maxShrinks (p : Property) : Report = let random = toGen p |> Gen.toRandom let nextSize size = @@ -145,7 +153,7 @@ module Property = | Failure -> { Tests = tests + 1 Discards = discards - Status = takeSmallest renderRecheck size seed result 0 } + Status = takeSmallest renderRecheck size seed result 0 maxShrinks} | Success () -> loop seed2 (nextSize size) (tests + 1) discards | Discard -> @@ -153,22 +161,33 @@ module Property = loop seed size0 0 0 - let private reportWith (renderRecheck : bool) (size : Size) (seed : Seed) (p : Property) : Report = - reportWith' renderRecheck size seed 100 p + let private reportWith (renderRecheck : bool) (size : Size) (seed : Seed) maxShrinks (p : Property) : Report = + reportWith' renderRecheck size seed 100 maxShrinks p + + let report'' (n : int) (maxShrinks : int) (p : Property) : Report = + let seed = Seed.random () + reportWith' true 1 seed n (Some maxShrinks) p let report' (n : int) (p : Property) : Report = let seed = Seed.random () - reportWith' true 1 seed n p + reportWith' true 1 seed n None p let report (p : Property) : Report = report' 100 p + let reportBool'' (n : int) (maxShrinks : int) (p : Property) : Report = + bind p ofBool |> report'' n maxShrinks + let reportBool' (n : int) (p : Property) : Report = bind p ofBool |> report' n let reportBool (p : Property) : Report = bind p ofBool |> report + let check'' (n : int) (maxShrinks : int) (p : Property) : unit = + report'' n maxShrinks p + |> Report.tryRaise + let check' (n : int) (p : Property) : unit = report' n p |> Report.tryRaise @@ -177,6 +196,10 @@ module Property = report p |> Report.tryRaise + let checkBool'' (n : int) (maxShrinks : int) (p : Property) : unit = + reportBool'' n maxShrinks p + |> Report.tryRaise + let checkBool (g : Property) : unit = bind g ofBool |> check @@ -193,10 +216,10 @@ module Property = | _ -> failure let reportRecheck' (size : Size) (seed : Seed) (n : int) (p : Property) : Report = - reportWith' false size seed n p + reportWith' false size seed n None p let reportRecheck (size : Size) (seed : Seed) (p : Property) : Report = - reportWith false size seed p + reportWith false size seed None p let reportRecheckBool' (size : Size) (seed : Seed) (n : int) (p : Property) : Report = bind p ofBool |> reportRecheck' size seed n diff --git a/tests/Hedgehog.Tests/ShrinkTests.fs b/tests/Hedgehog.Tests/ShrinkTests.fs index 901cdcff..13414d42 100644 --- a/tests/Hedgehog.Tests/ShrinkTests.fs +++ b/tests/Hedgehog.Tests/ShrinkTests.fs @@ -232,3 +232,18 @@ let ``towardsDouble returns empty list when run out of shrinks`` x0 destination |> Shrink.towards destination |> Seq.toList test <@ actual |> List.isEmpty @> + +[] +[] +[] +[] +let ``Property.report'' respects its maxShrinks`` maxShrinks = + let report = + property { + let! actual = Range.linear 1 1_000_000 |> Gen.int + return actual < 500_000 + } |> Property.report'' 100 maxShrinks + match report.Status with + | Failed failureData -> + failureData.Shrinks =! maxShrinks + | _ -> failwith "impossible"