{-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE ScopedTypeVariables #-} module Main where import qualified Data.HashMap.Strict as M import Data.Salak import Data.Salak.CommandLine import Data.Salak.Environment import Data.Salak.Operation () import Data.Text (Text, intercalate, pack) import System.Environment import Test.Hspec import Test.QuickCheck main = hspec spec spec :: Spec spec = do describe "Data.Salak.Types" specProperty describe "Data.Salak" specProperties describe "Data.Salak.Dynamic" specDynamic shouldFail :: (Show a, Eq a) => a -> a -> Expectation shouldFail f a = (f `shouldBe` a) `shouldThrow` anyErrorCall data Config = Config { name :: Text , dir :: Text , ext :: Int } deriving (Eq, Show) instance FromProperties Config where fromProperties v = Config <$> v .?> "name" <*> v .?> "dir" <*> v .?> "ext" .?= 1 specProperty = do context "empty" $ do it "normal" $ do let p = empty print p p `shouldBe` Properties [] [] context "toKeys" $ do it "normal" $ do [] `shouldBe` toKeys "" ["a"] `shouldBe` toKeys "a" ["a"] `shouldBe` toKeys "a." ["a","b"] `shouldBe` toKeys "a.b" ["a","b"] `shouldBe` toKeys "a.....b" it "quickCheck" $ do quickCheck $ \a -> let b = toKeys $ pack a in b == toKeys (intercalate "." b) context "insert" $ do let p = PStr "Hello" k = toKeys "a.b" m = insert k p empty it "normal" $ do insert [] p empty `shouldBe` Properties [p] [] insert k p empty `shouldBe` Properties [] [M.insert "a" (Properties [] [M.insert "b" (Properties [p] []) M.empty]) M.empty] it "Reject replacement" $ do insert k "1" m `shouldBe` m it "quickCheck" $ do quickCheck $ \a' (b :: Int) -> let a = pack a' in Just b == (insert (toKeys a) (PNum $ fromIntegral b) empty) .>> a quickCheck $ \a' (b :: Bool) -> let a = pack a' in Just b == (insert (toKeys a) (PBool b) empty) .>> a quickCheck $ \a' (b :: String) -> let a = pack a' in Just b == (insert (toKeys a) (PStr $ pack b) empty) .>> a context "lookup" $ do it "normal" $ do let m = insert ["a"] (PNum 1) empty n = insert ["a"] (PStr "true") empty (empty .>> "a" :: Maybe Int) `shouldBe` Nothing (m .>> "a" :: Maybe Int) `shouldBe` Just 1 (m .>> "a" :: Maybe Bool) `shouldFail` Nothing (m .>> "a" :: Maybe String) `shouldBe` Just "1.0" (n .>> "a" :: Maybe Int) `shouldFail` Nothing (n .>> "a" :: Maybe Bool) `shouldBe` Just True (n .>> "a" :: Maybe Text) `shouldBe` Just "true" context "makeProperties" $ do it "normal" $ do m <- makePropertiesFromEnvironment empty h <- getEnv "HOME" (m .>> "home") `shouldBe` Just h context "command-line" $ do it "normal" $ do let args = ["--package.a.enabled=true","--package.b.enabled=false","package.c.enabled=false"] m <- makePropertiesFromCommandLine' args defaultParseCommandLine empty (m .>> "package.a.enabled") `shouldBe` Just True (m .>> "package.b.enabled") `shouldBe` Just False (m .>> "package.c.enabled" :: Maybe Bool )`shouldBe` Nothing context "environment" $ do it "normal" $ do let args = [("PACKAGE_A_ENABLED","true"),("PACKAGE_B_ENABLED","false")] m = makePropertiesFromEnvironment' args empty (m .>> "package.a.enabled") `shouldBe` Just True (m .>> "package.b.enabled") `shouldBe` Just False (m .>> "package.c.enabled" :: Maybe Bool )`shouldBe` Nothing specProperties = do context "defaultPropertiesWithFile" $ do let confName = "salak.yml" :: String confName' = pack confName it "read config" $ do unsetEnv "SALAK_CONFIG_NAME" p <- defaultPropertiesWithFile confName p .>> "salak.config.name" `shouldBe` Just confName it "read config - replacement" $ do setEnv "SALAK_CONFIG_NAME" confName p <- defaultPropertiesWithFile "salak.ok" p .>> "salak.config.name" `shouldBe` Just confName it "read config - not found" $ do setEnv "SALAK_CONFIG_NAME" "salak.notfound" setEnv "SALAK_CONFIG_DIR" "test" defaultPropertiesWithFile confName `shouldThrow` anyException it "read config - read file parse Config" $ do setEnv "SALAK_CONFIG_NAME" confName setEnv "SALAK_CONFIG_DIR" "test" setEnv "SALAK_CONFIG" confName p <- defaultPropertiesWithFile confName (p .>> "salak.config.name") `shouldBe` Just confName (p .>> "salak.config") `shouldBe` Just confName (p .>> "salak.config" :: Maybe Config) `shouldBe` Just (Config confName' "test" 1) (p .>> "array" :: Maybe [String]) `shouldBe` Just ["a","b"] (p .>> "array" :: Maybe [Int]) `shouldFail` Nothing (p .>> "array" :: Maybe String) `shouldFail` Nothing specDynamic = do context "Dynamic" $ do it "dynamic load" $ do p <- defaultPropertiesWithFile "salak.yml" (c,s) <- runLoader p $ (,) <$> load "config" <*> askSetProperties c1 <- c s $ insert ["config","name"] "world" empty c2 <- c name c1 `shouldBe` "hello" name c2 `shouldBe` "world" dir c1 `shouldBe` dir c2 ext c1 `shouldBe` ext c2