使用Hakyll的MonadMetadata进行测试

时间:2018-11-01 17:23:45

标签: haskell hspec hakyll

对于我们的Hakyll代码库,我已经编写了一些辅助方法,并开始围绕较新的方法添加一些HSpec单元测试,例如:

-- | Reject an item unless @fieldName@ is set to "true"
unlessEnabled :: MonadMetadata m
              => String
              -> Item a
              -> m Bool
unlessEnabled fieldName item = do
    maybeValue <- getMetadataBool (itemIdentifier item) fieldName
    return $ maybe True not maybeValue

-- | Try to look up a boolean field ("true" maps to @Just True@)
getMetadataBool :: MonadMetadata m
                => Identifier
                -> String
                -> m (Maybe Bool)
getMetadataBool ident name = do
    maybeString <- getMetadataField ident name
    return $ ((== "true") . map toLower) <$> maybeString

现在创建一个ItemIdentifier进行测试已经很容易了,但是我不确定运行Hspec时应该使用MonadMetadata

我见过testCompiler,感觉好像可以复制/有用(Compiler has a MonadMetadata instance),但是我在这里没有Haskell的知识……

1 个答案:

答案 0 :(得分:1)

最终(感谢@Benji的建议),我开始工作了,然后进行了整理:

Notation "(matrix nat)" := (list (list nat))

哪些允许简单的单元测试,例如:

{-# LANGUAGE DeriveFunctor #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}

type KeyedValuesOf a = [(String, a)]

-- | Create Metadata from basic list of key-values -- stolen from Hakyll itself.
meta :: Yaml.ToJSON a => KeyedValuesOf a -> Metadata
meta pairs = HMS.fromList [(T.pack k, Yaml.toJSON v) | (k, v) <- pairs]

-- | A 'Reader' class of our own, with a specialised environment
--   for key-value metadata pairs.
newtype MonadMetadataReader a =
    MonadMetadataReader {runMonadMetadataReader :: KeyedValuesOf String -> a}
        deriving (Functor, Applicative, Monad)

-- | Simple 'Metadata' holder.
-- There are never any matches found,
-- and all metadata (for all items)
-- comes from from the Reader-like environment at setup.
instance MonadMetadata MonadMetadataReader where
    getMetadata identifier = MonadMetadataReader meta

    getMatches pattern = return []