express の test を読む

ええと Node塾 講義その4Ustream を見つつ中身を確認。

例示されていたのが test/app.del.js

中身が以下。

var express = require('../')
  , request = require('./support/http');

describe('app.del()', function(){
  it('should alias app.delete()', function(done){
    var app = express();

    app.del('/tobi', function(req, res){
      res.end('deleted tobi!');
    });

    request(app)
    .delete('/tobi')
    .expect('deleted tobi!', done);
  })
})

support/http.js が多用されているようで、この仕組みを理解してれば express な試験を書きやすいそうです。上記試験で何をしてるかというと

  • express なオブジェクト作って
  • '/tobi' な path の del メソド受け取った時のレスポンスを定義して
  • '/tobi' な path の del メソド発行して挙動確認

という形になっているとのこと。実際に support/http.js の中身を見てみるに request(app) なナニは以下か。

module.exports = request;

function request(app) {
  return new Request(app);
}

function Request(app) {
  var self = this;
  this.data = [];
  this.header = {};
  this.app = app;
  if (!this.server) {
    this.server = http.Server(app);
    this.server.listen(0, function(){
      self.addr = self.server.address();
      self.listening = true;
    });
  }
}

で、.delete('/tobi') なナニは、というと

methods.forEach(function(method){
  Request.prototype[method] = function(path){
    return this.request(method, path);
  };
});

で云々、とのこと。ええと methods は何かというと先頭あたりで

  , methods = require('../../').methods

なカンジで require されてますね。../../index.js は lib/express.js を require してます。その中で

/**
 * Expose HTTP methods.
 */

exports.methods = require('./router/methods');

なことしてますね。lib/router/methods が以下か。

module.exports = [
    'get'
  , 'post'
  , 'put'
  , 'head'
  , 'delete'
  , 'options'
  , 'trace'
  , 'copy'
  , 'lock'
  , 'mkcol'
  , 'move'
  , 'propfind'
  , 'proppatch'
  , 'unlock'
  , 'report'
  , 'mkactivity'
  , 'checkout'
  , 'merge'
  , 'm-search'
  , 'notify'
  , 'subscribe'
  , 'unsubscribe'
  , 'patch'
];

結局のところ request という手続きを云々、ということで http.js の中の定義が以下。

Request.prototype.request = function(method, path){
  this.method = method;
  this.path = path;
  return this;
};

属性設定して自分を戻してて最後に .expect('deleted tobi!', done); してます。expect の定義は以下で基本的には end の呼び出しになってますね。

Request.prototype.expect = function(body, fn){
  this.end(function(res){
    if ('number' == typeof body) {
      res.statusCode.should.equal(body);
    } else if (body instanceof RegExp) {
      res.body.should.match(body);
    } else {
      res.body.should.equal(body);
    }
    fn();
  });
};

end に渡す手続きが body の比較と fn の呼び出しになっていると。
で、end ですがざっくりベースでナニすると

  • this.listening が true なら
    • http.request 作って response 組み立てて end で res.body に代入して 引数で受け取った手続きオブジェクトに res を渡す

というナニになってます。あまり整理できてないけど許して下さひ。

実際

  • app.set とか app.use とかな試験てどうすんだろ
  • mongoose が云々なあたりをどうすりゃ良いやら

とりあえず express な試験の書き方はざっくりベースで理解できたと思うんですが、上記のあたりが若干微妙。

むむ

試験用の DB 作って云々、なのか。あと test/res.render.js というナニを見つけてます。ちょっと違うカンジですが

      app.use(function(req, res){
        res.render('user.jade', { user: user });
      });

      request(app)
      .get('/')
      .end(function(res){
        res.body.should.equal('<p>tobi</p>');
        done();
      });

みたいなナニで body を should.equal で云々してますね。でもこれってコンテンツが複雑だとチェックが煩雑だなぁ。

今日は

体調微妙なのでこれで一時停止。