module Test.Property ( NamedProperty , namedProperty , singletonNamedProperty , NamedDBProperty , namedDBProperty , singletonNamedDBProperty , singletonProperty , Group (..) , group , checkGroups , checkGroup , allPassed ) where import qualified Control.Monad as Monad import qualified Data.String as String import qualified GHC.Stack as CallStack import qualified Hedgehog as HH import qualified Hedgehog.Internal.Config as Config import qualified Hedgehog.Internal.Property as Property import qualified Hedgehog.Internal.Report as Report import qualified Hedgehog.Internal.Runner as Runner import qualified Hedgehog.Internal.Seed as Seed import qualified Orville.PostgreSQL as Orville type NamedProperty = (HH.PropertyName, HH.Property) type NamedDBProperty = Orville.ConnectionPool -> NamedProperty namedProperty :: String -> HH.PropertyT IO () -> NamedProperty namedProperty nameString propertyT = (String.fromString nameString, HH.property propertyT) singletonNamedProperty :: String -> HH.PropertyT IO () -> NamedProperty singletonNamedProperty nameString property = HH.withTests 1 <$> namedProperty nameString property namedDBProperty :: String -> (Orville.ConnectionPool -> HH.PropertyT IO ()) -> NamedDBProperty namedDBProperty nameString dbProperty pool = namedProperty nameString (dbProperty pool) singletonNamedDBProperty :: String -> (Orville.ConnectionPool -> HH.PropertyT IO ()) -> NamedDBProperty singletonNamedDBProperty nameString dbProperty pool = HH.withTests 1 <$> namedProperty nameString (dbProperty pool) singletonProperty :: CallStack.HasCallStack => HH.PropertyT IO () -> HH.Property singletonProperty = HH.withTests 1 . HH.property data Group = Group { groupName :: String , groupProperties :: [NamedProperty] } group :: String -> [NamedProperty] -> Group group = Group checkGroups :: Foldable f => f Group -> IO Report.Summary checkGroups groups = do useColor <- Config.resolveColor Nothing summary <- foldMap (checkGroup useColor) groups putStrLn =<< Report.renderSummary useColor summary pure summary checkGroup :: Config.UseColor -> Group -> IO Report.Summary checkGroup useColor propGroup = do let name = groupName propGroup properties = groupProperties propGroup putStrLn $ "• " <> name <> " : " <> show (length properties) <> " properties" foldMap (checkProperty useColor) properties checkProperty :: Config.UseColor -> NamedProperty -> IO Report.Summary checkProperty useColor (name, prop) = do seed <- Seed.random report <- Runner.checkReport (Property.propertyConfig prop) 0 seed (Property.propertyTest prop) (\_ -> pure ()) let result = Report.reportStatus report Monad.when (result /= Report.OK) $ do putStrLn =<< Report.renderResult useColor (Just name) report pure $ Report.fromResult result allPassed :: Report.Summary -> Bool allPassed summary = Report.summaryFailed summary == 0 && Report.summaryGaveUp summary == 0