git-config-0.1.0: test/Text/GitConfig/ParserTest.hs
{-# LANGUAGE ScopedTypeVariables #-}
module Text.GitConfig.ParserTest where
import qualified Data.HashMap.Strict as M
import Data.Monoid ((<>))
import Data.Text (Text)
import qualified Data.Text as T
import Test.SmallCheck.Series.Instances ()
import Test.Tasty (TestTree, testGroup)
import Test.Tasty.HUnit (Assertion, assertEqual,
assertFailure, testCase)
import Test.Tasty.SmallCheck (testProperty)
import qualified Text.GitConfig.Parser as P
import Text.Megaparsec (parse)
-- | Simple assert helper for HUnit tests on parse results
assertSuccess :: Either e a -> Assertion
assertSuccess res =
case res of
Left _ -> assertFailure ""
Right _ -> return ()
assertFail :: Either e a -> Assertion
assertFail res =
case res of
Left _ -> return ()
Right _ -> assertFailure ""
test_symbol :: TestTree
test_symbol = testProperty
"symbol should parse the given text and consume trailing whitespace" $
\(t :: Text) ->
case parse (P.symbol t) "" (t <> " ") of
Left _ -> False
Right t' -> t == t'
test_brackets :: TestTree
test_brackets = testProperty
"brackets should parse the given text between '[' and ']' characters" $
\(t :: Text) ->
let tBetweenBrackets = "[" <> t <> "]" in
case parse (P.brackets (P.symbol t)) "" tBetweenBrackets of
Left _ -> False
Right t' -> t == t'
test_quotes :: TestTree
test_quotes = testProperty
"quotes should parse the given text between '\"' characters" $
\(t :: Text) ->
let tBetweenQuotes = "\"" <> t <> "\"" in
case parse (P.quotes (P.symbol t)) "" tBetweenQuotes of
Left _ -> False
Right t' -> t == t'
(<&>) :: Functor f => f a -> (a -> b) -> f b
(<&>) = flip fmap
test_escSeq :: TestTree
test_escSeq = testGroup "ensure all valid escape sequences are parsed" $
["\"", "\\", "/", "n", "t", "r", "b", "f"] <&> \(t :: Text) ->
let escaped = "\\" <> t in
testCase (T.unpack $ "char " <> escaped) $
assertSuccess $ parse P.escSeq "" escaped
test_sectionName :: TestTree
test_sectionName = testGroup
"sectionName parses both section and subsection names"
[
testCase "section" $
assertSuccess $ parse P.sectionName "" "core",
testCase "subSection" $
assertSuccess $ parse P.sectionName "" "core \"sub/+Section\""
]
test_sectionHeader :: TestTree
test_sectionHeader = testGroup
"sectionHeader parses an entire section header"
[
testCase "section" $
assertSuccess $ parse P.sectionHeader "" "[core]",
testCase "subSection" $
assertSuccess $ parse P.sectionHeader "" "[core \"sub/+Section\"]"
]
test_variableName :: TestTree
test_variableName = testGroup "variableName parses a key in a key/val pair"
[
testCase "valid" $
assertSuccess $ parse P.variableName "" "aSdF",
testCase "fail start with nonalpha" $
assertFail $ parse P.variableName "" "+ASDF",
testCase "pass with dash" $
assertSuccess $ parse P.variableName "" "foo-bar"
]
test_variableValue :: TestTree
test_variableValue = testGroup
"variableValue parses the value in a key/value pair"
[
testCase "valid" $
assertSuccess $ parse P.variableValue "" "foo\n",
testCase "fail without eol" $
assertFail $ parse P.variableValue "" "foo"
]
test_mapping :: TestTree
test_mapping = testGroup
"mapping parses entire key/value pairs"
[
testCase "valid" $
assertSuccess $ parse P.mapping "" "key = value\n",
testCase "temporarily invalid boolean switch" $
assertFail $ parse P.mapping "" "key\n"
]
test_section :: TestTree
test_section = testGroup
"section parses entire sections in a git config"
[
testCase "valid" $
assertSuccess $ parse P.section "" "[core]\nfoo = bar\n",
testCase "valid multiple mappings" $
assertSuccess $ parse P.section "" "[core]\nfoo = bar\nbaz = quux\n",
testCase "valid stop at one section" $
case parse P.section "" "[core \"subsec\"]\nfoo = bar\n[next \"section\"]\nlol = hi\n" of
Left _ -> assertFailure ""
Right p ->
assertEqual ""
(P.Section ["core", "subsec"] (M.fromList [("foo", "bar")])) p
]
test_config :: TestTree
test_config = testGroup
"config parses an entire git configuration"
[
testCase "valid" $
assertSuccess $ parse P.config "" "[core]\nfoo=bar\n[remote \"origin\"]\nkey=val\n",
testCase "invalid mapping without section" $
assertFail $ parse P.config "" "foo=bar\n[remote \"origin\"]\nkey=val\n"
]