Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/Test/Mutagen.hs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
-- | Convenience module re-exporting all public test modules
-- | Convenience module re-exporting all public test modules.
module Test.Mutagen
( module Test.Mutagen.Config
, module Test.Mutagen.Test.Driver
Expand Down
24 changes: 12 additions & 12 deletions src/Test/Mutagen/Config.hs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}

-- | Configuration options for Mutagen
-- | Configuration options for Mutagen.
module Test.Mutagen.Config
( -- * Configuration options
Config (..)
Expand Down Expand Up @@ -34,7 +34,7 @@ import Test.Mutagen.Tracer.Store (TraceBackend (..))
-- * Configuration options
-------------------------------------------------------------------------------}

-- | Configuration options for Mutagen
-- | Configuration options for Mutagen.
data Config
= Config
{ maxSuccess :: Int
Expand Down Expand Up @@ -118,7 +118,7 @@ data Config
-- ^ Whether to use a terminal user interface (TUI) for displaying progress.
}

-- | Default configuration options for Mutagen
-- | Default configuration options for Mutagen.
defaultConfig :: Config
defaultConfig =
Config
Expand Down Expand Up @@ -149,34 +149,34 @@ defaultConfig =
-- * Helpers
-------------------------------------------------------------------------------}

-- | Allow a type to be saved in the fragment store
-- | Allow a type to be saved in the fragment store.
allow :: forall a. (Typeable a) => FragmentTypeFilter
allow = FragmentTypeFilter (Set.singleton (typeRep (Proxy @a))) mempty

-- | Like 'allow' but taking a t'Proxy' argument
-- | Like 'allow' but taking a t'Proxy' argument.
allow' :: forall a. (Typeable a) => Proxy a -> FragmentTypeFilter
allow' _ = allow @a

-- | Deny a type from being saved in the fragment store
-- | Deny a type from being saved in the fragment store.
deny :: forall a. (Typeable a) => FragmentTypeFilter
deny = FragmentTypeFilter mempty (Set.singleton (typeRep (Proxy @a)))

-- | Like 'deny' but taking a t'Proxy' argument
-- | Like 'deny' but taking a t'Proxy' argument.
deny' :: forall a. (Typeable a) => Proxy a -> FragmentTypeFilter
deny' _ = deny @a

-- | Helper to create an example input of any supported argument type
-- | Helper to create an example input of any supported argument type.
example :: forall a. (IsArgs a) => a -> Args
example = Args

-- | Debugging mode
-- | Debugging mode.
--
-- Allows stopping the loop between test cases to inspect the internal state.
data DebugMode
= -- | Run normally without stopping between tests
= -- | Run normally without stopping between tests.
NoDebug
| -- | Stop after every passed test case
| -- | Stop after every passed test case.
StopOnPassed
| -- | Stop after every test case (passed or discarded)
| -- | Stop after every test case (passed or discarded).
AlwaysStop
deriving (Eq, Show)
14 changes: 7 additions & 7 deletions src/Test/Mutagen/Exception.hs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
-- | Exception handling utilities
-- | Exception handling utilities.
module Test.Mutagen.Exception
( -- * Exception handling utilities
AnException
Expand All @@ -17,14 +17,14 @@ import qualified Control.Exception as Exception
-- * Exception handling utilities
-------------------------------------------------------------------------------}

-- | A general exception type
-- | A general exception type.
type AnException = Exception.SomeException

-- | Evaluate a value to weak head normal form, catching any exceptions
-- | Evaluate a value to weak head normal form, catching any exceptions.
tryEvaluate :: a -> IO (Either AnException a)
tryEvaluate x = tryEvaluateIO (return x)

-- | Evaluate an IO action to weak head normal form, catching any exceptions
-- | Evaluate an IO action to weak head normal form, catching any exceptions.
tryEvaluateIO :: IO a -> IO (Either AnException a)
tryEvaluateIO m =
Exception.tryJust notAsync (m >>= Exception.evaluate)
Expand All @@ -34,12 +34,12 @@ tryEvaluateIO m =
Just (Exception.SomeAsyncException _) -> Nothing
Nothing -> Just e

-- | Evaluate a value to weak head normal form
-- | Evaluate a value to weak head normal form.
evaluate :: a -> IO a
evaluate = Exception.evaluate

