node.js向けのmktempを書いたよ

必要になった気がしたのでmktempコマンドのnode.js向けモジュールを書いてみました。
GitHub - sasaplus1/mktemp: mktemp command for node.js
実装は大したことないし、テストも割といい加減だったりなのでこれから直していきたいかなーというところ。
そもそも使うのかどうか怪しいところではあるのですけど。


そういえば、OS X(Mountain Lion)のmktemp(BSDの、の方が正しいのかな)とUbuntuのmktempだと微妙に動作が違うみたい。

$ mktemp XXX_

を両OSで試すと、OS Xはそのままなのに、UbuntuだとXXXの部分がちゃんとランダムな文字列になったりします。
OS Xは必ず末尾にないとランダムな文字列にしてくれなかったです。
mktempは正規表現を書くのが楽だったのでOS Xの方に合わせました。


そうそう、今回テストを書くにあたってSinon.JSのstubを初めて使ってみたのですよ。
spyとかmockを使って便利だなーと思ってたのですが、stubも便利でした。

$ npm install sinon
#!/usr/bin/env node
var fs = require('fs'),
    sinon = require('sinon'),
    createFile;

sinon.stub(fs, 'writeFile').callsArgWith(2, null);

createFile = function(path, callback) {
  fs.writeFile(path, '', function(err) {
    callback(err, path);
  });
};
createFile('あああああ', function(err, path) {
  console.log(err === null);
  console.log(path === 'あああああ');
});

fs.writeFile.restore();

fs.writeFileやfs.mkdirを内部で使っているのですが、実際にファイルやディレクトリを作成したり削除したり、というのが面倒だったのと、特にその辺を確認したいわけではなかったのでstubでごにょごにょしました。

sinon.stub(fs, 'writeFile').callsArgWith(2, null);

でfs.writeFileを上書きしています。
callsArgWithは第一引数にコールバック関数の引数を何番目の引数で受け取るか指定して、第二引数以降にコールバック関数に渡す引数を指定します。


第一引数が2となっているのは

  fs.writeFile(path/*0*/, ''/*1*/, function(err) {
    callback(err, path);
  }/*2*/);

となっているためです。それと、渡されたコールバック関数はerrを受け取るだけの関数なのでnullを指定して渡しています。


あとは普通に使うと……

createFile('あああああ', function(err, path) {
  console.log(err === null);           // true
  console.log(path === 'あああああ');  // true
});

stubのfs.writeFileを介してコールバックが呼ばれます。


最後に後始末として元の関数に戻します。

fs.writeFile.restore();

このあと使われないのですけど、一応。


Sinon.JSの練習のために作られたモジュールのようになった感じがしなくもないですが、まあ得られたものが大きかったので良しとします。
Sinon.JSの情報が妙に少なくて調べるの大変だった……