packages feed

nonempty-containers-0.3.6.0: test/Tests/IntMap.hs

{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TupleSections #-}
{-# LANGUAGE TypeApplications #-}

module Tests.IntMap (intMapTests) where

import Control.Applicative
import Control.Comonad
import Data.Coerce
import Data.Foldable
import qualified Data.Foldable.WithIndex as IFoldable
import Data.Functor.Alt
import Data.Functor.Identity
import qualified Data.Functor.WithIndex as IFunctor
import qualified Data.IntMap as M
import qualified Data.IntMap.NonEmpty as NEM
import Data.List.NonEmpty (NonEmpty (..))
import qualified Data.List.NonEmpty as NE
import Data.Semigroup.Foldable
import Data.Semigroup.Traversable
import Data.Text (Text)
import qualified Data.Text as T
import qualified Data.Traversable.WithIndex as TWI
import qualified GHC.Exts as Exts
import Hedgehog
import qualified Hedgehog.Gen as Gen
import qualified Hedgehog.Range as Range
import Test.Tasty
import Tests.Util

intMapTests :: TestTree
intMapTests = groupTree $$discover

prop_valid :: Property
prop_valid =
  property $
    assert . NEM.valid =<< forAll neIntMapGen

-- | We cannot implement these because there is no 'valid' for IntSet
-- prop_valid_toMap :: Property
-- prop_valid_toMap = property $
--     assert . M.valid . NEM.toMap =<< forAll neIntMapGen

-- prop_valid_insertMinIntMap :: Property
-- prop_valid_insertMinIntMap = property $ do
--     n  <- forAll $ do
--         m <- intMapGen
--         let k = maybe 0 (subtract 1 . fst) $ M.lookupMin m
--         v <- valGen
--         pure $ NEM.insertMinIntMap k v m
--     assert $ M.valid n

-- prop_valid_insertMaxIntMap :: Property
-- prop_valid_insertMaxIntMap = property $ do
--     n  <- forAll $ do
--         m <- intMapGen
--         let k = maybe 0 ((+ 1) . fst) $ M.lookupMax m
--         v <- valGen
--         pure $ NEM.insertMaxIntMap k v m
--     assert $ M.valid n

prop_valid_insertMapMin :: Property
prop_valid_insertMapMin = property $ do
  n <- forAll $ do
    m <- intMapGen
    let k = maybe 0 (subtract 1 . fst) $ M.lookupMin m
    v <- valGen
    pure $ NEM.insertMapMin k v m
  assert $ NEM.valid n

prop_valid_insertMapMax :: Property
prop_valid_insertMapMax = property $ do
  n <- forAll $ do
    m <- intMapGen
    let k = maybe 0 ((+ 1) . fst) $ M.lookupMax m
    v <- valGen
    pure $ NEM.insertMapMax k v m
  assert $ NEM.valid n

prop_toMapIso1 :: Property
prop_toMapIso1 = property $ do
  m0 <- forAll intMapGen
  tripping
    m0
    NEM.nonEmptyMap
    (Identity . maybe M.empty NEM.toMap)

prop_toMapIso2 :: Property
prop_toMapIso2 = property $ do
  m0 <- forAll $ Gen.maybe neIntMapGen
  tripping
    m0
    (maybe M.empty NEM.toMap)
    (Identity . NEM.nonEmptyMap)

prop_read_show :: Property
prop_read_show = readShow neIntMapGen

prop_read1_show1 :: Property
prop_read1_show1 = readShow1 neIntMapGen

prop_show_show1 :: Property
prop_show_show1 = showShow1 neIntMapGen

prop_splitRoot :: Property
prop_splitRoot = property $ do
  n <- forAll neIntMapGen
  let rs = NEM.splitRoot n
      allItems = foldMap1 NEM.keys rs
      n' = NEM.unions rs
  assert $ ascending allItems
  mapM_ (assert . (`NEM.isSubmapOf` n)) rs
  length allItems === length n'
  n === n'
  where
    ascending (x :| xs) = case NE.nonEmpty xs of
      Nothing -> True
      Just ys@(y :| _) -> x < y && ascending ys

prop_functorWithIndex :: Property
prop_functorWithIndex =
  property $ do
    m <- forAll neIntMapGen
    let f k v = v <> T.pack (show k)
    IFunctor.imap f m === NEM.mapWithKey f m

prop_foldableWithIndex :: Property
prop_foldableWithIndex =
  property $ do
    m <- forAll neIntMapGen
    IFoldable.ifoldMap (\k v -> [(k, v)]) m === toList (NEM.toList m)

prop_traversableWithIndex :: Property
prop_traversableWithIndex =
  property $ do
    m <- forAll neIntMapGen
    let f k v = v <> T.pack (show k)
    TWI.itraverse (\k v -> Identity (f k v)) m === Identity (NEM.mapWithKey f m)
    TWI.itraverse (\k v -> Const [(k, v)]) m === Const (toList (NEM.toList m))

prop_extract_duplicate :: Property
prop_extract_duplicate = property $ do
  n <- forAll neIntMapGen
  tripping
    n
    duplicate
    (Identity . extract)

prop_fmap_extract_duplicate :: Property
prop_fmap_extract_duplicate = property $ do
  n <- forAll neIntMapGen
  tripping
    n
    duplicate
    (Identity . fmap extract)

prop_duplicate_duplicate :: Property
prop_duplicate_duplicate = property $ do
  n <- forAll neIntMapGen
  let dd1 = duplicate . duplicate $ n
      dd2 = fmap duplicate . duplicate $ n
  assert $ NEM.valid dd1
  assert $ NEM.valid dd2
  dd1 === dd2

prop_insertMapWithKey :: Property
prop_insertMapWithKey =
  ttProp
    (gf3 valGen :?> GTIntKey :-> GTVal :-> GTIntMap :-> TTNEIntMap)
    M.insertWithKey
    NEM.insertMapWithKey

prop_singleton :: Property
prop_singleton =
  ttProp
    (GTIntKey :-> GTVal :-> TTNEIntMap)
    M.singleton
    NEM.singleton

prop_fromSet :: Property
prop_fromSet =
  ttProp
    (gf1 valGen :?> GTNEIntSet :-> TTNEIntMap)
    M.fromSet
    NEM.fromSet

prop_fromAscList :: Property
prop_fromAscList =
  ttProp
    (GTSorted STAsc (GTNEList Nothing (GTIntKey :&: GTVal)) :-> TTNEIntMap)
    M.fromAscList
    NEM.fromAscList

prop_fromAscListWithKey :: Property
prop_fromAscListWithKey =
  ttProp
    (gf3 valGen :?> GTSorted STAsc (GTNEList Nothing (GTIntKey :&: GTVal)) :-> TTNEIntMap)
    M.fromAscListWithKey
    NEM.fromAscListWithKey

prop_fromDistinctAscList :: Property
prop_fromDistinctAscList =
  ttProp
    (GTSorted STDistinctAsc (GTNEList Nothing (GTIntKey :&: GTVal)) :-> TTNEIntMap)
    M.fromDistinctAscList
    NEM.fromDistinctAscList

prop_fromListWithKey :: Property
prop_fromListWithKey =
  ttProp
    (gf3 valGen :?> GTNEList Nothing (GTIntKey :&: GTVal) :-> TTNEIntMap)
    M.fromListWithKey
    NEM.fromListWithKey

prop_toFromOverloadedList :: Property
prop_toFromOverloadedList =
  property $ do
    s <- forAll neIntMapGen
    s === Exts.fromList (Exts.toList s)

prop_fromToOverloadedList :: Property
prop_fromToOverloadedList =
  property $ do
    l <- forAll neIntTextListUniqGen
    l === Exts.toList (Exts.fromList @(NEM.NEIntMap Text) l)

prop_insert :: Property
prop_insert =
  ttProp
    (GTIntKey :-> GTVal :-> GTNEIntMap :-> TTNEIntMap)
    M.insert
    NEM.insert

prop_insertWithKey :: Property
prop_insertWithKey =
  ttProp
    (gf3 valGen :?> GTIntKey :-> GTVal :-> GTNEIntMap :-> TTNEIntMap)
    M.insertWithKey
    NEM.insertWithKey

prop_delete :: Property
prop_delete =
  ttProp
    (GTIntKey :-> GTNEIntMap :-> TTOther)
    M.delete
    NEM.delete

prop_deleteMaybe :: Property
prop_deleteMaybe =
  property $ do
    k <- forAll intKeyGen
    m <- forAll neIntMapGen
    NEM.deleteMaybe k m === NEM.nonEmptyMap (M.delete k (NEM.toMap m))

prop_adjustWithKey :: Property
prop_adjustWithKey =
  ttProp
    (gf2 valGen :?> GTIntKey :-> GTNEIntMap :-> TTNEIntMap)
    M.adjustWithKey
    NEM.adjustWithKey

prop_updateWithKey :: Property
prop_updateWithKey =
  ttProp
    (gf2 (Gen.maybe valGen) :?> GTIntKey :-> GTNEIntMap :-> TTOther)
    M.updateWithKey
    NEM.updateWithKey

prop_updateLookupWithKey :: Property
prop_updateLookupWithKey =
  ttProp
    (gf2 (Gen.maybe valGen) :?> GTIntKey :-> GTNEIntMap :-> TTMaybe TTVal :*: TTOther)
    M.updateLookupWithKey
    NEM.updateLookupWithKey

prop_alter :: Property
prop_alter =
  ttProp
    (gf1 (Gen.maybe valGen) :?> GTIntKey :-> GTNEIntMap :-> TTOther)
    M.alter
    NEM.alter

prop_alter' :: Property
prop_alter' =
  ttProp
    (gf1 valGen :?> GTIntKey :-> GTNEIntMap :-> TTNEIntMap)
    (M.alter . fmap Just)
    NEM.alter'

prop_alterF :: Property
prop_alterF =
  ttProp
    ( gf1 (Gen.maybe valGen)
        :?> GTIntKey
        :-> GTNEIntMap
        :-> TTCtx (GTMaybe GTVal :-> TTOther) (TTMaybe TTVal)
    )
    (M.alterF . Context)
    (NEM.alterF . Context)

prop_alterF_rules_Const :: Property
prop_alterF_rules_Const =
  ttProp
    ( gf1 (Const <$> valGen)
        :?> GTIntKey
        :-> GTNEIntMap
        :-> TTOther
    )
    (\f k m -> getConst (M.alterF f k m))
    (\f k m -> getConst (NEM.alterF f k m))

prop_alterF_rules_Identity :: Property
prop_alterF_rules_Identity =
  ttProp
    ( gf1 (Identity <$> Gen.maybe valGen)
        :?> GTIntKey
        :-> GTNEIntMap
        :-> TTOther
    )
    (\f k m -> runIdentity (M.alterF f k m))
    (\f k m -> runIdentity (NEM.alterF f k m))

prop_alterF' :: Property
prop_alterF' =
  ttProp
    (gf1 valGen :?> GTIntKey :-> GTNEIntMap :-> TTCtx (GTVal :-> TTNEIntMap) (TTMaybe TTVal))
    (M.alterF . Context . fmap Just)
    (NEM.alterF' . Context)

prop_alterF'_rules_Const :: Property
prop_alterF'_rules_Const =
  ttProp
    ( gf1 (Const <$> valGen)
        :?> GTIntKey
        :-> GTNEIntMap
        :-> TTOther
    )
    (\f k m -> let f' = fmap Just . f in getConst (M.alterF f' k m))
    (\f k m -> getConst (NEM.alterF' f k m))

-- -- | This fails, but isn't possible to fix without copying-and-pasting more
-- -- in code from containers.
-- prop_alterF'_rules_Identity :: Property
-- prop_alterF'_rules_Identity = ttProp ( gf1 (Identity <$> valGen)
--                                    :?> GTIntKey
--                                    :-> GTNEIntMap
--                                    :-> TTNEIntMap
--                                      )
--     (\f k m -> let f' = fmap Just . f in runIdentity (M.alterF   f' k m))
--     (\f k m -> runIdentity (NEM.alterF' f k m))

prop_lookup :: Property
prop_lookup =
  ttProp
    (GTIntKey :-> GTNEIntMap :-> TTMaybe TTVal)
    M.lookup
    NEM.lookup

prop_findWithDefault :: Property
prop_findWithDefault =
  ttProp
    (GTVal :-> GTIntKey :-> GTNEIntMap :-> TTVal)
    M.findWithDefault
    NEM.findWithDefault

prop_member :: Property
prop_member =
  ttProp
    (GTIntKey :-> GTNEIntMap :-> TTOther)
    M.member
    NEM.member

prop_notMember :: Property
prop_notMember =
  ttProp
    (GTIntKey :-> GTNEIntMap :-> TTOther)
    M.notMember
    NEM.notMember

prop_lookupLT :: Property
prop_lookupLT =
  ttProp
    (GTIntKey :-> GTNEIntMap :-> TTMaybe (TTOther :*: TTVal))
    M.lookupLT
    NEM.lookupLT

prop_lookupGT :: Property
prop_lookupGT =
  ttProp
    (GTIntKey :-> GTNEIntMap :-> TTMaybe (TTOther :*: TTVal))
    M.lookupGT
    NEM.lookupGT

prop_lookupLE :: Property
prop_lookupLE =
  ttProp
    (GTIntKey :-> GTNEIntMap :-> TTMaybe (TTOther :*: TTVal))
    M.lookupLE
    NEM.lookupLE

prop_lookupGE :: Property
prop_lookupGE =
  ttProp
    (GTIntKey :-> GTNEIntMap :-> TTMaybe (TTOther :*: TTVal))
    M.lookupGE
    NEM.lookupGE

prop_size :: Property
prop_size =
  ttProp
    (GTNEIntMap :-> TTOther)
    M.size
    NEM.size

prop_union :: Property
prop_union =
  ttProp
    (GTNEIntMap :-> GTNEIntMap :-> TTNEIntMap)
    M.union
    NEM.union

prop_unionMapLeft :: Property
prop_unionMapLeft =
  ttProp
    (GTIntMap :-> GTNEIntMap :-> TTNEIntMap)
    M.union
    NEM.unionMapLeft

prop_unionMapRight :: Property
prop_unionMapRight =
  ttProp
    (GTNEIntMap :-> GTIntMap :-> TTNEIntMap)
    M.union
    NEM.unionMapRight

prop_unionWith :: Property
prop_unionWith =
  ttProp
    (gf2 valGen :?> GTNEIntMap :-> GTNEIntMap :-> TTNEIntMap)
    M.unionWith
    NEM.unionWith

prop_unionMapWithLeft :: Property
prop_unionMapWithLeft =
  ttProp
    (gf2 valGen :?> GTIntMap :-> GTNEIntMap :-> TTNEIntMap)
    M.unionWith
    NEM.unionMapWithLeft

prop_unionMapWithRight :: Property
prop_unionMapWithRight =
  ttProp
    (gf2 valGen :?> GTNEIntMap :-> GTIntMap :-> TTNEIntMap)
    M.unionWith
    NEM.unionMapWithRight

prop_unionWithKey :: Property
prop_unionWithKey =
  ttProp
    (gf3 valGen :?> GTNEIntMap :-> GTNEIntMap :-> TTNEIntMap)
    M.unionWithKey
    NEM.unionWithKey

prop_unionMapWithKeyLeft :: Property
prop_unionMapWithKeyLeft =
  ttProp
    (gf3 valGen :?> GTIntMap :-> GTNEIntMap :-> TTNEIntMap)
    M.unionWithKey
    NEM.unionMapWithKeyLeft

prop_unionMapWithKeyRight :: Property
prop_unionMapWithKeyRight =
  ttProp
    (gf3 valGen :?> GTNEIntMap :-> GTIntMap :-> TTNEIntMap)
    M.unionWithKey
    NEM.unionMapWithKeyRight

prop_unions :: Property
prop_unions =
  ttProp
    (GTNEList (Just (Range.linear 2 5)) GTNEIntMap :-> TTNEIntMap)
    M.unions
    NEM.unions

prop_unionsWith :: Property
prop_unionsWith =
  ttProp
    (gf2 valGen :?> GTNEList (Just (Range.linear 2 5)) GTNEIntMap :-> TTNEIntMap)
    M.unionsWith
    NEM.unionsWith

prop_difference :: Property
prop_difference =
  ttProp
    (GTNEIntMap :-> GTNEIntMap :-> TTOther)
    M.difference
    NEM.difference

prop_differenceWithKey :: Property
prop_differenceWithKey =
  ttProp
    (gf3 (Gen.maybe valGen) :?> GTNEIntMap :-> GTNEIntMap :-> TTOther)
    M.differenceWithKey
    NEM.differenceWithKey

prop_intersection :: Property
prop_intersection =
  ttProp
    (GTNEIntMap :-> GTNEIntMap :-> TTOther)
    M.intersection
    NEM.intersection

prop_intersectionWithKey :: Property
prop_intersectionWithKey =
  ttProp
    (gf3 valGen :?> GTNEIntMap :-> GTNEIntMap :-> TTOther)
    M.intersectionWithKey
    NEM.intersectionWithKey

prop_map :: Property
prop_map =
  ttProp
    (gf1 valGen :?> GTNEIntMap :-> TTNEIntMap)
    M.map
    NEM.map

prop_map_rules_map :: Property
prop_map_rules_map =
  ttProp
    (gf1 valGen :?> gf1 valGen :?> GTNEIntMap :-> TTNEIntMap)
    (\f g xs -> M.map f (M.map g xs))
    (\f g xs -> NEM.map f (NEM.map g xs))

prop_map_rules_coerce :: Property
prop_map_rules_coerce =
  ttProp
    (GTNEIntMap :-> TTNEIntMap)
    (M.map @Text @Text coerce)
    (NEM.map @Text @Text coerce)

prop_map_rules_mapWithKey :: Property
prop_map_rules_mapWithKey =
  ttProp
    (gf1 valGen :?> gf2 valGen :?> GTNEIntMap :-> TTNEIntMap)
    (\f g xs -> M.map f (M.mapWithKey g xs))
    (\f g xs -> NEM.map f (NEM.mapWithKey g xs))

prop_mapWithKey :: Property
prop_mapWithKey =
  ttProp
    (gf2 valGen :?> GTNEIntMap :-> TTNEIntMap)
    M.mapWithKey
    NEM.mapWithKey

prop_mapWithKey_rules_mapWithKey :: Property
prop_mapWithKey_rules_mapWithKey =
  ttProp
    (gf2 valGen :?> gf2 valGen :?> GTNEIntMap :-> TTNEIntMap)
    (\f g xs -> M.mapWithKey f (M.mapWithKey g xs))
    (\f g xs -> NEM.mapWithKey f (NEM.mapWithKey g xs))

prop_mapWithKey_rules_map :: Property
prop_mapWithKey_rules_map =
  ttProp
    (gf2 valGen :?> gf1 valGen :?> GTNEIntMap :-> TTNEIntMap)
    (\f g xs -> M.mapWithKey f (M.map g xs))
    (\f g xs -> NEM.mapWithKey f (NEM.map g xs))

prop_traverseWithKey1 :: Property
prop_traverseWithKey1 =
  ttProp
    (gf1 valGen :?> GTNEIntMap :-> TTBazaar GTVal TTNEIntMap TTVal)
    (\f -> M.traverseWithKey (\k -> (`More` Done (f . (k,)))))
    (\f -> NEM.traverseWithKey1 (\k -> (`More` Done (f . (k,)))))

prop_traverseWithKey :: Property
prop_traverseWithKey =
  ttProp
    (gf1 valGen :?> GTNEIntMap :-> TTBazaar GTVal TTNEIntMap TTVal)
    (\f -> M.traverseWithKey (\k -> (`More` Done (f . (k,)))))
    (\f -> NEM.traverseWithKey (\k -> (`More` Done (f . (k,)))))

prop_sequence1 :: Property
prop_sequence1 =
  ttProp
    (GTNEIntMap :-> TTBazaar GTVal TTNEIntMap TTVal)
    (traverse (`More` Done id))
    (traverse1 (`More` Done id))

prop_sequenceA :: Property
prop_sequenceA =
  ttProp
    (GTNEIntMap :-> TTBazaar GTVal TTNEIntMap TTVal)
    (traverse (`More` Done id))
    (traverse (`More` Done id))

prop_mapAccumWithKey :: Property
prop_mapAccumWithKey =
  ttProp
    ( gf3 ((,) <$> valGen <*> valGen)
        :?> GTOther valGen
        :-> GTNEIntMap
        :-> TTOther
        :*: TTNEIntMap
    )
    M.mapAccumWithKey
    NEM.mapAccumWithKey

prop_mapAccumRWithKey :: Property
prop_mapAccumRWithKey =
  ttProp
    ( gf3 ((,) <$> valGen <*> valGen)
        :?> GTOther valGen
        :-> GTNEIntMap
        :-> TTOther
        :*: TTNEIntMap
    )
    M.mapAccumRWithKey
    NEM.mapAccumRWithKey

prop_mapKeys :: Property
prop_mapKeys =
  ttProp
    (gf1 intKeyGen :?> GTNEIntMap :-> TTNEIntMap)
    M.mapKeys
    NEM.mapKeys

prop_mapKeysWith :: Property
prop_mapKeysWith =
  ttProp
    ( gf2 valGen
        :?> gf1 intKeyGen
        :?> GTNEIntMap
        :-> TTNEIntMap
    )
    M.mapKeysWith
    NEM.mapKeysWith

prop_mapKeysMonotonic :: Property
prop_mapKeysMonotonic =
  ttProp
    (GTNEIntMap :-> TTNEIntMap)
    (M.mapKeysMonotonic (* 2))
    (NEM.mapKeysMonotonic (* 2))

prop_foldr :: Property
prop_foldr =
  ttProp
    ( gf2 valGen
        :?> GTOther valGen
        :-> GTNEIntMap
        :-> TTOther
    )
    M.foldr
    NEM.foldr

prop_foldl :: Property
prop_foldl =
  ttProp
    ( gf2 valGen
        :?> GTOther valGen
        :-> GTNEIntMap
        :-> TTOther
    )
    M.foldl
    NEM.foldl

prop_foldr1 :: Property
prop_foldr1 =
  ttProp
    ( gf2 valGen
        :?> GTNEIntMap
        :-> TTOther
    )
    foldr1
    NEM.foldr1

prop_foldl1 :: Property
prop_foldl1 =
  ttProp
    ( gf2 valGen
        :?> GTNEIntMap
        :-> TTOther
    )
    foldl1
    NEM.foldl1

prop_foldrWithKey :: Property
prop_foldrWithKey =
  ttProp
    ( gf3 valGen
        :?> GTOther valGen
        :-> GTNEIntMap
        :-> TTOther
    )
    M.foldrWithKey
    NEM.foldrWithKey

prop_foldlWithKey :: Property
prop_foldlWithKey =
  ttProp
    ( gf3 valGen
        :?> GTOther valGen
        :-> GTNEIntMap
        :-> TTOther
    )
    M.foldlWithKey
    NEM.foldlWithKey

prop_foldMapWithKey :: Property
prop_foldMapWithKey =
  ttProp
    (gf2 valGen :?> GTNEIntMap :-> TTOther)
    (\f -> foldMap (uncurry f) . M.toList)
    NEM.foldMapWithKey

prop_foldr' :: Property
prop_foldr' =
  ttProp
    ( gf2 valGen
        :?> GTOther valGen
        :-> GTNEIntMap
        :-> TTOther
    )
    M.foldr'
    NEM.foldr'

prop_foldl' :: Property
prop_foldl' =
  ttProp
    ( gf2 valGen
        :?> GTOther valGen
        :-> GTNEIntMap
        :-> TTOther
    )
    M.foldl'
    NEM.foldl'

prop_foldr1' :: Property
prop_foldr1' =
  ttProp
    ( gf2 valGen
        :?> GTNEIntMap
        :-> TTOther
    )
    foldr1
    NEM.foldr1'

prop_foldl1' :: Property
prop_foldl1' =
  ttProp
    ( gf2 valGen
        :?> GTNEIntMap
        :-> TTOther
    )
    foldl1
    NEM.foldl1'

prop_foldrWithKey' :: Property
prop_foldrWithKey' =
  ttProp
    ( gf3 valGen
        :?> GTOther valGen
        :-> GTNEIntMap
        :-> TTOther
    )
    M.foldrWithKey'
    NEM.foldrWithKey'

prop_foldlWithKey' :: Property
prop_foldlWithKey' =
  ttProp
    ( gf3 valGen
        :?> GTOther valGen
        :-> GTNEIntMap
        :-> TTOther
    )
    M.foldlWithKey'
    NEM.foldlWithKey'

prop_elems :: Property
prop_elems =
  ttProp
    (GTNEIntMap :-> TTNEList TTVal)
    M.elems
    NEM.elems

prop_keys :: Property
prop_keys =
  ttProp
    (GTNEIntMap :-> TTNEList TTOther)
    M.keys
    NEM.keys

prop_assocs :: Property
prop_assocs =
  ttProp
    (GTNEIntMap :-> TTNEList (TTOther :*: TTVal))
    M.assocs
    NEM.assocs

prop_keysSet :: Property
prop_keysSet =
  ttProp
    (GTNEIntMap :-> TTNEIntSet)
    M.keysSet
    NEM.keysSet

prop_toList :: Property
prop_toList =
  ttProp
    (GTNEIntMap :-> TTNEList (TTOther :*: TTVal))
    M.toList
    NEM.toList

prop_toDescList :: Property
prop_toDescList =
  ttProp
    (GTNEIntMap :-> TTNEList (TTOther :*: TTVal))
    M.toDescList
    NEM.toDescList

prop_filter :: Property
prop_filter =
  ttProp
    (gf1 Gen.bool :?> GTNEIntMap :-> TTOther)
    M.filter
    NEM.filter

prop_filterWithKey :: Property
prop_filterWithKey =
  ttProp
    (gf2 Gen.bool :?> GTNEIntMap :-> TTOther)
    M.filterWithKey
    NEM.filterWithKey

prop_restrictKeys :: Property
prop_restrictKeys =
  ttProp
    (GTNEIntMap :-> GTIntSet :-> TTOther)
    M.restrictKeys
    NEM.restrictKeys

prop_withoutKeys :: Property
prop_withoutKeys =
  ttProp
    (GTNEIntMap :-> GTIntSet :-> TTOther)
    M.withoutKeys
    NEM.withoutKeys

prop_partitionWithKey :: Property
prop_partitionWithKey =
  ttProp
    (gf2 Gen.bool :?> GTNEIntMap :-> TTThese TTNEIntMap TTNEIntMap)
    M.partitionWithKey
    NEM.partitionWithKey

prop_mapMaybeWithKey :: Property
prop_mapMaybeWithKey =
  ttProp
    (gf2 (Gen.maybe valGen) :?> GTNEIntMap :-> TTOther)
    M.mapMaybeWithKey
    NEM.mapMaybeWithKey

prop_mapEitherWithKey :: Property
prop_mapEitherWithKey =
  ttProp
    ( gf2 (Gen.choice [Left <$> valGen, Right <$> valGen])
        :?> GTNEIntMap
        :-> TTThese TTNEIntMap TTNEIntMap
    )
    M.mapEitherWithKey
    NEM.mapEitherWithKey

prop_split :: Property
prop_split =
  ttProp
    (GTIntKey :-> GTNEIntMap :-> TTMThese TTNEIntMap TTNEIntMap)
    M.split
    NEM.split

prop_splitLookup :: Property
prop_splitLookup =
  ttProp
    (GTIntKey :-> GTNEIntMap :-> TTTThese TTVal TTNEIntMap TTNEIntMap)
    (\k -> (\(x, y, z) -> (y, x, z)) . M.splitLookup k)
    NEM.splitLookup

prop_isSubmapOfBy :: Property
prop_isSubmapOfBy =
  ttProp
    (gf2 Gen.bool :?> GTNEIntMap :-> GTNEIntMap :-> TTOther)
    M.isSubmapOfBy
    NEM.isSubmapOfBy

prop_isProperSubmapOfBy :: Property
prop_isProperSubmapOfBy =
  ttProp
    (gf2 Gen.bool :?> GTNEIntMap :-> GTNEIntMap :-> TTOther)
    M.isProperSubmapOfBy
    NEM.isProperSubmapOfBy

prop_findMin :: Property
prop_findMin =
  ttProp
    (GTNEIntMap :-> TTOther :*: TTVal)
    M.findMin
    NEM.findMin

prop_findMax :: Property
prop_findMax =
  ttProp
    (GTNEIntMap :-> TTOther :*: TTVal)
    M.findMax
    NEM.findMax

prop_deleteMin :: Property
prop_deleteMin =
  ttProp
    (GTNEIntMap :-> TTOther)
    M.deleteMin
    NEM.deleteMin

prop_deleteMax :: Property
prop_deleteMax =
  ttProp
    (GTNEIntMap :-> TTOther)
    M.deleteMax
    NEM.deleteMax

prop_deleteFindMin :: Property
prop_deleteFindMin =
  ttProp
    (GTNEIntMap :-> (TTOther :*: TTVal) :*: TTOther)
    M.deleteFindMin
    NEM.deleteFindMin

prop_deleteFindMax :: Property
prop_deleteFindMax =
  ttProp
    (GTNEIntMap :-> (TTOther :*: TTVal) :*: TTOther)
    M.deleteFindMax
    NEM.deleteFindMax

prop_updateMinWithKey :: Property
prop_updateMinWithKey =
  ttProp
    (gf2 (Gen.maybe valGen) :?> GTNEIntMap :-> TTOther)
    M.updateMinWithKey
    NEM.updateMinWithKey

prop_updateMaxWithKey :: Property
prop_updateMaxWithKey =
  ttProp
    (gf2 (Gen.maybe valGen) :?> GTNEIntMap :-> TTOther)
    M.updateMaxWithKey
    NEM.updateMaxWithKey

prop_adjustMinWithKey :: Property
prop_adjustMinWithKey =
  ttProp
    (gf2 valGen :?> GTNEIntMap :-> TTNEIntMap)
    (M.updateMinWithKey . (fmap . fmap) Just)
    NEM.adjustMinWithKey

prop_adjustMaxWithKey :: Property
prop_adjustMaxWithKey =
  ttProp
    (gf2 valGen :?> GTNEIntMap :-> TTNEIntMap)
    (M.updateMaxWithKey . (fmap . fmap) Just)
    NEM.adjustMaxWithKey

prop_minView :: Property
prop_minView =
  ttProp
    (GTNEIntMap :-> TTMaybe (TTVal :*: TTOther))
    M.minView
    (Just . NEM.minView)

prop_maxView :: Property
prop_maxView =
  ttProp
    (GTNEIntMap :-> TTMaybe (TTVal :*: TTOther))
    M.maxView
    (Just . NEM.maxView)

prop_elem :: Property
prop_elem =
  ttProp
    (GTVal :-> GTNEIntMap :-> TTOther)
    elem
    elem

prop_fold1 :: Property
prop_fold1 =
  ttProp
    (GTNEIntMap :-> TTVal)
    fold
    fold1

prop_fold :: Property
prop_fold =
  ttProp
    (GTNEIntMap :-> TTVal)
    fold
    fold

prop_foldMap1 :: Property
prop_foldMap1 =
  ttProp
    (gf1 valGen :?> GTNEIntMap :-> TTOther)
    (\f -> foldMap ((: []) . f))
    (\f -> foldMap1 ((: []) . f))

prop_foldMap :: Property
prop_foldMap =
  ttProp
    (gf1 valGen :?> GTNEIntMap :-> TTOther)
    (\f -> foldMap ((: []) . f))
    (\f -> foldMap ((: []) . f))

prop_alt :: Property
prop_alt =
  ttProp
    (GTNEIntMap :-> GTNEIntMap :-> TTNEIntMap)
    (<!>)
    (<!>)