-- | Ensure that a cleanup action is run after an IO action, even if
-- an exception is thrown
-- an exception is thrown.
finally :: IO a -> IO b -> IO a
finally = Exception.finally

Expand All @@ -50,7 +50,7 @@ finally = Exception.finally
discard :: a
discard = error discardMsg

-- | Predicate to check whether an exception is our special 'discard'
-- | Predicate to check whether an exception is our special 'discard'.
isDiscard :: AnException -> Bool
isDiscard e =
case Exception.fromException e of
Expand Down
12 changes: 6 additions & 6 deletions src/Test/Mutagen/Fragment.hs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}

-- | Test case fragments and fragment stores
-- | Test case fragments and fragment stores.
module Test.Mutagen.Fragment
( -- * Fragments and Fragmentable class
IsFragment
Expand All @@ -25,10 +25,10 @@ import Data.Word (Word16, Word32, Word64, Word8)
-- * Fragments and Fragmentable class
-------------------------------------------------------------------------------}

-- | Fragment type class constraint
-- | Fragment type class constraint.
type IsFragment a = (Typeable a, Ord a, Show a)

-- | A test case fragment hidden behind an existential
-- | A test case fragment hidden behind an existential.
data Fragment = forall a. (IsFragment a) => Fragment a

instance Eq Fragment where
Expand All @@ -46,15 +46,15 @@ instance Ord Fragment where
instance Show Fragment where
show (Fragment a) = "Fragment(" <> show a <> ")"

-- | Turn an entire value into a singleton fragment set
-- | Turn an entire value into a singleton fragment set.
singleton :: (IsFragment a) => a -> Set Fragment
singleton = Set.singleton . Fragment

-- ** Fragmentable class

-- | Types that can be fragmented into smaller pieces
-- | Types that can be fragmented into smaller pieces.
class (IsFragment a) => Fragmentable a where
-- | Extract fragments from a value
-- | Extract fragments from a value.
fragmentize :: a -> Set Fragment
fragmentize = singleton

Expand Down
18 changes: 9 additions & 9 deletions src/Test/Mutagen/Fragment/Store.hs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
-- | Type-indexed fragment store for collecting and sampling fragments from
-- | Type-indexed fragment store for collecting and sampling fragments from.
module Test.Mutagen.Fragment.Store
( -- * Type-indexed fragment store
FragmentStore (..)
Expand Down Expand Up @@ -26,7 +26,7 @@ import Test.QuickCheck (Gen, shuffle)
-- * Type-indexed fragment store
-------------------------------------------------------------------------------}

-- | A collection of fragments indexed by their type representation
-- | A collection of fragments indexed by their type representation.
newtype FragmentStore = FragmentStore (Map TypeRep (Set Fragment))

instance Semigroup FragmentStore where
Expand All @@ -36,18 +36,18 @@ instance Semigroup FragmentStore where
instance Monoid FragmentStore where
mempty = emptyFragmentStore

-- | An empty fragment store
-- | An empty fragment store.
emptyFragmentStore :: FragmentStore
emptyFragmentStore = FragmentStore mempty

-- | Get the number of fragments stored for each type
-- | Get the number of fragments stored for each type.
fragmentStoreSize :: FragmentStore -> [(TypeRep, Int)]
fragmentStoreSize (FragmentStore fs) =
[ (tyRep, Set.size frags)
| (tyRep, frags) <- Map.toList fs
]

-- | Store fragments from a value into the fragment store
-- | Store fragments from a value into the fragment store.
storeFragments
:: (Fragmentable a)
=> FragmentTypeFilter
Expand All @@ -65,7 +65,7 @@ storeFragments typeFilter a (FragmentStore store) =
| otherwise =
store'

