Skip to content
Fetching contributors…
Cannot retrieve contributors at this time
193 lines (155 sloc) 4.31 KB
title"Testing with Therie"
doc"
Therie is a small and simple behavioral-style testing suite that comes with \
Atomy.
"
dynamic(nesting-level, 0)
doc"
A trivial container of \hl{passed} and \hl{failed} counts, with accessors \
for both.
" for:
class(Stats):
attr-accessor(#passed, #failed)
initialize := do:
@passed = 0
@failed = 0
inspect := f"Stats(@passed = %d, @failed = %d)" [@passed, @failed]
dynamic(stats, nil)
section("Structure"):
doc"
Run \hl{tests} and keep track of how many passed and how many failed, \
printing the stats at the end and returning them.
" spec {
=> Stats
} for {
theorize(&tests) :=
let(stats = Stats new):
tests call
"\n" display
^stats onto:
f"total of %d tests (%s passed, %s failed)" [
failed + passed
passed to-s colored(#green)
if(failed == 0)
then: "0"
else: failed to-s colored(#red)
] display
"\n" display
^stats
} examples:
theorize:
describe("foo"):
it("does x"): true should-be(false)
it("does x"): true should-be(true)
doc"
Logically group together a set of behavior.
Prints out \hl{what}, with each test in \hl{body} indented afterward.
" for {
describe(what, &body) := do:
f"- %s" [what] indented println
let(nesting-level = ^nesting-level + 1):
body call
nil
} examples:
describe("foo"):
it("does x"): true should-be(false)
it("does x"): true should-be(true)
doc"
Describe some behavior that the tests in \hl{body} will demonstrate.
" for {
it(description, &tests) := do:
{ tests call
f"✓ %s" [description] indented colored(#green) println
} rescue {
e:
when(^stats):
^stats failed += 1
f"✗ %s" [description] indented colored(#red) println
f" ` %s: %s" [
e class name
e message
] indented colored(#yellow) println
e backtrace first((ENV["THERIE_BT_LIMIT"] || 5) to-i) each [l]:
f" %s" [l colored(#cyan)] indented println
} else:
when(^stats):
^stats passed += 1
nil
} examples:
it("adds correctly"): (2 + 2) should-be(4)
it("adds correctly"): (1 + 2) should-be(4)
section("Tests"):
doc"
Test that \hl{predicate} is satisified by \hl{o} by evaluating it with \
\hl{o} as \hl{self}.
" for {
macro(x should ~(check: Block)):
`(unless(~x onto ~check):
raise(f"assertion failed for %v" ['~x pretty]))
} examples:
(2 + 2) should: even?
(2 + 2) should: odd?
doc"
Test for \hl{x == y}.
" for {
x should-be(y) :=
unless(x == y):
raise(f"expected %v, got %v" [y, x])
} examples:
(2 + 2) should-be(4)
(1 + 2) should-be(4)
doc"
Test that executing \hl{x} will raise an exception of class \hl{y}.
" spec {
x respond-to?(#call)
y is-a?(Class)
} for {
x should-raise(y) :=
x rescue {
e ->
unless(e kind-of?(y)):
raise(f"expected exception %s, got: %s" [y, e])
} else:
raise("#should-raise - no exception raised")
} examples:
{ abc } should-raise(NoMethodError)
{ #ok } should-raise(NoMethodError)
doc"
Test that executing \hl{x} will signal an error of class \hl{y}.
" spec {
x respond-to?(#call)
y is-a?(Class)
} for {
x should-error(y) :=
{ with-restarts(errored -> nil):
x call
raise("#should-error - no error signaled")
} bind {
(e: ExceptionError) ->
raise(e exception)
(e: Error):
when(e kind-of?(y)):
restart(#errored)
raise(f"expected error %s, got: %s" [y, e message])
}
} examples:
{ error(#foo) } should-error(SimpleError)
{ #ok } should-error(SimpleError)
-- helpers
String indented := " " * (^nesting-level * 2) + self
String colored(color) := do:
-- only makes sense to colorize if we're outputting to a terminal
unless(^output-port tty?):
return(self)
codes =
[ #black
#red
#green
#yellow
#blue
#magenta
#cyan
#white
] to-a zip((0 .. 7) to-a)
hash = Hash [codes]
"\e[3" + hash [color] to-s + "m" + self + "\e[0m"
Something went wrong with that request. Please try again.