ずっと前回の続きです。やっとこさ、テストが出来ます。コマンドはkarma startです!

$ karma start

すると、、、やたら長い出力が。。。webpackのバンドルの結果がだらだらでてくるですね。
んで、残念なことに結局エラーが出てきてしまいます:

webpack: bundle is now VALID.
16 05 2016 22:38:17.701:WARN [karma]: No captured browser, open http://localhost:9876/
16 05 2016 22:38:17.710:INFO [karma]: Karma v0.13.22 server started at http://localhost:9876/
16 05 2016 22:38:17.724:INFO [launcher]: Starting browser PhantomJS
16 05 2016 22:38:19.432:INFO [PhantomJS 2.1.1 (Mac OS X 0.0.0)]: Connected on socket /#wmEhwZU0LM4lxZ_BAAAA with id 18605804
PhantomJS 2.1.1 (Mac OS X 0.0.0) showcase 1. 取り扱い中のアイテムの一覧を表示する FAILED
 Can't find variable: assert
 /Users/showtarow/tutorials/project/spec/showcaseSpec.coffee:60:16
PhantomJS 2.1.1 (Mac OS X 0.0.0): Executed 1 of 11 (1 FAILED) (skipped 6) (0 sePhantomJS 2.1.1 (Mac OS X 0.0.0): Executed 1 of 11 (1 FAILED) (skipped 10) ERROR (0.016 secs / 0.004 secs)

Can’t find variable: assert と言われてしまいました。そうです、assertモジュールをrequireし忘れました。早速入れましょう。でも、せっかく数回前にpower-assertというassertの強力バージョンをいれたので、これを使うことにしましょう。前回述べたwebpack.ProveidePluginでpower-assertをオートロードすればOKです。また、power-assert形式のjsファイルをrequireするには変換が必要なのでwebpack-espower-loaderを使うようwebpackに伝えます。詳しくはpower-assertのREADMEを。

to gain power-assert output, you need to transform your test code to produce power-assert output

https://github.com/power-assert-js/power-assert/blob/master/README.md

“power-assert” poweredなwebpack.config.coffeeは以下のようになります:

#webpack.config.coffee
module.exports=
  #中略#
  module:
    loaders:[
      {test: /\.coffee$/, loader: "coffee"}
      {test: /\.jade$/, loader: "jade"}
      #...その他いろいろ
      {test: /\.json$/, loader: "json"}#これが必要
    ]
    postLoaders:[
      {test: /Spec\.coffee$/, loader: "webpack-espower-loader"}
    ]
  plugins:[
    new webpack.ProvidePlugin
      assert: "power-assert"
      #....
  ]

{test: /\.json$/, loader: "json"}が必要なのは、理由があるからです。
webpack-espower-loaderはpostLoadersに入れておきます。上のようにしておくと、「Specファイルは全てのローダーチェーンを通過した一番最後にwebpack-espower-loaderをロードする」という動作をしてくれます。また、”assert”識別子にpower-assertを割り当てたので、もはやSpecファイルを書き換える必要はなくなりました。

もう一度karma start!

PhantomJS 2.1.1 (Mac OS X 0.0.0) showcase 1. 取り扱い中のアイテムの一覧を表示する FAILED
    # showcaseSpec.coffee:9
    
    assert(showcase.items.every(function (item) {return item.status === true;}))
           |        |     |                                                     
           |        |     false                                                 
           |        Collection{length:4,models:#Array#,_byId:#Object#}          
           Object{items:#Collection#}                                           
    
  concreteAssert@/Users/showtarow/tutorials/project/spec/showcaseSpec.coffee:12876:56
  decoratedAssert@/Users/showtarow/tutorials/project/spec/showcaseSpec.coffee:20605:45
  powerAssert@/Users/showtarow/tutorials/project/spec/showcaseSpec.coffee:12763:38
  /Users/showtarow/tutorials/project/spec/showcaseSpec.coffee:64:23
PhantomJS 2.1.1 (Mac OS X 0.0.0): Executed 1 of 11 (1 FAILED) (skipped 10) ERROR (0.029 secs / 0.023 secs)

じゃじゃーん!すばらしい。ちゃんとテストが失敗して、その原因がエレガントに出力されています!コレがpower-assertの力、ということなんですね。

ふむ、どうやら、showcase.itemsが、適切にリセットされていない模様。。。showcaseSpec.coffeeを修正しましょう。エラーから察するに、everyメソッドに渡しているコールバックの処理に問題がありそうです・・・そう、itemオブジェクトにはstatusプロパティが定義されていません。itemはItemオブジェクトですんで、これにstatusメソッドを実装して、テストからはstatus()メソッドをコールすることにしましょう。item#status()は、いわゆるread-onlyなアクセッサメソッドということになるので、ちょっとしたマクロを継承元であるBackbone.Modelに追加してやりましょう:

#app/showcase/index.coffee
#Backbone.Modelコンストラクターにattr_readerクラスメソッドを追加
Backbone.Model.attr_reader= (attrs)->
  _.each attrs, (attr)=>
    @prototype[attr]= ->@get(attr)

class Item extends Backbone.Model
  @attr_reader ["status"] #status属性読み取りメソッドを追加
  defaults:
    status: off 
class Collection extends Backbone.Collection
  model: Item
module.exports.items= new Collection

#spec/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 #表示されるアイテムは全て取り扱い中である
  #...

さてコンソールを眺めると(そう、karmaもファイルの変更を監視してくれちゃってるんです、リロードは不要です)、、、

WARNING in ./~/power-assert/~/power-assert-formatter/~/acorn/dist/acorn.js
Critical dependencies:
1:478-485 This seems to be a pre-built javascript file. Though this is possible, it's not recommended. Try to require the original source to get better results.
 @ ./~/power-assert/~/power-assert-formatter/~/acorn/dist/acorn.js 1:478-485
webpack: bundle is now VALID.
PhantomJS 2.1.1 (Mac OS X 0.0.0): Executed 1 of 11 (skipped 10) SUCCESS (0.01 secs / 0.004 secs)

ちょっと意味不明なWARNINGがでちゃってますが、ともかく、

PhantomJS 2.1.1 (Mac OS X 0.0.0): Executed 1 of 11 (skipped 10) SUCCESS (0.01 secs / 0.004 secs)

うむ、どうやらテストは無事合格している模様です。今回はここまで。。。