From 5dd5cc2e929a599638305d45d258e9dca47ca572 Mon Sep 17 00:00:00 2001 From: Martin Janiczek Date: Thu, 13 Oct 2022 23:00:02 +0200 Subject: [PATCH 1/8] Skip values (moreso, RandomRuns) we have already tested --- src/Fuzz/Internal.elm | 14 +- src/RandomRun.elm | 8 + src/Test/Fuzz.elm | 197 ++++++++++++++--------- tests/src/FuzzerTests.elm | 17 ++ tests/src/Runner/String.elm | 41 ++--- tests/src/Runner/String/Distribution.elm | 7 +- 6 files changed, 186 insertions(+), 98 deletions(-) diff --git a/src/Fuzz/Internal.elm b/src/Fuzz/Internal.elm index e605fa54..2c8433db 100644 --- a/src/Fuzz/Internal.elm +++ b/src/Fuzz/Internal.elm @@ -1,4 +1,4 @@ -module Fuzz.Internal exposing (Fuzzer(..), generate) +module Fuzz.Internal exposing (Fuzzer(..), gen, genR, generate) {-| This module is here just to hide the `generate` function from the end users of the library. @@ -6,6 +6,8 @@ of the library. import GenResult exposing (GenResult) import PRNG exposing (PRNG) +import Random +import RandomRun type Fuzzer a @@ -15,3 +17,13 @@ type Fuzzer a generate : PRNG -> Fuzzer a -> GenResult a generate prng (Fuzzer fuzzer) = fuzzer prng + + +gen : List Int -> Fuzzer a -> GenResult a +gen randomRun fuzzer = + generate (PRNG.hardcoded (RandomRun.fromList randomRun)) fuzzer + + +genR : Int -> Fuzzer a -> GenResult a +genR seed fuzzer = + generate (PRNG.random (Random.initialSeed seed)) fuzzer diff --git a/src/RandomRun.elm b/src/RandomRun.elm index e58dc46d..476298fc 100644 --- a/src/RandomRun.elm +++ b/src/RandomRun.elm @@ -6,6 +6,7 @@ module RandomRun exposing , deleteChunk , empty , equal + , fromList , get , isEmpty , isFull @@ -332,3 +333,10 @@ update index fn run = equal : RandomRun -> RandomRun -> Bool equal run1 run2 = toList run1 == toList run2 + + +fromList : List Int -> RandomRun +fromList list = + { length = List.length list + , data = Queue.fromList list + } diff --git a/src/Test/Fuzz.elm b/src/Test/Fuzz.elm index 433238f1..5b1524ec 100644 --- a/src/Test/Fuzz.elm +++ b/src/Test/Fuzz.elm @@ -8,6 +8,8 @@ import MicroListExtra as List import MicroMaybeExtra as Maybe import PRNG import Random +import RandomRun exposing (RandomRun) +import Set exposing (Set) import Simplify import Test.Distribution exposing (DistributionReport(..)) import Test.Distribution.Internal exposing (Distribution(..), ExpectedDistribution(..)) @@ -39,16 +41,19 @@ validatedFuzzTest fuzzer getExpectation distribution = ElmTestVariant__FuzzTest (\seed runs -> let + constants : LoopConstants a + constants = + { fuzzer = fuzzer + , testFn = getExpectation + , initialSeed = seed + , runsNeeded = runs + , distribution = distribution + , skipsAllowed = runs * maxSkippedRunsRatio + } + runResult : RunResult runResult = - fuzzLoop - { fuzzer = fuzzer - , testFn = getExpectation - , initialSeed = seed - , runsNeeded = runs - , distribution = distribution - } - (initLoopState seed distribution) + fuzzLoop constants (initLoopState constants) in case runResult.failure of Nothing -> @@ -77,6 +82,7 @@ type alias LoopConstants a = , initialSeed : Random.Seed , runsNeeded : Int , distribution : Distribution a + , skipsAllowed : Int } @@ -86,15 +92,17 @@ type alias LoopState = , nextPowerOfTwo : Int , failure : Maybe Failure , currentSeed : Random.Seed + , seenRandomRuns : Set (List Int) + , runsSkipped : Int } -initLoopState : Random.Seed -> Distribution a -> LoopState -initLoopState initialSeed distribution = +initLoopState : LoopConstants a -> LoopState +initLoopState c = let initialDistributionCount : Maybe (Dict (List String) Int) initialDistributionCount = - Test.Distribution.Internal.getDistributionLabels distribution + Test.Distribution.Internal.getDistributionLabels c.distribution |> Maybe.map (\labels -> labels @@ -106,10 +114,29 @@ initLoopState initialSeed distribution = , distributionCount = initialDistributionCount , nextPowerOfTwo = 1 , failure = Nothing - , currentSeed = initialSeed + , currentSeed = c.initialSeed + , seenRandomRuns = Set.empty + , runsSkipped = 0 } +{-| If user specified 100 runs and this ratio is 10, we can only skip 100\*10 = +1000 values before stopping. + +Consider `Fuzz.bool`: it only has two possible RandomRuns: + + - [ 0 ] --> False + - [ 1 ] --> True + +We'll likely try those pretty soon. We don't have a good way of figuring out +that's all of them so we'll just skip them for until 1000 values have been tried. + +-} +maxSkippedRunsRatio : Int +maxSkippedRunsRatio = + 10 + + {-| Runs fuzz tests repeatedly and returns information about distribution and possible failure. The loop algorithm is roughly: @@ -151,13 +178,13 @@ fuzzLoop c state = Just distributionCount -> DistributionToReport { distributionCount = includeCombinationsInBaseCounts distributionCount - , runsElapsed = state.runsElapsed + , runsElapsed = state.runsElapsed + state.runsSkipped } , failure = Just failure } Nothing -> - if state.runsElapsed < c.runsNeeded then + if state.runsElapsed < c.runsNeeded && state.runsSkipped < c.skipsAllowed then let newState : LoopState newState = @@ -182,7 +209,7 @@ fuzzLoop c state = { distributionReport = DistributionToReport { distributionCount = includeCombinationsInBaseCounts distributionCount - , runsElapsed = state.runsElapsed + , runsElapsed = state.runsElapsed + state.runsSkipped } , failure = Nothing } @@ -210,7 +237,7 @@ fuzzLoop c state = { distributionReport = DistributionCheckSucceeded { distributionCount = distributionCount - , runsElapsed = state.runsElapsed + , runsElapsed = state.runsElapsed + state.runsSkipped } , failure = Nothing } @@ -282,7 +309,7 @@ allSufficientlyCovered c state normalizedDistributionCount = True AtLeast n -> - Test.Distribution.Internal.sufficientlyCovered state.runsElapsed count (n / 100) + Test.Distribution.Internal.sufficientlyCovered (state.runsElapsed + state.runsSkipped) count (n / 100) ) ) ) @@ -323,9 +350,9 @@ findBadZeroRelatedCase c state normalizedDistributionCount = |> Maybe.map (\count -> { label = label - , actualPercentage = toFloat count * 100 / toFloat state.runsElapsed + , actualPercentage = toFloat count * 100 / toFloat (state.runsElapsed + state.runsSkipped) , expectedDistribution = expectedDistribution - , runsElapsed = state.runsElapsed + , runsElapsed = state.runsElapsed + state.runsSkipped , distributionCount = distributionCount } ) @@ -369,14 +396,14 @@ findInsufficientlyCoveredLabel c state normalizedDistributionCount = False AtLeast n -> - Test.Distribution.Internal.insufficientlyCovered state.runsElapsed count (n / 100) + Test.Distribution.Internal.insufficientlyCovered (state.runsElapsed + state.runsSkipped) count (n / 100) ) |> Maybe.map (\( label, count, expectedDistribution ) -> { label = label - , actualPercentage = toFloat count * 100 / toFloat state.runsElapsed + , actualPercentage = toFloat count * 100 / toFloat (state.runsElapsed + state.runsSkipped) , expectedDistribution = expectedDistribution - , runsElapsed = state.runsElapsed + , runsElapsed = state.runsElapsed + state.runsSkipped , distributionCount = distributionCount } ) @@ -438,11 +465,11 @@ distributionInsufficientFailure failure = } -{-| Short-circuits on failure. +{-| Short-circuits on failure or the skipped values limit reached. -} runNTimes : Int -> LoopConstants a -> LoopState -> LoopState runNTimes times c state = - if times <= 0 || state.failure /= Nothing then + if times <= 0 || state.failure /= Nothing || state.runsSkipped >= c.skipsAllowed then state else @@ -475,11 +502,12 @@ runOnce c state = Nothing -> stepSeed state.currentSeed - - ( maybeFailure, newDistributionCounter ) = - case genResult of - Rejected { reason } -> - ( Just + in + case genResult of + Rejected { reason } -> + { state + | failure = + Just { given = Nothing , expectation = Test.Expectation.fail @@ -487,51 +515,76 @@ runOnce c state = , reason = Invalid InvalidFuzzer } } - , state.distributionCount - ) + , currentSeed = nextSeed + , runsElapsed = state.runsElapsed + 1 + } - Generated { prng, value } -> - let - failure : Maybe Failure - failure = - testGeneratedValue - { getExpectation = c.testFn - , fuzzer = c.fuzzer - , randomRun = PRNG.getRun prng - , value = value - , expectation = c.testFn value - } + Generated { prng, value } -> + let + randomRun : RandomRun + randomRun = + PRNG.getRun prng + + randomRunList : List Int + randomRunList = + RandomRun.toList randomRun + + nextDistributionCount : Maybe (Dict (List String) Int) + nextDistributionCount = + Maybe.map2 + (\labels old -> + let + foundLabels : List String + foundLabels = + labels + |> List.filterMap + (\( label, predicate ) -> + if predicate value then + Just label + + else + Nothing + ) + in + Dict.increment foundLabels old + ) + (Test.Distribution.Internal.getDistributionLabels c.distribution) + state.distributionCount + in + if Set.member randomRunList state.seenRandomRuns then + {- We've tried this RandomRun already and know it ends in Pass + (if it ended in Failure we'd have short-circuited). + Let's not do unneeded work! + + We still want to update the distribution counts though, + those don't care about whether the value passes or fails the + test. + -} + { state + | currentSeed = nextSeed + , distributionCount = nextDistributionCount + , runsSkipped = state.runsSkipped + 1 + } - distributionCounter : Maybe (Dict (List String) Int) - distributionCounter = - Maybe.map2 - (\labels old -> - let - foundLabels : List String - foundLabels = - labels - |> List.filterMap - (\( label, predicate ) -> - if predicate value then - Just label - - else - Nothing - ) - in - Dict.increment foundLabels old - ) - (Test.Distribution.Internal.getDistributionLabels c.distribution) - state.distributionCount - in - ( failure, distributionCounter ) - in - { state - | failure = maybeFailure - , distributionCount = newDistributionCounter - , currentSeed = nextSeed - , runsElapsed = state.runsElapsed + 1 - } + else + let + nextFailure : Maybe Failure + nextFailure = + testGeneratedValue + { getExpectation = c.testFn + , fuzzer = c.fuzzer + , randomRun = randomRun + , value = value + , expectation = c.testFn value + } + in + { state + | failure = nextFailure + , distributionCount = nextDistributionCount + , currentSeed = nextSeed + , runsElapsed = state.runsElapsed + 1 + , seenRandomRuns = Set.insert randomRunList state.seenRandomRuns + } includeCombinationsInBaseCounts : Dict (List String) Int -> Dict (List String) Int diff --git a/tests/src/FuzzerTests.elm b/tests/src/FuzzerTests.elm index c81b0cdf..a0ac401a 100644 --- a/tests/src/FuzzerTests.elm +++ b/tests/src/FuzzerTests.elm @@ -1189,6 +1189,23 @@ distributionTests = (Fuzz.intRange 1 20) "Int range boundaries - mandatory" (\n -> Expect.pass) + + {- + , Test.fuzzWith + { runs = 10000 + , distribution = + Test.expectDistribution + [ ( Test.Distribution.atLeast 5.5, "low", \n -> n == 1 ) + , ( Test.Distribution.atLeast 4, "high", \n -> n == 20 ) + , ( Test.Distribution.atLeast 80, "in between", \n -> n > 1 && n < 20 ) + , ( Test.Distribution.zero, "outside", \n -> n < 1 || n > 20 ) + , ( Test.Distribution.moreThanZero, "one", \n -> n == 1 ) + ] + } + (Fuzz.intRange 1 20) + "Failing distribution test" + (\n -> Expect.pass) + -} ] diff --git a/tests/src/Runner/String.elm b/tests/src/Runner/String.elm index 1cd4920a..349a82a6 100644 --- a/tests/src/Runner/String.elm +++ b/tests/src/Runner/String.elm @@ -75,25 +75,19 @@ fromExpectation labels expectation summary = expectation |> Test.Runner.getDistributionReport |> Runner.String.Distribution.report labels - - summaryWithDistribution : Summary - summaryWithDistribution = - case distributionReport of - Nothing -> - summary - - Just distribution -> - { summary - | output = - summary.output - ++ "\n\n" - ++ distribution - ++ "\n" - } in case Test.Runner.getFailureReason expectation of Nothing -> - { summaryWithDistribution | passed = summaryWithDistribution.passed + 1 } + { summary + | passed = summary.passed + 1 + , output = + distributionReport + |> Maybe.map + (\distribution -> + summary.output ++ "\n\n" ++ distribution ++ "\n" + ) + |> Maybe.withDefault summary.output + } Just { given, description, reason } -> let @@ -112,13 +106,20 @@ fromExpectation labels expectation summary = "\n\n" ++ outputLabels labels ++ "\n" + ++ (distributionReport + |> Maybe.map + (\distribution -> + "\n" ++ indentLines distribution ++ "\n\n" + ) + |> Maybe.withDefault "" + ) ++ (prefix ++ indentLines message) ++ "\n" in - { summaryWithDistribution - | output = summaryWithDistribution.output ++ newOutput - , failed = summaryWithDistribution.failed + 1 - , passed = summaryWithDistribution.passed + { summary + | output = summary.output ++ newOutput + , failed = summary.failed + 1 + , passed = summary.passed } diff --git a/tests/src/Runner/String/Distribution.elm b/tests/src/Runner/String/Distribution.elm index e6fa466b..47d82583 100644 --- a/tests/src/Runner/String/Distribution.elm +++ b/tests/src/Runner/String/Distribution.elm @@ -25,8 +25,5 @@ report testBreadcrumbs distributionReport = DistributionCheckSucceeded _ -> Nothing - DistributionCheckFailed _ -> - {- Don't show it here: it's already included in the failure message. - That way the Node runner will show it too. - -} - Nothing + DistributionCheckFailed r -> + Just <| Test.Distribution.distributionReportTable r From 73e6710e81a677b738df9e30d640690707ccde56 Mon Sep 17 00:00:00 2001 From: Martin Janiczek Date: Fri, 14 Oct 2022 00:22:17 +0200 Subject: [PATCH 2/8] Fix a condition --- src/Test/Fuzz.elm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Test/Fuzz.elm b/src/Test/Fuzz.elm index 5b1524ec..6c9ad24a 100644 --- a/src/Test/Fuzz.elm +++ b/src/Test/Fuzz.elm @@ -465,11 +465,11 @@ distributionInsufficientFailure failure = } -{-| Short-circuits on failure or the skipped values limit reached. +{-| Short-circuits on failure. -} runNTimes : Int -> LoopConstants a -> LoopState -> LoopState runNTimes times c state = - if times <= 0 || state.failure /= Nothing || state.runsSkipped >= c.skipsAllowed then + if times <= 0 || state.failure /= Nothing then state else From 434f81996cffcb1ec3c2ff18e6a2b029e9912ee3 Mon Sep 17 00:00:00 2001 From: Martin Janiczek Date: Fri, 14 Oct 2022 11:44:06 +0200 Subject: [PATCH 3/8] Tweak the ratio --- src/Test/Fuzz.elm | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/Test/Fuzz.elm b/src/Test/Fuzz.elm index 6c9ad24a..b20c7f9f 100644 --- a/src/Test/Fuzz.elm +++ b/src/Test/Fuzz.elm @@ -31,13 +31,13 @@ fuzzTest distribution fuzzer untrimmedDesc getExpectation = blankDescriptionFailure else - ElmTestVariant__Labeled desc <| validatedFuzzTest fuzzer getExpectation distribution + ElmTestVariant__Labeled desc <| validatedFuzzTest desc fuzzer getExpectation distribution {-| Knowing that the fuzz test isn't obviously invalid, run the test and package up the results. -} -validatedFuzzTest : Fuzzer a -> (a -> Expectation) -> Distribution a -> Test -validatedFuzzTest fuzzer getExpectation distribution = +validatedFuzzTest : String -> Fuzzer a -> (a -> Expectation) -> Distribution a -> Test +validatedFuzzTest description fuzzer getExpectation distribution = ElmTestVariant__FuzzTest (\seed runs -> let @@ -49,6 +49,7 @@ validatedFuzzTest fuzzer getExpectation distribution = , runsNeeded = runs , distribution = distribution , skipsAllowed = runs * maxSkippedRunsRatio + , description = description } runResult : RunResult @@ -83,6 +84,7 @@ type alias LoopConstants a = , runsNeeded : Int , distribution : Distribution a , skipsAllowed : Int + , description : String } @@ -120,8 +122,8 @@ initLoopState c = } -{-| If user specified 100 runs and this ratio is 10, we can only skip 100\*10 = -1000 values before stopping. +{-| If user specified 100 runs and this ratio is 2, we can only skip 100\*2 = +200 values before stopping. Consider `Fuzz.bool`: it only has two possible RandomRuns: @@ -129,12 +131,12 @@ Consider `Fuzz.bool`: it only has two possible RandomRuns: - [ 1 ] --> True We'll likely try those pretty soon. We don't have a good way of figuring out -that's all of them so we'll just skip them for until 1000 values have been tried. +that's all of them so we'll just skip them for until 200 values have been tried. -} maxSkippedRunsRatio : Int maxSkippedRunsRatio = - 10 + 2 {-| Runs fuzz tests repeatedly and returns information about distribution and possible failure. From 72b744b9c20626486391cc89b930e703125d5865 Mon Sep 17 00:00:00 2001 From: Martin Janiczek Date: Fri, 14 Oct 2022 11:45:21 +0200 Subject: [PATCH 4/8] Cleanup the diff --- src/Fuzz/Internal.elm | 12 +----------- src/RandomRun.elm | 8 -------- 2 files changed, 1 insertion(+), 19 deletions(-) diff --git a/src/Fuzz/Internal.elm b/src/Fuzz/Internal.elm index 2c8433db..631d680f 100644 --- a/src/Fuzz/Internal.elm +++ b/src/Fuzz/Internal.elm @@ -1,4 +1,4 @@ -module Fuzz.Internal exposing (Fuzzer(..), gen, genR, generate) +module Fuzz.Internal exposing (Fuzzer(..), generate) {-| This module is here just to hide the `generate` function from the end users of the library. @@ -17,13 +17,3 @@ type Fuzzer a generate : PRNG -> Fuzzer a -> GenResult a generate prng (Fuzzer fuzzer) = fuzzer prng - - -gen : List Int -> Fuzzer a -> GenResult a -gen randomRun fuzzer = - generate (PRNG.hardcoded (RandomRun.fromList randomRun)) fuzzer - - -genR : Int -> Fuzzer a -> GenResult a -genR seed fuzzer = - generate (PRNG.random (Random.initialSeed seed)) fuzzer diff --git a/src/RandomRun.elm b/src/RandomRun.elm index 476298fc..e58dc46d 100644 --- a/src/RandomRun.elm +++ b/src/RandomRun.elm @@ -6,7 +6,6 @@ module RandomRun exposing , deleteChunk , empty , equal - , fromList , get , isEmpty , isFull @@ -333,10 +332,3 @@ update index fn run = equal : RandomRun -> RandomRun -> Bool equal run1 run2 = toList run1 == toList run2 - - -fromList : List Int -> RandomRun -fromList list = - { length = List.length list - , data = Queue.fromList list - } From 21e9ba414da7ad7775d7621ea4c85cf36e3f904a Mon Sep 17 00:00:00 2001 From: Martin Janiczek Date: Fri, 14 Oct 2022 11:45:26 +0200 Subject: [PATCH 5/8] Skip the failing test properly --- tests/src/FuzzerTests.elm | 33 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/tests/src/FuzzerTests.elm b/tests/src/FuzzerTests.elm index a0ac401a..d8ff2830 100644 --- a/tests/src/FuzzerTests.elm +++ b/tests/src/FuzzerTests.elm @@ -1189,23 +1189,22 @@ distributionTests = (Fuzz.intRange 1 20) "Int range boundaries - mandatory" (\n -> Expect.pass) - - {- - , Test.fuzzWith - { runs = 10000 - , distribution = - Test.expectDistribution - [ ( Test.Distribution.atLeast 5.5, "low", \n -> n == 1 ) - , ( Test.Distribution.atLeast 4, "high", \n -> n == 20 ) - , ( Test.Distribution.atLeast 80, "in between", \n -> n > 1 && n < 20 ) - , ( Test.Distribution.zero, "outside", \n -> n < 1 || n > 20 ) - , ( Test.Distribution.moreThanZero, "one", \n -> n == 1 ) - ] - } - (Fuzz.intRange 1 20) - "Failing distribution test" - (\n -> Expect.pass) - -} + , Test.skip <| + -- we don't want failing tests around by default + Test.fuzzWith + { runs = 10000 + , distribution = + Test.expectDistribution + [ ( Test.Distribution.atLeast 5.5, "low", \n -> n == 1 ) + , ( Test.Distribution.atLeast 4, "high", \n -> n == 20 ) + , ( Test.Distribution.atLeast 80, "in between", \n -> n > 1 && n < 20 ) + , ( Test.Distribution.zero, "outside", \n -> n < 1 || n > 20 ) + , ( Test.Distribution.moreThanZero, "one", \n -> n == 1 ) + ] + } + (Fuzz.intRange 1 20) + "Failing distribution test" + (\n -> Expect.pass) ] From ae2a149e409f9bb416fb82bcbd730598d239260e Mon Sep 17 00:00:00 2001 From: Martin Janiczek Date: Fri, 14 Oct 2022 11:47:20 +0200 Subject: [PATCH 6/8] Cleanup some more --- src/Fuzz/Internal.elm | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Fuzz/Internal.elm b/src/Fuzz/Internal.elm index 631d680f..e605fa54 100644 --- a/src/Fuzz/Internal.elm +++ b/src/Fuzz/Internal.elm @@ -6,8 +6,6 @@ of the library. import GenResult exposing (GenResult) import PRNG exposing (PRNG) -import Random -import RandomRun type Fuzzer a From 73c035180c4541c6a1ce18a03ca0660db17017dc Mon Sep 17 00:00:00 2001 From: Martin Janiczek Date: Fri, 14 Oct 2022 11:48:04 +0200 Subject: [PATCH 7/8] It fails anyway because of Test.skip --- tests/src/FuzzerTests.elm | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/src/FuzzerTests.elm b/tests/src/FuzzerTests.elm index d8ff2830..494ac884 100644 --- a/tests/src/FuzzerTests.elm +++ b/tests/src/FuzzerTests.elm @@ -1189,8 +1189,8 @@ distributionTests = (Fuzz.intRange 1 20) "Int range boundaries - mandatory" (\n -> Expect.pass) - , Test.skip <| - -- we don't want failing tests around by default + , {- we don't want failing tests around by default + Test.fuzzWith { runs = 10000 , distribution = @@ -1205,6 +1205,7 @@ distributionTests = (Fuzz.intRange 1 20) "Failing distribution test" (\n -> Expect.pass) + -} ] From 5b472739177e28f3aa4e67cd9291f91804b8ec95 Mon Sep 17 00:00:00 2001 From: Martin Janiczek Date: Fri, 14 Oct 2022 11:48:28 +0200 Subject: [PATCH 8/8] Make it compile --- tests/src/FuzzerTests.elm | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/tests/src/FuzzerTests.elm b/tests/src/FuzzerTests.elm index 494ac884..8928b2c1 100644 --- a/tests/src/FuzzerTests.elm +++ b/tests/src/FuzzerTests.elm @@ -1189,22 +1189,23 @@ distributionTests = (Fuzz.intRange 1 20) "Int range boundaries - mandatory" (\n -> Expect.pass) - , {- we don't want failing tests around by default - Test.fuzzWith - { runs = 10000 - , distribution = - Test.expectDistribution - [ ( Test.Distribution.atLeast 5.5, "low", \n -> n == 1 ) - , ( Test.Distribution.atLeast 4, "high", \n -> n == 20 ) - , ( Test.Distribution.atLeast 80, "in between", \n -> n > 1 && n < 20 ) - , ( Test.Distribution.zero, "outside", \n -> n < 1 || n > 20 ) - , ( Test.Distribution.moreThanZero, "one", \n -> n == 1 ) - ] - } - (Fuzz.intRange 1 20) - "Failing distribution test" - (\n -> Expect.pass) + {- we don't want failing tests around by default + + , Test.fuzzWith + { runs = 10000 + , distribution = + Test.expectDistribution + [ ( Test.Distribution.atLeast 5.5, "low", \n -> n == 1 ) + , ( Test.Distribution.atLeast 4, "high", \n -> n == 20 ) + , ( Test.Distribution.atLeast 80, "in between", \n -> n > 1 && n < 20 ) + , ( Test.Distribution.zero, "outside", \n -> n < 1 || n > 20 ) + , ( Test.Distribution.moreThanZero, "one", \n -> n == 1 ) + ] + } + (Fuzz.intRange 1 20) + "Failing distribution test" + (\n -> Expect.pass) -} ]