packages feed

HStringTemplate 0.8.7 → 0.8.8

raw patch · 5 files changed

+210/−14 lines, 5 filesdep +HStringTemplatedep +HUnitdep +QuickCheckdep ~arraydep ~basedep ~blaze-builderPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

Dependencies added: HStringTemplate, HUnit, QuickCheck, random

Dependency ranges changed: array, base, blaze-builder, bytestring, containers, deepseq, directory, filepath, mtl, old-locale, parsec, pretty, semigroups, syb, template-haskell, text, time, void

API changes (from Hackage documentation)

- Text.StringTemplate.Base: instance GHC.Exception.Exception Text.StringTemplate.Base.TmplException
- Text.StringTemplate.Classes: instance Data.Semigroup.Semigroup (Text.StringTemplate.Classes.StFirst a)
- Text.StringTemplate.Classes: instance Text.StringTemplate.Classes.Stringable (Data.Monoid.Endo GHC.Base.String)
+ Text.StringTemplate.Base: instance GHC.Exception.Type.Exception Text.StringTemplate.Base.TmplException
+ Text.StringTemplate.Classes: instance GHC.Base.Semigroup (Text.StringTemplate.Classes.StFirst a)
+ Text.StringTemplate.Classes: instance Text.StringTemplate.Classes.Stringable (Data.Semigroup.Internal.Endo GHC.Base.String)
- Text.StringTemplate: (|=) :: (Monad m) => a -> m a1 -> m (a, a1)
+ Text.StringTemplate: (|=) :: Monad m => a -> m a1 -> m (a, a1)
- Text.StringTemplate: directoryGroup :: (Stringable a) => FilePath -> IO (STGroup a)
+ Text.StringTemplate: directoryGroup :: Stringable a => FilePath -> IO (STGroup a)
- Text.StringTemplate: directoryGroupExt :: (Stringable a) => FilePath -> FilePath -> IO (STGroup a)
+ Text.StringTemplate: directoryGroupExt :: Stringable a => FilePath -> FilePath -> IO (STGroup a)
- Text.StringTemplate: directoryGroupLazy :: (Stringable a) => FilePath -> IO (STGroup a)
+ Text.StringTemplate: directoryGroupLazy :: Stringable a => FilePath -> IO (STGroup a)
- Text.StringTemplate: directoryGroupLazyExt :: (Stringable a) => FilePath -> FilePath -> IO (STGroup a)
+ Text.StringTemplate: directoryGroupLazyExt :: Stringable a => FilePath -> FilePath -> IO (STGroup a)
- Text.StringTemplate: directoryGroupRecursive :: (Stringable a) => FilePath -> IO (STGroup a)
+ Text.StringTemplate: directoryGroupRecursive :: Stringable a => FilePath -> IO (STGroup a)
- Text.StringTemplate: directoryGroupRecursiveExt :: (Stringable a) => FilePath -> FilePath -> IO (STGroup a)
+ Text.StringTemplate: directoryGroupRecursiveExt :: Stringable a => FilePath -> FilePath -> IO (STGroup a)
- Text.StringTemplate: directoryGroupRecursiveLazy :: (Stringable a) => FilePath -> IO (STGroup a)
+ Text.StringTemplate: directoryGroupRecursiveLazy :: Stringable a => FilePath -> IO (STGroup a)
- Text.StringTemplate: directoryGroupRecursiveLazyExt :: (Stringable a) => FilePath -> FilePath -> IO (STGroup a)
+ Text.StringTemplate: directoryGroupRecursiveLazyExt :: Stringable a => FilePath -> FilePath -> IO (STGroup a)
- Text.StringTemplate: getStringTemplate :: (Stringable a) => String -> STGroup a -> Maybe (StringTemplate a)
+ Text.StringTemplate: getStringTemplate :: Stringable a => String -> STGroup a -> Maybe (StringTemplate a)
- Text.StringTemplate: getStringTemplate' :: (Stringable a) => String -> STGroup a -> Maybe (StringTemplate a)
+ Text.StringTemplate: getStringTemplate' :: Stringable a => String -> STGroup a -> Maybe (StringTemplate a)
- Text.StringTemplate: setEncoder :: (Stringable a) => (a -> a) -> StringTemplate a -> StringTemplate a
+ Text.StringTemplate: setEncoder :: Stringable a => (a -> a) -> StringTemplate a -> StringTemplate a
- Text.StringTemplate: setEncoderGroup :: (Stringable a) => (a -> a) -> STGroup a -> STGroup a
+ Text.StringTemplate: setEncoderGroup :: Stringable a => (a -> a) -> STGroup a -> STGroup a
- Text.StringTemplate: setManyNativeAttrib :: (Stringable b) => [(String, b)] -> StringTemplate b -> StringTemplate b
+ Text.StringTemplate: setManyNativeAttrib :: Stringable b => [(String, b)] -> StringTemplate b -> StringTemplate b
- Text.StringTemplate.Base: SEnv :: SMap a -> [(String, (SEnv a -> SElem a))] -> STGroup a -> (a -> a) -> SEnv a
+ Text.StringTemplate.Base: SEnv :: SMap a -> [(String, SEnv a -> SElem a)] -> STGroup a -> (a -> a) -> SEnv a
- Text.StringTemplate.Base: [sopts] :: SEnv a -> [(String, (SEnv a -> SElem a))]
+ Text.StringTemplate.Base: [sopts] :: SEnv a -> [(String, SEnv a -> SElem a)]
- Text.StringTemplate.Base: getStringTemplate :: (Stringable a) => String -> STGroup a -> Maybe (StringTemplate a)
+ Text.StringTemplate.Base: getStringTemplate :: Stringable a => String -> STGroup a -> Maybe (StringTemplate a)
- Text.StringTemplate.Base: getStringTemplate' :: (Stringable a) => String -> STGroup a -> Maybe (StringTemplate a)
+ Text.StringTemplate.Base: getStringTemplate' :: Stringable a => String -> STGroup a -> Maybe (StringTemplate a)
- Text.StringTemplate.Base: parseSTMP :: (Stringable a) => (Char, Char) -> String -> Either String (SEnv a -> a)
+ Text.StringTemplate.Base: parseSTMP :: Stringable a => (Char, Char) -> String -> Either String (SEnv a -> a)
- Text.StringTemplate.Base: setEncoder :: (Stringable a) => (a -> a) -> StringTemplate a -> StringTemplate a
+ Text.StringTemplate.Base: setEncoder :: Stringable a => (a -> a) -> StringTemplate a -> StringTemplate a
- Text.StringTemplate.Base: setManyNativeAttrib :: (Stringable b) => [(String, b)] -> StringTemplate b -> StringTemplate b
+ Text.StringTemplate.Base: setManyNativeAttrib :: Stringable b => [(String, b)] -> StringTemplate b -> StringTemplate b
- Text.StringTemplate.Classes: SM :: (SMap a) -> SElem a
+ Text.StringTemplate.Classes: SM :: SMap a -> SElem a

