hapistrano/spec/System/HapistranoPropsSpec.hs
William R. Arellano f8a869ce3d Quickcheck property tests (#128)
* Add property check quote command

* Add property test trim function

* Fix biased test cases for trim function

* Stack lock

* Separated property tests from other tests

* Fixes on imports

* PR quickcheck

* Remove wrong comment

* Add property test for generic and ungeneric command

* Refactoring isCmdString function

* Fix conflicts

* Add quickchek part 1
2019-11-11 13:01:17 -05:00

86 lines
2.8 KiB
Haskell

module System.HapistranoPropsSpec
( spec
) where
import Data.Char (isSpace)
import System.Hapistrano.Commands.Internal (mkGenericCommand,
quoteCmd, trim,
unGenericCommand)
import Test.Hspec hiding (shouldBe,
shouldReturn)
import Test.QuickCheck
spec :: Spec
spec =
describe "QuickCheck" $
context "Properties" $ do
it "property of quote command" $ property propQuote'
it "property of trimming a command" $
property $ forAll trimGenerator propTrim'
it "property of mkGenericCommand and unGenericCommand" $
property $ forAll genericCmdGenerator propGenericCmd'
-- Is quoted determine
isQuoted :: String -> Bool
isQuoted str = head str == '"' && last str == '"'
-- | Quote function property
propQuote :: String -> Bool
propQuote str =
if any isSpace str
then isQuoted $ quoteCmd str
else quoteCmd str == str
propQuote' :: String -> Property
propQuote' str =
classify (any isSpace str) "has at least a space" $ propQuote str
-- | Is trimmed
isTrimmed' :: String -> Bool
isTrimmed' [] = True
isTrimmed' [x] = not $ isSpace x
isTrimmed' str =
let a = not . isSpace $ head str
b = not . isSpace $ last str
in a && b
-- | Prop trimm
propTrim :: String -> Bool
propTrim = isTrimmed' . trim
propTrim' :: String -> Property
propTrim' str =
classify (not $ isTrimmed' str) "non trimmed strings" $ propTrim str
-- | Check that the string is perfect command String
isCmdString :: String -> Bool
isCmdString str = all ($str) [not . null, notElem '#', notElem '\n', isTrimmed']
-- | Prop Generic Command
-- If the string does not contain # or \n, is trimmed and non null, the command should be created
propGenericCmd :: String -> Bool
propGenericCmd str =
if isCmdString str
then maybe False ((== str) . unGenericCommand) (mkGenericCommand str)
else maybe True ((/= str) . unGenericCommand) (mkGenericCommand str) -- Either the command cannot be created or the command str is different to the original
propGenericCmd' :: String -> Property
propGenericCmd' str =
classify (isCmdString str) "perfect command string" propGenericCmd
-- | Trim String Generator
trimGenerator :: Gen String
trimGenerator =
let strGen = listOf arbitraryUnicodeChar
in frequency
[ (1, suchThat strGen isTrimmed')
, (1, suchThat strGen (not . isTrimmed'))
]
-- | Generic Command generator
genericCmdGenerator :: Gen String
genericCmdGenerator =
let strGen = listOf $ elements $ ['A'..'Z'] ++ ['a'..'z'] ++ [' ', '#', '*', '/', '.']
in frequency
[(1, suchThat strGen isCmdString), (1, suchThat strGen (elem '#'))]