mochaを使ってみようと思って、
describe('Array', function(){ describe('#indexOf()', function(){ it('should return -1 when the value is not present', function(){ [1,2,3].indexOf(5).should.equal(-1); [1,2,3].indexOf(0).should.equal(-1); }) }) })
のようなテストを用意してみたら、nodelintに怒られる。
$ nodelint sample.js
The "sys" module is now called "util". It should have a similar interface.
sample.js, line 1, character 1: 'describe' was used before it was defined.
describe('Array', function(){
sample.js, line 3, character 5: 'it' was used before it was defined.
it('should return -1 when the value is not present', function(){
2 errors"describe"とか"it"がどこにも宣言されていないので当然っちゃ当然。
自分はnodelintの結果をflymakeでhighlightさせるようにしているので、こういうのが出ると結構困る。
nodelintでflymake - すぎゃーんメモ
で、そもそもこのtestファイルはどう扱われるのか?bin/mochaを覗いてみると、
function load(files, fn) { var pending = files.length; files.forEach(function(file){ delete require.cache[file]; suite.emit('pre-require', global, file); suite.emit('require', require(file), file); suite.emit('post-require', global, file); --pending || fn(); }); }
というあたりで"pre-require"イベントをemitしたあとで、requireされているのが分かる。lib/interfaces/bdd.jsやlib/interfaces/tdd.jsでは、"pre-require"を受け取ったときに引数で渡されたglobalオブジェクトにそれぞれで使う関数を登録してやっている。事前にこういう処理を挟んでおくことで、testファイルがrequireされても正常に動く、ということらしい。
なので、実際に読まれるのはglobalから生えた関数たちなので、
global.describe('Array', function(){ global.describe('#indexOf()', function(){ global.it('should return -1 when the value is not present', function(){ [1,2,3].indexOf(5).should.equal(-1); [1,2,3].indexOf(0).should.equal(-1); }); }); });
とか
var describe = global.describe; var it = global.it; describe('Array', function(){ describe('#indexOf()', function(){ it('should return -1 when the value is not present', function(){ [1,2,3].indexOf(5).should.equal(-1); [1,2,3].indexOf(0).should.equal(-1); }); }); });
とかいう具合に書いておけばtestの効果は変わらず、nodelintに警告されることもなく済む。
他にもっと良い方法は無いだろうか…