PyF 0.5.0.0 → 0.6.0.0
raw patch · 5 files changed
+93/−4 lines, 5 filesdep ~megaparsecdep ~template-haskellPVP ok
version bump matches the API change (PVP)
Dependency ranges changed: megaparsec, template-haskell
API changes (from Hackage documentation)
- PyF: runFormat :: () => Format r a -> (Builder -> r) -> a
+ PyF: runFormat :: Format r a -> Builder -> r -> a
Files
- ChangeLog.md +6/−0
- PyF.cabal +4/−3
- src/PyF/Internal/PythonSyntax.hs +1/−1
- test/Spec.hs +3/−0
- test/SpecUtils.hs +79/−0
ChangeLog.md view
@@ -1,4 +1,10 @@ # Revision history for FormatStringLiteral++## 0.6.0.0 -- 2018-08-02++- Fix the espace parsing of `{{` and `}}` as `{` and `}`++ ## 0.5.0.0 -- 2018-04-16 - Support for negative zero
PyF.cabal view
@@ -1,5 +1,5 @@ name: PyF-version: 0.5.0.0+version: 0.6.0.0 synopsis: Quasiquotations for a python like interpolated string formater description: Quasiquotations for a python like interpolated string formater. license: BSD3@@ -19,10 +19,10 @@ PyF.Formatters build-depends: base >= 4.9 && < 5.0- , template-haskell >= 2.11 && < 2.13+ , template-haskell >= 2.11 && < 2.14 -- Parsec and some transitive deps- , megaparsec >= 6.0 && < 6.5+ , megaparsec >= 6.0 && < 6.6 , text >= 0.11 && < 1.3 , containers >= 0.5 && < 0.6 @@ -39,6 +39,7 @@ type: exitcode-stdio-1.0 hs-source-dirs: test main-is: Spec.hs+ other-modules: SpecUtils build-depends: base, PyF, hspec, text, template-haskell, formatting, process ghc-options: -Wall -threaded -rtsopts -with-rtsopts=-N default-language: Haskell2010
src/PyF/Internal/PythonSyntax.hs view
@@ -83,7 +83,7 @@ rawString = Raw . escapeChars <$> some (noneOf ("{}" :: [Char])) escapedParenthesis :: Parser Item-escapedParenthesis = Raw <$> (string "{{" <|> string "}}")+escapedParenthesis = Raw <$> (("{" <$ string "{{") <|> ("}" <$ string "}}")) {- | Replace escape chars with their value >>> escapeChars "hello \\n"
test/Spec.hs view
@@ -184,3 +184,6 @@ describe "escape strings" $ do it "works" $ do [fString|hello \n\b|] `shouldBe` "hello \n\b"++ it "escape chars" $ do+ [fString|}}{{}}{{|] `shouldBe` "}{}{"
+ test/SpecUtils.hs view
@@ -0,0 +1,79 @@+{-# LANGUAGE TemplateHaskell #-}+module SpecUtils+ ( checkExample+ , checkExampleDiff+ , check+)+where++import Test.Hspec+import PyF.Internal.QQ++import Language.Haskell.TH+import Language.Haskell.TH.Syntax++import Formatting+import System.Process+import System.Exit++-- * Utils++{- | Runs a python formatter example++For conveniance, it exports a few python symbols, `inf`, `nan` and pi.++>>> runPythonExample "{3.14159:.1f}+"3.1+-}+runPythonExample :: String -> IO (Maybe String)+runPythonExample s = do+ let+ pythonPath = "python"+ args = ["-c", "from math import pi;nan = float('NaN');inf = float('inf');print(f\'''" ++ s ++ "''', end='')"]+ (ecode, stdout, _stderr) <- readProcessWithExitCode pythonPath args ""+ pure $ case ecode of+ ExitSuccess -> Just stdout+ ExitFailure _ -> Nothing++{- | `pyCheck formatString reference` compares a format string against+a reference (if `Just`) and against the python implementation++This TH expression will return an expression compatible with `Hspec` `SpecM`.++This expression is a failure if python cannot format this formatString+or if the python result does not match the (provided) reference.+-}+pyCheck :: String -> Maybe String -> Q Exp+pyCheck s exampleStr = do+ pythonRes <- Language.Haskell.TH.Syntax.runIO (runPythonExample s)++ case pythonRes of+ Nothing -> [| expectationFailure $ "Expression: `" ++ s ++ "` fails in python" |]+ Just res -> do+ let qexp = [| formatToString $(toExp s) `shouldBe` res |]+ case exampleStr of+ Nothing -> qexp+ Just e -> if res == e+ then qexp+ else [| expectationFailure $ "Provided result `" ++ e ++ "` does not match the python result `" ++ res ++ "`" |]++-- * Exported++{- | `checkExample formatString result` checks if, once formated,+ `formatString` is equal to result. It also checks that the result is+ the same as the one provided by python.+-}+checkExample :: String -> String -> Q Exp+checkExample s res = pyCheck s (Just res)++{- | `checkExampleDiff formatString result` checks if, once formated,+ `formatString` is equal to result. It does not check the result+ against the python implementation+-}+checkExampleDiff :: String -> String -> Q Exp+checkExampleDiff s res = [| formatToString $(toExp s) `shouldBe` res |]++{- | `check formatString` checks only with the python implementation+-}+check :: String -> Q Exp+check s = pyCheck s Nothing