closed-intervals-0.1.0.1: test/Data/IntervalTest.hs
module Data.IntervalTest (
genDisjointIntervalSeq,
genInterval,
genIntervalSeq,
genLabeledSeq,
genNonEmptyInterval,
genNonEmptyIntervalSeq,
genSortedIntervals,
genSortedIntervalSeq,
genSortedList,
(/\),
(/\*),
) where
import Data.Interval
import qualified Data.Time as Time
import qualified Data.Sequence as Seq
import qualified Data.List as List
import Data.Foldable (toList)
import Data.Sequence (Seq)
import Data.Function (on)
import Data.Time (UTCTime)
import Control.Arrow (first)
import Control.Applicative (liftA2)
import qualified Test.QuickCheck as QC
type Intv = (UTCTime,UTCTime)
infixr 0 /\, /\*
(/\) :: (Show a, QC.Testable test) => Gen a -> (a -> test) -> QC.Property
(/\) = uncurry QC.forAllShrink
(/\*) ::
(Show a, QC.Testable test) =>
Gen a -> (a -> a -> test) -> QC.Property
(/\*) (gen,shrink) =
QC.forAllShrink
(liftA2 (,) gen gen)
(\(a,b) -> map (flip (,) b) (shrink a) ++ map ((,) a) (shrink b)) .
uncurry
type Gen a = (QC.Gen a, a -> [a])
withoutShrink :: QC.Gen a -> Gen a
withoutShrink gen = (gen, const [])
shrinkList :: [a] -> [[a]]
shrinkList xs = List.zipWith (++) (List.inits xs) (List.tail $ List.tails xs)
shrinkSeq :: Seq a -> [Seq a]
shrinkSeq = map Seq.fromList . shrinkList . toList
withShrinkList :: QC.Gen [a] -> Gen [a]
withShrinkList gen = (gen, shrinkList)
withShrinkSeq :: QC.Gen (Seq a) -> Gen (Seq a)
withShrinkSeq gen = (gen, shrinkSeq)
genInterval :: Gen Intv
genInterval = withoutShrink $ do
a <- genUTCTime
b <- genUTCTime
return (min a b, max a b)
genNonEmptyInterval :: Gen Intv
genNonEmptyInterval = withoutShrink $ do
a <- genUTCTime
b <- genUTCTime `QC.suchThat` (a/=)
return (min a b, max a b)
genUTCTime :: QC.Gen UTCTime
genUTCTime = do
day <- QC.arbitrary
return $ Time.UTCTime (Time.ModifiedJulianDay day) 0
genIntervalSeq :: Gen (Seq Intv)
genIntervalSeq =
withShrinkSeq $ fmap Seq.fromList $ QC.listOf $ fst genInterval
-- | generate a Sequence of intervals sorted by 'sortByLeft'
genDisjointIntervalSeq :: Gen (Seq Intv)
genDisjointIntervalSeq =
withShrinkSeq $
filterM (const QC.arbitrary) . sortByLeft . fromEndPoints . List.sort
=<< QC.listOf genUTCTime
genNonEmptyIntervalSeq :: Gen (Seq Intv)
genNonEmptyIntervalSeq =
withShrinkSeq $ fmap Seq.fromList $ QC.listOf $ fst genNonEmptyInterval
_genInterval :: Gen (Int,Int)
_genInterval = withoutShrink $ do
a <- QC.arbitrary
b <- QC.arbitrary
return (min a b, max a b)
genSortedIntervals :: Gen [Intv]
genSortedIntervals =
withShrinkList $
fmap (List.sortBy (compare `on` fst)) $ QC.listOf $ fst genInterval
genSortedIntervalSeq :: Gen (Seq Intv)
genSortedIntervalSeq = first (fmap sortByLeft) genIntervalSeq
genSortedList :: Gen [Int]
genSortedList = withShrinkList $ fmap List.sort QC.arbitrary
genLabeledSeq :: Gen (Seq (Char,Intv))
genLabeledSeq =
withShrinkSeq $
mapM (liftA2 (,) (QC.choose ('a','z')) . pure) =<< fst genIntervalSeq