-- 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: http://www.junit.org. @package HUnit @version 1.2.4.3 -- | 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 \r and -- \b characters specially so that the result string has the -- same final (or terminal, 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: -- --
--   if conditionIsMet 
--       then IO () 
--       else assertFailure msg
--   
assertFailure :: String -> Assertion -- | Performs a single test case. The meaning of the result is as follows: -- -- performTestCase :: Assertion -> IO (Maybe (Bool, String)) 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 -- Test.HUnit.Text 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 Tests sharing the same level in the hierarchy. TestList :: [Test] -> Test -- | A name or description for a subtree of the Tests. 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 Testable, with the specified -- label attached to it. -- -- Since Test is Testable, this can be used as a -- shorthand way of attaching a TestLabel to one or more tests. (~:) :: Testable t => String -> t -> Test -- | Creates a test case resulting from asserting the condition obtained -- from the specified AssertionPredicable. (~?) :: AssertionPredicable t => t -> String -> Test -- | Unconditionally signals that a failure has occured. All other -- assertions can be expressed with the form: -- --
--   if conditionIsMet 
--       then IO () 
--       else assertFailure msg
--   
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., ""), 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 "") 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 -- AssertionPredicable holds. (@?) :: AssertionPredicable t => t -> String -> Assertion -- | Allows the extension of the assertion mechanism. -- -- Since an Assertion can be a sequence of Assertions and -- IO actions, there is a fair amount of flexibility of what can -- be achieved. As a rule, the resulting Assertion should be the -- body of a TestCase or part of a TestCase; it should -- not be used to assert multiple, independent conditions. -- -- If more complex arrangements of assertions are needed, Tests -- and Testable should be used. class Assertable t assert :: Assertable t => t -> Assertion -- | A specialized form of Assertable 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: -- --
    --
  1. Do some processing or an action.
  2. --
  3. Assert certain conditions.
  4. --
-- -- However, this flow is not always suitable. AssertionPredicate -- 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: -- --
    --
  1. Write data to a file.
  2. --
  3. Read data from a file, evaluate conditions.
  4. --
  5. Clean up the file.
  6. --
  7. Assert that the side effects of the read operation meet certain -- conditions.
  8. --
  9. Assert that the conditions evaluated in step 2 are met.
  10. --
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 Test or set of -- Test. 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 Paths. data Node ListItem :: Int -> Node Label :: String -> Node -- | Determines the paths for all TestCases in a tree of -- Tests. testCasePaths :: Test -> [Path] -- | Counts the number of TestCases in a tree of Tests. 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 HUnit.Text.runTestTT 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 (runTestText) -- 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 -- PutText. A report string is known as a "line", although it -- includes no line terminator; the function in a PutText is -- responsible for terminating lines appropriately. Besides the line, the -- function receives a flag indicating the intended "persistence" of the -- line: True indicates that the line should be part of the final -- overall report; False 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 PutText function is also passed, and returns, an arbitrary -- state value (called st here). The initial state value is -- given in the PutText; the final value is returned by -- runTestText. data PutText st PutText :: (String -> Bool -> st -> IO st) -> st -> PutText st -- | Two reporting schemes are defined here. putTextToHandle -- writes report lines to a given handle. putTextToShowS -- accumulates persistent lines for return as a whole by -- runTestText. -- -- putTextToHandle writes persistent lines to the given handle, -- following each by a newline character. In addition, if the given flag -- is True, 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 -- runTestText. The accumulated lines are represented by a -- ShowS (String -> String) 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 -- show) 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 -- Test.HUnit: -- --
--   import Test.HUnit
--   
-- -- Define test cases as appropriate: -- --
--   test1 = TestCase (assertEqual for (foo 3), (1,2) (foo 3))
--   test2 = TestCase (do (x,y) <- partA 3
--                        assertEqual for the first result of partA, 5 x
--                        b <- partB y
--                        assertBool ((partB  ++ show y ++ ) failed) b)
--   
-- -- Name the test cases and group them together: -- --
--   tests = TestList [TestLabel test1 test1, TestLabel test2 test2]
--   
-- -- Run the tests as a group. At a Haskell interpreter prompt, apply the -- function runTestTT to the collected tests. (The TT -- suggests Text orientation with output to the Terminal.) -- --
--   > runTestTT tests
--   Cases: 2  Tried: 2  Errors: 0  Failures: 0
--   >
--   
-- -- If the tests are proving their worth, you might see: -- --
--   > runTestTT tests
--   # Failure in: 0:test1
--   for (foo 3),
--   expected: (1,2)
--    but got: (1,3)
--   Cases: 2  Tried: 2  Errors: 0  Failures: 1
--   >
--   
-- -- You can specify tests even more succinctly using operators and -- overloaded functions that HUnit provides: -- --
--   tests = test [ test1 ~: (foo 3) ~: (1,2) ~=? (foo 3),
--                  test2 ~: do (x, y) <- partA 3
--                                assertEqual for the first result of partA, 5 x
--                                partB y @? (partB  ++ show y ++ ) failed ]
--   
-- -- Assuming the same test failures as before, you would see: -- --
--   > runTestTT tests
--   # Failure in: 0:test1:(foo 3)
--   expected: (1,2)
--    but got: (1,3)
--   Cases: 2  Tried: 2  Errors: 0  Failures: 1
--   >
--   
module Test.HUnit