{-# 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" testIsKeyForListSetting
describe "load config" $ do
testEmptyFileDefaults
testPartialFileDefaults
testPartialFileDefaults2
testFileWithComments
testInvalidFile
testInvalidValue
testNonExistingFile
describe "save config" $ do
testSaveUserSetAndDefaults
createBakBeforeSaving
describe "set setting" 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