moduleTest.Framework.Providers.QuickCheck(testProperty)whereimportTest.Framework.Providers.APIimportTest.QuickCheckhiding(Property)importData.ListimportSystem.Random-- | Create a 'Test' for a QuickCheck 'Testable' propertytestProperty::Testablea=>TestName->a->TesttestPropertyname=Testname.PropertyinstanceTestResultlikePropertyTestCountPropertyResultwheretestSucceeded=propertySucceeded-- | Used to document numbers which we expect to be intermediate test counts from running propertiestypePropertyTestCount=Int-- | The failure information from the run of a propertydataPropertyResult=PropertyResult{pr_status::PropertyStatus,pr_used_seed::Int,pr_tests_run::MaybePropertyTestCount-- Due to technical limitations, it's currently not possible to find out the number of-- tests previously run if the test times out, hence we need a Maybe here for that case.}dataPropertyStatus=PropertyOK-- ^ The property is true as far as we could check it|PropertyArgumentsExhausted-- ^ The property may be true, but we ran out of arguments to try it out on|PropertyFalsifiable[String]-- ^ The property was not true. The list of strings are the arguments inducing failure.|PropertyTimedOut-- ^ The property timed out during executioninstanceShowPropertyResultwhereshow(PropertyResult{pr_status=status,pr_used_seed=used_seed,pr_tests_run=mb_tests_run})=casestatusofPropertyOK->"OK, passed "++tests_run_str++" tests"PropertyArgumentsExhausted->"Arguments exhausted after "++tests_run_str++" tests"PropertyFalsifiabletest_args->"Falsifiable with seed "++showused_seed++", after "++tests_run_str++" tests:\n"++unlinesConcisetest_argsPropertyTimedOut->"Timed out after "++tests_run_str++" tests"wheretests_run_str=fmapshowmb_tests_run`orElse`"an unknown number of"propertySucceeded::PropertyResult->BoolpropertySucceededresult=propertyStatusIsSuccess(pr_statusresult)propertyStatusIsSuccess::PropertyStatus->BoolpropertyStatusIsSuccessPropertyOK=TruepropertyStatusIsSuccessPropertyArgumentsExhausted=TruepropertyStatusIsSuccess_=FalsedataProperty=foralla.Testablea=>PropertyainstanceTestlikePropertyTestCountPropertyResultPropertywhererunTesttopts(Propertytestable)=runPropertytoptstestabletestTypeName_="Properties"runProperty::Testablea=>CompleteTestOptions->a->IO(PropertyTestCount:~>PropertyResult,IO())runPropertytoptstestable=do(gen,seed)<-newSeededStdGen(unK$topt_seedtopts)runImprovingIO$domb_result<-maybeTimeoutImprovingIO(unK(topt_timeouttopts))$myChecktoptsgentestablereturn$toPropertyResultseed$casemb_resultofNothing->(PropertyTimedOut,Nothing)Just(status,tests_run)->(status,Justtests_run)wheretoPropertyResultseed(status,mb_tests_run)=PropertyResult{pr_status=status,pr_used_seed=seed,pr_tests_run=mb_tests_run}myCheck::(Testablea)=>CompleteTestOptions->StdGen->a->ImprovingIOPropertyTestCountf(PropertyStatus,PropertyTestCount)myChecktoptsrnda=myTeststopts(evaluatea)rnd00[]myTests::CompleteTestOptions->GenResult->StdGen->PropertyTestCount->PropertyTestCount->[[String]]->ImprovingIOPropertyTestCountf(PropertyStatus,PropertyTestCount)myTeststoptsgenrnd0ntestnfailstamps|ntest==unK(topt_maximum_generated_teststopts)=doreturn(PropertyOK,ntest)|nfail==unK(topt_maximum_unsuitable_generated_teststopts)=doreturn(PropertyArgumentsExhausted,ntest)|otherwise=doyieldImprovementntestcaseokresultofNothing->myTeststoptsgenrnd1ntest(nfail+1)stampsJustTrue->myTeststoptsgenrnd1(ntest+1)nfail(stampresult:stamps)JustFalse->return(PropertyFalsifiable(argumentsresult),ntest)whereresult=generate(configSizedefaultConfigntest)rnd2gen(rnd1,rnd2)=splitrnd0