packages feed

app-settings-0.1.0.0: tests/Tests.hs

{-# LANGUAGE ScopedTypeVariables #-}

import Data.AppSettings

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

defaultConfig :: DefaultConfig
defaultConfig = getDefaultConfig $ do
	setting textSizeFromWidth
	setting textSizeFromHeight
	setting textFill

main :: IO ()
main = hspec $ do
	describe "load config" $ do
		testEmptyFileDefaults
		testPartialFileDefaults
		testFileWithComments
		testInvalidFile
		testInvalidValue
		testNonExistingFile
	describe "save config" $ do
		testSaveUserSetAndDefaults
		createBakBeforeSaving

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)
		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)
		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)
		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)
		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)
		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