{-# LANGUAGE QuasiQuotes #-} {-# LANGUAGE TemplateHaskell #-} module Text.Shakespeare.TextSpec (spec) where import Test.HUnit hiding (Test) import Test.Hspec import Prelude hiding (reverse) import Text.Shakespeare.Text import Data.List (intercalate) import qualified Data.Text as T import qualified Data.Text.Lazy as TL import qualified Data.List import qualified Data.List as L import Data.Text (Text, pack, unpack) import Data.Monoid (mappend) spec :: Spec spec = do it "text" $ do let var = "var" let urlp = (Home, [(pack "p", pack "q")]) flip telper [text|שלום #{var} @{Home} @?{urlp} ^{jmixin} |] $ intercalate "\n" [ "שלום" , var , "url" , "url?p=q" , "var x;" ] ++ "\n" it "textFile" $ do let var = "var" let urlp = (Home, [(pack "p", pack "q")]) flip telper $(textFile "test/texts/external1.text") $ unlines [ "שלום" , var , "url" , "url?p=q" , "var x;" ] it "textFileReload" $ do let var = "var" let urlp = (Home, [(pack "p", pack "q")]) flip telper $(textFileReload "test/texts/external1.text") $ unlines [ "שלום" , var , "url" , "url?p=q" , "var x;" ] {- TODO it "textFileReload" $ do let var = "somevar" test result = telper result $(textFileReload "test/texts/external2.text") writeFile "test/texts/external2.text" "var #{var} = 1;" test "var somevar = 1;" writeFile "test/texts/external2.text" "var #{var} = 2;" test "var somevar = 2;" writeFile "test/texts/external2.text" "var #{var} = 1;" -} it "text module names" $ let foo = "foo" double = 3.14 :: Double int = -5 :: Int in telper "oof oof 3.14 -5" [text|#{Data.List.reverse foo} #{L.reverse foo} #{show double} #{show int}|] it "stext module names" $ let foo = "foo" double = 3.14 :: Double int = -5 :: Int in simpT "oof oof 3.14 -5" [stext|#{Data.List.reverse foo} #{L.reverse foo} #{show double} #{show int}|] it "single dollar at and caret" $ do telper "$@^" [text|$@^|] telper "#{@{^{" [text|#\{@\{^\{|] it "single dollar at and caret" $ do simpT "$@^" [stext|$@^|] simpT "#{@{^{" [stext|#\{@\{^\{|] it "dollar operator" $ do let val = (1 :: Int, (2 :: Int, 3 :: Int)) telper "2" [text|#{ show $ fst $ snd val }|] telper "2" [text|#{ show $ fst $ snd $ val}|] it "dollar operator" $ do let val = (1 :: Int, (2 :: Int, 3 :: Int)) simpT "2" [stext|#{ show $ fst $ snd val }|] simpT "2" [stext|#{ show $ fst $ snd $ val}|] it "aligned text with bar" $ do let val = 3 :: Int simpT "hoge\r\n3\r\n1\r\n" (TL.fromStrict [sbt|hoge |#{val} |1 |]) simpT "hoge\r\n3\r\n1\r\n" [lbt|hoge |#{val} |1 |] simpT :: String -> TL.Text -> Assertion simpT a b = nocrlf (pack a) @=? nocrlf (TL.toStrict b) where nocrlf = T.replace (pack "\r\n") (pack "\n") data Url = Home | Sub SubUrl data SubUrl = SubUrl render :: Url -> [(Text, Text)] -> Text render Home qs = pack "url" `mappend` showParams qs render (Sub SubUrl) qs = pack "suburl" `mappend` showParams qs showParams :: [(Text, Text)] -> Text showParams [] = pack "" showParams z = pack $ '?' : intercalate "&" (map go z) where go (x, y) = go' x ++ '=' : go' y go' = concatMap encodeUrlChar . unpack -- | Taken straight from web-encodings; reimplemented here to avoid extra -- dependencies. encodeUrlChar :: Char -> String encodeUrlChar c -- List of unreserved characters per RFC 3986 -- Gleaned from http://en.wikipedia.org/wiki/Percent-encoding | 'A' <= c && c <= 'Z' = [c] | 'a' <= c && c <= 'z' = [c] | '0' <= c && c <= '9' = [c] encodeUrlChar c@'-' = [c] encodeUrlChar c@'_' = [c] encodeUrlChar c@'.' = [c] encodeUrlChar c@'~' = [c] encodeUrlChar ' ' = "+" encodeUrlChar y = let (a, c) = fromEnum y `divMod` 16 b = a `mod` 16 showHex' x | x < 10 = toEnum $ x + (fromEnum '0') | x < 16 = toEnum $ x - 10 + (fromEnum 'A') | otherwise = error $ "Invalid argument to showHex: " ++ show x in ['%', showHex' b, showHex' c] jmixin :: TextUrl url jmixin = [text|var x;|] telper :: String -> TextUrl Url -> Assertion telper res h = pack res @=? TL.toStrict (renderTextUrl render h) instance Show Url where show _ = "FIXME remove this instance show Url"