range-0.3.2.0: Test/Range.hs
{-# LANGUAGE TypeSynonymInstances, FlexibleInstances #-}
{-# OPTIONS_GHC -fno-warn-orphans #-}
-- This is only okay in test classes
module Main where
import Test.Framework (defaultMain, testGroup)
import Test.QuickCheck
import Test.Framework.Providers.QuickCheck2
import System.Random
import Data.Range
import qualified Data.Range.Algebra as Alg
import Test.RangeMerge
import Test.RangeLaws
import Test.RangeParser
import Test.RangeOrd
import Test.Generators ()
data UnequalPair a = UnequalPair (a, a)
deriving (Show)
instance (Integral a, Num a, Eq a) => Arbitrary (UnequalPair a) where
arbitrary = do
first <- arbitrarySizedIntegral
second <- arbitrarySizedIntegral `suchThat` (/= first)
return $ UnequalPair (first, second)
prop_singleton_in_range :: Integer -> Bool
prop_singleton_in_range a = inRange (SingletonRange a) a
prop_singleton_not_in_range :: (Ord a) => UnequalPair a -> Bool
prop_singleton_not_in_range (UnequalPair (first, second)) = not $ inRange (SingletonRange first) second
data SpanContains a = SpanContains (a, a) a
deriving (Show)
instance (Num a, Integral a, Ord a, Random a) => Arbitrary (SpanContains a) where
arbitrary = do
begin <- arbitrarySizedIntegral
end <- arbitrarySizedIntegral `suchThat` (>= begin)
middle <- choose (begin, end)
return $ SpanContains (begin, end) middle
prop_span_contains :: SpanContains Integer -> Bool
prop_span_contains (SpanContains (begin, end) middle) = inRange (SpanRange (Bound begin Inclusive) (Bound end Inclusive)) middle
prop_infinite_range_contains_everything :: Integer -> Bool
prop_infinite_range_contains_everything = inRange InfiniteRange
tests_inRange = testGroup "inRange Function"
[ testProperty "equal singletons in range" prop_singleton_in_range
, testProperty "unequal singletons not in range" prop_singleton_not_in_range
, testProperty "spans contain values in their middles" prop_span_contains
, testProperty "infinite ranges contain everything" prop_infinite_range_contains_everything
]
-- an intersection of a value followed by a union of that value should be the identity.
-- This is false. An intersection of a value followed by a union of that value should be
-- the value itself.
-- (1, 3) union (3, 4) => (1, 4)
-- (1, 3) intersection (3, 4) = (3, 3)
-- ((1, 3) intersection (3, 4)) union (3, 4) => (3, 4)
prop_in_range_out_of_range_after_invert :: (Integer, [Range Integer]) -> Bool
prop_in_range_out_of_range_after_invert (point, ranges) =
(inRanges ranges point) /= (inRanges (invert ranges) point)
test_ranges_invert = testGroup "invert function for ranges"
[ testProperty "element in range is now out of range after invert" prop_in_range_out_of_range_after_invert
]
prop_equivalence_eval_and_evalPredicate :: ([Integer], Alg.RangeExpr [Range Integer]) -> Bool
prop_equivalence_eval_and_evalPredicate (points, expr) = actual == expected
where
actual = map (inRanges $ Alg.eval expr) points
expected = map (Alg.eval $ fmap inRanges expr) points
test_algebra_equivalence = testGroup "algebra equivalence"
[ testProperty "eval and evalPredicate" prop_equivalence_eval_and_evalPredicate
]
--tests :: [Test]
tests =
[ tests_inRange
, test_ranges_invert
, test_algebra_equivalence
]
++ rangeMergeTestCases
++ rangeLawTestCases
++ rangeParserTestCases
++ rangeOrdTestCases
main = defaultMain tests