elocrypt-2.0.0: test/IntegTest/Elocrypt/PasswordTest.hs
{-# 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 (len' > 80) 30 "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 (any (any isUpper) passes) 80 "has caps" True