MochaでJavascript以外を指定してテストしたい
Node.js用テスティング環境であるmochaでは、compilersオプションを指定することにより、Javascript以外のコードも扱えるみたいです。 が、しかし、公式のマニュアルを読んでも、さっぱりやり方が分からなかったので、がんばってMochaのコードを追いかけてみました。
compilerオプションについて
compilerオプションでは、
"拡張子":"コンパイルモジュール"
を指定します。 これは、指定した拡張子のファイルに遭遇したら、指定したコンパイルモジュールでJavascriptにコンパイルしてね というおまじないになります。 規定では、.js のみが対象となっています。
Mochaは、テスト対象のフォルダを再帰的に走査して、遭遇したファイルが.jsと指定された拡張子以外であれば、無視するような仕掛けとなっています。
Node.jsでJavascript以外を扱う仕組み
対象の拡張子のファイルに遭遇すると、Mochaは、そのファイルをrequireで読み込もうとします。 Node.jsのマニュアルで require を調べると、
- .js
- .json
- .node
が読み込み対象と書かれています。 ではそれ以外のファイルがきた時は、どうなってしまうのでしょう?
Node.jsでは、上記以外のファイルの場合、require.extensions からの読み込みを試みます。 require.extensionsは、拡張子をキーに、指定されたファイルをJavascriptに変換する関数が登録された辞書です。
この関数の型は、
1 2 3 |
|
となっており、ここで、
- module - Moduleモジュール
- filename - 読み込むファイル名
Mochaに渡すコンパイルモジュールの仕様
仕様と言えるような、大それたものはなく、Javascriptに変換する関数を実装し、それを単に上述のrequire.extensions に追加するだけです。
この関数の実装において、一つ重要な点があります。 それは、Javascriptのコードに変換後、module._compile(<変換されたコード>)という非公開の関数を呼ぶということです。
この module._compile が呼ばれることで、ロードが完了する仕組みとなっているようです。
requireの呼び出し元は、module._compileが呼ばれるまで、ブロックされるようになっているため、Javascriptへの変換関数が非同期的に実装(fs.readFile等)されていても、まったく問題ないです。
変換関数の具体的な実装は、coffee-scriptモジュールを読んでみるよいでしょう。
例:Haxeの場合
Haxeには、mocha.js-haxeという、Mocha用のコードに変換するための拡張ライブラリが公開されています。 そこで、Haxeのオプション記述ファイル(.hxml)に対してコンパイルモジールを作成しておけば、MochaでHaxeのコードを直接テストできるようになります。
Javascriptへの変換関数関数の仕様として、
- child_processモジュールのexec関数で、hxmlファイルを渡して、HaxeのコードをJavascriptコンパイルする。
- コンパイルしたファイルを、fsモジュールのreadFile(またはfs.readFileSync)で読み込んで、コードを取得する。
- module._compileにそのコードを渡す。
とすれば、よいでしょう。