content: --------------------------------------------------------------------------------
  {-# LANGUAGE OverloadedStrings #-}
  {-# LANGUAGE TemplateHaskell   #-}
  module Hakyll.Web.Template.Tests
      ( tests
      ) where
  
  
  --------------------------------------------------------------------------------
  import           Test.Tasty                   (TestTree, testGroup)
  import           Test.Tasty.HUnit             (Assertion, assertBool, testCase,
                                                 (@=?), (@?=))
  
  import           Data.Either                  (isLeft)
  import           System.IO                    (nativeNewline, Newline(..))
  
  --------------------------------------------------------------------------------
  import           Hakyll.Core.Compiler
  import           Hakyll.Core.Identifier
  import           Hakyll.Core.Item
  import           Hakyll.Core.Provider
  import           Hakyll.Web.Template
  import           Hakyll.Web.Template.Context
  import           Hakyll.Web.Template.Internal
  import           Hakyll.Web.Template.List
  import           TestSuite.Util
  
  
  --------------------------------------------------------------------------------
  tests :: TestTree
  tests = testGroup "Hakyll.Web.Template.Tests" $ concat
      [ [ testCase "case01" $ test ("template.html.out", "template.html", "example.md")
        , testCase "case02" $ test ("strip.html.out", "strip.html", "example.md")
        , testCase "case03" $ test ("just-meta.html.out", "just-meta.html", "example.md")
        , testCase "applyJoinTemplateList" testApplyJoinTemplateList
        ]
  
      , fromAssertions "parseTemplate"
          [ Right [Chunk "Hello ", Expr (Call "guest" [])]
              @=? parse "Hello $guest()$"
          , Right [If (Call "a" [StringLiteral "bar"]) [Chunk "foo"] Nothing]
              @=? parse "$if(a(\"bar\"))$foo$endif$"
          -- 'If' trim check.
          , Right [ TrimL
            , If (Ident (TemplateKey "body"))
                 [ TrimR
                 , Chunk "\n"
                 , Expr (Ident (TemplateKey "body"))
                 , Chunk "\n"
                 , TrimL
                 ]
                 (Just [ TrimR
                       , Chunk "\n"
                       , Expr (Ident (TemplateKey "body"))
                       , Chunk "\n"
                       , TrimL
                       ])
            , TrimR
            ]
            @=? parse "$-if(body)-$\n$body$\n$-else-$\n$body$\n$-endif-$"
          -- 'For' trim check.
          , Right [ TrimL
            , For (Ident (TemplateKey "authors"))
                  [TrimR, Chunk "\n   body   \n", TrimL]
                  Nothing
            , TrimR
            ]
            @=? parse "$-for(authors)-$\n   body   \n$-endfor-$"
          -- 'Partial' trim check.
          , Right [ TrimL
            , Partial (StringLiteral "path")
            , TrimR
            ]
            @=? parse "$-partial(\"path\")-$"
          -- 'Expr' trim check.
          , Right [ TrimL
            , Expr (Ident (TemplateKey "foo"))
            , TrimR
            ]
            @=? parse "$-foo-$"
          -- fail on incomplete template.
          , assertBool "did not yield error" $ isLeft $
            parse "a$b"
          -- fail on mismatched template syntax.
          , assertBool "did not fail to parse" $ isLeft $
            parse "$for(xs)$\n  <p>foo</p>\n$endif$"
          ]
  
      , [testCase "embeddedTemplate" testEmbeddedTemplate]
      ]
    where
      parse = parseTemplateElemsFile ""
  
  
  --------------------------------------------------------------------------------
  test :: (Identifier, Identifier, Identifier) -> Assertion
  test (outf, tplf, itemf) = do
      store    <- newTestStore
      provider <- newTestProvider store
  
      out  <- resourceString provider outf
      tpl  <- testCompilerDone store provider tplf templateBodyCompiler
      item <- testCompilerDone store provider itemf $
          getResourceBody
          >>= renderParagraphs
          >>= applyTemplate (itemBody tpl) testContext
  
      out @=? itemBody item
      cleanTestEnv
  
  
  --------------------------------------------------------------------------------
  testContext :: Context String
  testContext = mconcat
      [ defaultContext
      , listField "authors" (bodyField "name") $ do
          n1 <- makeItem "Jan"
          n2 <- makeItem "Piet"
          return [n1, n2]
      , functionField "rev" $ \args _ -> return $ unwords $ map reverse args
      ]
  
  
  --------------------------------------------------------------------------------
  testApplyJoinTemplateList :: Assertion
  testApplyJoinTemplateList = do
      store    <- newTestStore
      provider <- newTestProvider store
      tpl      <- testCompilerDone store provider "tpl" $
          compileTemplateItem (Item "tpl" "<b>$body$</b>")
      str      <- testCompilerDone store provider "item3" $
          applyJoinTemplateList ", " tpl defaultContext [i1, i2]
  
      str @?= "<b>Hello</b>, <b>World</b>"
      cleanTestEnv
    where
      i1  = Item "item1" "Hello"
      i2  = Item "item2" "World"
  
  
  --------------------------------------------------------------------------------
  embeddedTemplate :: Template
  embeddedTemplate = $(embedTemplate "tests/data/embed.html")
  
  --------------------------------------------------------------------------------
  testEmbeddedTemplate :: Assertion
  testEmbeddedTemplate = do
      store    <- newTestStore
      provider <- newTestProvider store
      str      <- testCompilerDone store provider "item3" $
          applyTemplate embeddedTemplate defaultContext item
  
      itemBody str @?= ("<p>Hello, world</p>" ++ (newline nativeNewline))
      cleanTestEnv
    where
      item = Item "item1" "Hello, world"
      
      newline LF   = "\n"
      newline CRLF = "\r\n"
  
  