{-# 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