錯誤訊息目前 documentationify(fn) 只呈現 Then expression, 缺少上層 describe/context 的文字

bdd interface
- 相容於 mocha 預設的 bdd interface. 可以直接用, 無痛轉換
- 底層實作跟 Given 的系統互通, before/beforeEach/after/afterEach 與 G/W/T/I/A 的順序要確定
- Then 會使用 before/after
- it 會使用 Given/Then 嗎???

把 rspec-given 的 test case porting 過來
整理 code

豐富 good-habit-mode 的檢查
- Then 不許使用 label


-------------- done -----------------


natrual assertion
  - error location
  - 類似 power-assert 的 expression 解析
  - 作法: 把要求值的 expression function list 在 loader transform 時就產生好

整理 code, 減少重複

再抽出一層抽象層, 讓跟 mocha 相依的部份只剩下一層 adadpter
  this binding 是一個問題. 把 Given/When/Then 綁到 Core object 上,
  this 就必須指向它而非 ctx = {}, 而這不是我們想要的
  必須在 factory 那邊做...


             mocha interface
                   |
                 Core (有沒有更好的名字...)
                   |
              BlockManager
                   |
                 Stack

不依賴 mocha 的 beforeEach / afterEach


afterEach clean up 只能在宣告的那一層，因此內層沒有 afterEach cleanup
當然也可以沿著 prototype chain 把 context 用 for (var x in ctx) 全部 delete 掉, BUT!
object prototype chain 的硬傷：一旦清掉就沒了. 而 Given 的 defineProperty 只在 declare time 執行一次阿！
所以連 Given/When 都必須記下來了...

踩到大雷  難快 given.js 不支援 Given 'x', 1   只支援 Given 'x', -> 1
因為 Given 'x', [] 會很有問題...
因為 closure 的關係, 每次都會 reference 到同一個變數. 你也無法複製, 也許淺層複製並不夠. 深層複製一定正確嗎?
這不是我們可以決定的. 這責任要讓開發者去擔
Given 'x', 1 允許數字、字串、布林、null、undefined、NaN 這些...?
決定：完全禁止.
理由：
連字串都可能會變, object 跟 array 更是.
唯一不變的只有 primitive type 不會變, 那你直接用就好(直接寫 null, 直接寫 123), 何須 Given?

  - 支援 return false 就 fail


Then 應該支援 async style 嗎? natural assertion 不支援 async. 我覺得應該不鼓勵在 Then 使用 async, 有需要的話應該用 When
或許強制規定這件事會更好? (意圖鮮明. 這個工具本來就有鮮明的立場, 不是嗎? 這也吻合 rspec-given 的原始精神)

只要 require loader, 就 enable natural assertion.
但不一定會做 transform (也因此不一定會 enable detail report). 視個別 Then 的情況而定.
不過就算沒有 enable detail report, return false 依然會報錯. 只是沒提供易懂訊息.
這樣太亂了, 不管有沒有 enable natural assertion, 都要抓 last statement 當做報告.
所以這不該做在loader, 而是要做在 core 裡面才對!

重點：natural assertion 一旦 enable, 就一定會看 return value. 這是不能默默忽略的, 否則會造成 false positive


enable natural assertion detail report 的條件, 加上一條: Then(fn), fn 只能包含一個 ReturnStatement.
因為如果含有 assignment, 找到正確的值會變得很麻煩, 而 declaration 也能用來做 assignment, 所以同樣不允許.
如有需要 assign 的情況, 請愛用 Let()


解法: require enable-good-habit-mode

- invariant fail 的訊息更易懂 (告知錯誤發生在 Invariant, 而非 Then. And 同理.)

coffee script loader

then 如果有 undefined reference, 會變成 timeout

mocha@2.4.5 以上的 workaround

rspec-given 的 Failure, 用來驗證 Error
如果沒有這功能的話, 會寫出這種測試:

  Then -> @result instanceof MyError
  And -> @result.message.match /my error message/

可以有更好的介面嗎? 試寫看看.

  Then -> Failure(@result, MyError, /my error message/)
  Then -> IsFailure(@result, MyError, /my error message/)
  Then -> FailureMatch(@result, MyError, /my error message/)
  Then -> Failure(MyError, /my error message/).matches @result

支援 generator & Observable

when fail 的時候, 錯誤訊息讓人以為是 then

When(fn) 發生 error 會被報出來               pass
Given(fn) 發生 error 會被報出來              pass
When(result, fn) 發生 error 會被塞給 result  pass
GivenI(varname, fn) 發生 error 會???         fail
  目前因為 GivenI 是 WhenLike, 所以會塞給 varname.
  但 rspec-given Given! 是 let! 的 alias, let! 會怎麼做呢?
  文件沒寫, 實際試試看吧!
  會報錯. Given 跟 Given! 都會!
  所以 GivenI 跟 When 在這點的行為是不同的


一口氣處理各種 expression

