From 80e8a1c8c566fed63e8b8ce74b537e007c9abd31 Mon Sep 17 00:00:00 2001 From: Joey Payne Date: Wed, 8 Jul 2015 08:52:41 -0600 Subject: [PATCH] Added tearDown method to the test suites. --- README.md | 7 ++++++- einheit.nim | 51 ++++++++++++++++++++++++++++++++++++++++++--------- test.nim | 13 +++++++++++-- 3 files changed, 59 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index c8b0947..966678a 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ Methods are used for inheritance, so if you want to derive a test suite, then yo If you don't want inheritance, you can just use procs. -A special proc/method is called setup(). The macro will inject this method/proc if it doesn't exist and it will be called before running the test suite. +Two special methods/procs are called setup() and tearDown(). The macro will inject these methods/procs if they don't exist and they will be called before and after running the test suite, respectively. Test methods/procs to be run are prefixed with "test" in the method/proc name. This is so that you can write tests that call procs that do other things and won't be run as a test. @@ -43,6 +43,11 @@ testSuite SuiteName of TestSuite: self.suiteVar = "Testing" self.testObj = 90 + method tearDown()= + ## do tear down code here + self.suiteVar = nil + self.testObj = 0 + method testAddingString()= ## adds a string to the suiteVar self.suiteVar &= " 123" diff --git a/einheit.nim b/einheit.nim index 697d91f..5309501 100644 --- a/einheit.nim +++ b/einheit.nim @@ -42,6 +42,10 @@ method setup*(suite: TestSuite)= ## Base method for setup code discard +method tearDown*(suite: TestSuite)= + ## Base method for setup code + discard + method runTests*(suite: TestSuite)= ## Base method for running tests discard @@ -68,9 +72,10 @@ template returnException(name, testName, snip, vals)= exc.testName = testName raise exc -# --------------------------- Templates for assertion -------------------------------------- +# ------------------------ Templates for assertion ---------------------------- -template assertEqual*(self: TestSuite, lhs: untyped, rhs: untyped): untyped {.immediate.}= +template assertEqual*(self: TestSuite, lhs: untyped, + rhs: untyped): untyped {.immediate.}= ## Raises a TestAssertError when the lhs and the rhs are not equal. if (lhs) != (rhs): var snip = astToStr(lhs) & ", " & astToStr(rhs) @@ -104,7 +109,8 @@ template assertFalse*(self: TestSuite, code: untyped): untyped {.immediate.}= returnException("assertFalse", testName, snip, vals) -template assertRaises*(self: TestSuite, error: Exception, code: untyped): untyped {.immediate.}= +template assertRaises*(self: TestSuite, error: Exception, + code: untyped): untyped {.immediate.}= ## Raises a TestAssertError when the exception "error" is ## not thrown in the code try: @@ -130,7 +136,7 @@ template assertRaises*(self: TestSuite, error: Exception, code: untyped): untype discard -# -------------------------------------------------------------------------------------------------- +# ----------------------------------------------------------------------------- # A list to hold all test suites that are created @@ -306,7 +312,9 @@ macro testSuite*(head: untyped, body: untyped): untyped = var runTests = getAst(runTestsProc(ident(objReference), typeName, baseMethodName, typeMethodName)) - var foundSetup = false + var + foundSetup = false + foundTeardown = false # Make forward declarations so that function order # does not matter, just like in real OOP! @@ -328,8 +336,10 @@ macro testSuite*(head: untyped, body: untyped): untyped = setNodeName(n2, procName, typeName) - if procName == "setup": + if procName.toLower() == "setup": foundSetup = true + if procName.toLower() == "teardown": + foundTeardown = true else: discard @@ -341,12 +351,32 @@ macro testSuite*(head: untyped, body: untyped): untyped = template setupDecl(self, baseMethod)= method setup()= self.baseMethod() - discard var setupProcTypename = ident("setup" & $typeName.toStrLit()) var baseMethodName = ident("setup" & $baseName.toStrLit()) result.add(getAst(setupProc(ident(objReference), typeName, setupProcTypename))) - body.add(getAst(setupDecl(ident(objReference), baseMethodName))[0]) + var setupBaseAst = getAst(setupDecl(ident(objReference), baseMethodName)) + body.add(setupBaseAst[0]) + + if not foundTeardown: + template teardownProc(self, typeName, tdProc)= + method tearDown(self: typeName) + method tdProc(self: typeName) + + template teardownDecl(self, baseMethod)= + method tearDown()= + when compiles(self.baseMethod()): + self.baseMethod() + + var teardownProcTypename = ident("tearDown" & $typeName.toStrLit()) + var baseTearMethodName = ident("tearDown" & $baseName.toStrLit()) + result.add(getAst(teardownProc(ident(objReference), + typeName, + teardownProcTypename))) + var teardownBaseAst = getAst(teardownDecl(ident(objReference), + baseTearMethodName)) + body.add(teardownBaseAst[0]) + # Iterate over the statements, adding `self: T` # to the parameters of functions @@ -368,10 +398,12 @@ macro testSuite*(head: untyped, body: untyped): untyped = setNodeName(n2, procName, typeName) - if procName == "setup": + if procName.toLower() == "setup": let dotName = newDotExpr(ident(objReference), ident("name")) let setName = newAssignment(dotName, newLit(typeName)) n2.body.add(setName) + elif procName.toLower() == "teardown": + discard elif procName.startswith("test"): let procCall = newDotExpr(ident(objReference), ident(procName & typeName)) @@ -498,6 +530,7 @@ proc runTests*()= fgYellow, "\n[Running]", fgWhite, " $1\n".format(suite.name)) suite.runTests() + suite.tearDown() # Output red if tests didn't pass, green otherwise var color = fgGreen diff --git a/test.nim b/test.nim index 22d7f6c..760933c 100644 --- a/test.nim +++ b/test.nim @@ -10,9 +10,11 @@ testSuite UnitTests: self.assertTrue(self.testObj == 400) method setup()= - self.testObj = 5 self.testObj = 90 + method tearDown()= + self.testObj = 0 + method testForB()= var b = 0 self.doThings() @@ -29,9 +31,11 @@ testSuite UnitTestsNew: testObj: int method setup()= - self.testObj = 5 self.testObj = 90 + method tearDown()= + self.testObj = 0 + method testTestObj()= self.assertTrue(self.testObj == 90) @@ -76,6 +80,11 @@ testSuite MoreInheritance of TestInherit: # fail. This is expected. self.testObj = 12345 + method tearDown()= + # Calling the direct parent's tearDown method + self.tearDownTestInherit() + self.testObj = 0 + method testTestObj()= # This method is overwritten. To call the base method, # simply use