module Test.Sloth.TestCase
(
Mapping(..), mapping,
TestCase(..), showTestCase, isFailure, isValid
) where
import Control.Monad.Writer ( execWriter, Writer )
import Data.Monoid ( Sum(..) )
import Data.Data ( Data )
import Test.Sloth.CoMonad
import Test.Sloth.PVal ( PVal, toPVal, showsPrecPValWithSub, isBottom,
simplifyPos, mapPoly )
import Test.Sloth.Pos ( Pos )
import Test.Sloth.Search ( Search, isComplete, SearchT(..), isCompleteT )
import Test.Sloth.Config ( Config(..) )
import Test.Sloth.Color ( Color(..), showColor )
data Mapping = Mapping { argument :: PVal, result :: PVal }
instance Show Mapping where
show (Mapping pv fpv) = "\\" ++ showsPrec 11 pv " -> " ++ show fpv
mapping :: (Data a,Data b) => (a -> b) -> a -> Mapping
mapping f v = Mapping pv fpv
where
pv = toPVal v
fpv = toPVal (f v)
data TestCase = TestCase Mapping [(Pos,SearchT (Writer (Sum Int)) PVal)]
showTestCase :: Config -> Search TestCase -> String
showTestCase config stc = showTC (extract stc) ""
where
showTC (TestCase (Mapping pv fpv) l) =
showsTestCase (detailed config)
(isComplete stc)
(showsPrec 11 pv')
(showsPrec 0 fpv')
(showsPrecPValWithSub sub 0 fpv')
where
(pv',f) = simplifyPos pv
fpv' = mapPoly f fpv
sub = map (fmap (showsPrecSearchPVal config . fmap (mapPoly f))) l
showsTestCase :: Bool -> Bool -> ShowS -> ShowS -> ShowS -> ShowS
showsTestCase detail definite arg current proposed
| detail =
showString (if definite then "Argument(s): " else "Potential Argument(s): ")
. arg
. showString "\nCurrent Result: " . current
. showString "\nProposed Result: " . proposed
| otherwise =
(if definite then id else showColor Blue)
(showString "\\" . arg . showString " -> " . proposed)
showsPrecSearchPVal :: Config -> SearchT (Writer (Sum Int)) PVal -> Int -> ShowS
showsPrecSearchPVal config searcht prec
| not (colored config) = showsPrec prec pv
| samples == 0 = showChar '?'
| isBottom pv = showColor Green (shows pv)
| isCompleteT searcht = showColor Red (showsPrec prec pv)
| samples < minSamples = showChar '?'
| otherwise = showColor Magenta (showsPrec prec pv)
where
samples = getSum (execWriter (runSearchT searcht))
pv = extract searcht
minSamples = minInfSize config
isFailure :: Config -> TestCase -> Bool
isFailure _ (TestCase _ []) = False
isFailure config (TestCase _ l) =
any (\(_,s) -> not (isBottom (extract s))
&& (isCompleteT s || getSum (execWriter (runSearchT s)) >= minSamples)) l
where
minSamples = minInfSize config
isValid :: Config -> TestCase -> Bool
isValid config (TestCase _ []) = noBottomPos config
isValid config testcase = successes config || isFailure config testcase