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