Copyright | (c) NoviSci Inc 2020 |
---|---|
License | BSD3 |
Maintainer | bsaul@novisci.com |
Safe Haskell | None |
Language | Haskell2010 |
Synopsis
- encode :: ToJSON a => a -> ByteString
- class ToJSON a where
- toJSON :: a -> Value
- toEncoding :: a -> Encoding
- toJSONList :: [a] -> Value
- toEncodingList :: [a] -> Encoding
- newtype IO a = IO (State# RealWorld -> (# State# RealWorld, a #))
- withResource :: IO a -> (a -> IO ()) -> (IO a -> TestTree) -> TestTree
- askOption :: IsOption v => (v -> TestTree) -> TestTree
- localOption :: IsOption v => v -> TestTree -> TestTree
- adjustOption :: IsOption v => (v -> v) -> TestTree -> TestTree
- defaultMain :: TestTree -> IO ()
- defaultIngredients :: [Ingredient]
- defaultMainWithIngredients :: [Ingredient] -> TestTree -> IO ()
- includingOptions :: [OptionDescription] -> Ingredient
- after_ :: DependencyType -> Expr -> TestTree -> TestTree
- testGroup :: TestName -> [TestTree] -> TestTree
- type TestName = String
- data DependencyType
- data TestTree
- mkTimeout :: Integer -> Timeout
- data Timeout
- module Test.Tasty.HUnit
Re-exports
encode :: ToJSON a => a -> ByteString #
Efficiently serialize a JSON value as a lazy ByteString
.
This is implemented in terms of the ToJSON
class's toEncoding
method.
A type that can be converted to JSON.
Instances in general must specify toJSON
and should (but don't need
to) specify toEncoding
.
An example type and instance:
-- Allow ourselves to writeText
literals. {-# LANGUAGE OverloadedStrings #-} data Coord = Coord { x :: Double, y :: Double } instanceToJSON
Coord wheretoJSON
(Coord x y) =object
["x".=
x, "y".=
y]toEncoding
(Coord x y) =pairs
("x".=
x<>
"y".=
y)
Instead of manually writing your ToJSON
instance, there are two options
to do it automatically:
- Data.Aeson.TH provides Template Haskell functions which will derive an instance at compile time. The generated instance is optimized for your type so it will probably be more efficient than the following option.
- The compiler can provide a default generic implementation for
toJSON
.
To use the second, simply add a deriving
clause to your
datatype and declare a Generic
ToJSON
instance. If you require nothing other than
defaultOptions
, it is sufficient to write (and this is the only
alternative where the default toJSON
implementation is sufficient):
{-# LANGUAGE DeriveGeneric #-} import GHC.Generics data Coord = Coord { x :: Double, y :: Double } derivingGeneric
instanceToJSON
Coord wheretoEncoding
=genericToEncoding
defaultOptions
If on the other hand you wish to customize the generic decoding, you have to implement both methods:
customOptions =defaultOptions
{fieldLabelModifier
=map
toUpper
} instanceToJSON
Coord wheretoJSON
=genericToJSON
customOptionstoEncoding
=genericToEncoding
customOptions
Previous versions of this library only had the toJSON
method. Adding
toEncoding
had two reasons:
- toEncoding is more efficient for the common case that the output of
toJSON
is directly serialized to aByteString
. Further, expressing either method in terms of the other would be non-optimal. - The choice of defaults allows a smooth transition for existing users:
Existing instances that do not define
toEncoding
still compile and have the correct semantics. This is ensured by making the default implementation oftoEncoding
usetoJSON
. This produces correct results, but since it performs an intermediate conversion to aValue
, it will be less efficient than directly emitting anEncoding
. (this also means that specifying nothing more thaninstance ToJSON Coord
would be sufficient as a generically decoding instance, but there probably exists no good reason to not specifytoEncoding
in new instances.)
Nothing
Convert a Haskell value to a JSON-friendly intermediate type.
toEncoding :: a -> Encoding #
Encode a Haskell value as JSON.
The default implementation of this method creates an
intermediate Value
using toJSON
. This provides
source-level compatibility for people upgrading from older
versions of this library, but obviously offers no performance
advantage.
To benefit from direct encoding, you must provide an
implementation for this method. The easiest way to do so is by
having your types implement Generic
using the DeriveGeneric
extension, and then have GHC generate a method body as follows.
instanceToJSON
Coord wheretoEncoding
=genericToEncoding
defaultOptions
toJSONList :: [a] -> Value #
toEncodingList :: [a] -> Encoding #
Instances
A value of type
is a computation which, when performed,
does some I/O before returning a value of type IO
aa
.
There is really only one way to "perform" an I/O action: bind it to
Main.main
in your program. When your program is run, the I/O will
be performed. It isn't possible to perform I/O from an arbitrary
function, unless that function is itself in the IO
monad and called
at some point, directly or indirectly, from Main.main
.
IO
is a monad, so IO
actions can be combined using either the do-notation
or the >>
and >>=
operations from the Monad
class.
Instances
:: IO a | initialize the resource |
-> (a -> IO ()) | free the resource |
-> (IO a -> TestTree) |
|
-> TestTree |
Acquire the resource to run this test (sub)tree and release it afterwards
askOption :: IsOption v => (v -> TestTree) -> TestTree #
Customize the test tree based on the run-time options
localOption :: IsOption v => v -> TestTree -> TestTree #
Locally set the option value for the given test subtree
adjustOption :: IsOption v => (v -> v) -> TestTree -> TestTree #
Locally adjust the option value for the given test subtree
defaultMain :: TestTree -> IO () #
Parse the command line arguments and run the tests.
When the tests finish, this function calls exitWith
with the exit code
that indicates whether any tests have failed. Most external systems
(stack, cabal, travis-ci, jenkins etc.) rely on the exit code to detect
whether the tests pass. If you want to do something else after
defaultMain
returns, you need to catch the exception and then re-throw
it. Example:
import Test.Tasty import Test.Tasty.HUnit import System.Exit import Control.Exception test = testCase "Test 1" (2 @?= 3) main = defaultMain test `catch` (\e -> do if e == ExitSuccess then putStrLn "Yea" else putStrLn "Nay" throwIO e)
defaultIngredients :: [Ingredient] #
List of the default ingredients. This is what defaultMain
uses.
At the moment it consists of listingTests
and consoleTestReporter
.
defaultMainWithIngredients :: [Ingredient] -> TestTree -> IO () #
Parse the command line arguments and run the tests using the provided ingredient list.
When the tests finish, this function calls exitWith
with the exit code
that indicates whether any tests have failed. See defaultMain
for
details.
includingOptions :: [OptionDescription] -> Ingredient #
This ingredient doesn't do anything apart from registering additional options.
The option values can be accessed using askOption
.
:: DependencyType | whether to run the tests even if some of the dependencies fail |
-> Expr | the pattern |
-> TestTree | the subtree that depends on other tests |
-> TestTree | the subtree annotated with dependency information |
Like after
, but accepts the pattern as a syntax tree instead
of a string. Useful for generating a test tree programmatically.
Examples
Only match on the test's own name, ignoring the group names:
after_
AllFinish
(EQ
(Field
NF
) (StringLit
"Bar")) $testCase
"A test that depends on Foo.Bar" $ ...
Since: tasty-1.2
data DependencyType #
These are the two ways in which one test may depend on the others.
This is the same distinction as the hard vs soft dependencies in TestNG.
Since: tasty-1.2
AllSucceed | The current test tree will be executed after its dependencies finish, and only if all of the dependencies succeed. |
AllFinish | The current test tree will be executed after its dependencies finish, regardless of whether they succeed or not. |
Instances
Eq DependencyType | |
Defined in Test.Tasty.Core (==) :: DependencyType -> DependencyType -> Bool # (/=) :: DependencyType -> DependencyType -> Bool # | |
Show DependencyType | |
Defined in Test.Tasty.Core showsPrec :: Int -> DependencyType -> ShowS # show :: DependencyType -> String # showList :: [DependencyType] -> ShowS # |
The main data structure defining a test suite.
It consists of individual test cases and properties, organized in named groups which form a tree-like hierarchy.
There is no generic way to create a test case. Instead, every test
provider (tasty-hunit, tasty-smallcheck etc.) provides a function to
turn a test case into a TestTree
.
Groups can be created using testGroup
.
Timeout to be applied to individual tests
Timeout Integer String |
|
NoTimeout |
Instances
Show Timeout | |
IsOption Timeout | |
Defined in Test.Tasty.Options.Core defaultValue :: Timeout # parseValue :: String -> Maybe Timeout # optionName :: Tagged Timeout String # optionHelp :: Tagged Timeout String # showDefaultValue :: Timeout -> Maybe String # |
module Test.Tasty.HUnit