{-# LANGUAGE ScopedTypeVariables #-}

module Test.Cardano.Data.MapExtrasSpec (mapExtrasSpec) where

import Control.Monad
import Data.Map (Map)
import qualified Data.Map.Strict as Map
import Data.MapExtras
import Test.Cardano.Data
import Test.Hspec
import Test.Hspec.QuickCheck
import Test.QuickCheck

mapExtrasSpec :: Spec
mapExtrasSpec :: Spec
mapExtrasSpec =
  forall a. HasCallStack => String -> SpecWith a -> SpecWith a
describe String
"MapExtras" forall a b. (a -> b) -> a -> b
$ do
    forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"extract k m === (lookup k m, delete k m)" forall a b. (a -> b) -> a -> b
$ \(Map Int Float
m :: Map Int Float) Int
k -> do
      let (Maybe Float
v, Map Int Float
ma) = forall k b. Ord k => k -> Map k b -> (Maybe b, Map k b)
extract Int
k Map Int Float
m
      forall k a.
(HasCallStack, Ord k, Show k, Show a) =>
Map k a -> IO ()
expectValidMap Map Int Float
ma
      Map Int Float
ma forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO ()
`shouldBe` forall k a. Ord k => k -> Map k a -> Map k a
Map.delete Int
k Map Int Float
m
      Maybe Float
v forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO ()
`shouldBe` forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup Int
k Map Int Float
m
    forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"extractKeys m s === (withoutKeys m s, restrictKeys m s)" forall a b. (a -> b) -> a -> b
$ \(Map Int Float
m :: Map Int Float) Set Int
s -> do
      let (Map Int Float
wk, Map Int Float
rk) = forall k a. Ord k => Map k a -> Set k -> (Map k a, Map k a)
extractKeys Map Int Float
m Set Int
s
      forall k a.
(HasCallStack, Ord k, Show k, Show a) =>
Map k a -> IO ()
expectValidMap Map Int Float
wk
      forall k a.
(HasCallStack, Ord k, Show k, Show a) =>
Map k a -> IO ()
expectValidMap Map Int Float
rk
      Map Int Float
wk forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO ()
`shouldBe` forall k a. Ord k => Map k a -> Set k -> Map k a
Map.withoutKeys Map Int Float
m Set Int
s
      Map Int Float
rk forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO ()
`shouldBe` forall k a. Ord k => Map k a -> Set k -> Map k a
Map.restrictKeys Map Int Float
m Set Int
s
    forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"noKeys == withoutKeys" forall a b. (a -> b) -> a -> b
$ \(Map Int Float
m1 :: Map Int Float) (Map Int Char
m2 :: Map Int Char) -> do
      let nk :: Map Int Float
nk = forall k a b. Ord k => Map k a -> Map k b -> Map k a
noKeys Map Int Float
m1 Map Int Char
m2
      forall k a.
(HasCallStack, Ord k, Show k, Show a) =>
Map k a -> IO ()
expectValidMap Map Int Float
nk
      Map Int Float
nk forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO ()
`shouldBe` forall k a. Ord k => Map k a -> Set k -> Map k a
Map.withoutKeys Map Int Float
m1 (forall k a. Map k a -> Set k
Map.keysSet Map Int Char
m2)
    forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"intersectDomP" forall a b. (a -> b) -> a -> b
$ \Fun (Int, Word) Bool
fun (Map Int Char
m1 :: Map Int Char) (Map Int Word
m2 :: Map Int Word) -> do
      let f :: Int -> Word -> Bool
f = forall a b c. Fun (a, b) c -> a -> b -> c
applyFun2 Fun (Int, Word) Bool
fun :: Int -> Word -> Bool
          ma :: Map Int Word
ma = forall k v2 v1.
Ord k =>
(k -> v2 -> Bool) -> Map k v1 -> Map k v2 -> Map k v2
intersectDomP Int -> Word -> Bool
f Map Int Char
m1 Map Int Word
m2
      forall k a.
(HasCallStack, Ord k, Show k, Show a) =>
Map k a -> IO ()
expectValidMap Map Int Word
ma
      Map Int Word
ma forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO ()
`shouldBe` forall k a. (k -> a -> Bool) -> Map k a -> Map k a
Map.filterWithKey Int -> Word -> Bool
f (forall k a b. Ord k => Map k a -> Map k b -> Map k a
Map.intersection Map Int Word
m2 Map Int Char
m1)
    forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"intersectDomPLeft" forall a b. (a -> b) -> a -> b
$ \Fun (Int, Word) Bool
fun (Map Int Char
m1 :: Map Int Char) (Map Int Word
m2 :: Map Int Word) -> do
      let f :: Int -> Word -> Bool
f = forall a b c. Fun (a, b) c -> a -> b -> c
applyFun2 Fun (Int, Word) Bool
fun :: Int -> Word -> Bool
          ma :: Map Int Char
ma = forall k v2 v1.
Ord k =>
(k -> v2 -> Bool) -> Map k v1 -> Map k v2 -> Map k v1
intersectDomPLeft Int -> Word -> Bool
f Map Int Char
m1 Map Int Word
m2
      forall k a.
(HasCallStack, Ord k, Show k, Show a) =>
Map k a -> IO ()
expectValidMap Map Int Char
ma
      Map Int Char
ma forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO ()
`shouldBe` forall k a b. (k -> a -> Maybe b) -> Map k a -> Map k b
Map.mapMaybeWithKey (\Int
k Char
v -> Char
v forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ (forall (f :: * -> *). Alternative f => Bool -> f ()
guard forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Word -> Bool
f Int
k forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup Int
k Map Int Word
m2)) Map Int Char
m1