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


-- | A unit testing framework for Haskell
--   
--   HUnit is a unit testing framework for Haskell, inspired by the JUnit
--   tool for Java, see: <a>http://www.junit.org</a>.
@package HUnit
@version 1.2.5.2


-- | This module handles the complexities of writing information to the
--   terminal, including modifying text in place.
module Test.HUnit.Terminal

-- | Simplifies the input string by interpreting <tt>\r</tt> and
--   <tt>\b</tt> characters specially so that the result string has the
--   same final (or <i>terminal</i>, pun intended) appearance as would the
--   input string when written to a terminal that overwrites character
--   positions following carriage returns and backspaces.
terminalAppearance :: String -> String


-- | This module abstracts the differences between implementations of
--   Haskell (e.g., GHC, Hugs, and NHC).
module Test.HUnit.Lang

-- | When an assertion is evaluated, it will output a message if and only
--   if the assertion fails.
--   
--   Test cases are composed of a sequence of one or more assertions.
type Assertion = IO ()

-- | Unconditionally signals that a failure has occured. All other
--   assertions can be expressed with the form:
--   
--   <pre>
--   if conditionIsMet 
--       then IO () 
--       else assertFailure msg
--   </pre>
assertFailure :: String -> Assertion

-- | Performs a single test case. The meaning of the result is as follows:
--   
--   <ul>
--   <li><i><tt>Nothing</tt></i> test case success</li>
--   <li><i><tt>Just (True, msg)</tt></i> test case failure with the given
--   message</li>
--   <li><i><tt>Just (False, msg)</tt></i> test case error with the given
--   message</li>
--   </ul>
performTestCase :: Assertion -> IO (Maybe (Bool, String))
data HUnitFailure
HUnitFailure :: String -> HUnitFailure
instance Show HUnitFailure
instance Exception HUnitFailure
instance Typeable HUnitFailure


-- | Basic definitions for the HUnit library.
--   
--   This module contains what you need to create assertions and test cases
--   and combine them into test suites.
--   
--   This module also provides infrastructure for implementing test
--   controllers (which are used to execute tests). See
--   <a>Test.HUnit.Text</a> for a great example of how to implement a test
--   controller.
module Test.HUnit.Base

-- | The basic structure used to create an annotated tree of test cases.
data Test

-- | A single, independent test case composed.
TestCase :: Assertion -> Test

-- | A set of <tt>Test</tt>s sharing the same level in the hierarchy.
TestList :: [Test] -> Test

-- | A name or description for a subtree of the <tt>Test</tt>s.
TestLabel :: String -> Test -> Test

-- | Shorthand for a test case that asserts equality (with the expected
--   value on the left-hand side, and the actual value on the right-hand
--   side).
(~=?) :: (Eq a, Show a) => a -> a -> Test

-- | Shorthand for a test case that asserts equality (with the actual value
--   on the left-hand side, and the expected value on the right-hand side).
(~?=) :: (Eq a, Show a) => a -> a -> Test

-- | Creates a test from the specified <a>Testable</a>, with the specified
--   label attached to it.
--   
--   Since <a>Test</a> is <tt>Testable</tt>, this can be used as a
--   shorthand way of attaching a <a>TestLabel</a> to one or more tests.
(~:) :: Testable t => String -> t -> Test

-- | Creates a test case resulting from asserting the condition obtained
--   from the specified <a>AssertionPredicable</a>.
(~?) :: AssertionPredicable t => t -> String -> Test

-- | Unconditionally signals that a failure has occured. All other
--   assertions can be expressed with the form:
--   
--   <pre>
--   if conditionIsMet 
--       then IO () 
--       else assertFailure msg
--   </pre>
assertFailure :: String -> Assertion

-- | Asserts that the specified condition holds.
assertBool :: String -> Bool -> Assertion

-- | Asserts that the specified actual value is equal to the expected
--   value. The output message will contain the prefix, the expected value,
--   and the actual value.
--   
--   If the prefix is the empty string (i.e., <tt>""</tt>), then the prefix
--   is omitted and only the expected and actual values are output.
assertEqual :: (Eq a, Show a) => String -> a -> a -> Assertion

-- | Signals an assertion failure if a non-empty message (i.e., a message
--   other than <tt>""</tt>) is passed.
assertString :: String -> Assertion

-- | When an assertion is evaluated, it will output a message if and only
--   if the assertion fails.
--   
--   Test cases are composed of a sequence of one or more assertions.
type Assertion = IO ()

-- | Asserts that the specified actual value is equal to the expected value
--   (with the expected value on the left-hand side).
(@=?) :: (Eq a, Show a) => a -> a -> Assertion

-- | Asserts that the specified actual value is equal to the expected value
--   (with the actual value on the left-hand side).
(@?=) :: (Eq a, Show a) => a -> a -> Assertion

-- | Asserts that the condition obtained from the specified
--   <a>AssertionPredicable</a> holds.
(@?) :: AssertionPredicable t => t -> String -> Assertion

