前幾天弄完 JSLint.vim 後,就對 server side JavaScript 產生了一些興趣,還抓了 v8 引擎 來用,於是就想到之前想弄很久的自動單元測試,想說要跑 QUnit ,不過 QUnit 雖然獨立於 jQuery 了,但還是要在瀏覽器環境下才能執行,純 JavaScript engine 還少了 DOM 和 BOM,就是說它需要 document, window 這些物件,找了一下發現 John Resig 有弄 env.js 這個專案,就是要在 js shell 裡面做出瀏覽器的環境,不過問題是目前只能跑在 Rhino 下,因為他是 java based ,可以在 JavaScript 裡面寫 Java ,所以可以做很多壞事,但是其他的 js shell 沒辦法這樣跑, John Resig 好像有想要 port 成 python + v8 的版本,不過不知道有沒有成功,因為也 沒放出 。
剛好最近有點紅的 node.js ,似乎可以拿來做一樣的事情(要做 http request、開檔案、DOM),於是也調查了一下,結果缺少了重要的 DOM ,這樣也跑不起 Qunit,傷心難過之餘只好把方向改成尋找簡單的 JavaScript Unit Test Framework,希望能找到不會存取到 BOM 和 DOM 的版本,結果找到 這個 ,雖然沒完全符合需求,不過裡面要改的地方很少,所以改了一下就拿來用了(還不知道授權所以不敢丟出來),把幾個要用到 jQuery, DOM 的地方註解掉,還有 log 改成有錯誤才輸出,然後 ~/.vimrc 加上:
function Jsunit ()
let ut = 'unit.test.js'
let fn = expand('<afile>:t')
if fn != ut
let cwd = expand('<afile>:p:h')
if filereadable(cwd.'/unit.test.js')
let has_error = 0
let cmd = 'js '. ut
let output = system(cmd)
for error in split(output, "\n")
let has_error = 1
caddexpr expand("%") . fn . ":0:0:" . error
endfor
if has_error == 1
copen
else
echo 'Unit : All OK.'
endif
endif
endif
endfunction
autocmd FileWritePost,BufWritePost *.js :call Jsunit()
存檔的時候會自動找 unit.test.js ,如果存在的話就會執行它,unit.test.js 裡面長得像這樣:
load('testrunner.js');
load('lib.js');
test('all', function () {
ok(libFunc(true) == 530, 'send true');
isObj(libFunc(false), {a:'1'}, 'send false');
});
不過這個 testrunner 不能做任何和 html 文件、瀏覽器有關的測試,只能做很核心部份的測試。