min-max-pqueue-0.1.0.0: test/hedgehog/MinMaxQueueSpec.hs
{-# LANGUAGE TemplateHaskell #-}
module MinMaxQueueSpec where
import qualified Data.Foldable as Foldable
import qualified Data.List as List
import Hedgehog
import qualified Hedgehog.Gen as Gen
import qualified Hedgehog.Range as Range
import Data.MinMaxQueue (MinMaxQueue)
import qualified Data.MinMaxQueue as PQ
genQueue :: Gen (MinMaxQueue Int Int)
genQueue = do
xs <- Gen.list (Range.linear 0 500) (Gen.int (Range.linear 0 50))
pure $ PQ.fromListWith id xs
prop_ascendingOrder :: Property
prop_ascendingOrder = property $ do
q <- forAll genQueue
let ascList = dequeueAllAsc q
ascList === List.sort ascList
PQ.size q === length ascList
prop_descendingOrder :: Property
prop_descendingOrder = property $ do
q <- forAll genQueue
let descList = dequeueAllDesc q
descList === List.sortBy (flip compare) descList
PQ.size q === length descList
prop_takeMin :: Property
prop_takeMin = property $ do
q <- forAll genQueue
n <- forAll $ Gen.int (Range.linear (-100) (PQ.size q + 100))
take n (dequeueAllAsc q) === dequeueAllAsc (PQ.takeMin n q)
length (take n (dequeueAllAsc q)) === PQ.size (PQ.takeMin n q)
prop_takeMax :: Property
prop_takeMax = property $ do
q <- forAll genQueue
n <- forAll $ Gen.int (Range.linear (-100) (PQ.size q + 100))
take n (dequeueAllDesc q) === dequeueAllDesc (PQ.takeMax n q)
length (take n (dequeueAllDesc q)) === PQ.size (PQ.takeMax n q)
prop_dropMin :: Property
prop_dropMin = property $ do
q <- forAll genQueue
n <- forAll $ Gen.int (Range.linear (-100) (PQ.size q + 100))
drop n (dequeueAllAsc q) === dequeueAllAsc (PQ.dropMin n q)
length (drop n (dequeueAllAsc q)) === PQ.size (PQ.dropMin n q)
prop_dropMax :: Property
prop_dropMax = property $ do
q <- forAll genQueue
n <- forAll $ Gen.int (Range.linear (-100) (PQ.size q + 100))
drop n (dequeueAllDesc q) === dequeueAllDesc (PQ.dropMax n q)
length (drop n (dequeueAllDesc q)) === PQ.size (PQ.dropMax n q)
prop_maxSize :: Property
prop_maxSize = property $ do
q <- forAll genQueue
n <- forAll $ Gen.int (Range.linear (-100) (PQ.size q + 100))
let q' = q `PQ.withMaxSize` n
PQ.size q' === max 0 (min (PQ.size q) n)
PQ.maxSize q' === Just (max 0 n)
dequeueAllAsc q' === take (PQ.size q') (dequeueAllAsc q)
prop_insertWithMaxSize :: Property
prop_insertWithMaxSize = property $ do
q <- forAll genQueue
let q' = q `PQ.withMaxSize` PQ.size q
PQ.insert id maxBound q' === q'
PQ.insert id minBound q' === PQ.insert id minBound (PQ.deleteMax q')
prop_fold :: Property
prop_fold = property $ do
q <- forAll genQueue
let f a s = show a ++ s
g = flip f
f' prio a s = show prio ++ show a ++ s
g' s prio a = f' prio a s
h prio a = show prio ++ show a
PQ.foldr f "" q === foldr f "" (PQ.elems q)
PQ.foldl g "" q === foldl g "" (PQ.elems q)
PQ.foldrWithPriority f' "" q === foldr (uncurry f') "" (PQ.toAscList q)
PQ.foldlWithPriority g' "" q === foldl (uncurry . g') "" (PQ.toAscList q)
Foldable.foldMap show q === Foldable.foldMap show (PQ.elems q)
PQ.foldMapWithPriority h q === Foldable.foldMap (uncurry h) (PQ.toAscList q)
dequeueAllAsc :: Ord prio => MinMaxQueue prio a -> [a]
dequeueAllAsc = List.unfoldr PQ.pollMin
dequeueAllDesc :: Ord prio => MinMaxQueue prio a -> [a]
dequeueAllDesc = List.unfoldr PQ.pollMax
tests :: IO Bool
tests =
checkParallel $$(discover)