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 "" closingTag = BS.pack "" 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 "# Example\n") 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