I have a bunch of functions like: method1, method2, method3. For all of them there are HUnit test functions like: testMethod1, testMethod2, testMethod3.
testMethod1 = TestCase $
assertEqual "testmethod1" ...
testMethod2 = TestCase $
assertEqual "testmethod2" ...
testMethod3 = TestCase $
assertEqual "testmethod3" ...
I would like to avoid redundant copying of function’s name as prefix of error
message and call it something like that:
testMethod1 = TestCase $
assertEqual_ ...
How can it be achieved (any “magic” trick is appreciated)?
So actually question is how can function name be taken inside of it’s definition?
Update.
It’s not actually clear from original question, that I wanna handle that type of situation too:
tProcess = TestCase $ do
assertEqual "tProcess" testResult $ someTest
assertEqual "tProcess" anotherTestResult $ anotherTest
assertEqual "tProcess" resultAgain $ testAgain
Finally I want to write something like that:
tProcess = TestCase $ do
assertEqual_ testResult $ someTest
assertEqual_ anotherTestResult $ anotherTest
assertEqual_ resultAgain $ testAgain
You can’t do this directly (i.e. so that your test case starts with
testMethodN = ...), but you can use Template Haskell to get this:This involves writing
testCase :: String -> Q Exp -> Q [Dec], a function to turn the name of the test case and a quoted expression into a list of declarations. For instance:The basic idea here is to generate a definition of the name given, and replace every occurrence of the variable
assertEqual_in the quoted expression withassertEqual lowerName. Thanks to Template Haskell’s Scrap Your Boilerplate support, we don’t need to traverse the entire AST, just specify a transformation for eachExpnode.Note that
assertEqual_must be a bound identifier with the correct type, since the quoted expression is typechecked before being passed on totestCase. Additionally,testCasemust be defined in a separate module than the one it’s used in, due to GHC’s stage restriction.