-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | Check multiple items during a tasty test
--   
--   Allows the test to check a number of items during a test and only
--   signal pass or fail when the end if the checklist is reached.
--   
--   Also provides an easy method to check multiple derived values from a
--   single input value.
@package tasty-checklist
@version 1.0.4.0


-- | This package provides the ability to run a Checklist of several
--   "checks" during a single test. A "bad" check does not immediately
--   result in a test failure; at the end of the test (passed or failed due
--   to primary testing), all failed checks are reported (and any failed
--   checks will result in an overall test failure at the end.
--   
--   This type of checking can be very useful when needing to test various
--   aspects of an operation that is complex to setup, has multiple
--   effects, or where the checks are related such that knowing about the
--   multiple failures makes debugging easier.
--   
--   An alternative approach is to have some sort of common preparation
--   code and use a separate test for each item. This module simply
--   provides a convenient method to collate related items under the aegis
--   of a single test.
--   
--   This package also provides the <a>checkValues</a> function which can
--   be used to check a number of derived values from a single input value
--   via a checklist. This can be used to independently verify a number of
--   record fields of a data structure or to validate related operations
--   performed from a single input.
--   
--   See the documentation for <a>check</a> and <a>checkValues</a> for
--   examples of using this library. The tests in the source package also
--   provide additional examples of usage.
module Test.Tasty.Checklist

-- | This should be used to wrap the test that contains checks. This
--   initializes the environment needed for the checks to run, and on exit
--   from the test, reports any (and all) failed checks as a test failure.
withChecklist :: (MonadIO m, MonadMask m) => Text -> (CanCheck => m a) -> m a

-- | A convenient Constraint to apply to functions that will perform checks
--   (i.e. call <a>check</a> one or more times)
type CanCheck = (?checker :: IORef [CheckResult])

-- | This is used to run a check within the code. The first argument is the
--   "name" of this check, the second is a function that takes a value and
--   returns <a>True</a> if the value is OK, or <a>False</a> if the value
--   fails the check. The last argument is the value to check.
--   
--   <pre>
--   &gt;&gt;&gt; :set -XOverloadedStrings
--   
--   &gt;&gt;&gt; import Test.Tasty
--   
--   &gt;&gt;&gt; import Test.Tasty.HUnit
--   
--   &gt;&gt;&gt; :{
--   
--   &gt;&gt;&gt; defaultMain $ testCase "odd numbers" $ withChecklist "odds" $ do
--   
--   &gt;&gt;&gt; let three = 3 :: Int
--   
--   &gt;&gt;&gt; check "three is odd" odd three
--   
--   &gt;&gt;&gt; check "two is odd" odd (2 :: Int)
--   
--   &gt;&gt;&gt; check "7 + 3 is odd" odd $ 7 + three
--   
--   &gt;&gt;&gt; check "7 is odd" odd (7 :: Int)
--   
--   &gt;&gt;&gt; :}
--   odd numbers: FAIL
--     Exception: ERROR: odds
--       2 checks failed in this checklist:
--       -Failed check of two is odd with: 2
--       -Failed check of 7 + 3 is odd with: 10
--   
--   1 out of 1 tests failed (...s)
--   *** Exception: ExitFailure 1
--   </pre>
--   
--   Any check failures are also printed to stdout (and omitted from the
--   above for clarity). This is so that those failures are reported even
--   if a more standard test assertion is used that prevents completion of
--   the checklist. Thus, if an <tt>assertEqual "values" three 7</tt> had
--   been added to the above, that would have been the only actual (and
--   immediate) fail for the test, but any failing <a>check</a>s appearing
--   before that <tt>assertEqual</tt> would still have printed.
check :: (CanCheck, TestShow a, MonadIO m) => Text -> (a -> Bool) -> a -> m ()

-- | Sometimes checks are provided in common testing code, often in
--   setup/preparation for the main tests. In some cases, the check is not
--   applicable for that particular test. This function can be used to
--   discard any pending failures for the associated named check.
--   
--   This is especially useful when a common code block is used to perform
--   a set of checks: if a few of the common checks are not appropriate for
--   the current situation, <a>discardCheck</a> can be used to throw away
--   the results of those checks by matching on the check name.
discardCheck :: (CanCheck, MonadIO m) => Text -> m ()

-- | The <a>checkValues</a> is a checklist that tests various values that
--   can be derived from the input value. The input value is provided,
--   along with an <a>Assignment</a> list of extraction functions and the
--   expected result value (and name) of that extraction. Each extraction
--   is performed as a check within the checklist.
--   
--   This is convenient to gather together a number of validations on a
--   single datatype and represent them economically.
--   
--   One example is testing the fields of a record structure, given the
--   above code:
--   
--   <pre>
--   &gt;&gt;&gt; defaultMain test
--   someFun result: FAIL
--     Exception: ERROR: results for someFun
--       3 checks failed in this checklist:
--       -Failed check of foo on input &lt;&lt;The answer to the universe is 18?&gt;&gt;
--             expected:    42
--             failed with: 18
--       -Failed check of shown on input &lt;&lt;The answer to the universe is 18?&gt;&gt;
--             expected:    "The answer to the universe is 42!"
--             failed with: "The answer to the universe is 18?"
--       -Failed check of double-checking foo on input &lt;&lt;The answer to the universe is 18?&gt;&gt;
--             expected:    42
--             failed with: 18
--   
--   1 out of 1 tests failed (...s)
--   *** Exception: ExitFailure 1
--   </pre>
--   
--   In this case, several of the values checked were correct, but more
--   than one was wrong. Helpfully, this test output lists <i>all</i> the
--   wrong answers for the single input provided.
checkValues :: CanCheck => TestShow dType => dType -> Assignment (DerivedVal dType) idx -> IO ()

-- | Each entry in the <a>Assignment</a> list for <a>checkValues</a> should
--   be one of these <a>DerivedVal</a> values.
--   
--   The <tt>i</tt> type parameter is the input type, and the <tt>d</tt> is
--   the value derived from that input type.
data DerivedVal i d

-- | Val allows specification of a description string, an extraction
--   function, and the expected value to be extracted. The
--   <a>checkValues</a> function will add a Failure if the expected value
--   is not obtained.
[Val] :: (TestShow d, Eq d) => Text -> (i -> d) -> d -> DerivedVal i d

-- | Got allows specification of a description string and an extraction
--   function. The <a>checkValues</a> function will add a Failure if the
--   extraction result is False.
--   
--   <pre>
--   Val "what" f True === Got "what" f
--   </pre>
[Got] :: Text -> (i -> Bool) -> DerivedVal i Bool

-- | Observe performs the same checking as Val except the TestShow
--   information for the actual and expected values are not as useful (e.g.
--   they are lengthy, multi-line, or gibberish) so instead this allows the
--   specification of a function that will take the supplied expected value
--   and the result of the extraction function (the actual), respectively,
--   and generate its own description of the failure.
[Observe] :: Eq d => Text -> (i -> d) -> d -> (d -> d -> String) -> DerivedVal i d

-- | The internal <a>CheckResult</a> captures the failure information for a
--   check
data CheckResult

-- | The ChecklistFailures exception is thrown if any checks have failed
--   during testing.
data ChecklistFailures

-- | The <a>TestShow</a> class is defined to provide a way for the various
--   data objects tested by this module to be displayed when tests fail.
--   The default <a>testShow</a> will use a <a>Show</a> instance, but this
--   can be overridden if there are alternate ways to display a particular
--   object (e.g. pretty-printing, etc.)
class TestShow v
testShow :: TestShow v => v -> String
testShow :: (TestShow v, Show v) => v -> String

-- | A helper function for defining a testShow for lists of items.
--   
--   <pre>
--   instance TestShow [Int] where testShow = testShowList
--   </pre>
testShowList :: TestShow v => [v] -> String

-- | The multiLineDiff is another helper function that can be used to
--   format a line-by-line difference display of two Text representations.
--   This is provided as a convenience function to help format large text
--   regions for easier comparison.
multiLineDiff :: Text -> Text -> String
instance Test.Tasty.Checklist.TestShow ()
instance Test.Tasty.Checklist.TestShow GHC.Types.Bool
instance Test.Tasty.Checklist.TestShow GHC.Types.Int
instance Test.Tasty.Checklist.TestShow GHC.Num.Integer.Integer
instance Test.Tasty.Checklist.TestShow GHC.Types.Float
instance Test.Tasty.Checklist.TestShow GHC.Types.Char
instance Test.Tasty.Checklist.TestShow GHC.Base.String
instance (Test.Tasty.Checklist.TestShow a, Test.Tasty.Checklist.TestShow b) => Test.Tasty.Checklist.TestShow (a, b)
instance (Test.Tasty.Checklist.TestShow a, Test.Tasty.Checklist.TestShow b, Test.Tasty.Checklist.TestShow c) => Test.Tasty.Checklist.TestShow (a, b, c)
instance GHC.Exception.Type.Exception Test.Tasty.Checklist.ChecklistFailures
instance GHC.Show.Show Test.Tasty.Checklist.ChecklistFailures
instance GHC.Show.Show Test.Tasty.Checklist.CheckResult
