monoidmap-0.0.0.0: src/test/Data/MonoidMap/SliceSpec.hs
{- HLINT ignore "Redundant bracket" -}
{- HLINT ignore "Use camelCase" -}
{- HLINT ignore "Use null" -}
-- |
-- Copyright: © 2022–2023 Jonathan Knowles
-- License: Apache-2.0
--
module Data.MonoidMap.SliceSpec
( spec
, Slice (..)
) where
import Prelude
import Control.Monad
( forM_ )
import Data.Bifunctor
( Bifunctor (bimap) )
import Data.Function
( (&) )
import Data.Monoid.Null
( MonoidNull )
import Data.MonoidMap
( MonoidMap, nonNullCount )
import Data.Proxy
( Proxy (..) )
import GHC.Exts
( IsList (..) )
import Test.Common
( Key, Test, TestType (TestType), makeSpec, property, testTypesMonoidNull )
import Test.Hspec
( Spec, describe, it )
import Test.QuickCheck
( Arbitrary (..), Gen, Property, choose, cover, oneof, (===) )
import qualified Data.MonoidMap as MonoidMap
spec :: Spec
spec = describe "Slicing" $ do
forM_ testTypesMonoidNull $ \(TestType p) -> specFor (Proxy @Key) p
specFor :: forall k v. Test k v => Proxy k -> Proxy v -> Spec
specFor = makeSpec $ do
it "prop_take_toList_fromList" $
prop_take_toList_fromList
@k @v & property
it "prop_drop_toList_fromList" $
prop_drop_toList_fromList
@k @v & property
it "prop_splitAt_toList_fromList" $
prop_splitAt_toList_fromList
@k @v & property
data Slice k v = Slice Int (MonoidMap k v)
deriving (Eq, Show)
instance (Arbitrary k, Arbitrary v, MonoidNull v, Ord k) =>
Arbitrary (Slice k v)
where
arbitrary = do
m <- genMap
i <- genIndex m
pure $ Slice i m
where
genMap :: Gen (MonoidMap k v)
genMap = arbitrary
genIndex :: MonoidMap k v -> Gen Int
genIndex m = oneof
[ choose (negate (length m), -1)
, pure 0
, choose (1, length m - 1)
, pure (length m)
, choose (length m + 1, 2 * length m)
]
prop_take_toList_fromList
:: Test k v => Slice k v -> Property
prop_take_toList_fromList (Slice i m) =
MonoidMap.take i m
=== (fromList . Prelude.take i . toList) m
& cover 2
(i == 0 && 0 < nonNullCount m)
"i == 0 && 0 < nonNullCount m"
& cover 2
(0 < i && i < nonNullCount m)
"0 < i && i < nonNullCount m"
& cover 2
(0 < nonNullCount m && nonNullCount m == i)
"0 < nonNullCount m && nonNullCount m == i"
& cover 2
(0 < nonNullCount m && nonNullCount m < i)
"0 < nonNullCount m && nonNullCount m < i"
prop_drop_toList_fromList
:: Test k v => Slice k v -> Property
prop_drop_toList_fromList (Slice i m) =
MonoidMap.drop i m
=== (fromList . Prelude.drop i . toList) m
& cover 2
(i == 0 && 0 < nonNullCount m)
"i == 0 && 0 < nonNullCount m"
& cover 2
(0 < i && i < nonNullCount m)
"0 < i && i < nonNullCount m"
& cover 2
(0 < nonNullCount m && nonNullCount m == i)
"0 < nonNullCount m && nonNullCount m == i"
& cover 2
(0 < nonNullCount m && nonNullCount m < i)
"0 < nonNullCount m && nonNullCount m < i"
prop_splitAt_toList_fromList
:: Test k v => Slice k v -> Property
prop_splitAt_toList_fromList (Slice i m) =
MonoidMap.splitAt i m
=== (bimap fromList fromList . Prelude.splitAt i . toList) m
& cover 2
(i == 0 && 0 < nonNullCount m)
"i == 0 && 0 < nonNullCount m"
& cover 2
(0 < i && i < nonNullCount m)
"0 < i && i < nonNullCount m"
& cover 2
(0 < nonNullCount m && nonNullCount m == i)
"0 < nonNullCount m && nonNullCount m == i"
& cover 2
(0 < nonNullCount m && nonNullCount m < i)
"0 < nonNullCount m && nonNullCount m < i"