2016-02-08 54 views
4

我在unittest模塊的幫助下寫了大部分單元測試,但我不確定如何將它用於編譯器在編譯時應拒絕的代碼。例如,如果我想編寫下面的代碼並確保編譯器在編譯過程中始終出現錯誤(類型和模板將位於單獨的模塊中),那麼如何爲此編寫測試用例?如何爲在Nim中編譯失敗的代碼編寫單元測試?

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) 

回答

3

您可以使用系統模塊提供的compiles魔術做類似的事情。

這裏是從編譯器測試套件的例子:
https://github.com/nim-lang/Nim/blob/devel/tests/metatype/tbindtypedesc.nim#L19

注意如何在文件的頂部,我們定義使用compiles魔術acceptreject爲簡單的靜態斷言,我們用它們在整個文件測試有效和無效的重載呼叫。我個人認爲在編譯時失敗會更好,但是您可以將compiles的結果分配給運行時值,或者在check語句中使用它。這樣做的唯一好處就是將以單元測試庫的標準方式報告失敗。

+0

即使在「編譯」中,編譯仍會在遇到第一個「錯誤」調用時中止。所以沒有辦法使測試自動化。 – jxy

+0

我也無法找到一種方法來將'compiles'的結果保存到用'unittest'編寫的運行時值中。 – jxy

0

https://github.com/shaunc/cucumber_nim/blob/b1601a795dbf8ea0d0b5d96bf5b6a1cd90271327/tests/steps/dynmodule.nim

我已經編譯並加載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" 
1

我想補充的如何checkcompiles結合一個例子:

template notCompiles*(e: untyped): untyped = 
    not compiles(e) 

# usage in unit tests: 
check: 
    notCompiles: 
    does not compile 
    notCompiles: 
    let x = 1 # would fail 

我使用模板,因爲直接組合not與塊是不可能的,我不想使用括號。