Files

HStringTemplate.cabal view
@@ -1,5 +1,6 @@+Cabal-Version:       1.18 name:                HStringTemplate-version:             0.8.7+version:             0.8.8 synopsis:            StringTemplate implementation in Haskell. description:         A port of the Java library by Terrence Parr. category:            Text@@ -7,17 +8,37 @@ license-file:        LICENSE author:              Sterling Clover maintainer:          s.clover@gmail.com-Tested-With:         GHC == 8.2+Tested-With:         GHC == 8.2, GHC == 9.0.1 Build-Type:          Simple-Cabal-Version:       >= 1.6  -library -  build-depends:   syb, base >= 4, base < 5, filepath, parsec < 4, containers, pretty >= 1.1.0.0,-                   time >= 1.4.2 && < 1.9, bytestring, directory, array, text, deepseq, blaze-builder,void, template-haskell >= 2.3, mtl,-                   old-locale, semigroups >= 0.16+source-repository head+  type:     darcs+  location: http://hub.darcs.net/sterlingclover/hstringtemplate +library+  default-language: Haskell2010+  build-depends:+    base             >= 4 && < 5,+    array            < 0.6,+    blaze-builder    < 0.5,+    bytestring       < 0.11,+    deepseq          < 1.5,+    text             < 1.3,+    containers       < 0.7,+    template-haskell >= 2.3 && < 2.18,+    pretty           < 1.2,+    directory        < 1.4,+    filepath         < 1.5,+    mtl              < 2.3,+    old-locale       < 1.1,+    parsec           > 3 && < 4,+    semigroups       >= 0.16 && < 0.20,+    syb              < 0.8,+    void             < 0.8,+    time >= 1.4.2 && < 1.10+   exposed-modules:   Text.StringTemplate                      Text.StringTemplate.Base                      Text.StringTemplate.Classes@@ -28,6 +49,11 @@                      Text.StringTemplate.Renderf   ghc-options:       -Wall -source-repository head-  type:     darcs-  location: http://hub.darcs.net/sterlingclover/hstringtemplate+test-suite test+  default-language: Haskell2010+  type:             exitcode-stdio-1.0+  main-is:          Main.hs+  hs-source-dirs:   tests+  build-depends:    HStringTemplate, base, containers, QuickCheck >= 2.13, random >= 1.0 , HUnit >= 1.5+  other-modules:    Properties+                    Units
Text/StringTemplate/Group.hs view
@@ -40,8 +40,8 @@    hSetEncoding h utf8    hGetContents h -readFile' :: FilePath -> IO String-readFile' f = do+readFileStrictly :: FilePath -> IO String+readFileStrictly f = do    x <- readFileUTF f    length x `seq` return x @@ -80,7 +80,7 @@ -- | Given a path, returns a group which generates all files in said directory which have the supplied extension. directoryGroupExt :: (Stringable a) => FilePath -> FilePath -> IO (STGroup a) directoryGroupExt ext path =-    groupFromFiles readFile' .+    groupFromFiles readFileStrictly .     map ((</>) path &&& takeBaseName) . filter ((ext ==) . takeExtension) =<<     getDirectoryContents path @@ -108,7 +108,7 @@  -- | As with 'directoryGroupRecursive', but a template extension is supplied. directoryGroupRecursiveExt :: (Stringable a) => FilePath -> FilePath -> IO (STGroup a)-directoryGroupRecursiveExt ext path = groupFromFiles readFile' =<< getTmplsRecursive ext "" path+directoryGroupRecursiveExt ext path = groupFromFiles readFileStrictly =<< getTmplsRecursive ext "" path  -- | See documentation for 'directoryGroupRecursive'. directoryGroupRecursiveLazy :: (Stringable a) => FilePath -> IO (STGroup a)
+ tests/Main.hs view
@@ -0,0 +1,8 @@+module Main where++import qualified Properties+import qualified Units++main = do+  Properties.main+  Units.main
+ tests/Properties.hs view
@@ -0,0 +1,120 @@+{-# OPTIONS -O2 -fglasgow-exts #-}++module Properties where+import Text.Printf+import Control.Monad+import Control.Arrow+import Control.Applicative hiding ((<|>),many)+import Data.Maybe+import Data.Monoid+import Data.List+import System.IO+import System.Random hiding (next)+import qualified Data.Map as M++import Text.StringTemplate+import Text.StringTemplate.Classes+import Text.StringTemplate.Base+import Test.QuickCheck+import System.Environment+++main :: IO ()+main = do+    args <- getArgs+    let n = if null args then 100 else read (head args)+    results <- mapM (\ (s, a) -> printf "%-25s: " s >> fmap (\x->(s,x)) a) tests+    mapM print results+    when (not $ all (isSuccess  . snd) results) $ fail "Not all tests passed!"+ where+    isSuccess (Success _ _ _ _ _ _) = True+    isSuccess _ = False+    tests =+        [("prop_paddedTrans" , mytest prop_paddedTrans),+         ("prop_constStr" , mytest prop_constStr),+         ("prop_emptyNulls" , mytest prop_emptyNulls),+         ("prop_fullNulls" , mytest prop_fullNulls),+         ("prop_substitution" , mytest prop_substitution),+         ("prop_separator" , mytest prop_separator),+         ("prop_attribs" , mytest prop_attribs),+         ("prop_comment" , mytest prop_comment),+         ("prop_ifelse" , mytest prop_ifelse),+         ("prop_simpleGroup" , mytest prop_simpleGroup)+        ]+mytest x = quickCheckResult x+{-----------------------------------------------------------------------+  Limited tests for now: just for list juggling and some basic parsing.+-----------------------------------------------------------------------}++prop_paddedTrans (x::[Int]) (y::[Int]) (z::[Int]) n =+   (length pt == length npt) &&+   all (3 ==) (map length pt) &&+   all (all (==n)) (zipWith unmerge (paddedTrans n pt) [x,y,z])+          where pt   = paddedTrans n [x,y,z]+                npt  = transpose [x,y,z]+                unmerge xl@(x:xs) (y:ys)+                    | x == y = unmerge xs ys+                    | otherwise = xl+                unmerge x y = x++prop_constStr (LitString x) = x == (toString . newSTMP $ x)++prop_emptyNulls (LitString x) (LitString y) i =+    (concat . replicate i' $ x) ==+      (toString . newSTMP . concat . replicate i' $ tmpl)+    where tmpl = x++"$"++y++"$"+          i' = min (abs i) 10++prop_fullNulls (LitString x) (LitString y) i =+    length y > 0 ==>+               (concat . replicate i' $ x++y) ==+               (toString . newSTMP . concat . replicate i' $ tmpl)+    where tmpl = x++"$"++y++";null='"++y++"'$"+          i' = min (abs i) 10++prop_substitution (LitString x) (LitString y) (LitString z) i =+    length y > 0 ==>+               (concat . replicate i' $ x++z) ==+               (toString . setAttribute y z .+                newSTMP . concat . replicate i' $ tmpl)+    where tmpl = x++"$"++y++"$"+          i' = min (abs i) 10++prop_separator (LitString x) (LitString y) (LitString z) i =+    length x > 0 ==>+               (concat . intersperse z . replicate i' $ y) ==+               (toString . setAttribute x (replicate i' y)+                . newSTMP $ tmpl)+    where tmpl = "$"++x++";separator='"++z++"'$"+          i' = min (abs i) 10++prop_comment (LitString x) (LitString y) (LitString z) =+    toString (newSTMP (x ++ "$!" ++ y ++ "!$" ++ z)) == x ++ z++prop_attribs (LitString x) i =+    toString (setManyAttrib (replicate i' ("f",x)) $ newSTMP "$f$")+                 == (concat . replicate i' $ x)+        where+          i' = min (abs i) 10++prop_ifelse a b c d =+    toString (setManyAttrib alist . newSTMP $ "$if(a)$a$elseif(b)$b$elseif(c)$c$else$$if(d)$d$else$e$endif$$endif$") == (fst . head . filter snd) alist+        where alist = [("a",a),("b",b),("c",c),("d",d),("e",True)]++prop_simpleGroup (LitString x) (LitString y) (LitString z) (LitString t) =+    length x > 0 && length y > 0 && length z > 0 && length t > 0+               && length (nub [x,y,z,t]) == 4 ==>+                  x == (toString . fromJust . getStringTemplate x $ grp)+    where tm   = newSTMP x+          tm'  = newSTMP $ "$"++y++"()$"+          tmIt = newSTMP "$it$"+          tm'' = newSTMP $ "$"++z++"():"++t++"()$"+          grp = groupStringTemplates [(y,tm),(z,tm'),(t,tmIt),(x,tm'')]++newtype LitChar = LitChar {unLitChar :: Char} deriving Show+instance Arbitrary LitChar where+  arbitrary = LitChar <$> choose ('a','z')++newtype LitString = LitString String deriving Show+instance Arbitrary LitString where+  arbitrary = LitString . map unLitChar <$> sized (\n -> choose (0,n) >>= vector)
+ tests/Units.hs view
@@ -0,0 +1,42 @@+{-# OPTIONS -O2 -fglasgow-exts #-}++module Units where+import System.IO+import qualified Data.Map as M++import Text.StringTemplate+import Text.StringTemplate.Classes+import Text.StringTemplate.Base+import Test.HUnit+import Control.Monad+import System.Environment++no_prop = toString (setAttribute "foo" "f" $ newSTMP "a$foo.bar$a")+          ~=? "aa"++one_prop = toString (setAttribute "foo" (M.singleton "bar" "baz") $ newSTMP "a$foo.bar$a")+           ~=? "abaza"++anon_tmpl = toString (setAttribute "foo" "f" $ newSTMP "a$foo:{{$foo$\\}}$a")+            ~=? "a{f}a"++setA = setAttribute "foo" ["a","b","c"]+func_first = toString (setA $ newSTMP "$first(foo)$") ~=? "a"+func_last = toString (setA $ newSTMP "$last(foo)$") ~=? "c"+func_rest = toString (setA $ newSTMP "$rest(foo)$") ~=? "bc"+func_length = toString (setA $ newSTMP "$length(foo)$") ~=? "3"+func_reverse = toString (setA $ newSTMP "$reverse(foo)$") ~=? "cba"++tests = TestList ["no_prop" ~: no_prop,+                  "one_prop" ~: one_prop,+                  "func_first" ~: func_first,+                  "func_last" ~: func_last,+                  "func_rest" ~: func_rest,+                  "func_reverse" ~: func_reverse,+                  "func_length" ~: func_length,+                  "anon_tmpl" ~: anon_tmpl]++main = do+  c <- runTestTT tests+  when (errors c > 0 || failures c > 0) $+    fail "Not all tests passed."