-- | Sample fragments of the same type as the given value from a fragment store
-- | Sample fragments of the same type as the given value from a fragment store.
sampleFragments
:: (Typeable a)
=> a
Expand All @@ -78,7 +78,7 @@ sampleFragments a (FragmentStore store) = do
Just frags ->
mapMaybe (\(Fragment a') -> cast a') <$> shuffle (Set.toList frags)

-- | Print the contents of a fragment store for debugging purposes
-- | Print the contents of a fragment store for debugging purposes.
printFragmentStore :: FragmentStore -> IO ()
printFragmentStore (FragmentStore fs) = do
forM_ (Map.assocs fs) $ \(tyRep, frags) -> do
Expand All @@ -88,7 +88,7 @@ printFragmentStore (FragmentStore fs) = do

-- ** Fragment type filters

-- | Fragment type allow and deny lists
-- | Fragment type allow and deny lists.
data FragmentTypeFilter = FragmentTypeFilter
{ allowList :: Set TypeRep
-- ^ List of allowed fragment types
Expand All @@ -104,7 +104,7 @@ instance Semigroup FragmentTypeFilter where
instance Monoid FragmentTypeFilter where
mempty = FragmentTypeFilter mempty mempty

-- | Check if a type is allowed by the fragment type filter
-- | Check if a type is allowed by the fragment type filter.
isFragmentTypeAllowed :: FragmentTypeFilter -> TypeRep -> Bool
isFragmentTypeAllowed (FragmentTypeFilter allow deny) tr =
(tr `Set.member` allow)
Expand Down
16 changes: 8 additions & 8 deletions src/Test/Mutagen/Lazy.hs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{-# LANGUAGE BangPatterns #-}

-- | Tracking lazy evaluation of expressions
-- | Tracking lazy evaluation of expressions.
module Test.Mutagen.Lazy
( -- * Lazy evaluation tracking interface
__evaluated__
Expand All @@ -23,36 +23,36 @@ import Test.Mutagen.Mutation (Pos)
-- * Lazy evaluation tracking interface
-------------------------------------------------------------------------------}

-- | Injectable function to mark the evaluation an expression at some possition
-- | Injectable function to mark the evaluation an expression at some position.
__evaluated__ :: Pos -> a -> a
__evaluated__ pos expr =
unsafePerformIO $ do
addEvaluatedPos pos
return expr
{-# INLINE __evaluated__ #-}

-- | Global IORef to store evaluated positions
-- | Global IORef to store evaluated positions.
posRef :: IORef [Pos]
posRef = unsafePerformIO (newIORef [])
{-# NOINLINE posRef #-}

-- | Add evaluated position to the global IORef
-- | Add evaluated position to the global IORef.
addEvaluatedPos :: Pos -> IO ()
addEvaluatedPos pos = modifyIORef' posRef (reverse pos :)

-- | Reset the global IORef of evaluated positions
-- | Reset the global IORef of evaluated positions.
resetPosRef :: IO ()
resetPosRef = modifyIORef' posRef (const [])

-- | Read the global IORef of evaluated positions
-- | Read the global IORef of evaluated positions.
readPosRef :: IO [Pos]
readPosRef = reverse <$> readIORef posRef

{-------------------------------------------------------------------------------
-- * Lazy type class
-------------------------------------------------------------------------------}

-- | Class for types that can track lazy evaluation of their subexpressions
-- | Class for types that can track lazy evaluation of their subexpressions.
class Lazy a where
-- | Wrap an entire value (i.e., at every subexpression) with calls to
-- '__evaluated__' with their corresponding positions.
Expand Down Expand Up @@ -96,7 +96,7 @@ withLazy f a = do
ps <- readPosRef
return (ps, b)

-- | Like 'withLazy', but for functions that already run on IO
-- | Like 'withLazy', but for functions that already run on IO.
withLazyIO :: (Lazy a) => (a -> IO b) -> a -> IO ([Pos], b)
withLazyIO f a = do
resetPosRef
Expand Down
8 changes: 4 additions & 4 deletions src/Test/Mutagen/Mutant.hs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
-- | Abtract test case mutants and their concretization
-- | Abstract test case mutants and their concretization.
module Test.Mutagen.Mutant
( -- * Abstract mutants
Mutant (..)
Expand Down Expand Up @@ -46,15 +46,15 @@ instance Functor Mutant where
-- * Concretized test cases
-------------------------------------------------------------------------------}

-- | Kinds of concretized mutants
-- | Kinds of concretized mutants.
data MutantKind = PureMutant | RandMutant | FragMutant
deriving (Show)

-- | Values obtained by concretizing a mutant
-- | Values obtained by concretizing a mutant.
data Concretized a = Concretized MutantKind a
deriving (Show)

-- | Turn an abstract mutant into a concrete set of values
-- | Turn an abstract mutant into a concrete set of values.
concretize
:: (Typeable a)
=> (Int, Int)
Expand Down
Loading