-- | Allows the extension of the assertion mechanism.
--   
--   Since an <a>Assertion</a> can be a sequence of <tt>Assertion</tt>s and
--   <tt>IO</tt> actions, there is a fair amount of flexibility of what can
--   be achieved. As a rule, the resulting <tt>Assertion</tt> should be the
--   body of a <a>TestCase</a> or part of a <tt>TestCase</tt>; it should
--   not be used to assert multiple, independent conditions.
--   
--   If more complex arrangements of assertions are needed, <a>Test</a>s
--   and <a>Testable</a> should be used.
class Assertable t
assert :: Assertable t => t -> Assertion

-- | A specialized form of <a>Assertable</a> to handle lists.
class ListAssertable t
listAssert :: ListAssertable t => [t] -> Assertion

-- | The result of an assertion that hasn't been evaluated yet.
--   
--   Most test cases follow the following steps:
--   
--   <ol>
--   <li>Do some processing or an action.</li>
--   <li>Assert certain conditions.</li>
--   </ol>
--   
--   However, this flow is not always suitable. <tt>AssertionPredicate</tt>
--   allows for additional steps to be inserted without the initial action
--   to be affected by side effects. Additionally, clean-up can be done
--   before the test case has a chance to end. A potential work flow is:
--   
--   <ol>
--   <li>Write data to a file.</li>
--   <li>Read data from a file, evaluate conditions.</li>
--   <li>Clean up the file.</li>
--   <li>Assert that the side effects of the read operation meet certain
--   conditions.</li>
--   <li>Assert that the conditions evaluated in step 2 are met.</li>
--   </ol>
type AssertionPredicate = IO Bool

-- | Used to signify that a data type can be converted to an assertion
--   predicate.
class AssertionPredicable t
assertionPredicate :: AssertionPredicable t => t -> AssertionPredicate

-- | Provides a way to convert data into a <tt>Test</tt> or set of
--   <tt>Test</tt>.
class Testable t
test :: Testable t => t -> Test

-- | Keeps track of the remaining tests and the results of the performed
--   tests. As each test is performed, the path is removed and the counts
--   are updated as appropriate.
data State
State :: Path -> Counts -> State
path :: State -> Path
counts :: State -> Counts

-- | A data structure that hold the results of tests that have been
--   performed up until this point.
data Counts
Counts :: Int -> Int -> Int -> Int -> Counts
cases :: Counts -> Int
tried :: Counts -> Int
errors :: Counts -> Int
failures :: Counts -> Int

-- | Uniquely describes the location of a test within a test hierarchy.
--   Node order is from test case to root.
type Path = [Node]

-- | Composed into <a>Path</a>s.
data Node
ListItem :: Int -> Node
Label :: String -> Node

-- | Determines the paths for all <a>TestCase</a>s in a tree of
--   <tt>Test</tt>s.
testCasePaths :: Test -> [Path]

-- | Counts the number of <a>TestCase</a>s in a tree of <tt>Test</tt>s.
testCaseCount :: Test -> Int

-- | Report generator for reporting the start of a test run.
type ReportStart us = State -> us -> IO us

-- | Report generator for reporting problems that have occurred during a
--   test run. Problems may be errors or assertion failures.
type ReportProblem us = String -> State -> us -> IO us

-- | Performs a test run with the specified report generators.
--   
--   This handles the actual running of the tests. Most developers will
--   want to use <tt>HUnit.Text.runTestTT</tt> instead. A developer could
--   use this function to execute tests via another IO system, such as a
--   GUI, or to output the results in a different manner (e.g., upload
--   XML-formatted results to a webservice).
--   
--   Note that the counts in a start report do not include the test case
--   being started, whereas the counts in a problem report do include the
--   test case just finished. The principle is that the counts are sampled
--   only between test case executions. As a result, the number of test
--   case successes always equals the difference of test cases tried and
--   the sum of test case errors and failures.
performTest :: ReportStart us -> ReportProblem us -> ReportProblem us -> us -> Test -> IO (Counts, us)
instance Eq Counts
instance Show Counts
instance Read Counts
instance Eq Node
instance Show Node
instance Read Node
instance Eq State
instance Show State
instance Read State
instance Testable t => Testable [t]
instance Assertable t => Testable (IO t)
instance Testable Test
instance Show Test
instance AssertionPredicable t => AssertionPredicable (IO t)
instance AssertionPredicable Bool
instance ListAssertable Char
instance Assertable t => Assertable (IO t)
instance ListAssertable t => Assertable [t]
instance Assertable Bool
instance Assertable ()


-- | Text-based test controller for running HUnit tests and reporting
--   results as text, usually to a terminal.
module Test.HUnit.Text

