trie-simple-0.4.1.1: test/Data/Trie/MapSpec.hs
module Data.Trie.MapSpec(
spec
) where
import Test.Hspec
import Test.QuickCheck
import Data.List (sortBy, foldl')
import Data.Ord
import Data.Map (Map)
import qualified Data.Map as Map
import Data.Semigroup
import Data.Trie.Map as T
import Data.Trie.Map.Gen
import qualified Data.Trie.Set as TSet
import Data.Trie.Set.Gen
spec :: Spec
spec = do
specify "toList empty = []" $
toList (empty :: TMap C Int) `shouldSatisfy` Prelude.null
specify "toList (just a) = [([], a)]" $
property $ \a -> toList (just a :: TMap C Int) === [([], a)]
specify "toList (singleton k a) = [(k,a)]" $
property $ \k a -> toList (singleton k a :: TMap C Int) === [(k,a)]
specify "toAscList . fromList = Map.toAscList . Map.fromList" $
property $ \strs -> toAscList (fromList strs :: TMap C Int) ==
(Map.toAscList . Map.fromList) strs
specify "fromAscList . sortBy (comparing fst) = fromList" $
property $ \strs -> fromAscList (sortBy (comparing fst) strs) ==
(fromList strs :: TMap C Int)
specify "fromMap . Map.fromList = fromList" $
property $ \strs -> fromMap (Map.fromList strs) ==
(fromList strs :: TMap C Int)
specify "null . toList = null" $
property $ \(TMap' t) -> Prelude.null (toList t) === T.null t
specify "length . toList = count" $
property $ \(TMap' t) -> length (toList t) === count t
specify "keys = map fst . toList" $
property $ \(TMap' t) -> keys t == map fst (toList t)
specify "elems = map snd . toList" $
property $ \(TMap' t) -> elems t == map snd (toList t)
specify "keysTSet = TSet.fromAscList . keys" $
property $ \(TMap' t) -> keysTSet t == TSet.fromAscList (keys t)
specify "fromTSet id = fromAscList . map (\\k -> (k,k)) . TSet.toAscList" $
property $ \(TSet' t) ->
fromTSet id t == fromAscList (map (\k -> (k,k)) (TSet.toAscList t))
specify "member k t = (k `Map.member` toMap t)" $
property $ \(TMap'' t) ->
let strMap = toMap t
in property $ \str -> member str t == Map.member str strMap
specify "lookup k t = (k `Map.lookup` toMap t)" $
property $ \(TMap'' t) ->
let strMap = toMap t
in property $ \str -> T.lookup str t == Map.lookup str strMap
specify "lookup (k ++ l) t == lookup l (snd (match k t))" $
property $ \k l (TMap'' t) ->
T.lookup (k ++ l) t == T.lookup l (snd (T.match k t))
specify "toMap (insert k 1 a) = Map.insert k 1 (toMap a)" $
property $ \k (TMap'' a) ->
toMap (insert k 1 a) == Map.insert k 1 (toMap a)
specify "toMap (delete k a) = Map.delete k (toMap a)" $
property $ \k (TMap'' a) ->
toMap (delete k a) == Map.delete k (toMap a)
specify "toMap (insertWith (+) k 1 a) = Map.insertWith (+) k 1 (toMap a)" $
property $ \k (TMap'' a) ->
toMap (insertWith (+) k 1 a) ==
Map.insertWith (+) k 1 (toMap a)
let sub b a = if a < b then Nothing else Just (a - b)
specify "toMap (deleteWith sub k 1 a) = Map.update (sub 1) k (toMap a)" $
property $ \k (TMap'' a) ->
toMap (deleteWith sub k 1 a) ==
Map.update (sub 1) k (toMap a)
specify "toMap (adjust (*2) k a) = Map.adjust (*2) k (toMap a)" $
property $ \k (TMap'' a) ->
toMap (adjust (*2) k a) == Map.adjust (*2) k (toMap a)
let alterer Nothing = Just 100
alterer (Just a) | odd a = Nothing
| otherwise = Just (a `div` 2)
specify "toMap (alter alterer k a) = Map.alter alterer k (toMap a)" $
property $ \k (TMap'' a) ->
toMap (alter alterer k a) == Map.alter alterer k (toMap a)
specify "toMap (union a b) = Map.union (toMap a) (toMap b)" $
property $ \(TMap' a) (TMap' b) ->
toMap (union a b) == Map.union (toMap a) (toMap b)
specify "toMap (unionWith f a b) = Map.unionWith f (toMap a) (toMap b)" $
property $ \(Fn2 f) (TMap' a) (TMap' b) ->
toMap (unionWith f a b) == Map.unionWith f (toMap a) (toMap b)
specify "toMap (intersection a b) = Map.intersection (toMap a) (toMap b)" $
property $ \(TMap' a) (TMap' b) ->
toMap (intersection a b) == Map.intersection (toMap a) (toMap b)
specify "toMap (difference a b) = Map.difference (toMap a) (toMap b)" $
property $ \(TMap' a) (TMap' b) ->
toMap (difference a b) == Map.difference (toMap a) (toMap b)
specify "toMap (append a b) = mapAppend (toMap a) (toMap b)" $
property $ \(TMap' a) (TMap' b) ->
toMap (getSum <$> appendWith (\x y -> Sum (x * y)) a b) ==
mapAppend (toMap a) (toMap b)
specify "validTMap (union a b)" $
property $ \(TMap' a) (TMap' b) ->
validTMap (union a b)
specify "validTMap (intersection a b)" $
property $ \(TMap' a) (TMap' b) ->
validTMap (intersection a b)
specify "validTMap (difference a b)" $
property $ \(TMap' a) (TMap' b) ->
validTMap (difference a b)
specify "validTMap (append a b)" $
property $ \(TMap' a) (TMap' b) ->
validTMap (getSum <$> appendWith (\x y -> Sum (x * y)) a b)
mapAppend :: (Ord c) => Map [c] Int -> Map [c] Int -> Map [c] Int
mapAppend ass bss =
sumUnions
[ Map.mapKeysMonotonic (as ++) $ Map.map (v *) bss
| (as, v) <- Map.toAscList ass ]
where
sumUnions = foldl' (Map.unionWith (+)) Map.empty