CoffeeScriptでjasmine-node

CoffeeScriptでもさくさくBDDできるぞ!
この記事はCoffeeScriptjasmine-nodeの記事の続きっぽいです。

準備

srcディレクトリの作成

CoffeeScriptファイルを置くディレクトリを作成する。

mkdir src
specs.jsの編集

CoffeeScriptでスペックを書くためにspecs.jsの先頭行に以下を追加。

require('coffee-script')
コンパイルの設定

実コードもCoffeeScriptで書くが、テストはjsファイルに対して行う。

CoffeeScriptの実コードを更新したら自動的にコンパイルされるように以下のコマンドをターミナルのひとつで実行しておく。

coffee -w -b -o lib/ -c src/

新しいファイルを作ると、そのファイルはコンパイル対象に含まれていないのでコマンド実行し直す必要あり。
Vimを使っているならvim-coffee-scriptを使う手もある。

なぜテスト対象をjsファイルにするのか

これはcoffeeコマンドのコンパイルオプション(具体的には-bオプション)で若干jsファイルのコードが違ってくるため、確実に使われるコンパイル済みのコードの方をテストしたいから。

Node.js環境ならばコンパイルしないCoffeeScriptも使えるので、CoffeeScript一筋でいくなら直接CoffeeScriptのファイルをテスト対象にしてもよい。
ただしその場合もrequireのパスにjsファイルとCoffeeScriptのファイルが両方あった場合混乱の元になるので注意。
そういう混乱の危険性も踏まえるとやっぱりテスト対象(ついでに言うと実際に利用するファイルも)はjsファイルに絞った方がシンプルでいい思う。

コード例

以前のjasmine-nodeの記事で示したコードは実はCoffeeScriptで書いていた。

stylist.coffee
class Stylist
    styles: {}
    decorate: (target, options) ->
        return @styles[options.style] if !target
        for key, value of @styles[options.style]
            target[key] = value if options.override || !target[key]
        target

exports = {} if !exports
exports.Stylist = Stylist

JavaScriptよりスッキリ書ける。

stylist_spec.coffee
Stylist = require('stylist').Stylist

describe('Stylist', ->
    beforeEach ->
        @stylist = new Stylist
        @stylist.styles["normal"] =        {width:  '50', height: '100'}
        @stylist.styles["double height"] = {width:  '50', height: '200'}

    describe('オブジェクトをデコレートした場合', ->
        it 'オブジェクトに指定されたスタイルを付与すること', ->
            obj = {name: 'マネキン'}
            @stylist.decorate(obj, {style: "double height"})
            expect(obj.width).toEqual '50'
            expect(obj.height).toEqual '200'
            expect(obj.name).toEqual 'マネキン'

        describe('オブジェクトにスタイルと同名のプロパティがあった場合', ->
            it 'プロパティを上書きしないこと', ->
                obj = {name: 'マネキン', width: '1000'}
                @stylist.decorate(obj, {style: "double height"})
                expect(obj.width).toEqual '1000'
                expect(obj.height).toEqual '200'
                expect(obj.name).toEqual 'マネキン'

            it '上書きフラグが立っていればプロパティを上書きすること', ->
                obj = {name: 'マネキン', width: '1000'}
                @stylist.decorate(obj, {style: "normal", override: true})
                expect(obj.width).toEqual '50'
                expect(obj.name).toEqual 'マネキン'
        )
    )
)

こちらもいくらかスッキリ。
functionをいちいち書かなくていいのと、括弧のタイプ量がだいぶ減る。

スペックファイルの方はコンパイルせずにそのまま動かせる。

実行

実行方法は変わらず。

$ node specs.js

前の記事

ドメイン引っ越し中

次の記事

jasmine-nodeで非同期処理のテスト