gulpで自動テストとコード圧縮

## やりたいこと
ビルド時に、自動的テスト、コード圧縮を行う。

#### 自動テスト

[gulp-mocha](https://www.npmjs.com/package/gulp-mocha)というモジュールを使う。
そもそも[mocha](http://mochajs.org/)使ったことないので、そこから調べました。

参考：
> [javascriptでテスト駆動開発 Mocha+expect.js+testem【前編】](http://yutapon.hatenablog.com/entry/2013/05/19/173048)

[BDD](http://ja.wikipedia.org/wiki/%E3%83%93%E3%83%98%E3%82%A4%E3%83%93%E3%82%A2%E9%A7%86%E5%8B%95%E9%96%8B%E7%99%BA)で使われるテストフレームワークぽいですね。

参考:
> [javascriptでテスト駆動開発 Mocha+expect.js+testem【前編】](http://yutapon.hatenablog.com/entry/2013/05/19/173048)
> [node.jsでこんなのもテストしたい!! という話](http://qiita.com/fnobi/items/14c9f298d88fc2a2e53d)

とりあえず、以下のサンプルコードを元にmocha+shouldを使ってテストする場合についてやってみました。

``` math.js
var math = {
	addition : function(a,b){
		return a+b;
	},
	multiplication : function(a,b){
		return a*b;
	}
};

module.exports = math;
```

テストコードはこんな感じです。

``` test/math.test.js
var should = require('should');
var math = require('../math.js');

describe('math', function(){
  it('1+1は2', function(){
    math.addition(1, 1).should.equal(2);
  });

  it('1*1は1', function(){
    math.multiplication(1, 1).should.equal(1);
  });
});
```

テストコードは、`test`ディレクトリを作って、その下においてあります。
で、実行。

`mocha` or `mocha test/math.test.js`

mochaがtestディレクトリ配下のテストコードを勝手みてくれるぽいです。

```
  math
    ✓ 1+1は2 
    ✓ 1*1は1 


  2 passing (5ms)
```

テストコードが問題なく動いたので、passingと表示されています。
なんとなく使い方がわかったので、gulp-mochaを使ってみます。

``` gulpfile.js
var gulp = require('gulp');
var mocha = require('gulp-mocha');

gulp.task('mocha', function() {
  return gulp.src(['test/math.test.js'], {read: false})
    .pipe(mocha({ reporter: 'nyan'}))
});

gulp.task('default', ['mocha']);
```

テストコードのファイルを指定して、readオプションを指定しているぽいですが、
英語を読んでも意味がわかりませんでした。

```
options.read
Type: Boolean Default: true
Setting this to false will return file.contents as null and not read the file at all.
```

で、reporterですが、`nyan`と指定すると結果に猫プラスされてコンソールに表示され、
`list`と指定すると結果がリスト上で表示されます。猫が好きだったんですね。

実行結果がこんな感じです。

``` repoter.nyan

[01:45:47] Using gulpfile ~/Desktop/project/github/math-gulp/gulpfile.js
[01:45:47] Starting 'mocha'...
 2   -_-_,------,
 0   -_-_|   /\_/\ 
 0   -_-^|__( ^ .^) 
     -_-  ""  "" 

  2 passing (5ms)

[01:45:47] Finished 'mocha' after 32 ms
[01:45:47] Starting 'default'...
[01:45:47] Finished 'default' after 7.71 μs
```

``` repoter.list

[01:49:30] Using gulpfile ~/Desktop/project/github/math-gulp/gulpfile.js
[01:49:30] Starting 'mocha'...

  ․ math 1+1は2: 0ms
  ․ math 1*1は1: 0ms

  2 passing (3ms)

[01:49:30] Finished 'mocha' after 30 ms
[01:49:30] Starting 'default'...
[01:49:30] Finished 'default' after 7.91 μs

```

gulp-mochaを使う場合は、mochaをインストールしなくてもいいぽいです。

#### コード圧縮

[gulp-uglify](https://www.npmjs.com/package/gulp-uglify)というモジュールを使う。
サンプルコードです。さっきの`gulpfile.js`に追記してあります。

参考：
> [gulpのタスクを同期的に実行する方法](http://qiita.com/morou/items/d54000396a2a7d0714de)

``` gulpfile.js
var gulp = require('gulp');
var mocha = require('gulp-mocha');
var uglify = require('gulp-uglify');

gulp.task('mocha', function() {
	return gulp.src(['test/math.test.js'], {read: false})
	.pipe(mocha({ reporter: 'list'}))
});

gulp.task('compress', ['mocha'], function() {
	gulp.src(['math.js'])
    .pipe(uglify())
    .pipe(gulp.dest('dist'))
});

gulp.task('default', ['mocha','compress']);
```

`mocha`タスクが終わった後に、`compress`タスクが動くように、
gulp.task()メソッドの２番目の引数に依存するタスク名の配列を指定し、
`mocha`タスクの結果を`return`してやればいいそうです。

```
[01:55:47] Using gulpfile ~/Desktop/project/github/math-gulp/gulpfile.js
[01:55:47] Starting 'mocha+compress'...

  ․ math 1+1は2: 0ms
  ․ math 1*1は1: 0ms

  2 passing (3ms)

[01:55:47] Finished 'mocha+compress' after 33 ms
[01:55:47] Starting 'default'...
[01:55:47] Finished 'default' after 9.15 μs
```

結果は、

```math.js
var math={addition:function(t,n){return t+n},multiplication:function(t,n){return t*n}};module.exports=math;
```

ちなみにテストが失敗するとどうなるのか試してみました。

テストコードの一部を変更します。
`math.addition(1, 1).should.equal(1);`

これで実行。

```
[01:58:35] Using gulpfile ~/Desktop/project/github/math-gulp/gulpfile.js
[01:58:35] Starting 'mocha+compress'...

  1) math 1+1は2
  ․ math 1*1は1: 1ms

  1 passing (4ms)
  1 failing

  1) math 1+1は2:

      AssertionError: expected 2 to be 1
      + expected - actual

      +1
      -2
```

エラーが発生して、圧縮ファイルは作られないみたいです。
予想通りですが、失敗した時の処理をどう書くか気になります。

とりあえず、このくらいにしておきます。
一連のソースは[こちら](https://github.com/takuhou/math-gulp)にあります。

そのうち、この前やった[browserify](http://browserify.org/)と合わせて使う予定です。
後は、ファイル変更検知[gulp-watch](https://www.npmjs.com/package/gulp-watch)と、Webサーバへの自動アップロード[gulp-ftp](https://www.npmjs.com/package/gulp-ftp)もやる予定です。

後、javascriptの開発環境で調べていたら[Web Starter Kit](https://developers.google.com/web/starter-kit/)というgoogleが提供するWebの開発スタートキットみたいなのが見つかったので、これについてもやってみます。