我在unittest
模块的帮助下编写了大部分单元测试,但我不确定如何将它用于编译器在编译时应拒绝的代码。例如,如果我想编写以下代码并确保编译器在编译期间总是出错(类型和模板将在一个单独的模块中),我该如何为此编写测试用例?
import macros
type
T[n:static[int]] = object
template foo3(n: int): expr =
static:
if n > 3: error "n > 3"
type T3 = T[n]
T3
var
bar: foo3(4)
答案 0 :(得分:3)
您可以使用系统模块提供的compiles
魔法做类似的事情。
以下是编译器测试套件的示例:
https://github.com/nim-lang/Nim/blob/devel/tests/metatype/tbindtypedesc.nim#L19
请注意,在文件的顶部,我们使用accept
魔法将reject
和compiles
定义为简单的静态断言,我们在整个文件中使用它们来测试有效和无效的重载调用
就我个人而言,我认为在编译时失败更好,但您可以将compiles
的结果分配给运行时值或在check
语句中使用它。这样做的唯一好处是将以标准方式报告单元测试库的失败。
答案 1 :(得分:1)
只是添加一个如何将check
与compiles
结合使用的示例:
template notCompiles*(e: untyped): untyped =
not compiles(e)
# usage in unit tests:
check:
notCompiles:
does not compile
notCompiles:
let x = 1 # would fail
我正在使用模板,因为直接将not
与块直接组合是不可能的,我不想使用括号。
答案 2 :(得分:0)
我有一个包装器,可以编译并加载一个nim源模块。当然,你不想运行它,但这项技术可能适合你:
sourceFN = "foo.nim"
... (write source) ...
libFN = "foo.dll"
let output = execProcess(
"nim c --verbosity:0 --app:lib $1" % sourceFN,
options = {poStdErrToStdOut, poUsePath, poEvalCommand})
if not fileExists(libFN):
echo "COULDN'T COMPILE"