diff --git a/src/Test/Test.elm b/src/Test/Test.elm index ec8d57d..92b6d9c 100644 --- a/src/Test/Test.elm +++ b/src/Test/Test.elm @@ -17,50 +17,40 @@ fuzzTest : String -> Fuzzer a -> (a -> Expectation) -> Test fuzzTest desc fuzzer getOutcome = let run seed runs = - let - runWithInput val = - let - outcome = - getOutcome val - - shrunkenVal = - if isFail outcome then - Shrink.shrink (getOutcome >> isFail) fuzzer.shrinker val - else - val - - shrunkenTest = - getOutcome shrunkenVal - in - ( Just (toString shrunkenVal), shrunkenTest ) - - -- testRuns : Generator (List a) - testRuns = - Random.list runs fuzzer.generator - - generators = - Random.map (List.map runWithInput) testRuns - - dedupe pairs = - pairs - |> List.map (\( mk, v ) -> ( Maybe.withDefault "" mk, v )) - |> Dict.fromList - |> Dict.toList - |> List.map - (\( s, v ) -> - ( if s == "" then - Nothing - else - Just s - , v - ) - ) - in - seed - |> Random.step generators - |> fst - |> dedupe - |> List.map formatExpectation + if runs < 1 then + [ Fail ("Fuzz test run count must be at least 1, not " ++ toString runs) ] + else + let + runWithInput val = + ( val, getOutcome val ) + + generators = + fuzzer.generator + |> Random.list runs + |> Random.map (List.map runWithInput) + + ( pairs, _ ) = + Random.step generators seed + in + -- Make sure if we passed, we don't do any more work. + if List.all (\( _, outcome ) -> outcome == Pass) pairs then + [ Pass ] + else + let + shrink ( val, outcome ) = + if isFail outcome then + let + shrunkenVal = + Shrink.shrink (getOutcome >> isFail) fuzzer.shrinker val + in + ( Just (toString shrunkenVal), getOutcome shrunkenVal ) + else + ( Just (toString val), outcome ) + in + pairs + |> List.map shrink + |> dedupe + |> List.map formatExpectation in Labeled desc (Test run) @@ -70,6 +60,23 @@ formatExpectation ( input, outcome ) = Test.Expectation.formatFailure (prependInput input) outcome +dedupe : List ( Maybe String, a ) -> List ( Maybe String, a ) +dedupe pairs = + pairs + |> List.map (\( mk, v ) -> ( Maybe.withDefault "" mk, v )) + |> Dict.fromList + |> Dict.toList + |> List.map + (\( s, v ) -> + ( if s == "" then + Nothing + else + Just s + , v + ) + ) + + prependInput : Maybe String -> String -> String prependInput input original = case input of