Hi! I wrote some helper functions operating on NimNode, to aid in writing of macros. They are complex enough that I would like to write some tests for them. Is there a way to do that? Also, I would like to write some benchmarks to see how much slower they are than the code they're trying to replace. But when I call e.g. ident("foo") in benchmarks, I'm getting an error:
Error: 'ident' can only be used in compile-time context
Is there a way to construct NimNode in non-compile-time code? or to workaround this somehow, so that I could test & benchmark the functions in non-compile-time code?
The default unittest module also works at compile time, so you should be able to use this for your testing needs.
I recently found the need for benchmarking at compile time as well, but none of the obvious methods are available at compile time. I found myself printing dots to my terminal ever 10ms and then counting dots between echo output - not the most productive method. I guess we should file an issue for this and see if we can get a basic cpuTime() and a monotonous clock available in the Nim VM.
You can use libffi and so windows/posix time facilities at compile-time with the hidden flags mentionned in this PR:
https://github.com/nim-lang/Nim/pull/10150#issuecomment-462660376
:/ So, I tried to add a test, but it doesn't really seem to work with the usual approach in a static: block:
$ cat tests/test1.nim
import unittest
import macros
import macromatch
static:
test "simple ident":
let
t1 = ident("foobar")
check t1 =~ Ident(_)
check t1 =~ Ident("foobar")
check t1 !~ Empty(_)
check t1 !~ StmtList(_)
$ nimble test
...
/nix/store/...-nim-0.20.2/lib/pure/unittest.nim(480, 5) Error: cannot evaluate at compile time: checkpoints
Error: Execution failed with exit code 1
... Command: "/nix/store/...-nim-0.20.2/bin/nim" c --noNimblePath "-r" "--path:." "/home/akavel/prog/macromatch/tests/test1.nim"
If I remove the test "simple ident": line (and adjust indentation), I'm getting:
.../lib/pure/unittest.nim(543, 5) Error: cannot evaluate at compile time: programResult
Error: Execution failed with exit code 1
... Command: "/nix/store/...-nim-0.20.2/bin/nim" c --noNimblePath "-r" "--path:." "/home/akavel/prog/macromatch/tests/test1.nim"
maybe it's not a good idea but I put my tests inside a macro. and then i call that macro
it doesn't compatible with unittest but it's better than nothing.
example
macro test1 =
let
nl1 = quote: command 1 "arg2"
nl2 = quote:
command
1
"arg2"
let res = flattenDeepCommands(nl1) == nl2
if not res:
warning "flattenDeepCommands(nl1) == nl2"
test "macro utils test #1":
test1()