QuickCheckVariant-0.1.1.0: src/Test/QuickCheck/Variant.hs
{-# OPTIONS_GHC -fno-warn-tabs #-}
{-|
Module : Test.QuickCheck.Variant
Description : Varaint class
Copyright : (c) Jorge Santiago Alvarez Cuadros, 2015
License : GPL-3
Maintainer : sanjorgek@ciencias.unam.mx
Stability : experimental
Portability : portable
To get random "invalid" and "valid" data
-}
module Test.QuickCheck.Variant where
import Test.QuickCheck
{-|
You can define
>>> instance (Varaint a) => Arbitrary a where {arbitrary = oneof [valid, invalid]}
-}
class Variant a where
-- |Get a generator of valid random data type
valid :: Gen a
-- |Get a generator of invalid random data type
invalid :: Gen a
{-|
Variant of a list.
A valid list only had valid data.
A invalid list had only invalid data or some valid data with invalid data.
-}
instance (Variant a) => Variant [a] where
valid = do
x <- valid
xs <- valid
(oneof . map return) [[], [x], x:xs]
invalid = do
x <- invalid
xs <- invalid
y <- valid
ys <- valid
(oneof . map return) [[x], x:xs, x:ys, y:xs]
{-|
Variant Maybe
Only Just data can be invalid, nothing always is valid.
-}
instance (Variant a) => Variant (Maybe a) where
invalid = do
x <- invalid
return (Just x)
valid = do
x <- valid
(oneof . map return) [Nothing, Just x]
{-|
Varaint Either.
-}
instance (Variant a, Variant b) => Variant (Either a b) where
invalid = do
x <- invalid
y <- invalid
(oneof . map return) [Left x, Right y]
valid = do
x <- valid
y <- valid
(oneof . map return) [Left x, Right y]
{-|
Varaint tuple
Invalid tuple may had some valid data with invalid data or only invalid data.
Valid tuple had only valid data.
-}
instance (Variant a, Variant b) => Variant ((,) a b) where
invalid = do
x <- invalid
y <- invalid
z <- valid
w <- valid
(oneof . map return) [(x,y), (x,z), (w,y)]
valid = do
x <- valid
y <- valid
return (x, y)
{-|
Varaint 3-tuple
Invalid 3-tuple may had some valid data with invalid data or only invalid data.
Valid 3-tuple had only valid data.
-}
instance (Variant a, Variant b, Variant c) => Variant ((,,) a b c) where
invalid = do
x <- invalid
y <- invalid
z <- invalid
w <- valid
v <- valid
u <- valid
(oneof . map return) [(x,y,z), (x,y,u), (x,v,z), (w,y,z), (w,v,z), (x,v,u), (w,y,u)]
valid = do
x <- valid
y <- valid
z <- valid
return (x, y, z)
{-|
The class of things wich can be tested with invalid or valid input.
-}
class VarTesteable prop where
-- |Property for valid input
propertyValid::prop -> Property
-- |Property for invalid input
propertyInvalid::prop -> Property
{-|
Same as Testeable
-}
instance VarTesteable Bool where
propertyValid = property
propertyInvalid = property
{-|
Instead of variant we use valid or invalid generators
-}
instance (Arbitrary a, Variant a, Show a, Testable prop) => VarTesteable (a->prop) where
propertyValid = forAllShrink valid shrink
propertyInvalid = forAllShrink invalid shrink