{-# LANGUAGE TemplateHaskell #-} module Tests.IntSet (intSetTests) where import Data.Functor.Identity import Data.List.NonEmpty (NonEmpty(..)) import Data.Semigroup.Foldable import Hedgehog import Test.Tasty import Tests.Util import qualified Data.IntSet as S import qualified Data.IntSet.NonEmpty as NES import qualified Data.IntSet.NonEmpty.Internal as NES import qualified Data.List.NonEmpty as NE import qualified Hedgehog.Gen as Gen import qualified Hedgehog.Range as Range intSetTests :: TestTree intSetTests = groupTree $$(discover) prop_valid :: Property prop_valid = property $ assert . NES.valid =<< forAll neIntSetGen -- | We cannot implement these because there is no 'valid' for IntSet -- prop_valid_toSet :: Property -- prop_valid_toSet = property $ do -- assert . S.valid . NES.toSet =<< forAll neIntSetGen -- prop_valid_insertMinIntSet :: Property -- prop_valid_insertMinIntSet = property $ do -- n <- forAll $ do -- m <- setGen -- let k = maybe dummyKey (subtract 1 . fst) $ S.maxView m -- pure $ NES.insertMinIntSet k m -- assert $ S.valid n -- prop_valid_insertMaxIntSet :: Property -- prop_valid_insertMaxIntSet = property $ do -- n <- forAll $ do -- m <- setGen -- let k = maybe dummyKey ((+ 1) . fst) $ S.maxView m -- pure $ NES.insertMaxIntSet k m -- assert $ S.valid n prop_valid_insertSetMin :: Property prop_valid_insertSetMin = property $ do n <- forAll $ do m <- intSetGen let k = maybe 0 (subtract 1 . fst) $ S.minView m pure $ NES.insertSetMin k m assert $ NES.valid n prop_valid_insertSetMax :: Property prop_valid_insertSetMax = property $ do n <- forAll $ do m <- intSetGen let k = maybe 0 ((+ 1) . fst) $ S.maxView m pure $ NES.insertSetMax k m assert $ NES.valid n prop_toSetIso1 :: Property prop_toSetIso1 = property $ do m0 <- forAll intSetGen tripping m0 NES.nonEmptySet (Identity . maybe S.empty NES.toSet) prop_toSetIso2 :: Property prop_toSetIso2 = property $ do m0 <- forAll $ Gen.maybe neIntSetGen tripping m0 (maybe S.empty NES.toSet) (Identity . NES.nonEmptySet) prop_read_show :: Property prop_read_show = readShow neIntSetGen prop_splitRoot :: Property prop_splitRoot = property $ do n <- forAll neIntSetGen let rs = NES.splitRoot n allItems = foldMap1 NES.toList rs n' = NES.unions rs assert $ ascending allItems mapM_ (assert . (`NES.isSubsetOf` n)) rs length allItems === NES.size n' n === n' where ascending (x :| xs) = case NE.nonEmpty xs of Nothing -> True Just ys@(y :| _) -> x < y && ascending ys prop_insertSet :: Property prop_insertSet = ttProp (GTIntKey :-> GTIntSet :-> TTNEIntSet) S.insert NES.insertSet prop_singleton :: Property prop_singleton = ttProp (GTIntKey :-> TTNEIntSet) S.singleton NES.singleton prop_fromAscList :: Property prop_fromAscList = ttProp (GTSorted STAsc (GTNEList Nothing (GTIntKey :&: GTVal)) :-> TTNEIntSet) (S.fromAscList . fmap fst) (NES.fromAscList . fmap fst) prop_fromDistinctAscList :: Property prop_fromDistinctAscList = ttProp (GTSorted STAsc (GTNEList Nothing GTIntKey) :-> TTNEIntSet) S.fromDistinctAscList NES.fromDistinctAscList prop_fromList :: Property prop_fromList = ttProp (GTNEList Nothing GTIntKey :-> TTNEIntSet) S.fromList NES.fromList prop_insert :: Property prop_insert = ttProp (GTIntKey :-> GTNEIntSet :-> TTNEIntSet) S.insert NES.insert prop_delete :: Property prop_delete = ttProp (GTIntKey :-> GTNEIntSet :-> TTOther) S.delete NES.delete prop_member :: Property prop_member = ttProp (GTIntKey :-> GTNEIntSet :-> TTOther) S.member NES.member prop_notMember :: Property prop_notMember = ttProp (GTIntKey :-> GTNEIntSet :-> TTOther) S.notMember NES.notMember prop_lookupLT :: Property prop_lookupLT = ttProp (GTIntKey :-> GTNEIntSet :-> TTMaybe TTOther) S.lookupLT NES.lookupLT prop_lookupGT :: Property prop_lookupGT = ttProp (GTIntKey :-> GTNEIntSet :-> TTMaybe TTOther) S.lookupGT NES.lookupGT prop_lookupLE :: Property prop_lookupLE = ttProp (GTIntKey :-> GTNEIntSet :-> TTMaybe TTOther) S.lookupLE NES.lookupLE prop_lookupGE :: Property prop_lookupGE = ttProp (GTIntKey :-> GTNEIntSet :-> TTMaybe TTOther) S.lookupGE NES.lookupGE prop_size :: Property prop_size = ttProp (GTNEIntSet :-> TTOther) S.size NES.size prop_isSubsetOf :: Property prop_isSubsetOf = ttProp (GTNEIntSet :-> GTNEIntSet :-> TTOther) S.isSubsetOf NES.isSubsetOf prop_isProperSubsetOf :: Property prop_isProperSubsetOf = ttProp (GTNEIntSet :-> GTNEIntSet :-> TTOther) S.isProperSubsetOf NES.isProperSubsetOf prop_disjoint :: Property prop_disjoint = ttProp (GTNEIntSet :-> GTNEIntSet :-> TTOther) NES.disjointSet NES.disjoint prop_union :: Property prop_union = ttProp (GTNEIntSet :-> GTNEIntSet :-> TTNEIntSet) S.union NES.union prop_unions :: Property prop_unions = ttProp (GTNEList (Just (Range.linear 2 5)) GTNEIntSet :-> TTNEIntSet) S.unions NES.unions prop_difference :: Property prop_difference = ttProp (GTNEIntSet :-> GTNEIntSet :-> TTOther) S.difference NES.difference prop_intersection :: Property prop_intersection = ttProp (GTNEIntSet :-> GTNEIntSet :-> TTOther) S.intersection NES.intersection prop_filter :: Property prop_filter = ttProp (gf1 Gen.bool :?> GTNEIntSet :-> TTOther) S.filter NES.filter prop_partition :: Property prop_partition = ttProp (gf1 Gen.bool :?> GTNEIntSet :-> TTThese TTNEIntSet TTNEIntSet) S.partition NES.partition prop_split :: Property prop_split = ttProp (GTIntKey :-> GTNEIntSet :-> TTMThese TTNEIntSet TTNEIntSet) S.split NES.split prop_splitMember :: Property prop_splitMember = ttProp (GTIntKey :-> GTNEIntSet :-> TTOther :*: TTMThese TTNEIntSet TTNEIntSet) (\k -> (\(x,y,z) -> (y,(x,z))) . S.splitMember k) NES.splitMember prop_map :: Property prop_map = ttProp (gf1 intKeyGen :?> GTNEIntSet :-> TTNEIntSet) S.map NES.map prop_foldr :: Property prop_foldr = ttProp ( gf2 valGen :?> GTOther valGen :-> GTNEIntSet :-> TTOther ) S.foldr NES.foldr prop_foldl :: Property prop_foldl = ttProp ( gf2 valGen :?> GTOther valGen :-> GTNEIntSet :-> TTOther ) S.foldl NES.foldl prop_foldr1 :: Property prop_foldr1 = ttProp ( gf2 intKeyGen :?> GTNEIntSet :-> TTOther ) (\f -> foldr1 f . S.toList) NES.foldr1 prop_foldl1 :: Property prop_foldl1 = ttProp ( gf2 intKeyGen :?> GTNEIntSet :-> TTOther ) (\f -> foldl1 f . S.toList) NES.foldl1 prop_foldr' :: Property prop_foldr' = ttProp ( gf2 intKeyGen :?> GTOther intKeyGen :-> GTNEIntSet :-> TTOther ) S.foldr' NES.foldr' prop_foldl' :: Property prop_foldl' = ttProp ( gf2 intKeyGen :?> GTOther intKeyGen :-> GTNEIntSet :-> TTOther ) S.foldl' NES.foldl' prop_foldr1' :: Property prop_foldr1' = ttProp ( gf2 intKeyGen :?> GTNEIntSet :-> TTOther ) (\f -> foldr1 f . S.toList) NES.foldr1' prop_foldl1' :: Property prop_foldl1' = ttProp ( gf2 intKeyGen :?> GTNEIntSet :-> TTOther ) (\f -> foldl1 f . S.toList) NES.foldl1' prop_findMin :: Property prop_findMin = ttProp (GTNEIntSet :-> TTOther) S.findMin NES.findMin prop_findMax :: Property prop_findMax = ttProp (GTNEIntSet :-> TTOther) S.findMax NES.findMax prop_deleteMin :: Property prop_deleteMin = ttProp (GTNEIntSet :-> TTOther) S.deleteMin NES.deleteMin prop_deleteMax :: Property prop_deleteMax = ttProp (GTNEIntSet :-> TTOther) S.deleteMax NES.deleteMax prop_deleteFindMin :: Property prop_deleteFindMin = ttProp (GTNEIntSet :-> TTOther :*: TTOther) S.deleteFindMin NES.deleteFindMin prop_deleteFindMax :: Property prop_deleteFindMax = ttProp (GTNEIntSet :-> TTOther :*: TTOther) S.deleteFindMax NES.deleteFindMax prop_toList :: Property prop_toList = ttProp (GTNEIntSet :-> TTNEList TTOther) S.toList NES.toList prop_toDescList :: Property prop_toDescList = ttProp (GTNEIntSet :-> TTNEList TTOther) S.toDescList NES.toDescList