dbus-core-0.2: Tests/Instances.hs
{-
Copyright (C) 2009 John Millikin <jmillikin@gmail.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
-}
module Tests.Instances (sized') where
import Control.Monad (replicateM)
import Data.List (intercalate)
import Data.Maybe (fromJust)
import Data.Word (Word8, Word16, Word32, Word64)
import Data.Int (Int16, Int32, Int64)
import Test.QuickCheck
import DBus.Types
instance Arbitrary Char where
coarbitrary = undefined
arbitrary = choose ('!', '~') -- TODO: unicode?
instance Arbitrary Word8 where
coarbitrary = undefined
arbitrary = gen where
gen = fmap fromIntegral (choose (0, max') :: Gen Integer)
max' = iexp 2 8 - 1
instance Arbitrary Word16 where
coarbitrary = undefined
arbitrary = gen where
gen = fmap fromIntegral (choose (0, max') :: Gen Integer)
max' = iexp 2 16 - 1
instance Arbitrary Word32 where
coarbitrary = undefined
arbitrary = gen where
gen = fmap fromIntegral (choose (0, max') :: Gen Integer)
max' = iexp 2 32 - 1
instance Arbitrary Word64 where
coarbitrary = undefined
arbitrary = gen where
gen = fmap fromIntegral (choose (0, max') :: Gen Integer)
max' = iexp 2 64 - 1
instance Arbitrary Int16 where
coarbitrary = undefined
arbitrary = gen where
gen = fmap fromIntegral (choose (0, max') :: Gen Integer)
max' = iexp 2 16 - 1
instance Arbitrary Int32 where
coarbitrary = undefined
arbitrary = gen where
gen = fmap fromIntegral (choose (0, max') :: Gen Integer)
max' = iexp 2 32 - 1
instance Arbitrary Int64 where
coarbitrary = undefined
arbitrary = gen where
gen = fmap fromIntegral (choose (0, max') :: Gen Integer)
max' = iexp 2 64 - 1
sized' :: Int -> Gen a -> Gen [a]
sized' atLeast g = sized $ \n -> do
n' <- choose (atLeast, max atLeast n)
replicateM n' g
clampedSize :: Arbitrary a => Int -> Gen String -> (String -> Maybe a) -> Gen a
clampedSize maxSize gen f = do
s <- gen
if length s > maxSize
then sized (\n -> resize (n `div` 2) arbitrary)
else return . fromJust . f $ s
instance Arbitrary ObjectPath where
coarbitrary = undefined
arbitrary = fmap (fromJust . mkObjectPath) path' where
c = ['a'..'z'] ++ ['A'..'Z'] ++ ['0'..'9'] ++ "_"
path = fmap (intercalate "/" . ([] :)) genElements
path' = frequency [(1, return "/"), (9, path)]
genElements = sized' 1 (sized' 1 (elements c))
instance Arbitrary InterfaceName where
coarbitrary = undefined
arbitrary = clampedSize 255 genName mkInterfaceName where
c = ['a'..'z'] ++ ['A'..'Z'] ++ "_"
c' = c ++ ['0'..'9']
genName = fmap (intercalate ".") genElements
genElements = sized' 2 genElement
genElement = do
x <- elements c
xs <- sized' 0 (elements c')
return (x:xs)
instance Arbitrary BusName where
coarbitrary = undefined
arbitrary = clampedSize 255 (oneof [unique, wellKnown]) mkBusName where
c = ['a'..'z'] ++ ['A'..'Z'] ++ "_-"
c' = c ++ ['0'..'9']
unique = do
elems' <- sized' 2 $ elems c'
return $ ':' : intercalate "." elems'
wellKnown = do
elems' <- sized' 2 $ elems c
return $ intercalate "." elems'
elems start = do
x <- elements start
xs <- sized' 0 (elements c')
return (x:xs)
instance Arbitrary MemberName where
coarbitrary = undefined
arbitrary = clampedSize 255 genName mkMemberName where
c = ['a'..'z'] ++ ['A'..'Z'] ++ "_"
c' = c ++ ['0'..'9']
genName = do
x <- elements c
xs <- sized' 0 (elements c')
return (x:xs)
instance Arbitrary ErrorName where
coarbitrary = undefined
arbitrary = fmap (fromJust . mkErrorName . strInterfaceName) arbitrary
instance Arbitrary Type where
coarbitrary = undefined
arbitrary = oneof [atomicType, containerType]
instance Arbitrary Signature where
coarbitrary = undefined
arbitrary = clampedSize 255 genSig mkSignature where
genSig = fmap (concatMap typeString) arbitrary
atomicType = elements
[ BooleanT
, ByteT
, UInt16T
, UInt32T
, UInt64T
, Int16T
, Int32T
, Int64T
, DoubleT
, StringT
, ObjectPathT
, SignatureT
]
containerType = do
c <- choose (0,3) :: Gen Int
case c of
0 -> fmap ArrayT arbitrary
1 -> do
kt <- atomicType
vt <- arbitrary
return $ DictT kt vt
2 -> sized structType
3 -> return VariantT
structType n | n >= 0 = fmap StructT $ resize (n `div` 2) arbitrary
instance Arbitrary Atom where
coarbitrary = undefined
arbitrary = atomicType >>= \t -> case t of
BooleanT -> fmap toAtom (arbitrary :: Gen Bool)
ByteT -> fmap toAtom (arbitrary :: Gen Word8)
UInt16T -> fmap toAtom (arbitrary :: Gen Word16)
UInt32T -> fmap toAtom (arbitrary :: Gen Word32)
UInt64T -> fmap toAtom (arbitrary :: Gen Word64)
Int16T -> fmap toAtom (arbitrary :: Gen Int16)
Int32T -> fmap toAtom (arbitrary :: Gen Int32)
Int64T -> fmap toAtom (arbitrary :: Gen Int64)
DoubleT -> fmap toAtom (arbitrary :: Gen Double)
StringT -> fmap toAtom (arbitrary :: Gen String)
ObjectPathT -> fmap toAtom (arbitrary :: Gen ObjectPath)
SignatureT -> fmap toAtom (arbitrary :: Gen Signature)
instance Arbitrary Array where
coarbitrary = undefined
arbitrary = do
-- Only generate arrays of atomic values, as generating
-- containers randomly almost never results in a valid
-- array.
x <- atomicType >>= \t -> case t of
BooleanT -> fmap toArray (arbitrary :: Gen [Bool])
ByteT -> fmap toArray (arbitrary :: Gen [Word8])
UInt16T -> fmap toArray (arbitrary :: Gen [Word16])
UInt32T -> fmap toArray (arbitrary :: Gen [Word32])
UInt64T -> fmap toArray (arbitrary :: Gen [Word64])
Int16T -> fmap toArray (arbitrary :: Gen [Int16])
Int32T -> fmap toArray (arbitrary :: Gen [Int32])
Int64T -> fmap toArray (arbitrary :: Gen [Int64])
DoubleT -> fmap toArray (arbitrary :: Gen [Double])
StringT -> fmap toArray (arbitrary :: Gen [String])
ObjectPathT -> fmap toArray (arbitrary :: Gen [ObjectPath])
SignatureT -> fmap toArray (arbitrary :: Gen [Signature])
maybe arbitrary return x
instance Arbitrary Dictionary where
coarbitrary = undefined
arbitrary = do
-- Only generate dictionaries of atomic values, as generating
-- containers randomly almost never results in a valid
-- array.
kt <- atomicType
vt <- atomicType
ks <- case kt of
BooleanT -> fmap (map toAtom) (arbitrary :: Gen [Bool])
ByteT -> fmap (map toAtom) (arbitrary :: Gen [Word8])
UInt16T -> fmap (map toAtom) (arbitrary :: Gen [Word16])
UInt32T -> fmap (map toAtom) (arbitrary :: Gen [Word32])
UInt64T -> fmap (map toAtom) (arbitrary :: Gen [Word64])
Int16T -> fmap (map toAtom) (arbitrary :: Gen [Int16])
Int32T -> fmap (map toAtom) (arbitrary :: Gen [Int32])
Int64T -> fmap (map toAtom) (arbitrary :: Gen [Int64])
DoubleT -> fmap (map toAtom) (arbitrary :: Gen [Double])
StringT -> fmap (map toAtom) (arbitrary :: Gen [String])
ObjectPathT -> fmap (map toAtom) (arbitrary :: Gen [ObjectPath])
SignatureT -> fmap (map toAtom) (arbitrary :: Gen [Signature])
vs <- case vt of
BooleanT -> fmap (map toVariant) (arbitrary :: Gen [Bool])
ByteT -> fmap (map toVariant) (arbitrary :: Gen [Word8])
UInt16T -> fmap (map toVariant) (arbitrary :: Gen [Word16])
UInt32T -> fmap (map toVariant) (arbitrary :: Gen [Word32])
UInt64T -> fmap (map toVariant) (arbitrary :: Gen [Word64])
Int16T -> fmap (map toVariant) (arbitrary :: Gen [Int16])
Int32T -> fmap (map toVariant) (arbitrary :: Gen [Int32])
Int64T -> fmap (map toVariant) (arbitrary :: Gen [Int64])
DoubleT -> fmap (map toVariant) (arbitrary :: Gen [Double])
StringT -> fmap (map toVariant) (arbitrary :: Gen [String])
ObjectPathT -> fmap (map toVariant) (arbitrary :: Gen [ObjectPath])
SignatureT -> fmap (map toVariant) (arbitrary :: Gen [Signature])
let kSig = fromJust . mkSignature . typeString $ kt
let vSig = fromJust . mkSignature . typeString $ vt
maybe arbitrary return (dictionaryFromItems kSig vSig (zip ks vs))
instance Arbitrary Structure where
coarbitrary = undefined
arbitrary = sized $ \n ->
fmap Structure $ resize (n `div` 2) arbitrary
instance Arbitrary Variant where
coarbitrary = undefined
arbitrary = arbitrary >>= \t -> case t of
BooleanT -> fmap toVariant (arbitrary :: Gen Bool)
ByteT -> fmap toVariant (arbitrary :: Gen Word8)
UInt16T -> fmap toVariant (arbitrary :: Gen Word16)
UInt32T -> fmap toVariant (arbitrary :: Gen Word32)
UInt64T -> fmap toVariant (arbitrary :: Gen Word64)
Int16T -> fmap toVariant (arbitrary :: Gen Int16)
Int32T -> fmap toVariant (arbitrary :: Gen Int32)
Int64T -> fmap toVariant (arbitrary :: Gen Int64)
DoubleT -> fmap toVariant (arbitrary :: Gen Double)
StringT -> fmap toVariant (arbitrary :: Gen String)
ObjectPathT -> fmap toVariant (arbitrary :: Gen ObjectPath)
SignatureT -> fmap toVariant (arbitrary :: Gen Signature)
ArrayT _ -> fmap toVariant (arbitrary :: Gen Array)
DictT _ _ -> fmap toVariant (arbitrary :: Gen Dictionary)
StructT _ -> fmap toVariant (arbitrary :: Gen Structure)
VariantT -> fmap toVariant (arbitrary :: Gen Variant)
instance Arbitrary Endianness where
coarbitrary = undefined
arbitrary = elements [LittleEndian, BigEndian]
instance Arbitrary Serial where
coarbitrary = undefined
arbitrary = fmap Serial arbitrary
iexp :: Integral a => a -> a -> a
iexp x y = floor $ fromIntegral x ** fromIntegral y