Unit Testing in Nim: Is it possible to get the name of a source file at compile time?
Asked Answered
B

2

5

I'm planning a project with multiple modules, and I was looking for a nice solution to run all existing unit tests in the project at once. I came up with the following idea: I can run nim --define:testing main.nim and use the following template as a wrapper for all my unit tests.

# located in some general utils module:
template runUnitTests*(code: stmt): stmt =
  when defined(testing):
    echo "Running units test in ..."
    code

This seems to be working well so far.

As a minor tweak, I was wondering if I can actually print out the file name which is calling the runUnitTests template. Is there any reflection mechanism to get the source file name at compile time?

Bluefield answered 1/4, 2015 at 18:41 Comment(0)
S
5

instantiationInfo seems to be what you want: http://nim-lang.org/docs/system.html#instantiationInfo,

template filename: string = instantiationInfo().filename

echo filename()
Sesquicentennial answered 1/4, 2015 at 19:26 Comment(1)
Thanks, that's it! One minor note: I have to call instantiationInfo().filename directly in the runUnitTests template. If I create this filename template in my utils.nim module and call this second template from the runUnitTests template, the output is always utils.nim (looks like nesting templates affects stack line information).Bluefield
P
5

The template currentSourcePath from the system module returns the path of the current source by using a special compiler built-in, called instantiationInfo.

In your case, you need to print the locations of callers of your template, which means you'll have to use instantiationInfo directly with its default stack index argument of -1 (meaning one position up in the stack, or the caller):

# located in some general utils module:
template runUnitTests*(code: stmt): stmt =
  when defined(testing):
    echo "Running units test in ", instantiationInfo(-1).filename
    code

It's worth mentioning that the Nim compiler itself uses a similar technique with this module, which get automatically imported in all other modules by applying a switch in nim.cfg:

Protrusive answered 6/4, 2015 at 13:15 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.