{-# LANGUAGE OverloadedStrings #-}
{-# OPTIONS -Wall #-}
{-# OPTIONS -Werror #-}
module Units
( tests
) where
import Control.Arrow (first)
import Control.Monad (foldM_, void)
import Control.Monad.IO.Class (MonadIO(..))
import Control.Monad.State.Strict (StateT, runStateT)
import Data.Aeson (eitherDecode)
import Data.ByteString.Char8 (ByteString)
import Data.ByteString.Lazy.Char8 as Lazy (readFile)
import Data.ByteString.Short (fromShort)
import Data.HashMap.Strict (toList)
import Data.Map.Strict (Map, empty)
import Data.Maybe (fromJust)
import Test.Tasty (TestTree, testGroup)
import Test.Tasty.HUnit (assertFailure, testCase)
import DFINITY.RadixTree
import Types
tests :: IO TestTree
tests = do
contents <- Lazy.readFile "test/tests.json"
vectors <- either fail return $ eitherDecode contents
pure $ testGroup "units"
[testCase name $ run ops | (name, ops) <- toList vectors]
run :: [Op] -> IO ()
run ops = void $ flip runStateT empty $ do
tree <- createRadixTree 262144 2048 Nothing ()
foldM_ step tree ops
step :: RadixTree () -> Op -> StateT (Map ByteString ByteString) IO (RadixTree ())
step tree op = do
liftIO $ print op
case op of
Insert key value -> do
tree' <- insertRadixTree key value tree
printRadixTree tree'
pure tree'
Delete key -> do
tree' <- deleteRadixTree key tree
printRadixTree tree'
pure tree'
Lookup key value -> do
result <- lookupRadixTree key tree
case result of
Nothing | value == Nothing -> pure tree
Nothing -> throw
["Expecting value ", ", but received no value for key "]
[fromJust value, key]
Just (value', tree') | value == Just value' -> pure tree'
Just (value', _) -> throw
["Expecting value ", ", but received value ", " for key "]
[maybe "null" id value, value', key]
Merkleize value -> do
(value', tree') <- first fromShort <$> merkleizeRadixTree tree
if value == value'
then pure tree'
else throw
["Expecting state root ", ", but received state root "]
[value, value']
throw :: MonadIO m => [String] -> [ByteString] -> m a
throw err = liftIO . assertFailure . concat . zipWith mappend err . map show