Skip to content

Instantly share code, notes, and snippets.

@ryuone
Created May 27, 2012 09:16
Show Gist options
  • Select an option

  • Save ryuone/2802990 to your computer and use it in GitHub Desktop.

Select an option

Save ryuone/2802990 to your computer and use it in GitHub Desktop.
Sinon.js Code Reading(mid-flow)

sinon.js

private variable
sinon用非公開変数群
  1. div documentオブジェクトが定義されていれば、document.createElementで div要素を作成する。
  2. hasOwn Object.prototype.hasOwnPropertyを参照する。
  3. sinon 外部に公開するオブジェクト
    • function
      1. wrapMethod(object, property, method) ・object : 必須 ・method : 必須(関数であること。) ・object[property]がisFunctionでtrueになること。 ・すでに、wrapMethodでwrapされている場合はエラーにする。 ・object[property]がstubまたはspyの場合は、エラーにする。 ・// IE 8 does not support hasOwnProperty on the window object.  なんですと!? ・object[property]にmethodを上書きして、  method.restore関数 / method.restore.sinonプロパティを定義する。  method.restore関数内では、object[property]のhasOwnがfalseの場合、  delete object[property]する。 ・オリジナルの関数のプロパティをwrapした関数にコピーする。 ・wrapしたmethodをreturnする。
      2. extend(target, …) ・第2引数以降のオブジェクトのプロパティをtargetに追加する。  toStringのみhasOwnPropertyでチェック、targetと異なる場合をして追加。
      3. create(proto) protoをprototypeに入れてインスタンスを生成して返す。
      4. deepEqual(a, b) aとbが同じかどうかチェック。a,b共に配列であれば、要素一つずつを更に deepEqualを使って比較している。
      5. functionName(func) 関数名を取得
      6. functionToString() 多分、spyで使用されるはず。 んー、よくわかんないなー。呼び出した関数(getCall)の名前を取り出してるのかな。
      7. getConfig(custom) sinon.defaultConfigと同じ名前がcustomにある場合は、customの値を取得、 ない場合は、sinon.defaultConfigの値を取得して、オブジェクトとして返す。
      8. format(val) return “” + valしているだけ。toStringと同じか。
      9. timesInWords(count) countが1なら”once” / 2なら”twice” / 3なら”thrice” / 0 or otherなら “n times”
      10. calledInOrder(spies) 順番通りに、spyが呼ばれているかチェックしているのかな?
      11. orderByFirstCall(spies) 呼ばれた順にspiesをソートかな?
      12. log() noop関数
      13. logError(label, err) なぜsetTimeoutを使ってthrowしてるの?
      14. typeOf(value) nullは”null” “[object String]”等の”String”.toLowerCase()を取得
    • variable
      1. defaultConfig
        • injectIntoThis: true
        • injectInto: null
        • properties: [“spy”, “stub”, “mock”, “clock”, “server”, “requests”]
        • useFakeTimers: true
        • useFakeServer: true
private function
sinon用非公開関数群
  1. isDOMNode(obj) 引数のobjに、div要素がappendChildできるかチェック。 appendChildできたら、trueが返る。
  2. isElement(obj) objのnodeType === 1をチェックし、 isDOMNodeを呼び出す。
  3. isFunction(obj) obj.constructor / obj.call / obj.apply が定義されている場合、trueを返す。
  4. mirrorProperties(target, source) targetに対して、sourceのキーをhasOwnでチェックして、 target自身が同じ名前のプロパティを持っていたらコピーはしない。
  • isNode moduleオブジェクトが存在し、requireが関すの場合に、trueが 設定される。
    1. spy
    2. stub
    3. mock
    4. collection
    5. assert
    6. sandbox
    7. test
    8. testCase
    9. assert 5::assertをダブってる。
    10. match
  • Node.js環境の場合 sinonディレクトリ内の各jsファイルをrequireする。
  • busterオブジェクトが定義されている場合 sinon.format関数を定義して、 buster.formatのasciiメソッドを呼び出すようにしている。
  • busterオブジェクトが定義されていなくて、Node.js環境の場合 sinon.format関数を定義して、 Node.jsのutilオブジェクトをrequireして、util.inspectを呼び出す。

sinon

spy.js

sinon.spy / sinon.spyCallに関する定義 sinon.spy(jQuery, “ajax”)で呼び出されるのは、 sinon.spy.create(func)とsinon.spyCall.create(spy, thisValue, args, returnValue, exception, id) のうち、前者。 sinon.spyCall.create(spy, thisValue, args, returnValue, exception, id)が呼ばれるのは、 sinon.spy.getCall(i)の中からのみ。(spy.jsを読む限り)

