dbus-core-0.4: 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.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 -> a) -> Gen a
clampedSize maxSize gen f = do
s <- gen
if length s > maxSize
then sized (\n -> resize (n `div` 2) arbitrary)
else return . f $ s
instance Arbitrary ObjectPath where
coarbitrary = undefined
arbitrary = fmap 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 (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 $ DictionaryT kt vt
2 -> sized structType
3 -> return VariantT
structType n | n >= 0 = fmap StructureT $ 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 = mkSignature' . typeString $ kt
let vSig = 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)
DictionaryT _ _ -> fmap toVariant (arbitrary :: Gen Dictionary)
StructureT _ -> 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