packages feed

hastache-0.1.2: tests/test.hs

{-# LANGUAGE DeriveDataTypeable #-}
module Tests where

import Test.HUnit
import Text.Hastache
import Text.Hastache.Context
import qualified Data.ByteString as BS
import qualified Data.ByteString.Lazy as LZ
import qualified Data.Text as T
import Control.Monad
import Control.Monad.Writer
import Data.Data
import Data.Generics

-- Hastache comments
commentsTest = do
    res <- hastacheStr defaultConfig (encodeStr template) undefined
    assertEqualStr "result correctness" (decodeStrLBS res) testRes
    where
    template = "\
        \hello {{! comment #1}} world! \n\
        \hello {{! comment #2 \n\
        \multiline\n\
        \}} world! \n\
        \"
    testRes  = "\
        \hello  world! \n\
        \hello  world! \n\
        \"

-- Variables
variablesTest = do
    res <- hastacheStr defaultConfig (encodeStr template) 
        (mkStrContext context)
    assertEqualStr "result correctness" (decodeStrLBS res) testRes
    where
    template = "\
        \   Char:               [ {{Char}} ]            \n\
        \   Double:             [ {{Double}} ]          \n\
        \   Int:                [ {{Int}} ]             \n\
        \   ByteString:         [ {{ByteString}} ]      \n\
        \   Text:               [ {{Text}} ]            \n\
        \   String:             [ {{String}} ]          \n\
        \   HtmlString:         [ {{HtmlString}} ]      \n\
        \   HtmlStringUnEsc:    [ {{{HtmlString}}} ]    \n\
        \   HtmlStringUnEsc2:   [ {{&HtmlString}} ]     \n\
        \"
    context "Char" = MuVariable 'Й'
    context "Double" = MuVariable (123.45 :: Double)
    context "Int" = MuVariable (5 :: Int)
    context "ByteString" = MuVariable (encodeStr "hello - привет")
    context "Text" = MuVariable (T.pack "hello - привет")
    context "String" = MuVariable "hello - привет"
    context "HtmlString" = MuVariable "<p>text</p>"
    
    testRes  = "\
        \   Char:               [ Й ]            \n\
        \   Double:             [ 123.45 ]          \n\
        \   Int:                [ 5 ]             \n\
        \   ByteString:         [ hello - привет ]      \n\
        \   Text:               [ hello - привет ]            \n\
        \   String:             [ hello - привет ]          \n\
        \   HtmlString:         [ &lt;p&gt;text&lt;/p&gt; ]      \n\
        \   HtmlStringUnEsc:    [ <p>text</p> ]    \n\
        \   HtmlStringUnEsc2:   [ <p>text</p> ]     \n\
        \"

-- Show/hide block according to list state
emptyListSectionsTest = do
    res <- hastacheStr defaultConfig (encodeStr template) 
        (mkStrContext context)
    assertEqualStr "result correctness" (decodeStrLBS res) testRes
    where
    template = "\
        \text 1\n\
        \{{#blankSection}}\n\
        \   some text\n\
        \{{/blankSection}}\n\
        \text 2\n\
        \{{^blankSection}}\n\
        \   empty list. {{someval}}\n\
        \{{/blankSection}}\n\
        \inline [{{#blankSection}}txt{{/blankSection}}]\n\
        \"
    context "blankSection" = MuList []
    context "someval" = MuVariable (5 :: Int)
    
    testRes = "\
        \text 1\n\
        \text 2\n\
        \   empty list. 5\n\
        \inline []\n\
        \"

-- Render list
listSectionTest = do
    res <- hastacheStr defaultConfig (encodeStr template) 
        (mkStrContext context)
    assertEqualStr "result correctness" (decodeStrLBS res) testRes
    where
    template = "\
        \text 1\n\
        \{{#section}}\n\
        \ * {{name}} \n\
        \{{/section}}\n\
        \text 2\n\
        \inline {{#section}}[{{name}}]{{/section}}\n\
        \"
    context "section" = MuList $ map nameCtx ["Neo", "Morpheus", "Trinity"]
    nameCtx name = mkStrContext (\"name" -> MuVariable name)
    
    testRes = "\
        \text 1\n\
        \ * Neo \n\
        \ * Morpheus \n\
        \ * Trinity \n\
        \text 2\n\
        \inline [Neo][Morpheus][Trinity]\n\
        \"

-- Show/hide block according to boolean variable
boolSectionTest = do
    res <- hastacheStr defaultConfig (encodeStr template) 
        (mkStrContext context)
    assertEqualStr "result correctness" (decodeStrLBS res) testRes
    where
    template = "\
        \text 1\n\
        \{{#bool_true}}\n\
        \   true: {{someval}} \n\
        \{{/bool_true}}\n\
        \{{^bool_true}}\n\
        \   true inv: {{someval}} \n\
        \{{/bool_true}}\n\
        \{{#bool_false}}\n\
        \   false: {{someval}} \n\
        \{{/bool_false}}\n\
        \{{^bool_false}}\n\
        \   false inv: {{someval}} \n\
        \{{/bool_false}}\n\
        \text 2\n\
        \"
    context "bool_true" = MuBool True
    context "bool_false" = MuBool False
    context "someval" = MuVariable "val"
    
    testRes = "\
        \text 1\n\
        \   true: val \n\
        \   false inv: val \n\
        \text 2\n\
        \"

-- Transorm section
lambdaSectionTest = do
    res <- hastacheStr defaultConfig (encodeStr template) 
        (mkStrContext context)
    assertEqualStr "result correctness" (decodeStrLBS res) testRes
    where
    template = "\
        \text 1\n\
        \{{#function}}Hello{{/function}}\n\
        \text 2\n\
        \"
    context "function" = MuLambda BS.reverse
    
    testRes = "\
        \text 1\n\
        \olleH\n\
        \text 2\n\
        \"

-- Transform section with monadic function
lambdaMSectionTest = do
    (res, writerState) <- runWriterT monadicFunction
    assertEqualStr "result correctness" (decodeStrLBS res) testRes
    assertEqualStr "monad state correctness" (decodeStr writerState)
        testMonad
    where
    monadicFunction = do
        res <- hastacheStr defaultConfig (encodeStr template) 
            (mkStrContext context)
        return res
    template = "\
        \[{{#mf}}abc{{/mf}}]\n\
        \[{{#mf}}def{{/mf}}]\n\
        \"
    context "mf" = MuLambdaM $ \i -> do
        tell i
        return $ BS.reverse i
    testRes = "\
        \[cba]\n\
        \[fed]\n\
        \"
    testMonad = "abcdef"

-- Change delimiters
setDelimiterTest = do
    res <- hastacheStr defaultConfig (encodeStr template) 
        (mkStrContext context)
    assertEqualStr "result correctness" (decodeStrLBS res) testRes
    where
    template = "\
        \text 1\n\
        \{{someVar}}\n\
        \{{=<% %>=}}\n\
        \<%someVar%>\n\
        \<%={{ }}=%>\n\
        \{{someVar}}\n\
        \text 2\n\
        \"
    context "someVar" = MuVariable "some value"
    
    testRes = "\
        \text 1\n\
        \some value\n\
        \some value\n\
        \some value\n\
        \text 2\n\
        \"

-- Render external (partial) template file
partialsTest = do
    res <- hastacheStr defaultConfig (encodeStr template) 
        (mkStrContext context)
    assertEqualStr "result correctness" (decodeStrLBS res) testRes
    where
    template = "\
        \text 1\n\
        \{{> partFile}}\n\
        \text 2\n\
        \"
    context "name" = MuVariable "Neo"
    
    testRes = "\
        \text 1\n\
        \Hi, Neo!\n\
        \text 2\n\
        \"

data InternalData = InternalData {
    intDataField1   :: String,
    intDataField2   :: Int
    }
    deriving (Data, Typeable, Show)
    
data SomeData = SomeData {
    someDataField1      :: String,
    someDataInternal    :: InternalData,
    someDataList        :: [Int],
    someDataObjList     :: [InternalData]
    }
    deriving (Data, Typeable, Show)

-- Make hastache context from Data.Data deriving type
genericContextTest = do
    res <- hastacheStr defaultConfig (encodeStr template) 
        (mkGenericContext context)
    assertEqualStr "result correctness" (decodeStrLBS res) testRes
    where
    template = "\
        \text 1\n\
        \{{someDataField1}} {{someDataInternal.intDataField1}} \n\
        \{{someDataInternal.intDataField2}} \n\
        \{{#someDataInternal}}\n\
        \* {{intDataField1}} {{intDataField2}} \n\
        \{{/someDataInternal}}\n\
        \Simple list:\n\
        \{{#someDataList}}\n\
        \* {{.}} \n\
        \{{/someDataList}}\n\
        \Obj list:\n\
        \{{#someDataObjList}}\n\
        \* {{intDataField1}} : {{intDataField2}} \n\
        \{{/someDataObjList}}\n\
        \text 2\n\
        \"
    context = SomeData {
        someDataField1 = "aaa",
        someDataInternal = InternalData { 
            intDataField1 = "zzz", intDataField2 = 100 },
        someDataList = [1,2,3],
        someDataObjList = [InternalData "a" 1, InternalData "b" 2,
            InternalData "c" 3]
        }
    
    testRes = "\
        \text 1\n\
        \aaa zzz \n\
        \100 \n\
        \* zzz 100 \n\
        \Simple list:\n\
        \* 1 \n\
        \* 2 \n\
        \* 3 \n\
        \Obj list:\n\
        \* a : 1 \n\
        \* b : 2 \n\
        \* c : 3 \n\
        \text 2\n\
        \"

tests = TestList [
     TestLabel "Comments test" (TestCase commentsTest)
    ,TestLabel "Variables test" (TestCase variablesTest)
    ,TestLabel "Empty list test" (TestCase emptyListSectionsTest)
    ,TestLabel "List test" (TestCase listSectionTest)
    ,TestLabel "Bool test" (TestCase boolSectionTest)
    ,TestLabel "Lambda test" (TestCase lambdaSectionTest)
    ,TestLabel "LambdaM test" (TestCase lambdaMSectionTest)
    ,TestLabel "Set delimiter test" (TestCase setDelimiterTest)
    ,TestLabel "Partials test" (TestCase partialsTest)
    ,TestLabel "Generic context test" (TestCase genericContextTest)
    ]

main = do
    runTestTT tests

assertEqualStr preface expected actual =
    unless (actual == expected) (assertFailure msg)
    where msg = (if null preface then "" else preface ++ "\n") ++
             "expected: \n" ++ expected ++ "\nbut got: \n" ++ actual