-- |
-- Module      : Test.FitSpec.Main
-- Copyright   : (c) 2015-2017 Rudy Matela
-- License     : 3-Clause BSD  (see the file LICENSE)
-- Maintainer  : Rudy Matela <rudy@matela.com.br>
--
-- Exports "main" functions for FitSpec.
-- They work exactly by 'report' and 'reportWith' but can be customized by
-- command line arguments.
--
-- > main = mainWith args { ... } functions properties
{-# Language DeriveDataTypeable, StandaloneDeriving #-}
module Test.FitSpec.Main
  ( mainWith
  , defaultMain
  , getArgs
  , getArgsWith
  , module Test.FitSpec.Report -- deprecated export, remove later
  )
where

import Test.FitSpec.Report
import System.Console.CmdArgs hiding (args)
import qualified System.Console.CmdArgs as CA (args)
import Control.Monad (liftM)
import Test.FitSpec.Mutable
import Test.FitSpec.ShowMutable

deriving instance Data ShowMutantAs
deriving instance Data Args
deriving instance Typeable ShowMutantAs
deriving instance Typeable Args

annotate :: Args -> Args
annotate :: Args -> Args
annotate Args
as = Args :: Int
-> Int
-> Int
-> [String]
-> Bool
-> ShowMutantAs
-> Maybe Int
-> [String]
-> Args
Args
  { nMutants :: Int
nMutants     = Args -> Int
nMutants     Args
as  Int -> Ann -> Int
forall val. Data val => val -> Ann -> val
&= String -> Ann
name String
"m"
      Int -> Ann -> Int
forall val. Data val => val -> Ann -> val
&= String -> Ann
help String
"(starting) number of function mutations"
  , nTests :: Int
nTests       = Args -> Int
nTests       Args
as  Int -> Ann -> Int
forall val. Data val => val -> Ann -> val
&= String -> Ann
name String
"n"
      Int -> Ann -> Int
forall val. Data val => val -> Ann -> val
&= String -> Ann
help String
"(starting) number of test values (each prop.)"
  , timeout :: Int
timeout      = Args -> Int
timeout      Args
as  Int -> Ann -> Int
forall val. Data val => val -> Ann -> val
&= String -> Ann
name String
"t" Int -> Ann -> Int
forall val. Data val => val -> Ann -> val
&= String -> Ann
name String
"s"
      Int -> Ann -> Int
forall val. Data val => val -> Ann -> val
&= String -> Ann
help String
"timeout in seconds, 0 for just T*M"
  , names :: [String]
names        = Args -> [String]
names        Args
as
      [String] -> Ann -> [String]
forall val. Data val => val -> Ann -> val
&= Ann
ignore
  , rows :: Maybe Int
rows         = Args -> Maybe Int
rows         Args
as
      Maybe Int -> Ann -> Maybe Int
forall val. Data val => val -> Ann -> val
&= String -> Ann
help String
"how many rows of results to show"
  , verbose :: Bool
verbose      = Args -> Bool
verbose      Args
as
      Bool -> Ann -> Bool
forall val. Data val => val -> Ann -> val
&= String -> Ann
help String
"activate verbose output"
  , showMutantAs :: ShowMutantAs
showMutantAs = Args -> ShowMutantAs
showMutantAs Args
as  ShowMutantAs -> Ann -> ShowMutantAs
forall val. Data val => val -> Ann -> val
&= String -> Ann
name String
"a"
      ShowMutantAs -> Ann -> ShowMutantAs
forall val. Data val => val -> Ann -> val
&= String -> Ann
help String
"how to show mutants (tuple / nestedtuple / definition / bindings)"
      ShowMutantAs -> Ann -> ShowMutantAs
forall val. Data val => val -> Ann -> val
&= String -> Ann
typ  String
"type"
  , extra :: [String]
extra        = Args -> [String]
extra        Args
as  [String] -> Ann -> [String]
forall val. Data val => val -> Ann -> val
&= Ann
CA.args
      [String] -> Ann -> [String]
forall val. Data val => val -> Ann -> val
&= String -> Ann
typ String
"extra arguments"
  } Args -> Ann -> Args
forall val. Data val => val -> Ann -> val
&= String -> Ann
summary String
"FitSpec"
    Args -> Ann -> Args
forall val. Data val => val -> Ann -> val
&= String -> Ann
program String
"program"
    Args -> Ann -> Args
forall val. Data val => val -> Ann -> val
&= String -> Ann
help String
"Refine property-sets for functional testing"

getArgsWith :: Args -> IO Args
getArgsWith :: Args -> IO Args
getArgsWith = Args -> IO Args
forall a. Data a => a -> IO a
cmdArgs (Args -> IO Args) -> (Args -> Args) -> Args -> IO Args
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Args -> Args
annotate

getArgs :: IO Args
getArgs :: IO Args
getArgs = Args -> IO Args
getArgsWith Args
args

-- | Same as 'reportWith', but allow overriding of configuration via command
--   line arguments.
mainWith :: (Mutable a, ShowMutable a)
         => Args
         -> a -> (a -> [Property]) -> IO ()
mainWith :: Args -> a -> (a -> [Property]) -> IO ()
mainWith Args
as a
f a -> [Property]
ps = do
  Args
as' <- Args -> IO Args
getArgsWith Args
as
  Args -> a -> (a -> [Property]) -> IO ()
forall a.
(Mutable a, ShowMutable a) =>
Args -> a -> (a -> [Property]) -> IO ()
reportWith Args
as' a
f a -> [Property]
ps

-- | Same as 'report', but allow configuration via command line arguments.
defaultMain :: (Mutable a, ShowMutable a)
            => a -> (a -> [Property]) -> IO ()
defaultMain :: a -> (a -> [Property]) -> IO ()
defaultMain = Args -> a -> (a -> [Property]) -> IO ()
forall a.
(Mutable a, ShowMutable a) =>
Args -> a -> (a -> [Property]) -> IO ()
mainWith Args
args