2022-05-26 10:29:47 -04:00
|
|
|
module Example
|
|
|
|
import TAP
|
|
|
|
|
2022-05-27 07:31:11 -04:00
|
|
|
-- this is for the examples, you don't need it for the library itself
|
|
|
|
import Data.String
|
|
|
|
import Data.IORef
|
|
|
|
|
|
|
|
|
|
|
|
E = List (String, Nat)
|
|
|
|
ToInfo Integer where toInfo n = [("val", show n)]
|
|
|
|
|
|
|
|
-- a test suite consists of a list of tests, like in haskell's tasty
|
|
|
|
-- or something like that. each one can be a group, so really it's a tree.
|
|
|
|
--
|
|
|
|
-- each test returns some `Either e a` (or `EitherT e IO a`), where
|
|
|
|
-- `Left` is failure and `Right` is success.
|
|
|
|
--
|
|
|
|
-- `a` and `b` both have to implement `ToInfo`, which allows them to be
|
|
|
|
-- printed as a YAML document. `()` implements `ToInfo` with an empty document,
|
|
|
|
-- which is probably what you want most of the time in a success. but you
|
|
|
|
-- can return any info you might need
|
|
|
|
--
|
|
|
|
-- if you expect a computation to fail, you can use `testThrows[IO]`, which
|
|
|
|
-- takes a function to classify what errors are expected
|
|
|
|
tests1 : Test
|
|
|
|
tests1 = "one" :- [
|
|
|
|
test "success" {e = E} $
|
|
|
|
Right (),
|
|
|
|
testIO "success in IO" {e = E} $ do
|
|
|
|
let val = Z
|
|
|
|
r <- newIORef val
|
|
|
|
res <- readIORef r
|
|
|
|
if res == val then pure () else
|
|
|
|
throwError [("wanted", val), ("got", res)],
|
|
|
|
test "failure" {a = ()} $
|
|
|
|
Left [("oops", "ouch")],
|
|
|
|
testThrows "throws 0" (== 0) {a = ()} $
|
|
|
|
throwError 0
|
|
|
|
]
|
|
|
|
|
|
|
|
-- idris has trouble inferring types that seem to be obvious to me, which is why
|
|
|
|
-- i keep having to specify `e` above.
|
|
|
|
-- but anyway, most of the time i wrap these basic test functions in something
|
|
|
|
-- more specific to the situation. like an hunit-style assertion
|
|
|
|
-- (maybe the library should provide some of these?)
|
|
|
|
|
|
|
|
assertEq : (Eq a, Show a) => (label : String) -> (got, exp : a) -> Test
|
|
|
|
assertEq label got exp = test label $
|
|
|
|
if got == exp then Right ()
|
|
|
|
else Left [("exp", exp), ("got", got)]
|
|
|
|
|
|
|
|
tests2 : Test
|
|
|
|
tests2 = "two" :- [
|
|
|
|
assertEq "2 + 2" (2 + 2) 4,
|
|
|
|
assertEq "im gay" (words "im gay") ["im", "gay"]
|
|
|
|
]
|
|
|
|
|
|
|
|
-- you can use `todo` and `skip` for tests you haven't written yet, can't run
|
|
|
|
-- in the current environment, or whatever. `todoWith` and `skipWith` take an
|
|
|
|
-- extra reason.
|
|
|
|
|
|
|
|
tests3 : Test
|
|
|
|
tests3 = "three" :- [
|
|
|
|
todo "drink water",
|
|
|
|
skip $ assertEq "im gay" (words "im gay") ["im", "gay"],
|
|
|
|
|
|
|
|
todoWith "take a sippy" "drink water",
|
|
|
|
skipWith "(everyone already knows)" $
|
|
|
|
assertEq "im gay" (words "im gay") ["im", "gay"]
|
|
|
|
]
|
|
|
|
|
2022-05-26 10:29:47 -04:00
|
|
|
|
2022-05-27 07:31:11 -04:00
|
|
|
-- if you pass `--version 14` (or `-V 14`) you get the output:
|
|
|
|
--
|
|
|
|
-- TAP version 14
|
|
|
|
-- 1..3
|
|
|
|
-- # Subtest: one
|
|
|
|
-- 1..4
|
|
|
|
-- ok 1 - success
|
|
|
|
-- ok 2 - success in IO
|
|
|
|
-- not ok 3 - failure
|
|
|
|
-- ---
|
|
|
|
-- oops: "ouch"
|
|
|
|
-- ...
|
|
|
|
-- ok 4 - throws 0
|
|
|
|
-- not ok 1 - one
|
|
|
|
-- # Subtest: two
|
|
|
|
-- 1..2
|
|
|
|
-- ok 1 - 2 + 2
|
|
|
|
-- ok 2 - im gay
|
|
|
|
-- ok 2 - two
|
|
|
|
-- # Subtest: three
|
|
|
|
-- 1..4
|
|
|
|
-- ok 1 - drink water # todo
|
|
|
|
-- ok 2 - im gay # skip
|
|
|
|
-- ok 3 - drink water # todo take a sippy
|
|
|
|
-- ok 4 - im gay # skip (everyone already knows)
|
|
|
|
-- ok 3 - three
|
|
|
|
--
|
|
|
|
--
|
|
|
|
-- if you pass `--version 13`, or nothing, it's flattened and you get
|
|
|
|
--
|
|
|
|
-- TAP version 13
|
|
|
|
-- 1..10
|
|
|
|
-- ok 1 - one ⟫ success
|
|
|
|
-- ok 2 - one ⟫ success in IO
|
|
|
|
-- not ok 3 - one ⟫ failure
|
|
|
|
-- ---
|
|
|
|
-- oops: "ouch"
|
|
|
|
-- ...
|
|
|
|
-- ok 4 - one ⟫ throws 0
|
|
|
|
-- ok 5 - two ⟫ 2 + 2
|
|
|
|
-- ok 6 - two ⟫ im gay
|
|
|
|
-- ok 7 - three ⟫ drink water # todo
|
|
|
|
-- ok 8 - three ⟫ im gay # skip
|
|
|
|
-- ok 9 - three ⟫ drink water # todo take a sippy
|
|
|
|
-- ok 10 - three ⟫ im gay # skip (everyone already knows)
|
|
|
|
--
|
|
|
|
-- it is `/usr/bin/prove`'s fault that flat is the default.
|
|
|
|
--
|
|
|
|
-- you can also have nice colours with `--colour/--color/-c`, and run only some
|
|
|
|
-- tests with `--filter`.
|
2022-05-26 10:29:47 -04:00
|
|
|
main : IO ()
|
2022-05-27 07:31:11 -04:00
|
|
|
main = TAP.main !getTestOpts [tests1, tests2, tests3]
|