-
Notifications
You must be signed in to change notification settings - Fork 17
/
Copy pathkiller.nim
57 lines (45 loc) · 1.33 KB
/
killer.nim
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
when not compiles(fail "bogus"):
import pkg/balls
type
Killer* = object
final: int
n: int
proc failMsg(k: Killer): string =
case k.n
of 0: "uninitialized"
of 1: "unused"
else: "misused; " & $(k.n - 1) & " uses, expected " & $(k.final - 1)
proc `=destroy`*(k: var Killer) {.raises: [].} =
## Raise a `Defect` if `k` has errors.
##
## `check()` should be used to have errors raised as test failures.
##
## This destructor is a last-ditch effort for when `check()` is not
## run.
# Only crash if there's no exception running
if k.final != k.n and getCurrentException() == nil:
raise newException(Defect, k.failMsg)
proc check*(k: Killer) {.raises: [FailError].} =
## Check `k` for errors.
if k.final != k.n:
fail k.failMsg
proc clear*(k: var Killer) =
## Clear and defuse `k`. `k` is not reusable after this.
k.final = 0
k.n = 0
proc initKiller*(final = 1): Killer =
Killer(n: 1, final: final + 1)
proc newKiller*(final = 1): Killer =
## FIXME: rename this to initKiller
Killer(n: 1, final: final + 1)
proc inc*(k: var Killer) = system.inc k.n
template step*(k: Killer): int = k.n - 1
template step*(k: var Killer, i: int) =
bind check
check k.n == i, "expected step " & $k.n & " but hit " & $i
inc k.n
k.final = max(i, k.final)
template step*(i: int) =
mixin k
bind step
step k, i