Merge pull request #3205 from fenekku/unittest-work-2

other unittest pull-request
This commit is contained in:
Andreas Rumpf 2015-08-21 21:30:10 +02:00
commit 47919e219b
2 changed files with 66 additions and 15 deletions

36
lib/pure/unittest.nim Normal file → Executable file
View file

@ -70,9 +70,6 @@ var ## Global unittest settings!
checkpoints = @[] checkpoints = @[]
template testSetupIMPL*: stmt {.immediate, dirty.} = discard #Should this be public or even exist?
template testTeardownIMPL*: stmt {.immediate, dirty.} = discard
proc shouldRun(testName: string): bool = proc shouldRun(testName: string): bool =
result = true result = true
@ -92,8 +89,8 @@ template suite*(name: expr, body: stmt): stmt {.immediate, dirty.} =
## test "2 + 2 = 4": ## test "2 + 2 = 4":
## check(2+2 == result) ## check(2+2 == result)
## ##
## test "2 + -2 != 4": ## test "(2 + -2) != 4":
## check(2+2 != result) ## check(2 + -2 != result)
## ##
## # No teardown needed ## # No teardown needed
## ##
@ -106,9 +103,11 @@ template suite*(name: expr, body: stmt): stmt {.immediate, dirty.} =
## [OK] (2 + -2) != 4 ## [OK] (2 + -2) != 4
block: block:
template setup(setupBody: stmt): stmt {.immediate, dirty.} = template setup(setupBody: stmt): stmt {.immediate, dirty.} =
var testSetupIMPLFlag = true
template testSetupIMPL: stmt {.immediate, dirty.} = setupBody template testSetupIMPL: stmt {.immediate, dirty.} = setupBody
template teardown(teardownBody: stmt): stmt {.immediate, dirty.} = template teardown(teardownBody: stmt): stmt {.immediate, dirty.} =
var testTeardownIMPLFlag = true
template testTeardownIMPL: stmt {.immediate, dirty.} = teardownBody template testTeardownIMPL: stmt {.immediate, dirty.} = teardownBody
body body
@ -149,7 +148,7 @@ template test*(name: expr, body: stmt): stmt {.immediate, dirty.} =
var testStatusIMPL {.inject.} = OK var testStatusIMPL {.inject.} = OK
try: try:
testSetupIMPL() when declared(testSetupIMPLFlag): testSetupIMPL()
body body
except: except:
@ -159,7 +158,7 @@ template test*(name: expr, body: stmt): stmt {.immediate, dirty.} =
fail() fail()
finally: finally:
testTeardownIMPL() when declared(testTeardownIMPLFlag): testTeardownIMPL()
testDone name, testStatusIMPL testDone name, testStatusIMPL
proc checkpoint*(msg: string) = proc checkpoint*(msg: string) =
@ -234,41 +233,48 @@ macro check*(conditions: stmt): stmt {.immediate.} =
when compiles(string($value)): when compiles(string($value)):
checkpoint(name & " was " & $value) checkpoint(name & " was " & $value)
proc inspectArgs(exp: NimNode) = proc inspectArgs(exp: NimNode): NimNode =
result = copyNimTree(exp)
for i in countup(1, exp.len - 1): for i in countup(1, exp.len - 1):
if exp[i].kind notin nnkLiterals: if exp[i].kind notin nnkLiterals:
inc counter inc counter
var arg = newIdentNode(":p" & $counter) var arg = newIdentNode(":p" & $counter)
var argStr = exp[i].toStrLit var argStr = exp[i].toStrLit
var paramAst = exp[i] var paramAst = exp[i]
if exp[i].kind in nnkCallKinds: inspectArgs(exp[i]) if exp[i].kind == nnkIdent:
argsPrintOuts.add getAst(print(argStr, paramAst))
if exp[i].kind in nnkCallKinds:
var callVar = newIdentNode(":c" & $counter)
argsAsgns.add getAst(asgn(callVar, paramAst))
result[i] = callVar
argsPrintOuts.add getAst(print(argStr, callVar))
if exp[i].kind == nnkExprEqExpr: if exp[i].kind == nnkExprEqExpr:
# ExprEqExpr # ExprEqExpr
# Ident !"v" # Ident !"v"
# IntLit 2 # IntLit 2
paramAst = exp[i][1] result[i] = exp[i][1]
if exp[i].typekind notin {ntyTypeDesc}: if exp[i].typekind notin {ntyTypeDesc}:
argsAsgns.add getAst(asgn(arg, paramAst)) argsAsgns.add getAst(asgn(arg, paramAst))
argsPrintOuts.add getAst(print(argStr, arg)) argsPrintOuts.add getAst(print(argStr, arg))
if exp[i].kind != nnkExprEqExpr: if exp[i].kind != nnkExprEqExpr:
exp[i] = arg result[i] = arg
else: else:
exp[i][1] = arg result[i][1] = arg
case checked.kind case checked.kind
of nnkCallKinds: of nnkCallKinds:
template rewrite(call, lineInfoLit: expr, callLit: string, template rewrite(call, lineInfoLit: expr, callLit: string,
argAssgs, argPrintOuts: stmt): stmt = argAssgs, argPrintOuts: stmt): stmt =
block: block:
argAssgs argAssgs #all callables (and assignments) are run here
if not call: if not call:
checkpoint(lineInfoLit & ": Check failed: " & callLit) checkpoint(lineInfoLit & ": Check failed: " & callLit)
argPrintOuts argPrintOuts
fail() fail()
var checkedStr = checked.toStrLit var checkedStr = checked.toStrLit
inspectArgs(checked) let parameterizedCheck = inspectArgs(checked)
result = getAst(rewrite(checked, checked.lineinfo, checkedStr, result = getAst(rewrite(parameterizedCheck, checked.lineinfo, checkedStr,
argsAsgns, argsPrintOuts)) argsAsgns, argsPrintOuts))
of nnkStmtList: of nnkStmtList:

View file

@ -38,3 +38,48 @@ proc defectiveRobot() =
test "unittest expect": test "unittest expect":
expect IOError, OSError, ValueError, AssertionError: expect IOError, OSError, ValueError, AssertionError:
defectiveRobot() defectiveRobot()
var
a = 1
b = -1
c = 1
#unittests are sequential right now
suite "suite with only teardown":
teardown:
b = 2
test "unittest with only teardown 1":
check a == c
test "unittest with only teardown 2":
check b > a
suite "suite with only setup":
setup:
var testVar = "from setup"
test "unittest with only setup 1":
check testVar == "from setup"
check b > a
b = -1
test "unittest with only setup 2":
check b < a
suite "suite with none":
test "unittest with none":
check b < a
suite "suite with both":
setup:
a = -2
teardown:
c = 2
test "unittest with both 1":
check b > a
test "unittest with both 2":
check c == 2