2012-10-10 5 views
16

Dire che voglio scrivere alcuni test unitari per la funzione (!!).Come dire a QuickCheck di generare solo indici di lista validi per un parametro?

my_prop xs n = ... 

voglio limitare n ai soli indici validi e so che potrei fare qualcosa di simile

my_prop xs n = (not.null) (drop n xs) ==> ... 

Ma questo fa in modo che la stragrande maggioranza dei casi generati non sono validi e avere buttato via . C'è un modo per impostare le cose in modo che QuickCheck generi prima l'elenco xs e utilizzi il suo valore per generare solo casi validi di n?

+1

Crea un nuovo tipo che contiene un elenco e un 'Int' con un'istanza appropriata' Arbitraria'. –

risposta

17

Utilizzando forAll, è possibile specificare un generator per n che dipende dagli argomenti precedenti, ad es.

my_prop (NonEmpty xs) = forAll (choose (0, length xs - 1)) $ \n -> ... 
+0

Neat. Se ho bisogno di due indici nella propety, come posso passare un Gen (Int, Int) a forAll? La mia soluzione attuale è nidificata per Tutto così: 'forAll (indici xs) $ \ x -> forAll (indici xs) $ \ y -> ...' (usando la definizione degli indici di Daniel Fischer vista in un'altra risposta). – Arild

10

si può fare un generatore che crea solo gli indici validi e scrivere la vostra proprietà come

import Test.QuickCheck 
import Test.QuickCheck.Gen 
import System.Random 

indices :: [a] -> Gen Int 
indices xs = MkGen $ \sg _ -> fst $ randomR (0, length xs - 1) sg 

my_prop :: [Char] -> Property 
my_prop xs = not (null xs) ==> forAll (indices xs) (\i -> xs !! i /= '0') 

eliminando l'argomento Int.

5

Come suggerito da Daniel Wagner, una possibilità è la creazione di mio proprio tipo di dati e dandogli un'istanza Arbitrary.

data ListAndIndex a = ListAndIndex [a] Int deriving (Show) 

instance Arbitrary a => Arbitrary (ListAndIndex a) where 
    arbitrary = do 
    (NonEmpty xs) <- arbitrary 
    n <- elements [0..(length xs - 1)] 
    return $ ListAndIndex xs n 

NonEmpty da un tipo personalizzato in Test.QuickCheck.Modifiers per generare liste non vuote.