前回の続き。それではテストを書いてみましょう。テストするにもテストするモジュールがないので(「こんちは!」のテストをしてもしょうがない)、なにか簡単なアプリをつくってみましょう。今回はショップカートを作ってみることにします。
調味料を販売するショップサイトを想定してみます。サイトのトップページにアクセスすると、取り扱い中の調味料がずらりと表示され、ユーザーがカートに入れて商品を選べる、とりあえずそこまでのスペックを設計して、モジュールとして実装してみましょう。
スペックはspecフォルダに書きます。
~/tutorials/project% mkdir spec && cd spec
スペックファイルの命名規則は、とりあえずモジュール名Spec.coffee
にしてみます。karmaからテストを行う際に、このファイル名のルールに従って自動的にスペックファイルが読み込まれテストが実行されます。
ショップカートのサイトですので、とりあえず「ショーケース(showcase)」と「カート(cart)」のモジュールを作ることにします。この二つのモジュールのスペックをそれぞれshowcaseSpec.coffee
とcartSpec.coffee
ファイルで設計してゆきましょう。具体的なモジュールの実装はこのスペックファイルを書きながら同時進行で進めていきます。まずは思いつくままに書いてみます。
#showcaseSpec.coffee
showcase= require "showcase"
describe "showcase", ->
it "1. 取り扱い中のアイテムの一覧を表示する"
it "2. 各アイテムの行にはタイトルとデフォルトの数量と金額を表示する"
it "3. アイテムを選択するとカートに商品が入り、ショーケース内の商品の数量がひとつ減る"
it "4. 数量指定のない商品についてはいくつでもカートに入れられる"
it "5. カートに入れられる商品の上限はデフォルト数量までとする"
#cartSpec.coffee
cart= require "cart"
describe "cart", ->
it "1. カートの中は最初は空である"
it "2. 商品がカートに入れられたらそのタイトルごとに分類しリスト表示し、それぞれの数量を表示する"
it "3. カートの中身が変わるごとに合計金額を更新して表示する"
it "4. あるタイトルのアイテムの数量を変更すると、それに応じてショーケースのアイテムの数量も更新する"
it "5. あるタイトルのアイテムを一括して削除することができる"
it "6. 中身を空にすることができる"
ここで、モジュールの名前解決のルールをwebpackに伝えておきましょう。
#webpack.config.coffee
path= require "path"
module.exports=
#中略#
resolve:
extensions: ["", ".coffee", ".js"]
root:[path.resolve "./app"]
こうすることで、./appディレクトリがモジュール探索のルートとして新たに追加されます。また、requireする際に、拡張子.coffeeも省略できます。
もう一つ、webpackの設定を追加しておきます。今回は多くのモジュールがBackbone.jsに依存するので、モジュール内に自動的にbackboneモジュールが読み込まれるようにwebpackを設定します(ついでにunderscoreとjqueryも入れておきます)。これにはwebpackのビルトインプラグインのProvidePluginを使用します:
#wepback.config.coffee
path= require "path"
webpack= require "webpack"
module.exports=
#中略#
plugins:[
new webpack.ProvidePlugin
$: "jquery"
Backbone: "backbone"
_: "underscore"
]
こうすると、”Backbone”という名前の変数には、自動的にbackboneモジュールのexportsがアサインされますので、モジュール内でrequireする必要がなくなります。
設計に戻ります。
showcaseSpec.coffeeで具体的にモジュールを設計してゆきます。
今回はBackbone.jsを使いますので、showcaseモジュールには、ビューオブジェクト(showcase.view)と、コレクションオブジェクト(showcase.items)を1つずつ用意しておけばよさそうです。“1. 取り扱い中のアイテムの一覧を表示する”は、showcase.collectionをリセットしたときの状態、ということになりそうです。
なにかしらリセットするためのデータが必要なようです。テスト用のダミーデータはspec/fixture.yaml
の中に準備しておき、テストの度に使用することにしましょう。showcaseSpec.coffeeでbeforeEach関数を呼んでおきます:
#showcaseSpec.coffee
showcase= require "showcase"
beforeEach -> @fixture= require "./fixture.yaml" #追加
describe "showcase", ->
it "1. 取り扱い中のアイテムの一覧を表示する"
#....
spec/fixture.yamlは以下
#spec/fixture.yaml
blackPepper:
title: 胡椒
status: true
price: 300
amount: 20
kumin:
title: クミン
status: true
price: 400
amount: 3
coriander:
title: コリアンダー
price: 450
amount: 8
turmeric:
title: ターメリック
status: true
price: 250
cayennePepper:
title: カイエンヌペッパー
status: true
price: 280
amount: 0
cardamon:
title: カルダモン
status: false
price: 420
ここで、yamlデータをバンドルに含める必要が出てきました。yaml-loaderとjson-loader(あ、これは前回いれてますね)をインストールし、webpackにその旨伝えておきましょう:
% npm i -D yaml-loader json-loader
#webpack.config.coffee
loaders:[
{test: /\.coffee$/, loader:"coffee"}
{test: /\.yaml$/, loader:"json!yaml"}#これを追加
]
上のloadersの2行目は「.yamlファイルはyaml-loaderでjson形式に変換しそれをjson-loaderでjs形式に変換してロードする」という意味になります。ローダーは!
でチェーンできるわけですね。
さらに、"1. 取り扱い中のアイテムの一覧を表示する"
の詳細な仕様を書いておきましょう:
showcaseSpec.coffeeは以下のようになりました:
#showcaseSpec.coffee
showcase= require "showcase"
beforeEach ->@fixture= require "./fixture.yaml"
describe "showcase", ->
it "1. 取り扱い中のアイテムの一覧を表示する", ->
availableItems= _.filter (_.values @fixture), (item)->item.status is on
showcase.items.reset availableItems
assert showcase.items.length > 0 #なにかしらアイテムは必ず表示される
assert showcase.items.every (item)->item.status is on #表示されるアイテムは全て取り扱い中である
it "2. 各アイテムの行にはタイトルとデフォルトの数量と金額を表示する"
it "3. アイテムを選択するとカートに商品が入り、ショーケース内の商品の数量がひとつ減る"
it "4. 数量指定のない商品についてはいくつでもカートに入れられる"
it "5. カートに入れられる商品の上限はデフォルト数量までとする"
今度はshowcaseモジュールを書いてみましょう。app/showcase/index.coffee
に書きます:
#app/showcase/index.coffee
class Item extends Backbone.Model
defaults:
status: off
class Collection extends Backbone.Collection
model: Item
module.exports.items= new Collection
cartモジュール(app/cart/index.coffee
)はからっぽにしておきます:
#app/cart/index.coffee
module.exports={}
、、、これでひとまず、スペックとモジュールが最低限そろいました。
テストはkarmaコマンドを使って行います。karmaはwebpack同様設定ファイルで細かい設定が出来ますので、そちらを書いておきましょう。ファイル名はデフォルトでkarma.conf.coffeeです(注:webpackは「webpack.config.coffee」です、間違えやすいです!!)、webpack同様プロジェクトのルートに置きます:
#~/tutorials/project/karma.conf.coffee
module.exports= (config)->
config.set
frameworks: ["mocha"]
files:["spec/**/*Spec.coffee"]
preprocessors:
"spec/**/*Spec.coffee":["webpack"]
webpack: require("./webpack.config.coffee")
browsers:["PhantomJS"]
さて!これで、やっとテストを起動できそうです。次回に・・・。