{-# LANGUAGE ScopedTypeVariables #-} import Data.AppSettings import Data.AppSettingsInternal import Test.Hspec import Test.HUnit (assertBool) import System.Directory (removeFile, copyFile, doesFileExist) import Control.Exception (try, SomeException) textSizeFromWidth :: Setting Double textSizeFromWidth = Setting "textSizeFromWidth" 0.04 textFill :: Setting (Double,Double,Double,Double) textFill = Setting "textFill" (1, 1, 0, 1) textSizeFromHeight :: Setting Double textSizeFromHeight = Setting "textSizeFromHeight" 12.4 testInlineList :: Setting [String] testInlineList = Setting "testInlineList" ["inline1", "inline2", "inline3"] testList :: Setting [String] testList = ListSetting "testList" ["list1", "list2", "list3"] defaultConfig :: DefaultConfig defaultConfig = getDefaultConfig $ do setting textSizeFromWidth setting textSizeFromHeight setting textFill setting testInlineList setting testList main :: IO () main = hspec $ do describe "unit tests" $ do testIsKeyForListSetting describe "load config" $ do testEmptyFileDefaults testPartialFileDefaults testPartialFileDefaults2 testFileWithComments testInvalidFile testInvalidValue testNonExistingFile describe "save config" $ do testSaveUserSetAndDefaults createBakBeforeSaving describe "set setting" $ do testSetListSetting testEmptyFileDefaults :: Spec testEmptyFileDefaults = it "parses correctly an empty file with defaults" $ do readResult <- try $ readSettings (Path "tests/empty.config") case readResult of Right (_, GetSetting getSetting) -> do getSetting textSizeFromWidth `shouldBe` 0.04 getSetting textSizeFromHeight `shouldBe` 12.4 getSetting textFill `shouldBe` (1,1,0,1) getSetting testInlineList `shouldBe` ["inline1", "inline2", "inline3"] getSetting testList `shouldBe` ["list1", "list2", "list3"] Left (x :: SomeException) -> assertBool (show x) False testPartialFileDefaults :: Spec testPartialFileDefaults = it "parses correctly a partial file with defaults" $ do readResult <- try $ readSettings (Path "tests/partial.config") case readResult of Right (_, GetSetting getSetting) -> do getSetting textSizeFromWidth `shouldBe` 1.02 getSetting textSizeFromHeight `shouldBe` 12.4 getSetting textFill `shouldBe` (1,2,3,4) getSetting testInlineList `shouldBe` ["un", "deux"] getSetting testList `shouldBe` ["one", "two"] Left (x :: SomeException) -> assertBool (show x) False testPartialFileDefaults2 :: Spec testPartialFileDefaults2 = it "parses correctly a partial2 file with defaults" $ do readResult <- try $ readSettings (Path "tests/partial2.config") case readResult of Right (_, GetSetting getSetting) -> do getSetting textSizeFromWidth `shouldBe` 1.02 getSetting textSizeFromHeight `shouldBe` 12.4 getSetting textFill `shouldBe` (1,2,3,4) getSetting testInlineList `shouldBe` ["un", "deux"] getSetting testList `shouldBe` [] Left (x :: SomeException) -> assertBool (show x) False testFileWithComments :: Spec testFileWithComments = it "parses correctly a partial file with comments" $ do readResult <- try $ readSettings (Path "tests/test-save.txt") case readResult of Right (_, GetSetting getSetting) -> do getSetting textSizeFromWidth `shouldBe` 1.02 getSetting textSizeFromHeight `shouldBe` 12.4 getSetting textFill `shouldBe` (1,2,3,4) getSetting testInlineList `shouldBe` ["un", "deux"] getSetting testList `shouldBe` ["one", "two"] Left (x :: SomeException) -> assertBool (show x) False testInvalidValue :: Spec testInvalidValue = it "parses correctly a file with invalid values" $ do readResult <- try $ readSettings (Path "tests/brokenvalue.config") case readResult of Right (_, GetSetting getSetting) -> do -- give the default for the invalid value getSetting textSizeFromWidth `shouldBe` 0.04 getSetting textSizeFromHeight `shouldBe` 12.4 getSetting textFill `shouldBe` (1,2,3,4) getSetting testInlineList `shouldBe` ["inline1", "inline2", "inline3"] getSetting testList `shouldBe` ["list1", "list2", "list3"] Left (x :: SomeException) -> assertBool (show x) False testNonExistingFile :: Spec testNonExistingFile = it "returns empty config for a non-existing file" $ do readResult <- try $ readSettings (Path "tests/dontexist.conf") case readResult of Right (_, GetSetting getSetting) -> do getSetting textSizeFromWidth `shouldBe` 0.04 getSetting textSizeFromHeight `shouldBe` 12.4 getSetting textFill `shouldBe` (1,1,0,1) getSetting testInlineList `shouldBe` ["inline1", "inline2", "inline3"] getSetting testList `shouldBe` ["list1", "list2", "list3"] Left (x :: SomeException) -> assertBool (show x) False testInvalidFile :: Spec testInvalidFile = it "reports errors properly for invalid files" $ do readResult <- try $ readSettings (Path "tests/broken.config") case readResult of Left (_ :: SomeException) -> assertBool "ok" True Right _ -> assertBool "did not get an error!" False testSaveUserSetAndDefaults :: Spec testSaveUserSetAndDefaults = it "saves a file with user-set and default settings" $ do readResult <- try $ readSettings (Path "tests/partial.config") case readResult of Right (conf, _) -> do saveSettings defaultConfig (Path "test.txt") conf actual <- readFile "test.txt" reference <- readFile "tests/test-save.txt" actual `shouldBe` reference removeFile "test.txt" Left (x :: SomeException) -> assertBool (show x) False createBakBeforeSaving :: Spec createBakBeforeSaving = it "creates a backup of the config file before overwriting it" $ do readResult <- try $ readSettings (Path "tests/partial.config") case readResult of Right (conf, _) -> do copyFile "tests/partial.config" "p.config" saveSettings defaultConfig (Path "p.config") conf doesFileExist "p.config.bak" >>= flip shouldBe True doesFileExist "p.config" >>= flip shouldBe True removeFile "p.config" removeFile "p.config.bak" Left (x :: SomeException) -> assertBool (show x) False testSetListSetting :: Spec testSetListSetting = it "overwrites correctly a list setting" $ do readResult <- try $ readSettings (Path "tests/empty.config") case readResult of Right (conf, GetSetting getSetting) -> do getSetting testList `shouldBe` ["list1", "list2", "list3"] getSetting testInlineList `shouldBe` ["inline1", "inline2", "inline3"] let conf0 = setSetting conf testList ["un"] let conf1 = setSetting conf0 testInlineList ["one"] getSetting' conf1 testList `shouldBe` ["un"] getSetting' conf1 testInlineList `shouldBe` ["one"] let conf2 = setSetting conf1 testList [] let conf3 = setSetting conf2 testInlineList [] getSetting' conf3 testList `shouldBe` [] getSetting' conf3 testInlineList `shouldBe` [] Left (x :: SomeException) -> assertBool (show x) False testIsKeyForListSetting :: Spec testIsKeyForListSetting = it "checks correctly whether a key is attached to a list setting" $ do isKeyForListSetting "listTest" "listTest_1" `shouldBe` True isKeyForListSetting "listTest" "listTest_13" `shouldBe` True isKeyForListSetting "listTest" "listTest_unrelated" `shouldBe` False isKeyForListSetting "listTest" "listTest_1notanumber" `shouldBe` False isKeyForListSetting "listTest" "listTestX_1" `shouldBe` False