Here is one way to do it. You can execute code at compile time with a macro or statement static. Please note that there is still no way to reliably count them on several modules.
import macros, strutils
proc beginTests()
var countTested = 0
var countFailed = 0
var countPassed = 0
var totalTests = 0
var totalTestsCT {.compiletime.} = 0
macro endTests(): stmt =
quote do:
proc beginTests() =
totalTests = `totalTestsCT`
proc assertEqualsImpl*[T](testName: string, expected: T, p: (proc(): T)) =
countTested += 1
write(stdout, format("[$num/$total] $name: ",
"num", countTested, "total", totalTests, "name", testName))
var val = p()
if val == expected:
write(stdout, "passed\n")
countPassed += 1
else:
write(stdout, "failed\n")
countFailed += 1
macro assertEquals*[T](testName: string, expected: T, p: (proc(): T)): stmt =
totalTestsCT += 1
quote do:
assertEqualsImpl(`testName`, `expected`, `p`)
when isMainModule:
beginTests()
assertEquals("test #A", 12, proc(): int = 14-2)
assertEquals("test #B", 12, proc(): int = 12-2)
endTests()
,
testSuite:
assertEquals("test #A", 12, proc(): int = 14-2)
assertEquals("test #B", 12, proc(): int = 12-2)
testSuite .
, .