shikensu-0.1.0: 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.IO as Text (readFile)
import qualified Data.Text.Encoding as Text (decodeUtf8)
import qualified Shikensu
import qualified Shikensu.Contrib as Contrib
import qualified Shikensu.Contrib.IO as Contrib.IO
import qualified Shikensu.Types as Shikensu
contribTests :: TestTree
contribTests = testGroup
"Contrib tests"
[ testClone
, testExclude
, testMetadata
, testPermalink
, testPrefixDirname
, testRead
, testRename
, testRenameExt
, testRenderContent
, testWrite
]
-- Test data
list :: Shikensu.Pattern -> IO Shikensu.Dictionary
list pattern = rootPath >>= Shikensu.list [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.head . List.reverse) dictionary
in
testCase "Should `clone`"
$ definition `rmap` Shikensu.localPath >>= assertEq "cloned.md"
testExclude :: TestTree
testExclude =
let
dictionary = fmap (Contrib.exclude "example.md") example_md
length_ = fmap length dictionary
in
testCase "Should `exclude`"
$ length_ >>= assertEq 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 = example_md
<&> ( Contrib.insertMetadata (HashMap.fromList [ (keyC, valueC) ])
.> Contrib.replaceMetadata (HashMap.fromList [ (keyA, valueA) ])
.> Contrib.copyPropsToMetadata
.> Contrib.insertMetadata (HashMap.fromList [ (keyB, valueB) ])
)
definition = fmap (List.head . List.reverse) 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"
$ definition `rmap` lookupRemoved >>= assertEq Nothing
, testCase "Should have `hello` key"
$ definition `rmap` lookupHello >>= assertEq (Just valueB)
, testCase "Should have `title` key"
$ definition `rmap` lookupTitle >>= assertEq (Just valueA)
, testCase "Should have `basename` key"
$ definition `rmap` lookupBasename >>= assertEq (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`"
$ definition `rmap` Shikensu.localPath >>= assertEq "example/index.md"
, testCase "Should have the correct `parentPath`"
$ definition `rmap` Shikensu.parentPath >>= assertEq (Just "../")
, testCase "Should have the correct `pathToRoot`"
$ definition `rmap` Shikensu.pathToRoot >>= assertEq "../"
]
testPrefixDirname :: TestTree
testPrefixDirname =
let
dictionary = fmap (Contrib.prefixDirname "prefix/") (list "tests/**/example.md")
definition = fmap List.head dictionary
in
testCase "Should `prefixDirname`"
$ definition `rmap` Shikensu.dirname >>= assertEq "prefix/fixtures"
testRead :: TestTree
testRead =
let
dictionary = example_md >>= Contrib.IO.read
definition = fmap List.head dictionary
in
testCase "Should `read`"
$ definition
<&> Shikensu.content
<&> fmap Text.decodeUtf8
>>= assertEq (Just (Text.pack "# Example\n"))
testRename :: TestTree
testRename =
let
dictionary = fmap (Contrib.rename "example.md" "renamed.md") example_md
definition = fmap (List.head) dictionary
in
testCase "Should `rename`"
$ definition `rmap` Shikensu.localPath >>= assertEq "renamed.md"
testRenameExt :: TestTree
testRenameExt =
let
dictionary = fmap (Contrib.renameExt ".md" ".html") example_md
definition = fmap (List.head) dictionary
in
testCase "Should `renameExt`"
$ definition `rmap` Shikensu.extname >>= assertEq ".html"
testRenderContent :: TestTree
testRenderContent =
let
dictionary = fmap (Contrib.renderContent renderer) (example_md >>= Contrib.IO.read)
definition = fmap (List.head) dictionary
expectedResult = Just (Text.pack "<html># Example\n</html>")
in
testCase "Should `renderContent`"
$ definition
<&> Shikensu.content
<&> fmap Text.decodeUtf8
>>= assertEq expectedResult
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`"
$ definition
<&> Shikensu.rootDirname
>>= \r -> Text.readFile (joinPath [r, destination, "fixtures/example.md"])
>>= \c -> assertEq "# Example\n" (Text.unpack c)