Hello community, here is the log from the commit of package ghc-HUnit for openSUSE:Factory checked in at 2016-01-28 17:23:54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/ghc-HUnit (Old) and /work/SRC/openSUSE:Factory/.ghc-HUnit.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "ghc-HUnit" Changes: -------- --- /work/SRC/openSUSE:Factory/ghc-HUnit/ghc-HUnit.changes 2016-01-22 01:08:35.000000000 +0100 +++ /work/SRC/openSUSE:Factory/.ghc-HUnit.new/ghc-HUnit.changes 2016-01-28 17:24:47.000000000 +0100 @@ -1,0 +2,5 @@ +Fri Jan 22 10:12:18 UTC 2016 - mimi...@gmail.com + +- update to 1.3.1.1 + +------------------------------------------------------------------- Old: ---- HUnit-1.3.1.0.tar.gz New: ---- HUnit-1.3.1.1.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ ghc-HUnit.spec ++++++ --- /var/tmp/diff_new_pack.1TwUXh/_old 2016-01-28 17:24:47.000000000 +0100 +++ /var/tmp/diff_new_pack.1TwUXh/_new 2016-01-28 17:24:47.000000000 +0100 @@ -19,7 +19,7 @@ %global pkg_name HUnit Name: ghc-HUnit -Version: 1.3.1.0 +Version: 1.3.1.1 Release: 0 Summary: A unit testing framework for Haskell License: BSD-3-Clause @@ -75,6 +75,6 @@ %files devel -f %{name}-devel.files %defattr(-,root,root,-) -%doc examples README.md doc +%doc examples README.md %changelog ++++++ HUnit-1.3.1.0.tar.gz -> HUnit-1.3.1.1.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/HUnit-1.3.1.0/CHANGELOG.md new/HUnit-1.3.1.1/CHANGELOG.md --- old/HUnit-1.3.1.0/CHANGELOG.md 1970-01-01 01:00:00.000000000 +0100 +++ new/HUnit-1.3.1.1/CHANGELOG.md 2016-01-19 17:16:50.000000000 +0100 @@ -0,0 +1,19 @@ +## Changes + +#### 1.3.1.1 + +- Various updates to metadata and documentation removing outdated information and making other things more visible + +### 1.3.1.0 + +- add minimal support for GHC 8.0 + +### 1.3.0.0 + +- removed support for old compilers + +- add source locations for failing assertions (GHC >= 7.10.2 only) + +#### 1.2.5.2 + +- Added support for GHC 7.7 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/HUnit-1.3.1.0/HUnit.cabal new/HUnit-1.3.1.1/HUnit.cabal --- old/HUnit-1.3.1.0/HUnit.cabal 2016-01-11 10:04:20.000000000 +0100 +++ new/HUnit-1.3.1.1/HUnit.cabal 2016-01-19 17:16:50.000000000 +0100 @@ -1,23 +1,22 @@ Name: HUnit -Version: 1.3.1.0 +Version: 1.3.1.1 Cabal-Version: >= 1.8 License: BSD3 License-File: LICENSE Author: Dean Herington Maintainer: Simon Hengel <s...@typeful.net> Stability: stable -Homepage: http://hunit.sourceforge.net/ +Homepage: https://github.com/hspec/HUnit#readme Category: Testing Synopsis: A unit testing framework for Haskell Description: HUnit is a unit testing framework for Haskell, inspired by the JUnit tool for Java, see: <http://www.junit.org>. Build-Type: Simple -Data-Files: - doc/Guide.html - examples/Example.hs - prologue.txt +Extra-Source-Files: + CHANGELOG.md README.md + examples/Example.hs source-repository head type: git @@ -38,7 +37,7 @@ Test-Suite tests Type: exitcode-stdio-1.0 Main-Is: HUnitTests.hs - HS-Source-Dirs: tests + HS-Source-Dirs: tests, examples Build-Depends: base == 4.*, deepseq, @@ -49,4 +48,5 @@ HUnitTestBase HUnitTestExtended TerminalTest + Example GHC-Options: -Wall diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/HUnit-1.3.1.0/README.md new/HUnit-1.3.1.1/README.md --- old/HUnit-1.3.1.0/README.md 2016-01-11 10:04:20.000000000 +0100 +++ new/HUnit-1.3.1.1/README.md 2016-01-19 17:16:50.000000000 +0100 @@ -1,28 +1,545 @@ -# HUnit +# HUnit User's Guide -HUnit is a unit testing framework for Haskell, inspired by the JUnit -tool for Java. HUnit is free software; see its "License" file for -details. HUnit is available at <http://hunit.sourceforge.net>. +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. You can obtain HUnit, including this guide, at +[https://github.com/hspec/HUnit](https://github.com/hspec/HUnit) -HUnit 1.1.1 consists of a number of files. Besides Haskell source files -in Test/HUnit (whose names end in ".hs" or ".lhs"), these files include: +## Introduction +A test-centered methodology for software development is most effective when tests are +easy to create, change, and execute. The [JUnit](www.junit.org) tool +pioneered support for test-first development in [Java](http://java.sun.com). +HUnit is an adaptation of JUnit to Haskell, a general-purpose, purely functional +programming language. (To learn more about Haskell, see www.haskell.org](http://www.haskell.org). +With HUnit, as with JUnit, you can easily create tests, name them, group them into +suites, and execute them, with the framework checking the results automatically. Test +specification in HUnit is even more concise and flexible than in JUnit, thanks to the +nature of the Haskell language. HUnit currently includes only a text-based test +controller, but the framework is designed for easy extension. (Would anyone care to +write a graphical test controller for HUnit?) + +The next section helps you get started using HUnit in simple ways. Subsequent sections +give details on [writing tests](#writing-tests) and [running tests](#running-tests). +The document concludes with a section describing HUnit's [constituent files](#constituent-files) +and a section giving [references](#references) to further information. + +## Getting Started + +In the Haskell module where your tests will reside, import module `Test.HUnit`: + +```haskell +import Test.HUnit +``` + +Define test cases as appropriate: + +```haskell +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: + +```haskell +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 +**T**ext orientation with output to the **T**erminal.) + +```haskell +> runTestTT tests +Cases: 2 Tried: 2 Errors: 0 Failures: 0 +> +``` + +If the tests are proving their worth, you might see: + +```haskell +> runTestTT tests +### Failure in: 0:test1 +for (foo 3), +expected: (1,2) + but got: (1,3) +Cases: 2 Tried: 2 Errors: 0 Failures: 1 +> +``` + +Isn't that easy? + +You can specify tests even more succinctly using operators and +overloaded functions that HUnit provides: + +```haskell +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: + +```haskell +> runTestTT tests +### Failure in: 0:test1:(foo 3) +expected: (1,2) + but got: (1,3) +Cases: 2 Tried: 2 Errors: 0 Failures: 1 +> +``` + +## Writing Tests + +Tests are specified compositionally. [Assertions](#assertions) are +combined to make a [test case](#test-case), and test cases are combined +into [tests](#tests). HUnit also provides [advanced +features](#advanced-features) for more convenient test specification. + +### Assertions + + The basic building block of a test is an **assertion**. + +```haskell +type Assertion = IO () +``` + +An assertion is an `IO` computation that always produces a void result. Why is an assertion an `IO` computation? So that programs with real-world side effects can be tested. How does an assertion assert anything if it produces no useful result? The answer is that an assertion can signal failure by calling `assertFailure`. + +```haskell +assertFailure :: String -> Assertion +assertFailure msg = ioError (userError ("HUnit:" ++ msg)) +``` + +`(assertFailure msg)` raises an exception. The string argument identifies the + failure. The failure message is prefixed by "`HUnit:`" to mark it as an HUnit + assertion failure message. The HUnit test framework interprets such an exception as + indicating failure of the test whose execution raised the exception. (Note: The details + concerning the implementation of `assertFailure` are subject to change and should + not be relied upon.) + +`assertFailure` can be used directly, but it is much more common to use it + indirectly through other assertion functions that conditionally assert failure. + +```haskell +assertBool :: String -> Bool -> Assertion +assertBool msg b = unless b (assertFailure msg) + +assertString :: String -> Assertion +assertString s = unless (null s) (assertFailure s) + +assertEqual :: (Eq a, Show a) => String -> a -> a -> Assertion +assertEqual preface expected actual = + unless (actual == expected) (assertFailure msg) + where msg = (if null preface then "" else preface ++ "\n") ++ + "expected: " ++ show expected ++ "\n but got: " ++ show actual +``` + +With `assertBool` you give the assertion condition and failure message separately. + With `assertString` the two are combined. With `assertEqual` you provide a + "preface", an expected value, and an actual value; the failure message shows the two + unequal values and is prefixed by the preface. Additional ways to create assertions are + described later under [Avanced Features](#advanced-features) + +Since assertions are `IO` computations, they may be combined--along with other + `IO` computations--using `(>>=)`, `(>>)`, and the `do` + notation. As long as its result is of type `(IO ())`, such a combination + constitutes a single, collective assertion, incorporating any number of constituent + assertions. The important features of such a collective assertion are that it fails if + any of its constituent assertions is executed and fails, and that the first constituent + assertion to fail terminates execution of the collective assertion. Such behavior is + essential to specifying a test case. + +### Test Case + +A **test case** is the unit of test execution. That is, distinct test cases are + executed independently. The failure of one is independent of the failure of any other. + +A test case consists of a single, possibly collective, assertion. The possibly multiple + constituent assertions in a test case's collective assertion are **not** independent. + Their interdependence may be crucial to specifying correct operation for a test. A test + case may involve a series of steps, each concluding in an assertion, where each step + must succeed in order for the test case to continue. As another example, a test may + require some "set up" to be performed that must be undone ("torn down" in JUnit + parlance) once the test is complete. In this case, you could use Haskell's + `IO.bracket` function to achieve the desired effect. + +You can make a test case from an assertion by applying the `TestCase` constructor. + For example, `(TestCase (return ()))` is a test case that never + fails, and `(TestCase (assertEqual "for x," 3 x))` + is a test case that checks that the value of `x` is 3. Additional ways + to create test cases are described later under [Advanced Features](#advanced-eatures). + +### Tests + +As soon as you have more than one test, you'll want to name them to tell them apart. As + soon as you have more than several tests, you'll want to group them to process them more + easily. So, naming and grouping are the two keys to managing collections of tests. + +In tune with the "composite" design pattern [1], a + **test** is defined as a package of test cases. Concretely, a test is either a single + test case, a group of tests, or either of the first two identified by a label. + +```haskell +data Test = TestCase Assertion + | TestList [Test] + | TestLabel String Test +``` + +There are three important features of this definition to note: + + +* A `TestList` consists of a list of tests rather than a list of test cases. + This means that the structure of a `Test` is actually a tree. Using a + hierarchy helps organize tests just as it helps organize files in a file system. +* A `TestLabel` is attached to a test rather than to a test case. This means + that all nodes in the test tree, not just test case (leaf) nodes, can be labeled. + Hierarchical naming helps organize tests just as it helps organize files in a file + system. +* A `TestLabel` is separate from both `TestCase` and `TestList`. + This means that labeling is optional everywhere in the tree. Why is this a good + thing? Because of the hierarchical structure of a test, each constituent test case + is uniquely identified by its path in the tree, ignoring all labels. Sometimes a + test case's path (or perhaps its subpath below a certain node) is a perfectly + adequate "name" for the test case (perhaps relative to a certain node). In this + case, creating a label for the test case is both unnecessary and inconvenient. + + +The number of test cases that a test comprises can be computed with `testCaseCount`. + +```haskell +testCaseCount :: Test -> Int +``` + +As mentioned above, a test is identified by its **path** in the test hierarchy. + +```haskell +data Node = ListItem Int | Label String + deriving (Eq, Show, Read) + +type Path = [Node] -- Node order is from test case to root. +``` + +Each occurrence of `TestList` gives rise to a `ListItem` and each + occurrence of `TestLabel` gives rise to a `Label`. The `ListItem`s + by themselves ensure uniqueness among test case paths, while the `Label`s allow + you to add mnemonic names for individual test cases and collections of them. + +Note that the order of nodes in a path is reversed from what you might expect: The first + node in the list is the one deepest in the tree. This order is a concession to + efficiency: It allows common path prefixes to be shared. + +The paths of the test cases that a test comprises can be computed with + `testCasePaths`. The paths are listed in the order in which the corresponding + test cases would be executed. + +```haskell +testCasePaths :: Test -> [Path] +``` + +The three variants of `Test` can be constructed simply by applying + `TestCase`, `TestList`, and `TestLabel` to appropriate arguments. + Additional ways to create tests are described later under [Advanced Features](#advanced-features). + +The design of the type `Test` provides great conciseness, flexibility, and + convenience in specifying tests. Moreover, the nature of Haskell significantly augments + these qualities: + +* Combining assertions and other code to construct test cases is easy with the + `IO` monad. +* Using overloaded functions and special operators (see below), specification of + assertions and tests is extremely compact. +* Structuring a test tree by value, rather than by name as in JUnit, provides for more + convenient, flexible, and robust test suite specification. In particular, a test + suite can more easily be computed "on the fly" than in other test frameworks. +* Haskell's powerful abstraction facilities provide unmatched support for test + refactoring. + +### Advanced Features + +HUnit provides additional features for specifying assertions and tests more conveniently + and concisely. These facilities make use of Haskell type classes. + +The following operators can be used to construct assertions. + +```haskell +infix 1 @?, @=?, @?= + +(@?) :: (AssertionPredicable t) => t -> String -> Assertion +pred @? msg = assertionPredicate pred >>= assertBool msg + +(@=?) :: (Eq a, Show a) => a -> a -> Assertion +expected @=? actual = assertEqual "" expected actual + +(@?=) :: (Eq a, Show a) => a -> a -> Assertion +actual @?= expected = assertEqual "" expected actual +``` + +You provide a boolean condition and failure message separately to `(@?)`, as for + `assertBool`, but in a different order. The `(@=?)` and `(@?=)` + operators provide shorthands for `assertEqual` when no preface is required. They + differ only in the order in which the expected and actual values are provided. (The + actual value--the uncertain one--goes on the "?" side of the operator.) + +The `(@?)` operator's first argument is something from which an assertion + predicate can be made, that is, its type must be `AssertionPredicable`. + +```haskell +type AssertionPredicate = IO Bool + +class AssertionPredicable t + where assertionPredicate :: t -> AssertionPredicate + +instance AssertionPredicable Bool + where assertionPredicate = return + +instance (AssertionPredicable t) => AssertionPredicable (IO t) + where assertionPredicate = (>>= assertionPredicate) +``` + +The overloaded `assert` function in the `Assertable` type class constructs + an assertion. + +```haskell +class Assertable t + where assert :: t -> Assertion + +instance Assertable () + where assert = return + +instance Assertable Bool + where assert = assertBool "" + +instance (ListAssertable t) => Assertable [t] + where assert = listAssert + +instance (Assertable t) => Assertable (IO t) + where assert = (>>= assert) +``` + +The `ListAssertable` class allows `assert` to be applied to `[Char]` + (that is, `String`). + +```haskell +class ListAssertable t + where listAssert :: [t] -> Assertion + +instance ListAssertable Char + where listAssert = assertString +``` + +With the above declarations, `(assert ())`, + `(assert True)`, and `(assert "")` (as well as + `IO` forms of these values, such as `(return ())`) are all + assertions that never fail, while `(assert False)` and + `(assert "some failure message")` (and their + `IO` forms) are assertions that always fail. You may define additional + instances for the type classes `Assertable`, `ListAssertable`, and + `AssertionPredicable` if that should be useful in your application. + +The overloaded `test` function in the `Testable` type class constructs a + test. + +```haskell +class Testable t + where test :: t -> Test + +instance Testable Test + where test = id + +instance (Assertable t) => Testable (IO t) + where test = TestCase . assert + +instance (Testable t) => Testable [t] + where test = TestList . map test +``` + +The `test` function makes a test from either an `Assertion` (using + `TestCase`), a list of `Testable` items (using `TestList`), or + a `Test` (making no change). + +The following operators can be used to construct tests. + +```haskell +infix 1 ~?, ~=?, ~?= +infixr 0 ~: + +(~?) :: (AssertionPredicable t) => t -> String -> Test +pred ~? msg = TestCase (pred @? msg) + +(~=?) :: (Eq a, Show a) => a -> a -> Test +expected ~=? actual = TestCase (expected @=? actual) + +(~?=) :: (Eq a, Show a) => a -> a -> Test +actual ~?= expected = TestCase (actual @?= expected) + +(~:) :: (Testable t) => String -> t -> Test +label ~: t = TestLabel label (test t) +``` + +`(~?)`, `(~=?)`, and `(~?=)` each make an assertion, as for + `(@?)`, `(@=?)`, and `(@?=)`, respectively, and then a test case + from that assertion. `(~:)` attaches a label to something that is + `Testable`. You may define additional instances for the type class + `Testable` should that be useful. + +## Running Tests + +HUnit is structured to support multiple test controllers. The first + subsection below describes the [test execution](#test-execution) + characteristics common to all test controllers. The second subsection + describes the text-based controller that is included with HUnit. + +## Test Execution + +All test controllers share a common test execution model. They differ only in how the + results of test execution are shown. + +The execution of a test (a value of type `Test`) involves the serial execution (in + the `IO` monad) of its constituent test cases. The test cases are executed in a + depth-first, left-to-right order. During test execution, four counts of test cases are + maintained: + +```haskell +data Counts = Counts { cases, tried, errors, failures :: Int } + deriving (Eq, Show, Read) ``` - * README.md -- this file - * doc/Guide.html -- user's guide, in HTML format - * LICENSE -- license for use of HUnit + + +* `cases` is the number of test cases included in the test. This number is a + static property of a test and remains unchanged during test execution. +* `tried` is the number of test cases that have been executed so far during the + test execution. +* `errors` is the number of test cases whose execution ended with an unexpected + exception being raised. Errors indicate problems with test cases, as opposed to the + code under test. +* `failures` is the number of test cases whose execution asserted failure. + Failures indicate problems with the code under test. + + +Why is there no count for test case successes? The technical reason is that the counts + are maintained such that the number of test case successes is always equal to + `(tried - (errors + failures))`. The + psychosocial reason is that, with test-centered development and the expectation that + test failures will be few and short-lived, attention should be focused on the failures + rather than the successes. + +As test execution proceeds, three kinds of reporting event are communicated to the test + controller. (What the controller does in response to the reporting events depends on the + controller.) + +* *start* -- Just prior to initiation of a test case, the path of the test case + and the current counts (excluding the current test case) are reported. +* *error* -- When a test case terminates with an error, the error message is + reported, along with the test case path and current counts (including the current + test case). +* *failure* -- When a test case terminates with a failure, the failure message is + reported, along with the test case path and current counts (including the current + test case). + +Typically, a test controller shows *error* and *failure* reports immediately + but uses the *start* report merely to update an indication of overall test + execution progress. + +### Text-Based Controller + +A text-based test controller is included with HUnit. + +```haskell +runTestText :: PutText st -> Test -> IO (Counts, st) +``` + +`runTestText` is generalized on a *reporting scheme* given as its first + argument. During execution of the test given as its second argument, the controller + creates a string for each reporting event and processes it according to the reporting + scheme. When test execution is complete, the controller returns the final counts along + with the final state for the reporting scheme. + +The strings for the three kinds of reporting event are as follows. + +* A *start* report is the result of the function `showCounts` applied to + the counts current immediately prior to initiation of the test case being started. +* An *error* report is of the form + "`Error in: *path*\n*message*`", + where *path* is the path of the test case in error, as shown by + `showPath`, and *message* is a message describing the error. If the path + is empty, the report has the form "`Error:\n*message*`". +* A *failure* report is of the form + "`Failure in: *path*\n*message*`", where + *path* is the path of the test case in error, as shown by + `showPath`, and *message* is the failure message. If the path is empty, + the report has the form "`Failure:\n*message*`". + +The function `showCounts` shows a set of counts. + +```haskell +showCounts :: Counts -> String +``` + +The form of its result is +`Cases: *cases* Tried: *tried* Errors: *errors* Failures: *failures*` +where *cases*, *tried*, *errors*, and *failures* are the count values. + +The function `showPath` shows a test case path. + +```haskell + showPath :: Path -> String +``` + +The nodes in the path are reversed (so that the path reads from the root down to the test + case), and the representations for the nodes are joined by '`:`' separators. The + representation for `(ListItem *n*)` is `(show n)`. The representation + for `(Label *label*)` is normally *label*. However, if *label* + contains a colon or if `(show *label*)` is different from *label* + surrounded by quotation marks--that is, if any ambiguity could exist--then `(Label + *label*)` is represented as `(show *label*)`. + +HUnit includes two reporting schemes for the text-based test controller. You may define + others if you wish. + +```haskell +putTextToHandle :: Handle -> Bool -> PutText Int +``` + +`putTextToHandle` writes error and failure reports, plus a report of the final + counts, to the given handle. Each of these reports is terminated by a newline. In + addition, if the given flag is `True`, it writes start reports to the handle as + well. A start report, however, is not terminated by a newline. Before the next report is + written, the start report is "erased" with an appropriate sequence of carriage return + and space characters. Such overwriting realizes its intended effect on terminal devices. + +```haskell +putTextToShowS :: PutText ShowS +``` + +`putTextToShowS` ignores start reports and simply accumulates error and failure + reports, terminating them with newlines. The accumulated reports are returned (as the + second element of the pair returned by `runTestText`) as a `ShowS` + function (that is, one with type `(String -> String)`) whose + first argument is a string to be appended to the accumulated report lines. + +HUnit provides a shorthand for the most common use of the text-based test controller. + +```haskell +runTestTT :: Test -> IO Counts ``` -See the user's guide for more information. +`runTestTT` invokes `runTestText`, specifying `(putTextToHandle stderr +True)` for the reporting scheme, and returns the final counts from the +test execution. -## Changes +## References -### 1.3.1.0 +* [1] Gamma, E., et al. Design Patterns: Elements of Reusable Object-Oriented Software, Addison-Wesley, Reading, MA, 1995: The classic book describing design patterns in an object-oriented context. -- add minimal support for GHC 8.0 +* [junit.org](http://www.junit.org): Web page for JUnit, the tool after which HUnit is modeled. -### 1.3.0.0 +* [http://junit.sourceforge.net/doc/testinfected/testing.htm](http://junit.sourceforge.net/doc/testinfected/testing.htm): A good introduction to test-first development and the use of JUnit. -- removed support for old compilers +* [http://junit.sourceforge.net/doc/cookstour/cookstour.htm](http://junit.sourceforge.net/doc/cookstour/cookstour.htm): A description of the internal structure of JUnit. Makes for an interesting comparison between JUnit and HUnit. -- add source locations for failing assertions (GHC >= 7.10.2 only) +The HUnit software and this guide were written by Dean Herington [herin...@cs.unc.edu](mailto:herin...@cs.unc.edu) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/HUnit-1.3.1.0/doc/Guide.html new/HUnit-1.3.1.1/doc/Guide.html --- old/HUnit-1.3.1.0/doc/Guide.html 2016-01-11 10:04:20.000000000 +0100 +++ new/HUnit-1.3.1.1/doc/Guide.html 1970-01-01 01:00:00.000000000 +0100 @@ -1,539 +0,0 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" - "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:schemaLocation="http://www.w3.org/MarkUp/SCHEMA/xhtml11.xsd" xml:lang="en"> - <head> - <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> - <meta name="Author" content="Dean Herington"/> - <meta name="KeyWords" content="HUnit, unit testing, test-first development, Haskell, JUnit"/> - <title>HUnit 1.0 User's Guide</title> - </head> - <body> - - <h1>HUnit 1.2 User's Guide</h1> - - <p>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. You can obtain HUnit, including this guide, at <a - href="http://code.haskell.org/HUnit">http://code.haskell.org/HUnit</a>.</p> - - <h2>Introduction</h2> - - <p>A test-centered methodology for software development is most effective when tests are - easy to create, change, and execute. The <a href="http://www.junit.org">JUnit</a> tool - pioneered support for test-first development in <a href="http://java.sun.com">Java</a>. - HUnit is an adaptation of JUnit to Haskell, a general-purpose, purely functional - programming language. (To learn more about Haskell, see <a href="http://www.haskell.org" - >http://www.haskell.org</a>.)</p> - - <p>With HUnit, as with JUnit, you can easily create tests, name them, group them into - suites, and execute them, with the framework checking the results automatically. Test - specification in HUnit is even more concise and flexible than in JUnit, thanks to the - nature of the Haskell language. HUnit currently includes only a text-based test - controller, but the framework is designed for easy extension. (Would anyone care to - write a graphical test controller for HUnit?)</p> - - <p>The next section helps you get started using HUnit in simple ways. Subsequent sections - give details on <a href="#WritingTests">writing tests</a> and <a href="#RunningTests" - >running tests</a>. The document concludes with a section describing HUnit's <a - href="#ConstituentFiles">constituent files</a> and a section giving <a - href="#References">references</a> to further information.</p> - - <h2 id="GettingStarted">Getting Started</h2> - - <p>In the Haskell module where your tests will reside, import module <tt>Test.HUnit</tt>:</p> - <pre> - import Test.HUnit -</pre> - <p>Define test cases as appropriate:</p> - <pre> - 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) -</pre> - <p>Name the test cases and group them together:</p> - <pre> - tests = TestList [TestLabel "test1" test1, TestLabel "test2" test2] -</pre> - <p>Run the tests as a group. At a Haskell interpreter prompt, apply the function - <tt>runTestTT</tt> to the collected tests. (The "<tt>TT</tt>" suggests - <strong>T</strong>ext orientation with output to the <strong>T</strong>erminal.)</p> - <pre> - > runTestTT tests - Cases: 2 Tried: 2 Errors: 0 Failures: 0 - > -</pre> - <p>If the tests are proving their worth, you might see:</p> - <pre> - > runTestTT tests - ### Failure in: 0:test1 - for (foo 3), - expected: (1,2) - but got: (1,3) - Cases: 2 Tried: 2 Errors: 0 Failures: 1 - > -</pre> - <p>Isn't that easy?</p> - - <p>You can specify tests even more succinctly using operators and overloaded functions that - HUnit provides:</p> - <pre> - 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" ] -</pre> - <p>Assuming the same test failures as before, you would see:</p> - <pre> - > runTestTT tests - ### Failure in: 0:test1:(foo 3) - expected: (1,2) - but got: (1,3) - Cases: 2 Tried: 2 Errors: 0 Failures: 1 - > -</pre> - - <h2 id="WritingTests">Writing Tests</h2> - - <p>Tests are specified compositionally. <a href="#Assertions">Assertions</a> are combined to - make a <a href="#TestCase">test case</a>, and test cases are combined into <a - href="#Tests">tests</a>. HUnit also provides <a href="#AdvancedFeatures">advanced - features</a> for more convenient test specification.</p> - - <h3 id="Assertions">Assertions</h3> - - <p>The basic building block of a test is an <b>assertion</b>.</p> - <pre> - type Assertion = IO () -</pre> - <p>An assertion is an <tt>IO</tt> computation that always produces a void result. Why is an - assertion an <tt>IO</tt> computation? So that programs with real-world side effects can - be tested. How does an assertion assert anything if it produces no useful result? The - answer is that an assertion can signal failure by calling <tt>assertFailure</tt>.</p> - <pre> - assertFailure :: String -> Assertion - assertFailure msg = ioError (userError ("HUnit:" ++ msg)) -</pre> - <p><tt>(assertFailure msg)</tt> raises an exception. The string argument identifies the - failure. The failure message is prefixed by "<tt>HUnit:</tt>" to mark it as an HUnit - assertion failure message. The HUnit test framework interprets such an exception as - indicating failure of the test whose execution raised the exception. (Note: The details - concerning the implementation of <tt>assertFailure</tt> are subject to change and should - not be relied upon.)</p> - - <p><tt>assertFailure</tt> can be used directly, but it is much more common to use it - indirectly through other assertion functions that conditionally assert failure.</p> - <pre> - assertBool :: String -> Bool -> Assertion - assertBool msg b = unless b (assertFailure msg) - - assertString :: String -> Assertion - assertString s = unless (null s) (assertFailure s) - - assertEqual :: (Eq a, Show a) => String -> a -> a -> Assertion - assertEqual preface expected actual = - unless (actual == expected) (assertFailure msg) - where msg = (if null preface then "" else preface ++ "\n") ++ - "expected: " ++ show expected ++ "\n but got: " ++ show actual -</pre> - <p>With <tt>assertBool</tt> you give the assertion condition and failure message separately. - With <tt>assertString</tt> the two are combined. With <tt>assertEqual</tt> you provide a - "preface", an expected value, and an actual value; the failure message shows the two - unequal values and is prefixed by the preface. Additional ways to create assertions are - described later under <a href="#AdvancedFeatures">Advanced Features</a>.</p> - - <p>Since assertions are <tt>IO</tt> computations, they may be combined--along with other - <tt>IO</tt> computations--using <tt>(>>=)</tt>, <tt>(>>)</tt>, and the <tt>do</tt> - notation. As long as its result is of type <tt>(IO ())</tt>, such a combination - constitutes a single, collective assertion, incorporating any number of constituent - assertions. The important features of such a collective assertion are that it fails if - any of its constituent assertions is executed and fails, and that the first constituent - assertion to fail terminates execution of the collective assertion. Such behavior is - essential to specifying a test case.</p> - - <h3 id="TestCase">Test Case</h3> - - <p>A <b>test case</b> is the unit of test execution. That is, distinct test cases are - executed independently. The failure of one is independent of the failure of any other.</p> - - <p>A test case consists of a single, possibly collective, assertion. The possibly multiple - constituent assertions in a test case's collective assertion are <b>not</b> independent. - Their interdependence may be crucial to specifying correct operation for a test. A test - case may involve a series of steps, each concluding in an assertion, where each step - must succeed in order for the test case to continue. As another example, a test may - require some "set up" to be performed that must be undone ("torn down" in JUnit - parlance) once the test is complete. In this case, you could use Haskell's - <tt>IO.bracket</tt> function to achieve the desired effect.</p> - - <p>You can make a test case from an assertion by applying the <tt>TestCase</tt> constructor. - For example, <tt>(TestCase (return ()))</tt> is a test case that never - fails, and - <tt>(TestCase (assertEqual "for x," 3 x))</tt> - is a test case that checks that the value of <tt>x</tt> is 3. Additional ways - to create test cases are described later under <a href="#AdvancedFeatures">Advanced - Features</a>.</p> - - <h3 id="Tests">Tests</h3> - - <p>As soon as you have more than one test, you'll want to name them to tell them apart. As - soon as you have more than several tests, you'll want to group them to process them more - easily. So, naming and grouping are the two keys to managing collections of tests.</p> - - <p>In tune with the "composite" design pattern [<a href="#DesignPatterns">1</a>], a - <b>test</b> is defined as a package of test cases. Concretely, a test is either a single - test case, a group of tests, or either of the first two identified by a label.</p> - <pre> - data Test = TestCase Assertion - | TestList [Test] - | TestLabel String Test -</pre> - <p>There are three important features of this definition to note:</p> - <ul> - <li>A <tt>TestList</tt> consists of a list of tests rather than a list of test cases. - This means that the structure of a <tt>Test</tt> is actually a tree. Using a - hierarchy helps organize tests just as it helps organize files in a file system.</li> - <li>A <tt>TestLabel</tt> is attached to a test rather than to a test case. This means - that all nodes in the test tree, not just test case (leaf) nodes, can be labeled. - Hierarchical naming helps organize tests just as it helps organize files in a file - system.</li> - <li>A <tt>TestLabel</tt> is separate from both <tt>TestCase</tt> and <tt>TestList</tt>. - This means that labeling is optional everywhere in the tree. Why is this a good - thing? Because of the hierarchical structure of a test, each constituent test case - is uniquely identified by its path in the tree, ignoring all labels. Sometimes a - test case's path (or perhaps its subpath below a certain node) is a perfectly - adequate "name" for the test case (perhaps relative to a certain node). In this - case, creating a label for the test case is both unnecessary and inconvenient.</li> - </ul> - <p>The number of test cases that a test comprises can be computed with - <tt>testCaseCount</tt>.</p> - <pre> - testCaseCount :: Test -> Int -</pre> - <p>As mentioned above, a test is identified by its <b>path</b> in the test hierarchy.</p> - <pre> - data Node = ListItem Int | Label String - deriving (Eq, Show, Read) - - type Path = [Node] -- Node order is from test case to root. -</pre> - <p>Each occurrence of <tt>TestList</tt> gives rise to a <tt>ListItem</tt> and each - occurrence of <tt>TestLabel</tt> gives rise to a <tt>Label</tt>. The <tt>ListItem</tt>s - by themselves ensure uniqueness among test case paths, while the <tt>Label</tt>s allow - you to add mnemonic names for individual test cases and collections of them.</p> - - <p>Note that the order of nodes in a path is reversed from what you might expect: The first - node in the list is the one deepest in the tree. This order is a concession to - efficiency: It allows common path prefixes to be shared.</p> - - <p>The paths of the test cases that a test comprises can be computed with - <tt>testCasePaths</tt>. The paths are listed in the order in which the corresponding - test cases would be executed.</p> - <pre> - testCasePaths :: Test -> [Path] -</pre> - - <p>The three variants of <tt>Test</tt> can be constructed simply by applying - <tt>TestCase</tt>, <tt>TestList</tt>, and <tt>TestLabel</tt> to appropriate arguments. - Additional ways to create tests are described later under <a href="#AdvancedFeatures" - >Advanced Features</a>.</p> - - <p>The design of the type <tt>Test</tt> provides great conciseness, flexibility, and - convenience in specifying tests. Moreover, the nature of Haskell significantly augments - these qualities:</p> - <ul> - <li>Combining assertions and other code to construct test cases is easy with the - <tt>IO</tt> monad.</li> - <li>Using overloaded functions and special operators (see below), specification of - assertions and tests is extremely compact.</li> - <li>Structuring a test tree by value, rather than by name as in JUnit, provides for more - convenient, flexible, and robust test suite specification. In particular, a test - suite can more easily be computed "on the fly" than in other test frameworks.</li> - <li>Haskell's powerful abstraction facilities provide unmatched support for test - refactoring.</li> - </ul> - - <h3 id="AdvancedFeatures">Advanced Features</h3> - - <p>HUnit provides additional features for specifying assertions and tests more conveniently - and concisely. These facilities make use of Haskell type classes.</p> - - <p>The following operators can be used to construct assertions.</p> - <pre> - infix 1 @?, @=?, @?= - - (@?) :: (AssertionPredicable t) => t -> String -> Assertion - pred @? msg = assertionPredicate pred >>= assertBool msg - - (@=?) :: (Eq a, Show a) => a -> a -> Assertion - expected @=? actual = assertEqual "" expected actual - - (@?=) :: (Eq a, Show a) => a -> a -> Assertion - actual @?= expected = assertEqual "" expected actual -</pre> - <p>You provide a boolean condition and failure message separately to <tt>(@?)</tt>, as for - <tt>assertBool</tt>, but in a different order. The <tt>(@=?)</tt> and <tt>(@?=)</tt> - operators provide shorthands for <tt>assertEqual</tt> when no preface is required. They - differ only in the order in which the expected and actual values are provided. (The - actual value--the uncertain one--goes on the "?" side of the operator.)</p> - - <p>The <tt>(@?)</tt> operator's first argument is something from which an assertion - predicate can be made, that is, its type must be <tt>AssertionPredicable</tt>.</p> - <pre> - type AssertionPredicate = IO Bool - - class AssertionPredicable t - where assertionPredicate :: t -> AssertionPredicate - - instance AssertionPredicable Bool - where assertionPredicate = return - - instance (AssertionPredicable t) => AssertionPredicable (IO t) - where assertionPredicate = (>>= assertionPredicate) -</pre> - <p>The overloaded <tt>assert</tt> function in the <tt>Assertable</tt> type class constructs - an assertion.</p> - <pre> - class Assertable t - where assert :: t -> Assertion - - instance Assertable () - where assert = return - - instance Assertable Bool - where assert = assertBool "" - - instance (ListAssertable t) => Assertable [t] - where assert = listAssert - - instance (Assertable t) => Assertable (IO t) - where assert = (>>= assert) -</pre> - <p>The <tt>ListAssertable</tt> class allows <tt>assert</tt> to be applied to <tt>[Char]</tt> - (that is, <tt>String</tt>).</p> - <pre> - class ListAssertable t - where listAssert :: [t] -> Assertion - - instance ListAssertable Char - where listAssert = assertString -</pre> - <p>With the above declarations, <tt>(assert ())</tt>, - <tt>(assert True)</tt>, and <tt>(assert "")</tt> (as well as - <tt>IO</tt> forms of these values, such as <tt>(return ())</tt>) are all - assertions that never fail, while <tt>(assert False)</tt> and - <tt>(assert "some failure message")</tt> (and their - <tt>IO</tt> forms) are assertions that always fail. You may define additional - instances for the type classes <tt>Assertable</tt>, <tt>ListAssertable</tt>, and - <tt>AssertionPredicable</tt> if that should be useful in your application.</p> - - <p>The overloaded <tt>test</tt> function in the <tt>Testable</tt> type class constructs a - test.</p> - <pre> - class Testable t - where test :: t -> Test - - instance Testable Test - where test = id - - instance (Assertable t) => Testable (IO t) - where test = TestCase . assert - - instance (Testable t) => Testable [t] - where test = TestList . map test -</pre> - <p>The <tt>test</tt> function makes a test from either an <tt>Assertion</tt> (using - <tt>TestCase</tt>), a list of <tt>Testable</tt> items (using <tt>TestList</tt>), or - a <tt>Test</tt> (making no change).</p> - - <p>The following operators can be used to construct tests.</p> - <pre> - infix 1 ~?, ~=?, ~?= - infixr 0 ~: - - (~?) :: (AssertionPredicable t) => t -> String -> Test - pred ~? msg = TestCase (pred @? msg) - - (~=?) :: (Eq a, Show a) => a -> a -> Test - expected ~=? actual = TestCase (expected @=? actual) - - (~?=) :: (Eq a, Show a) => a -> a -> Test - actual ~?= expected = TestCase (actual @?= expected) - - (~:) :: (Testable t) => String -> t -> Test - label ~: t = TestLabel label (test t) -</pre> - <p><tt>(~?)</tt>, <tt>(~=?)</tt>, and <tt>(~?=)</tt> each make an assertion, as for - <tt>(@?)</tt>, <tt>(@=?)</tt>, and <tt>(@?=)</tt>, respectively, and then a test case - from that assertion. <tt>(~:)</tt> attaches a label to something that is - <tt>Testable</tt>. You may define additional instances for the type class - <tt>Testable</tt> should that be useful.</p> - - <h2 id="RunningTests">Running Tests</h2> - - <p>HUnit is structured to support multiple test controllers. The first subsection below - describes the <a href="#TestExecution">test execution</a> characteristics common to all - test controllers. The second subsection describes the <a href="#Text-BasedController" - >text-based controller</a> that is included with HUnit.</p> - - <h3 id="TestExecution">Test Execution</h3> - - <p>All test controllers share a common test execution model. They differ only in how the - results of test execution are shown.</p> - - <p>The execution of a test (a value of type <tt>Test</tt>) involves the serial execution (in - the <tt>IO</tt> monad) of its constituent test cases. The test cases are executed in a - depth-first, left-to-right order. During test execution, four counts of test cases are - maintained:</p> - <pre> - data Counts = Counts { cases, tried, errors, failures :: Int } - deriving (Eq, Show, Read) -</pre> - <ul> - <li><tt>cases</tt> is the number of test cases included in the test. This number is a - static property of a test and remains unchanged during test execution.</li> - <li><tt>tried</tt> is the number of test cases that have been executed so far during the - test execution.</li> - <li><tt>errors</tt> is the number of test cases whose execution ended with an unexpected - exception being raised. Errors indicate problems with test cases, as opposed to the - code under test.</li> - <li><tt>failures</tt> is the number of test cases whose execution asserted failure. - Failures indicate problems with the code under test.</li> - </ul> - <p>Why is there no count for test case successes? The technical reason is that the counts - are maintained such that the number of test case successes is always equal to - <tt>(tried - (errors + failures))</tt>. The - psychosocial reason is that, with test-centered development and the expectation that - test failures will be few and short-lived, attention should be focused on the failures - rather than the successes.</p> - - <p>As test execution proceeds, three kinds of reporting event are communicated to the test - controller. (What the controller does in response to the reporting events depends on the - controller.)</p> - <ul> - <li><i>start</i> -- Just prior to initiation of a test case, the path of the test case - and the current counts (excluding the current test case) are reported.</li> - <li><i>error</i> -- When a test case terminates with an error, the error message is - reported, along with the test case path and current counts (including the current - test case).</li> - <li><i>failure</i> -- When a test case terminates with a failure, the failure message is - reported, along with the test case path and current counts (including the current - test case).</li> - </ul> - <p>Typically, a test controller shows <i>error</i> and <i>failure</i> reports immediately - but uses the <i>start</i> report merely to update an indication of overall test - execution progress.</p> - - <h3 id="Text-BasedController">Text-Based Controller</h3> - - <p>A text-based test controller is included with HUnit.</p> - <pre> - runTestText :: PutText st -> Test -> IO (Counts, st) -</pre> - <p><tt>runTestText</tt> is generalized on a <i>reporting scheme</i> given as its first - argument. During execution of the test given as its second argument, the controller - creates a string for each reporting event and processes it according to the reporting - scheme. When test execution is complete, the controller returns the final counts along - with the final state for the reporting scheme.</p> - - <p>The strings for the three kinds of reporting event are as follows.</p> - <ul> - <li>A <i>start</i> report is the result of the function <tt>showCounts</tt> applied to - the counts current immediately prior to initiation of the test case being started.</li> - <li>An <i>error</i> report is of the form - "<tt>Error in: <i>path</i>\n<i>message</i></tt>", - where <i>path</i> is the path of the test case in error, as shown by - <tt>showPath</tt>, and <i>message</i> is a message describing the error. If the path - is empty, the report has the form "<tt>Error:\n<i>message</i></tt>".</li> - <li>A <i>failure</i> report is of the form - "<tt>Failure in: <i>path</i>\n<i>message</i></tt>", where - <i>path</i> is the path of the test case in error, as shown by - <tt>showPath</tt>, and <i>message</i> is the failure message. If the path is empty, - the report has the form "<tt>Failure:\n<i>message</i></tt>".</li> - </ul> - - <p>The function <tt>showCounts</tt> shows a set of counts.</p> - <pre> - showCounts :: Counts -> String -</pre> - <p>The form of its result is - "<tt>Cases: <i>cases</i> Tried: <i>tried</i> Errors: <i>errors</i> Failures: <i>failures</i></tt>" - where <i>cases</i>, <i>tried</i>, <i>errors</i>, and <i>failures</i> are the count - values.</p> - - <p>The function <tt>showPath</tt> shows a test case path.</p> - <pre> - showPath :: Path -> String -</pre> - <p>The nodes in the path are reversed (so that the path reads from the root down to the test - case), and the representations for the nodes are joined by '<tt>:</tt>' separators. The - representation for <tt>(ListItem <i>n</i>)</tt> is <tt>(show n)</tt>. The representation - for <tt>(Label <i>label</i>)</tt> is normally <i>label</i>. However, if <i>label</i> - contains a colon or if <tt>(show <i>label</i>)</tt> is different from <i>label</i> - surrounded by quotation marks--that is, if any ambiguity could exist--then <tt>(Label - <i>label</i>)</tt> is represented as <tt>(show <i>label</i>)</tt>.</p> - - <p>HUnit includes two reporting schemes for the text-based test controller. You may define - others if you wish.</p> - <pre> - putTextToHandle :: Handle -> Bool -> PutText Int -</pre> - <p><tt>putTextToHandle</tt> writes error and failure reports, plus a report of the final - counts, to the given handle. Each of these reports is terminated by a newline. In - addition, if the given flag is <tt>True</tt>, it writes start reports to the handle as - well. A start report, however, is not terminated by a newline. Before the next report is - written, the start report is "erased" with an appropriate sequence of carriage return - and space characters. Such overwriting realizes its intended effect on terminal devices.</p> - <pre> - putTextToShowS :: PutText ShowS -</pre> - <p><tt>putTextToShowS</tt> ignores start reports and simply accumulates error and failure - reports, terminating them with newlines. The accumulated reports are returned (as the - second element of the pair returned by <tt>runTestText</tt>) as a <tt>ShowS</tt> - function (that is, one with type <tt>(String -> String)</tt>) whose - first argument is a string to be appended to the accumulated report lines.</p> - - <p>HUnit provides a shorthand for the most common use of the text-based test controller.</p> - <pre> - runTestTT :: Test -> IO Counts -</pre> - <p><tt>runTestTT</tt> invokes <tt>runTestText</tt>, specifying <tt>(putTextToHandle stderr - True)</tt> for the reporting scheme, and returns the final counts from the test - execution.</p> - - - <h2 id="References">References</h2> - - <dl> - - <dt id="DesignPatterns">[1] Gamma, E., et al. Design Patterns: Elements of Reusable - Object-Oriented Software, Addison-Wesley, Reading, MA, 1995.</dt> - <dd>The classic book describing design patterns in an object-oriented context.</dd> - - <dt> - <a href="http://www.junit.org">http://www.junit.org</a> - </dt> - <dd>Web page for JUnit, the tool after which HUnit is modeled.</dd> - - <dt> - <a href="http://junit.sourceforge.net/doc/testinfected/testing.htm"> - http://junit.sourceforge.net/doc/testinfected/testing.htm</a> - </dt> - <dd>A good introduction to test-first development and the use of JUnit.</dd> - - <dt> - <a href="http://junit.sourceforge.net/doc/cookstour/cookstour.htm"> - http://junit.sourceforge.net/doc/cookstour/cookstour.htm</a> - </dt> - <dd>A description of the internal structure of JUnit. Makes for an interesting - comparison between JUnit and HUnit.</dd> - - </dl> - - <hr/> - - <p>The HUnit software and this guide were written by Dean Herington (<a - href="mailto:herin...@cs.unc.edu">herin...@cs.unc.edu</a>).</p> - </body> -</html> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/HUnit-1.3.1.0/examples/Example.hs new/HUnit-1.3.1.1/examples/Example.hs --- old/HUnit-1.3.1.0/examples/Example.hs 2016-01-11 10:04:20.000000000 +0100 +++ new/HUnit-1.3.1.1/examples/Example.hs 2016-01-19 17:16:50.000000000 +0100 @@ -1,9 +1,9 @@ -- Example.hs -- Examples from HUnit user's guide -- -- For more examples, check out the tests directory. It contains unit tests --- for HUnit. +-- for HUnit. -module Main where +module Example where import Test.HUnit @@ -36,5 +36,5 @@ partB y @? "(partB " ++ show y ++ ") failed" ] main :: IO Counts -main = do runTestTT tests +main = do _ <- runTestTT tests runTestTT tests' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/HUnit-1.3.1.0/prologue.txt new/HUnit-1.3.1.1/prologue.txt --- old/HUnit-1.3.1.0/prologue.txt 2016-01-11 10:04:20.000000000 +0100 +++ new/HUnit-1.3.1.1/prologue.txt 1970-01-01 01:00:00.000000000 +0100 @@ -1,2 +0,0 @@ -HUnit is a unit testing framework for Haskell, inspired by the JUnit -tool for Java, see: <http://www.junit.org>. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/HUnit-1.3.1.0/tests/HUnitTests.hs new/HUnit-1.3.1.1/tests/HUnitTests.hs --- old/HUnit-1.3.1.0/tests/HUnitTests.hs 2016-01-11 10:04:20.000000000 +0100 +++ new/HUnit-1.3.1.1/tests/HUnitTests.hs 2016-01-19 17:16:50.000000000 +0100 @@ -10,6 +10,7 @@ import HUnitTestBase import HUnitTestExtended import TerminalTest +import Example () main :: IO () main = do