camfort-0.903: tests/Camfort/Specification/Units/ParserSpec.hs
module Camfort.Specification.Units.ParserSpec (spec) where
import Camfort.Specification.Parser (runParser, SpecParseError)
import Camfort.Specification.Units.Parser (unitParser, UnitParseError)
import Camfort.Specification.Units.Parser.Types (UnitStatement)
import Test.Hspec
spec :: Spec
spec = do
let shouldParseSameAs s s' =
parseUnits s `shouldBe` parseUnits s'
unitEquivalences =
[ ("m * s", "m s")
, ("m * s**2", "m s**2")
, ("m * s/t", "m s/t")
]
describe "Parsing Equivalence" $
mapM_ (\(s1,s2) -> it (concat ["\"", s1, "\" is the same as \"", s2, "\""]) $
s1 `shouldParseSameAs` s2) unitEquivalences
describe "error messages" $ do
invalidUnitSpecTestStr "invalid identifier character"
"= unit ($) :: a"
"Invalid character in identifier: '$'"
invalidUnitSpecTestStr "invalid syntax"
"= unit :: s"
"Could not parse specification at: \"[]\"\n"
-- | Check that a unit specification does not parse, and that the
-- error string matches that provided.
--
-- Tests the @unitStr@ as is.
invalidUnitSpecTestStr :: String -- ^ Test description
-> String -- ^ Specification string
-> String -- ^ Expected error string
-> SpecWith ()
invalidUnitSpecTestStr description unitStr errStr =
it description $ show (parse unitStr) `shouldBe` ("Left " ++ errStr)
parseUnits :: String -> Either (SpecParseError UnitParseError) UnitStatement
parseUnits = parse . (\s -> "= unit " ++ s ++ " :: a")
parse :: String -> Either (SpecParseError UnitParseError) UnitStatement
parse = runParser unitParser