pushme-3.1.0: test/Main.hs
{-# LANGUAGE OverloadedStrings #-}
module Main where
import qualified Data.ByteString.Char8 as B
import qualified Data.Map.Strict as M
import Data.Text (Text)
import Data.Yaml (ParseException, decodeEither')
import Hedgehog
import qualified Hedgehog.Gen as Gen
import qualified Hedgehog.Range as Range
import Pushme.Options
import Test.Tasty
import Test.Tasty.Hedgehog
main :: IO ()
main = defaultMain tests
tests :: TestTree
tests =
testGroup
"pushme"
[ testGroup
"combineFilters"
[ testProperty "Nothing is left identity" prop_combineFilters_leftId
, testProperty "Nothing is right identity" prop_combineFilters_rightId
, testProperty "associative" prop_combineFilters_assoc
, testProperty "both Just concatenates with newline" prop_combineFilters_concat
]
, testGroup
"RsyncOptions Semigroup"
[ testProperty "associative" prop_rsyncOptions_assoc
]
, testGroup
"filter set references"
[ testProperty "interpolates a named filter set" prop_filterReference_exact
, testProperty "resolves Filters and ExtraFilters" prop_resolveRsyncFilterReferences
, testProperty "parses and resolves config filter sets" prop_optionsParseFilterSets
]
]
-- Generators
genText :: Gen Text
genText = Gen.text (Range.linear 0 50) Gen.alphaNum
genMaybeText :: Gen (Maybe Text)
genMaybeText = Gen.maybe genText
genMaybeTextList :: Gen (Maybe [Text])
genMaybeTextList = Gen.maybe (Gen.list (Range.linear 0 5) genText)
genMaybeBool :: Gen (Maybe Bool)
genMaybeBool = Gen.maybe Gen.bool
genRsyncOptions :: Gen RsyncOptions
genRsyncOptions =
RsyncOptions
<$> genMaybeText
<*> genMaybeText
<*> Gen.bool
<*> Gen.bool
<*> genMaybeBool -- PreserveACLs
<*> genMaybeBool -- PreserveXattrs
<*> genMaybeBool -- PreserveAtimes
<*> genMaybeBool -- PreserveCrtimes
<*> genMaybeBool -- PreserveHardLinks
<*> genMaybeBool -- PreserveExecutability
<*> Gen.bool
<*> genMaybeTextList
<*> genMaybeTextList
<*> Gen.bool
emptyRsyncOptions :: RsyncOptions
emptyRsyncOptions =
RsyncOptions
Nothing
Nothing
False
False
Nothing
Nothing
Nothing
Nothing
Nothing
Nothing
False
Nothing
Nothing
True
-- combineFilters properties
prop_combineFilters_leftId :: Property
prop_combineFilters_leftId = property $ do
x <- forAll genMaybeText
combineFilters Nothing x === x
prop_combineFilters_rightId :: Property
prop_combineFilters_rightId = property $ do
x <- forAll genMaybeText
combineFilters x Nothing === x
prop_combineFilters_assoc :: Property
prop_combineFilters_assoc = property $ do
a <- forAll genMaybeText
b <- forAll genMaybeText
c <- forAll genMaybeText
combineFilters (combineFilters a b) c === combineFilters a (combineFilters b c)
prop_combineFilters_concat :: Property
prop_combineFilters_concat = property $ do
a <- forAll genText
b <- forAll genText
combineFilters (Just a) (Just b) === Just (a <> "\n" <> b)
-- RsyncOptions Semigroup properties
prop_rsyncOptions_assoc :: Property
prop_rsyncOptions_assoc = property $ do
a <- forAll genRsyncOptions
b <- forAll genRsyncOptions
c <- forAll genRsyncOptions
(a <> b) <> c === a <> (b <> c)
-- Filter set reference properties
prop_filterReference_exact :: Property
prop_filterReference_exact =
property $
interpolateFilterReferences
(M.fromList [("srcFilters", "- dist/\n- result")])
"$srcFilters"
=== "- dist/\n- result"
prop_resolveRsyncFilterReferences :: Property
prop_resolveRsyncFilterReferences = property $ do
let filterSets =
M.fromList
[ ("commonFilters", "- dist/")
, ("extraFilters", "- .cache/")
]
resolved =
resolveRsyncFilterReferences
filterSets
emptyRsyncOptions
{ _rsyncFilters = Just "$commonFilters"
, _rsyncExtraFilters = Just "- tmp/\n$extraFilters"
}
_rsyncFilters resolved === Just "- dist/"
_rsyncExtraFilters resolved === Just "- tmp/\n- .cache/"
prop_optionsParseFilterSets :: Property
prop_optionsParseFilterSets = property $
case decodeEither' configYaml :: Either ParseException Options of
Left err -> do
annotateShow err
failure
Right opts -> do
_optsFilterSets opts
=== M.fromList [("srcFilters", "- dist/\n- result\n")]
fmap _rsyncFilters (_optsRsyncOpts (resolveOptionsFilterReferences opts))
=== Just (Just "- dist/\n- result\n")
where
configYaml =
B.pack $
unlines
[ "Filters:"
, " srcFilters: |"
, " - dist/"
, " - result"
, "GlobalOptions:"
, " Filters: $srcFilters"
]