-- | As the general text-based test controller (<a>runTestText</a>)
--   executes a test, it reports each test case start, error, and failure
--   by constructing a string and passing it to the function embodied in a
--   <a>PutText</a>. A report string is known as a "line", although it
--   includes no line terminator; the function in a <a>PutText</a> is
--   responsible for terminating lines appropriately. Besides the line, the
--   function receives a flag indicating the intended "persistence" of the
--   line: <a>True</a> indicates that the line should be part of the final
--   overall report; <a>False</a> indicates that the line merely indicates
--   progress of the test execution. Each progress line shows the current
--   values of the cumulative test execution counts; a final, persistent
--   line shows the final count values.
--   
--   The <a>PutText</a> function is also passed, and returns, an arbitrary
--   state value (called <tt>st</tt> here). The initial state value is
--   given in the <a>PutText</a>; the final value is returned by
--   <a>runTestText</a>.
data PutText st
PutText :: (String -> Bool -> st -> IO st) -> st -> PutText st

-- | Two reporting schemes are defined here. <tt>putTextToHandle</tt>
--   writes report lines to a given handle. <a>putTextToShowS</a>
--   accumulates persistent lines for return as a whole by
--   <a>runTestText</a>.
--   
--   <tt>putTextToHandle</tt> writes persistent lines to the given handle,
--   following each by a newline character. In addition, if the given flag
--   is <tt>True</tt>, it writes progress lines to the handle as well. A
--   progress line is written with no line termination, so that it can be
--   overwritten by the next report line. As overwriting involves writing
--   carriage return and blank characters, its proper effect is usually
--   only obtained on terminal devices.
putTextToHandle :: Handle -> Bool -> PutText Int

-- | Accumulates persistent lines (dropping progess lines) for return by
--   <a>runTestText</a>. The accumulated lines are represented by a
--   <tt><a>ShowS</a> (<a>String</a> -&gt; <a>String</a>)</tt> function
--   whose first argument is the string to be appended to the accumulated
--   report lines.
putTextToShowS :: PutText ShowS

-- | Executes a test, processing each report line according to the given
--   reporting scheme. The reporting scheme's state is threaded through
--   calls to the reporting scheme's function and finally returned, along
--   with final count values.
runTestText :: PutText st -> Test -> IO (Counts, st)

-- | Converts a test case path to a string, separating adjacent elements by
--   the colon (':'). An element of the path is quoted (as with
--   <a>show</a>) when there is potential ambiguity.
showPath :: Path -> String

-- | Converts test execution counts to a string.
showCounts :: Counts -> String

-- | Provides the "standard" text-based test controller. Reporting is made
--   to standard error, and progress reports are included. For possible
--   programmatic use, the final counts are returned.
--   
--   The "TT" in the name suggests "Text-based reporting to the Terminal".
runTestTT :: Test -> IO Counts


-- | HUnit is a unit testing framework for Haskell, inspired by the JUnit
--   tool for Java. This guide describes how to use HUnit, assuming you are
--   familiar with Haskell, though not necessarily with JUnit.
--   
--   In the Haskell module where your tests will reside, import module
--   <tt>Test.HUnit</tt>:
--   
--   <pre>
--   import Test.HUnit
--   </pre>
--   
--   Define test cases as appropriate:
--   
--   <pre>
--   test1 = TestCase (assertEqual "for (foo 3)," (1,2) (foo 3))
--   test2 = TestCase (do (x,y) &lt;- partA 3
--                        assertEqual "for the first result of partA," 5 x
--                        b &lt;- partB y
--                        assertBool ("(partB " ++ show y ++ ") failed") b)
--   </pre>
--   
--   Name the test cases and group them together:
--   
--   <pre>
--   tests = TestList [TestLabel "test1" test1, TestLabel "test2" test2]
--   </pre>
--   
--   Run the tests as a group. At a Haskell interpreter prompt, apply the
--   function <tt>runTestTT</tt> to the collected tests. (The <i>TT</i>
--   suggests <i>T</i>ext orientation with output to the <i>T</i>erminal.)
--   
--   <pre>
--   &gt; runTestTT tests
--   Cases: 2  Tried: 2  Errors: 0  Failures: 0
--   &gt;
--   </pre>
--   
--   If the tests are proving their worth, you might see:
--   
--   <pre>
--   &gt; runTestTT tests
--   # Failure in: 0:test1
--   for (foo 3),
--   expected: (1,2)
--    but got: (1,3)
--   Cases: 2  Tried: 2  Errors: 0  Failures: 1
--   &gt;
--   </pre>
--   
--   You can specify tests even more succinctly using operators and
--   overloaded functions that HUnit provides:
--   
--   <pre>
--   tests = test [ "test1" ~: "(foo 3)" ~: (1,2) ~=? (foo 3),
--                  "test2" ~: do (x, y) &lt;- partA 3
--                                assertEqual "for the first result of partA," 5 x
--                                partB y @? "(partB " ++ show y ++ ") failed" ]
--   </pre>
--   
--   Assuming the same test failures as before, you would see:
--   
--   <pre>
--   &gt; runTestTT tests
--   # Failure in: 0:test1:(foo 3)
--   expected: (1,2)
--    but got: (1,3)
--   Cases: 2  Tried: 2  Errors: 0  Failures: 1
--   &gt;
--   </pre>
module Test.HUnit
