{-# LANGUAGE TypeSynonymInstances, FlexibleInstances, GeneralizedNewtypeDeriving #-}moduleTest.Hspec.Core.Type(Spec,SpecM(..),runSpecM,fromSpecList,SpecTree(..),Example(..),Result(..),Params(..),defaultParams,describe,it)whereimportqualifiedControl.ExceptionasEimportControl.ApplicativeimportControl.Monad.Trans.Writer(Writer,execWriter,tell)importTest.Hspec.UtilimportTest.Hspec.ExpectationsimportTest.HUnit.Lang(HUnitFailure(..))importqualifiedTest.QuickCheckasQCtypeSpec=SpecM()-- | A writer monad for `SpecTree` forests.newtypeSpecMa=SpecM(Writer[SpecTree]a)deriving(Functor,Applicative,Monad)-- | Convert a `Spec` to a forest of `SpecTree`s.runSpecM::Spec->[SpecTree]runSpecM(SpecMspecs)=execWriterspecs-- | Create a `Spec` from a forest of `SpecTree`s.fromSpecList::[SpecTree]->SpecfromSpecList=SpecM.tell-- | The result of running an example.dataResult=Success|Pending(MaybeString)|FailStringderiving(Eq,Show)dataParams=Params{paramsQuickCheckArgs::QC.Args}defaultParams::ParamsdefaultParams=ParamsQC.stdArgs-- | Internal representation of a spec.dataSpecTree=SpecGroupString[SpecTree]|SpecItemString(Params->IOResult)-- | The @describe@ function combines a list of specs into a larger spec.describe::String->[SpecTree]->SpecTreedescribe=SpecGroup-- | Create a spec item.it::Examplea=>String->a->SpecTreeitse=SpecItems(`evaluateExample`e)-- | A type class for examples.classExampleawhereevaluateExample::Params->a->IOResultinstanceExampleBoolwhereevaluateExample_b=ifbthenreturnSuccesselsereturn(Fail"")instanceExampleExpectationwhereevaluateExample_action=(action>>returnSuccess)`E.catch`\(HUnitFailureerr)->return(Failerr)instanceExampleResultwhereevaluateExample_r=r`seq`returnrinstanceExampleQC.PropertywhereevaluateExamplecp=dor<-QC.quickCheckWithResult(paramsQuickCheckArgsc)preturn$caserofQC.Success{}->Successf@(QC.Failure{})->Fail(QC.outputf)QC.GaveUp{QC.numTests=n}->Fail("Gave up after "++quantifyn"test")QC.NoExpectedFailure{}->Fail("No expected failure")