{-# LANGUAGE TemplateHaskell #-} module IntegTest.Elocrypt.PasswordTest where import Data.Char import Data.List import Data.Maybe import Control.Monad import Test.Tasty hiding (Timeout) import Test.Tasty.QuickCheck (testProperty) import Test.Tasty.TH import Test.Elocrypt.QuickCheck tests :: TestTree tests = $(testGroupGenerator) elocrypt = "elocrypt" -- |All passwords have specified length prop_printsPasswordsWithLength :: WordCliOptions -> Property prop_printsPasswordsWithLength (WordCliOptions opts) = isJust len ==> ioProperty $ do (_, out, _, _) <- run opts response <- readHandle out let len' = fromJust len words' = words response return (all ((==) len' . length) words') where CliOptions{cliLength=len} = opts -- |Prints nothing when length is 0 prop_printsNothingWhenLengthIsZero :: WordCliOptions -> Property prop_printsNothingWhenLengthIsZero (WordCliOptions opts) = ioProperty $ do let opts' = opts { cliLength = Just 0 } (_, out, _, _) <- run opts' response <- readHandle out return (response == "") -- |Always prints at least 1 password prop_printsLongPasswords :: WordCliOptions -> Property prop_printsLongPasswords (WordCliOptions opts) = forAll (scale (*7) arbitrary) $ \len -> ioProperty $ do let len' = getPositive len opts' = opts { cliLength = Just len' } (_, out, _, _) <- run opts' response <- readHandle out return $ cover 30 (len' > 80) "long" $ all (>=1) . map (length . words) . lines $ response -- |Prints the specified number of passwords prop_printsNumberPasswords :: Positive Int -> WordCliOptions -> Property prop_printsNumberPasswords (Positive num) (WordCliOptions opts) = ioProperty $ do let opts' = opts { cliNumber = Just num } (_, out, _, _) <- run opts' response <- readHandle out let words' = words response return $ num == length words' -- |Prints multiple passwords per line when length is sufficiently small prop_printsMultiplePasswordsPerLine :: WordCliOptions -> Property prop_printsMultiplePasswordsPerLine (WordCliOptions opts) = isNothing len || fromJust len <= 38 ==> ioProperty $ do (_, out, _, _) <- run opts response <- readHandle out return $ all (>1) . tail . reverse . map (length . words) . lines $ response where CliOptions{cliLength=len} = opts -- |Prints capitals when specified prop_printsCapitals :: WordCliOptions -> Property prop_printsCapitals (WordCliOptions opts) = ioProperty $ do let opts' = opts { cliCapitals = True } (_, out, _, _) <- run opts' response <- readHandle out let passes = words response return $ cover 80 (any (any isUpper) passes) "has caps" True