dojang-0.1.0: test/Dojang/Types/FileRouteSpec.hs
{-# LANGUAGE ImportQualifiedPost #-}
{-# LANGUAGE OverloadedLists #-}
{-# LANGUAGE OverloadedRecordDot #-}
{-# LANGUAGE OverloadedStrings #-}
module Dojang.Types.FileRouteSpec (monikerMap, paths, spec) where
import Data.HashMap.Strict (HashMap, fromList)
import Data.Text (Text)
import System.OsPath (encodeFS)
import Test.Hspec (Spec, describe, specify)
import Test.Hspec.Expectations.Pretty (shouldBe, shouldNotBe, shouldReturn)
import Test.Hspec.Hedgehog (forAll, hedgehog, (===))
import Dojang.MonadFileSystem (FileType (..))
import Dojang.Types.Environment (Environment (Environment), Kernel (Kernel))
import Dojang.Types.EnvironmentPredicate
( EnvironmentPredicate (Moniker, OperatingSystem, Or)
)
import Dojang.Types.EnvironmentPredicate.Evaluate (EvaluationWarning (..))
import Dojang.Types.FilePathExpression (FilePathExpression (Root, Substitution))
import Dojang.Types.FilePathExpression.Expansion (ExpansionWarning (..))
import Dojang.Types.FileRoute
( FileRoute (monikerResolver, predicates)
, RouteWarning (..)
, dispatch
, fileRoute
, fileRoute'
, routePath
)
import Dojang.Types.Gen qualified as Gen
import Dojang.Types.MonikerName (MonikerName, parseMonikerName)
moniker :: Text -> MonikerName
moniker name = case parseMonikerName name of
Right monikerName -> monikerName
Left _ -> error "Invalid moniker name"
monikerMap :: HashMap MonikerName EnvironmentPredicate
monikerMap =
fromList
[ (moniker "linux", OperatingSystem "linux")
, (moniker "macos", OperatingSystem "macos")
, (moniker "windows", OperatingSystem "windows")
,
( moniker "posix"
, Or [Moniker $ moniker "linux", Moniker $ moniker "macos"]
)
]
paths :: [(MonikerName, Maybe FilePathExpression)]
paths =
[ (moniker "posix", Just $ Substitution "HOME")
,
( moniker "windows"
, Just $ Substitution "USERPROFILE" -- cSpell:disable-line
)
]
spec :: Spec
spec = do
let route = fileRoute monikerMap paths Directory
describe "FileRoute" $ do
specify "monikerResolver" $ do
route.monikerResolver (moniker "linux")
`shouldBe` Just (OperatingSystem "linux")
route.monikerResolver (moniker "non-existent") `shouldBe` Nothing
describe "Eq" $ do
specify "properties" $ hedgehog $ do
x <- forAll Gen.fileRoute
y <- forAll Gen.fileRoute
(x == x) === True
(x == y) === (y == x)
(x /= y) === (y /= x)
specify "examples" $ do
route `shouldBe` route
route
`shouldBe` fileRoute
monikerMap
[ (moniker "posix", Just $ Substitution "HOME")
,
( moniker "windows"
, Just $ Substitution "USERPROFILE" -- cSpell:disable-line
)
]
Directory
route
`shouldNotBe` fileRoute
monikerMap
[ (moniker "posix", Just $ Substitution "HOME")
, (moniker "windows", Just $ Substitution "HOME")
]
Directory
route
`shouldNotBe` fileRoute'
(const Nothing)
[ (Moniker $ moniker "posix", Just $ Substitution "HOME")
,
( Moniker $ moniker "windows"
, Just $ Substitution "USERPROFILE" -- cSpell:disable-line
)
]
Directory
specify "predicates" $ do
route.predicates
`shouldBe` ( [
( Moniker $ moniker "windows"
, Just $ Substitution "USERPROFILE" -- cSpell:disable-line
)
, (Moniker $ moniker "posix", Just $ Substitution "HOME")
]
:: [(EnvironmentPredicate, Maybe FilePathExpression)]
)
specify "Show" $ do
show route
`shouldBe` ("FileRoute " ++ show (route.predicates) ++ " Directory")
showList [route] ""
`shouldBe` ("[FileRoute " ++ show (route.predicates) ++ " Directory]")
specify "dispatch" $ do
dispatch (Environment "linux" "x86_64" $ Kernel "Linux" "5.10.0-8") route
`shouldBe` ([Just $ Substitution "HOME"], [])
dispatch (Environment "macos" "aarch64" $ Kernel "Darwin" "23.1.0") route
`shouldBe` ([Just $ Substitution "HOME"], [])
dispatch
( Environment "windows" "x86_64"
$ Kernel "Microsoft Windows" "10.0.23585.1001"
)
route
`shouldBe` ([Just $ Substitution "USERPROFILE"], []) -- cSpell:disable-line
dispatch
( Environment "windows" "x86_64"
$ Kernel "Microsoft Windows" "10.0.23585.1001"
)
route
`shouldBe` ([Just $ Substitution "USERPROFILE"], []) -- cSpell:disable-line
let withWarnings =
fileRoute
monikerMap
(paths ++ [(moniker "non-existent", Just $ Root Nothing)])
Directory
dispatch
(Environment "linux" "x86_64" $ Kernel "Linux" "5.10.0-8")
withWarnings
`shouldBe` ( [Just $ Substitution "HOME"]
, [UndefinedMoniker (moniker "non-existent")]
)
specify "routePath" $ do
routePath
route
(Environment "freebsd" "x86_64" $ Kernel "FreeBSD" "13.2-RELEASE-p4")
(const $ return Nothing)
`shouldReturn` (Nothing, [])
routePath
route
(Environment "linux" "x86_64" $ Kernel "Linux" "5.10.0-8")
(const $ return Nothing)
`shouldReturn` ( Just mempty
,
[ FilePathExpressionWarning
(UndefinedEnvironmentVariable "HOME")
]
)
home <- encodeFS "/home/hong"
routePath
route
(Environment "linux" "aarch64" $ Kernel "Linux" "5.10.0-8")
(const $ return $ Just $ home)
`shouldReturn` (Just home, [])