- private variable
- sinon用非公開変数群
- div documentオブジェクトが定義されていれば、document.createElementで div要素を作成する。
- hasOwn Object.prototype.hasOwnPropertyを参照する。
- sinon
外部に公開するオブジェクト
- function
- 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する。
- extend(target, …) ・第2引数以降のオブジェクトのプロパティをtargetに追加する。 toStringのみhasOwnPropertyでチェック、targetと異なる場合をして追加。
- create(proto) protoをprototypeに入れてインスタンスを生成して返す。
- deepEqual(a, b) aとbが同じかどうかチェック。a,b共に配列であれば、要素一つずつを更に deepEqualを使って比較している。
- functionName(func) 関数名を取得
- functionToString() 多分、spyで使用されるはず。 んー、よくわかんないなー。呼び出した関数(getCall)の名前を取り出してるのかな。
- getConfig(custom) sinon.defaultConfigと同じ名前がcustomにある場合は、customの値を取得、 ない場合は、sinon.defaultConfigの値を取得して、オブジェクトとして返す。
- format(val) return “” + valしているだけ。toStringと同じか。
- timesInWords(count) countが1なら”once” / 2なら”twice” / 3なら”thrice” / 0 or otherなら “n times”
- calledInOrder(spies) 順番通りに、spyが呼ばれているかチェックしているのかな?
- orderByFirstCall(spies) 呼ばれた順にspiesをソートかな?
- log() noop関数
- logError(label, err) なぜsetTimeoutを使ってthrowしてるの?
- typeOf(value) nullは”null” “[object String]”等の”String”.toLowerCase()を取得
- variable
- defaultConfig
- injectIntoThis: true
- injectInto: null
- properties: [“spy”, “stub”, “mock”, “clock”, “server”, “requests”]
- useFakeTimers: true
- useFakeServer: true
- defaultConfig
- function
- private function
- sinon用非公開関数群
- isDOMNode(obj) 引数のobjに、div要素がappendChildできるかチェック。 appendChildできたら、trueが返る。
- isElement(obj) objのnodeType === 1をチェックし、 isDOMNodeを呼び出す。
- isFunction(obj) obj.constructor / obj.call / obj.apply が定義されている場合、trueを返す。
- mirrorProperties(target, source) targetに対して、sourceのキーをhasOwnでチェックして、 target自身が同じ名前のプロパティを持っていたらコピーはしない。
- isNode
moduleオブジェクトが存在し、requireが関すの場合に、trueが
設定される。
- spy
- stub
- mock
- collection
- assert
- sandbox
- test
- testCase
- assert 5::assertをダブってる。
- 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 / 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用非公開変数群
- commonJSModule
- spyCall
- private function
- spyCall用非公開関数
- throwYieldError(proxy, text, args) yieldとyieldToから呼ばれる。
- public function
- spyCall用公開関数
- create(spy, thisValue, args, returnValue, exception, id)
- calledOn(thisValue)
- calledWith()
- calledWithMatch()
- calledWithExactly()
- notCalledWith()
- notCalledWithMatch()
- returned(value)
- threw(error)
- calledWithNew(thisValue)
- calledBefore(other)
- calledAfter(other)
- callArg(pos)
- callArgWith(pos)
- yield()
- yieldTo(prop)
- toString()
- callId
- private function
- spy用非公開関数群
- push([].push)
- slice(Array.prototype.slice)
- spy(object, property)
- sinonオブジェクトが定義されていない場合 上位階層のsinon.jsをrequireする。 読み込めなかった場合、spy.jsの処理を終了
- spy関数にspyApiオブジェクトのプロパティを追加
- private variable
- spyApi用
- uuid
- spyApi
- spyApiがもともと実装している関数
- 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 = [];
- create(func)
- invoke(func, thisValue, args)
- getCall(i)
- calledBefore(spyFn)
- calledAfter(spyFn)
- withArgs
- matches(args, strict)
- printf(format)
- delegateしている関数
- 以下delegate関数は、spy.*に登録されるが、実際はspyCallの関数が呼ばれる。
処理は以下の通り
- sinon.spy(window, “alert”);
- window.alert(“”);
- window.alert.alwaysCalledOn(window) // => true
この時に、使用される関数は、
delegateToCalls(spyApi, “alwaysCalledOn”, false, “calledOn”);
で定義されたalwaysCalledOnが呼ばれるが、内部的にはcalledOnが呼ばれる。
delegateToCalls(spyApi, “calledOn”, true);
と何が違うかというと、第3引数がtrueの場合は、
matchAnyなので、一つでもマッチしたらという事になり、
falseの場合には、全てチェックして、マッチした合計と関数(spyに置き換えられた)の呼び出し合計が
同じであることを確認している。
- 呼び出しcalledOnの呼び出しメモ delegateToCallsの中で、spyCall.createを呼び出し this.getCall(n) -> spyCall.create spyCallのコンテキストで、calledOnを呼び出す。 calledOnの実態は、spyCall.calledOn
- delegate関数一覧
- calledOn
- alwaysCalledOn
- calledWith
- calledWithMatch
- alwaysCalledWith
- alwaysCalledWithMatch
- calledWithExactly
- alwaysCalledWithExactly
- neverCalledWith
- neverCalledWithMatch
- threw
- alwaysThrew
- returned
- alwaysReturned
- calledWithNew
- alwaysCalledWithNew
- callArg
- yield
- yieldTo
- 以下delegate関数は、spy.*に登録されるが、実際はspyCallの関数が呼ばれる。
処理は以下の通り
- spyApi.formattersを実装
- c(spy) 実行回数を返す。
- n(spy) spy.toString(sinon.functionToString)の結果を返す
- C(spy) 呼び出した関数の一覧を文字列で取得
- t(spy) spyのthisValuesを文字列(“, “でjoin)にして返す。
- *(spy, args) args.join(“, “)の結果を返す
- spyApiがもともと実装している関数
- private function
- spyApi用
- delegateToCalls(api, method, matchAny, actual, notCalled)
- matchingFake(fakes, args, strict)
- incrementCallCount()
- createCallProperties()
- spy.spyCallに非公開変数spyCallを代入
- sinon.spyCallに非公開変数spyCallを代入 sinon.spyCall === sinon.spy.spyCallとなる。