private variable
spy用非公開変数群
  1. commonJSModule
  2. spyCall
    private function
    spyCall用非公開関数
    1. throwYieldError(proxy, text, args) yieldとyieldToから呼ばれる。
    public function
    spyCall用公開関数
    1. create(spy, thisValue, args, returnValue, exception, id)
    2. calledOn(thisValue)
    3. calledWith()
    4. calledWithMatch()
    5. calledWithExactly()
    6. notCalledWith()
    7. notCalledWithMatch()
    8. returned(value)
    9. threw(error)
    10. calledWithNew(thisValue)
    11. calledBefore(other)
    12. calledAfter(other)
    13. callArg(pos)
    14. callArgWith(pos)
    15. yield()
    16. yieldTo(prop)
    17. toString()
  3. callId
private function
spy用非公開関数群
  1. push([].push)
  2. slice(Array.prototype.slice)
  3. spy(object, property)
  • sinonオブジェクトが定義されていない場合 上位階層のsinon.jsをrequireする。 読み込めなかった場合、spy.jsの処理を終了
  • spy関数にspyApiオブジェクトのプロパティを追加
    private variable
    spyApi用
    1. uuid
    2. spyApi
      • spyApiがもともと実装している関数
        1. reset() :: 下記プロパティはspyApiのプロパティで、最終的には、spyに追加される。 this.called = false; this.calledOnce = false; this.calledTwice = false; this.calledThrice = false; this.callCount = 0; this.firstCall = null; this.secondCall = null; this.thirdCall = null; this.lastCall = null; this.args = []; this.returnValues = []; this.thisValues = []; this.exceptions = []; this.callIds = [];
        2. create(func)
        3. invoke(func, thisValue, args)
        4. getCall(i)
        5. calledBefore(spyFn)
        6. calledAfter(spyFn)
        7. withArgs
        8. matches(args, strict)
        9. printf(format)
      • delegateしている関数
        • 以下delegate関数は、spy.*に登録されるが、実際はspyCallの関数が呼ばれる。 処理は以下の通り
          1. sinon.spy(window, “alert”);
          2. window.alert(“”);
          3. window.alert.alwaysCalledOn(window) // => true この時に、使用される関数は、  delegateToCalls(spyApi, “alwaysCalledOn”, false, “calledOn”); で定義されたalwaysCalledOnが呼ばれるが、内部的にはcalledOnが呼ばれる。  delegateToCalls(spyApi, “calledOn”, true); と何が違うかというと、第3引数がtrueの場合は、 matchAnyなので、一つでもマッチしたらという事になり、 falseの場合には、全てチェックして、マッチした合計と関数(spyに置き換えられた)の呼び出し合計が 同じであることを確認している。
            1. 呼び出しcalledOnの呼び出しメモ delegateToCallsの中で、spyCall.createを呼び出し  this.getCall(n) -> spyCall.create spyCallのコンテキストで、calledOnを呼び出す。 calledOnの実態は、spyCall.calledOn
        • delegate関数一覧
          1. calledOn
          2. alwaysCalledOn
          3. calledWith
          4. calledWithMatch
          5. alwaysCalledWith
          6. alwaysCalledWithMatch
          7. calledWithExactly
          8. alwaysCalledWithExactly
          9. neverCalledWith
          10. neverCalledWithMatch
          11. threw
          12. alwaysThrew
          13. returned
          14. alwaysReturned
          15. calledWithNew
          16. alwaysCalledWithNew
          17. callArg
          18. yield
          19. yieldTo
      • spyApi.formattersを実装
        1. c(spy) 実行回数を返す。
        2. n(spy) spy.toString(sinon.functionToString)の結果を返す
        3. C(spy) 呼び出した関数の一覧を文字列で取得
        4. t(spy) spyのthisValuesを文字列(“, “でjoin)にして返す。
        5. *(spy, args) args.join(“, “)の結果を返す
    private function
    spyApi用
    1. delegateToCalls(api, method, matchAny, actual, notCalled)
    2. matchingFake(fakes, args, strict)
    3. incrementCallCount()
    4. createCallProperties()
  • spy.spyCallに非公開変数spyCallを代入
  • sinon.spyCallに非公開変数spyCallを代入 sinon.spyCall === sinon.spy.spyCallとなる。

assert.js

collection.js

match.js

mock.js

sandbox.js

stub.js

test.js

test_case.js

util

sinon/util/event.js

sinon/util/fake_server.js

sinon/util/fake_server_with_clock.js

sinon/util/fake_timers.js

sinon/util/fake_xml_http_request.js

sinon/util/timers_ie.js

sinon/util/xhr_ie.js

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment