shikensu-0.3.4: tests/Test/Contrib.hs
module Test.Contrib
( contribTests
) where
import Data.ByteString (ByteString)
import Flow
import System.FilePath (joinPath)
import Test.Helpers
import Test.Tasty
import Test.Tasty.HUnit
import qualified Data.Aeson.Types as Aeson (Value(..))
import qualified Data.ByteString as B (empty)
import qualified Data.ByteString.Char8 as BS (intercalate, pack)
import qualified Data.HashMap.Strict as HashMap (fromList, lookup)
import qualified Data.List as List (head, reverse)
import qualified Data.Text as Text (pack, unpack)
import qualified Data.Text.Encoding as Text (decodeUtf8)
import qualified Data.Text.IO as Text (readFile)
import qualified Shikensu
import qualified Shikensu.Contrib as Contrib
import qualified Shikensu.Contrib.IO as Contrib.IO
contribTests :: TestTree
contribTests = testGroup
"Contrib tests"
[ testClone
, testExclude
, testMetadata
, testPermalink
, testPrefixDirname
, testRead
, testRename
, testRenameExt
, testRenderContent
, testWrite
]
-- Test data
list :: String -> IO Shikensu.Dictionary
list pattern =
Shikensu.listRelative [pattern] "."
example_md :: IO Shikensu.Dictionary
example_md =
list "tests/fixtures/example.md"
renderer :: Shikensu.Definition -> Maybe ByteString
renderer def =
let
openingTag = BS.pack "<html>"
closingTag = BS.pack "</html>"
in
def
|> Shikensu.content
|> fmap (\c -> BS.intercalate B.empty [openingTag, c, closingTag])
-- Tests
testClone :: TestTree
testClone =
let
dictionary = fmap (Contrib.clone "example.md" "cloned.md") example_md
definition = fmap (List.reverse .> List.head) dictionary
in
testCase "Should `clone`"
$ assertDef definition Shikensu.localPath "cloned.md"
testExclude :: TestTree
testExclude =
let
dictionary = fmap (Contrib.exclude "example.md") example_md
dictLength = fmap length dictionary
in
testCase "Should `exclude`"
$ assertEqm dictLength 0
testMetadata :: TestTree
testMetadata =
let
keyA = Text.pack "title"
valueA = Aeson.String (Text.pack "Hello world!")
keyB = Text.pack "hello"
valueB = Aeson.String (Text.pack "Guardian.")
keyC = Text.pack "removed"
valueC = Aeson.String (Text.pack "Me.")
keyBase = Text.pack "basename"
valueBase = Aeson.String (Text.pack "example")
-- 1. Insert C
-- 2. Replace with A
-- 3. Insert B
dictionary = fmap
( id
.> Contrib.insertMetadata (HashMap.fromList [ (keyC, valueC) ])
.> Contrib.replaceMetadata (HashMap.fromList [ (keyA, valueA) ])
.> Contrib.copyPropsToMetadata
.> Contrib.insertMetadata (HashMap.fromList [ (keyB, valueB) ])
)
example_md
definition = fmap (List.reverse .> List.head) dictionary
lookupTitle = \def -> HashMap.lookup keyA (Shikensu.metadata def)
lookupHello = \def -> HashMap.lookup keyB (Shikensu.metadata def)
lookupRemoved = \def -> HashMap.lookup keyC (Shikensu.metadata def)
lookupBasename = \def -> HashMap.lookup keyBase (Shikensu.metadata def)
in
testGroup
"Metadata"
[ testCase "Should no longer have `removed` key"
$ assertDef definition lookupRemoved Nothing
, testCase "Should have `hello` key"
$ assertDef definition lookupHello (Just valueB)
, testCase "Should have `title` key"
$ assertDef definition lookupTitle (Just valueA)
, testCase "Should have `basename` key"
$ assertDef definition lookupBasename (Just valueBase)
]
testPermalink :: TestTree
testPermalink =
let
dictionary = fmap (Contrib.permalink "index") example_md
definition = fmap List.head dictionary
in
testGroup
"Permalink"
[ testCase "Should have the correct `localPath`"
$ assertDef definition Shikensu.localPath "example/index.md"
, testCase "Should have the correct `parentPath`"
$ assertDef definition Shikensu.parentPath (Just "../")
, testCase "Should have the correct `pathToRoot`"
$ assertDef definition Shikensu.pathToRoot "../"
]
testPrefixDirname :: TestTree
testPrefixDirname =
let
dictionary = fmap (Contrib.prefixDirname "prefix/") (list "tests/**/example.md")
definition = fmap List.head dictionary
in
testGroup
"PrefixDirname"
[ testCase "Should have the correct `dirname`"
$ assertDef definition Shikensu.dirname "prefix/fixtures"
, testCase "Should have the correct `pathToRoot`"
$ assertDef definition Shikensu.pathToRoot "../../"
, testCase "Should have the correct `parentPath`"
$ assertDef definition Shikensu.parentPath (Just "../")
]
testRead :: TestTree
testRead =
let
theResult = Just (Text.pack "# Example\n")
definition = fmap List.head (example_md >>= Contrib.IO.read)
in
testCase "Should `read`"
$ assertDef definition (Shikensu.content .> fmap Text.decodeUtf8) theResult
testRename :: TestTree
testRename =
let
dictionary = fmap (Contrib.rename "example.md" "renamed.md") example_md
definition = fmap List.head dictionary
in
testCase "Should `rename`"
$ assertDef definition Shikensu.localPath "renamed.md"
testRenameExt :: TestTree
testRenameExt =
let
dictionary = fmap (Contrib.renameExt ".md" ".html") example_md
definition = fmap List.head dictionary
in
testCase "Should `renameExt`"
$ assertDef definition Shikensu.extname ".html"
testRenderContent :: TestTree
testRenderContent =
let
theResult = Just (Text.pack "<html># Example\n</html>")
dictionary = fmap (Contrib.renderContent renderer) (example_md >>= Contrib.IO.read)
definition = fmap List.head dictionary
in
testCase "Should `renderContent`"
$ assertDef definition (Shikensu.content .> fmap Text.decodeUtf8) theResult
testWrite :: TestTree
testWrite =
let
destination = "tests/build/"
dictionary = list "tests/**/example.md"
>>= Contrib.IO.read
>>= Contrib.IO.write destination
definition = fmap List.head dictionary
in
testCase "Should `write`"
$ fmap Shikensu.rootDirname definition
>>= \r -> readFile (joinPath [r, destination, "fixtures/example.md"])
>>= \c -> assertEq "# Example\n" c