Release: remove antiquated release-notes.js
[jquery.git] / external / sinon / sinon-1.14.1.js
blobdfbeae46a54cee6341fd7f37a1c52eac45629bc7
1 /**
2  * Sinon.JS 1.14.1, 2015/03/16
3  *
4  * @author Christian Johansen (christian@cjohansen.no)
5  * @author Contributors: https://github.com/cjohansen/Sinon.JS/blob/master/AUTHORS
6  *
7  * (The BSD License)
8  *
9  * Copyright (c) 2010-2014, Christian Johansen, christian@cjohansen.no
10  * All rights reserved.
11  *
12  * Redistribution and use in source and binary forms, with or without modification,
13  * are permitted provided that the following conditions are met:
14  *
15  *     * Redistributions of source code must retain the above copyright notice,
16  *       this list of conditions and the following disclaimer.
17  *     * Redistributions in binary form must reproduce the above copyright notice,
18  *       this list of conditions and the following disclaimer in the documentation
19  *       and/or other materials provided with the distribution.
20  *     * Neither the name of Christian Johansen nor the names of his contributors
21  *       may be used to endorse or promote products derived from this software
22  *       without specific prior written permission.
23  *
24  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
25  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
26  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
27  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
28  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
30  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
31  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
32  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
33  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34  */
36 (function (root, factory) {
37         if (typeof define === 'function' && define.amd) {
38                 define('sinon', [], function () {
39                         return (root.sinon = factory());
40                 });
41         } else if (typeof exports === 'object') {
42                 module.exports = factory();
43         } else {
44                 root.sinon = factory();
45         }
46 }(this, function () {
47         var samsam, formatio;
48         (function () {
49                                                                 function define(mod, deps, fn) {
50                                                                         if (mod == "samsam") {
51                                                                                 samsam = deps();
52                                                                         } else if (typeof deps === "function" && mod.length === 0) {
53                                                                                 lolex = deps();
54                                                                         } else if (typeof fn === "function") {
55                                                                                 formatio = fn(samsam);
56                                                                         }
57                                                                 }
58                 define.amd = {};
59 ((typeof define === "function" && define.amd && function (m) { define("samsam", m); }) ||
60  (typeof module === "object" &&
61                         function (m) { module.exports = m(); }) || // Node
62  function (m) { this.samsam = m(); } // Browser globals
63 )(function () {
64                 var o = Object.prototype;
65                 var div = typeof document !== "undefined" && document.createElement("div");
67                 function isNaN(value) {
68                                 // Unlike global isNaN, this avoids type coercion
69                                 // typeof check avoids IE host object issues, hat tip to
70                                 // lodash
71                                 var val = value; // JsLint thinks value !== value is "weird"
72                                 return typeof value === "number" && value !== val;
73                 }
75                 function getClass(value) {
76                                 // Returns the internal [[Class]] by calling Object.prototype.toString
77                                 // with the provided value as this. Return value is a string, naming the
78                                 // internal class, e.g. "Array"
79                                 return o.toString.call(value).split(/[ \]]/)[1];
80                 }
82                 /**
83                  * @name samsam.isArguments
84                  * @param Object object
85                  *
86                  * Returns ``true`` if ``object`` is an ``arguments`` object,
87                  * ``false`` otherwise.
88                  */
89                 function isArguments(object) {
90                                 if (getClass(object) === 'Arguments') { return true; }
91                                 if (typeof object !== "object" || typeof object.length !== "number" ||
92                                                                 getClass(object) === "Array") {
93                                                 return false;
94                                 }
95                                 if (typeof object.callee == "function") { return true; }
96                                 try {
97                                                 object[object.length] = 6;
98                                                 delete object[object.length];
99                                 } catch (e) {
100                                                 return true;
101                                 }
102                                 return false;
103                 }
105                 /**
106                  * @name samsam.isElement
107                  * @param Object object
108                  *
109                  * Returns ``true`` if ``object`` is a DOM element node. Unlike
110                  * Underscore.js/lodash, this function will return ``false`` if ``object``
111                  * is an *element-like* object, i.e. a regular object with a ``nodeType``
112                  * property that holds the value ``1``.
113                  */
114                 function isElement(object) {
115                                 if (!object || object.nodeType !== 1 || !div) { return false; }
116                                 try {
117                                                 object.appendChild(div);
118                                                 object.removeChild(div);
119                                 } catch (e) {
120                                                 return false;
121                                 }
122                                 return true;
123                 }
125                 /**
126                  * @name samsam.keys
127                  * @param Object object
128                  *
129                  * Return an array of own property names.
130                  */
131                 function keys(object) {
132                                 var ks = [], prop;
133                                 for (prop in object) {
134                                                 if (o.hasOwnProperty.call(object, prop)) { ks.push(prop); }
135                                 }
136                                 return ks;
137                 }
139                 /**
140                  * @name samsam.isDate
141                  * @param Object value
142                  *
143                  * Returns true if the object is a ``Date``, or *date-like*. Duck typing
144                  * of date objects work by checking that the object has a ``getTime``
145                  * function whose return value equals the return value from the object's
146                  * ``valueOf``.
147                  */
148                 function isDate(value) {
149                                 return typeof value.getTime == "function" &&
150                                                 value.getTime() == value.valueOf();
151                 }
153                 /**
154                  * @name samsam.isNegZero
155                  * @param Object value
156                  *
157                  * Returns ``true`` if ``value`` is ``-0``.
158                  */
159                 function isNegZero(value) {
160                                 return value === 0 && 1 / value === -Infinity;
161                 }
163                 /**
164                  * @name samsam.equal
165                  * @param Object obj1
166                  * @param Object obj2
167                  *
168                  * Returns ``true`` if two objects are strictly equal. Compared to
169                  * ``===`` there are two exceptions:
170                  *
171                  *   - NaN is considered equal to NaN
172                  *   - -0 and +0 are not considered equal
173                  */
174                 function identical(obj1, obj2) {
175                                 if (obj1 === obj2 || (isNaN(obj1) && isNaN(obj2))) {
176                                                 return obj1 !== 0 || isNegZero(obj1) === isNegZero(obj2);
177                                 }
178                 }
181                 /**
182                  * @name samsam.deepEqual
183                  * @param Object obj1
184                  * @param Object obj2
185                  *
186                  * Deep equal comparison. Two values are "deep equal" if:
187                  *
188                  *   - They are equal, according to samsam.identical
189                  *   - They are both date objects representing the same time
190                  *   - They are both arrays containing elements that are all deepEqual
191                  *   - They are objects with the same set of properties, and each property
192                  *     in ``obj1`` is deepEqual to the corresponding property in ``obj2``
193                  *
194                  * Supports cyclic objects.
195                  */
196                 function deepEqualCyclic(obj1, obj2) {
198                                 // used for cyclic comparison
199                                 // contain already visited objects
200                                 var objects1 = [],
201                                                 objects2 = [],
202                                 // contain pathes (position in the object structure)
203                                 // of the already visited objects
204                                 // indexes same as in objects arrays
205                                                 paths1 = [],
206                                                 paths2 = [],
207                                 // contains combinations of already compared objects
208                                 // in the manner: { "$1['ref']$2['ref']": true }
209                                                 compared = {};
211                                 /**
212                                  * used to check, if the value of a property is an object
213                                  * (cyclic logic is only needed for objects)
214                                  * only needed for cyclic logic
215                                  */
216                                 function isObject(value) {
218                                                 if (typeof value === 'object' && value !== null &&
219                                                                                 !(value instanceof Boolean) &&
220                                                                                 !(value instanceof Date)    &&
221                                                                                 !(value instanceof Number)  &&
222                                                                                 !(value instanceof RegExp)  &&
223                                                                                 !(value instanceof String)) {
225                                                                 return true;
226                                                 }
228                                                 return false;
229                                 }
231                                 /**
232                                  * returns the index of the given object in the
233                                  * given objects array, -1 if not contained
234                                  * only needed for cyclic logic
235                                  */
236                                 function getIndex(objects, obj) {
238                                                 var i;
239                                                 for (i = 0; i < objects.length; i++) {
240                                                                 if (objects[i] === obj) {
241                                                                                 return i;
242                                                                 }
243                                                 }
245                                                 return -1;
246                                 }
248                                 // does the recursion for the deep equal check
249                                 return (function deepEqual(obj1, obj2, path1, path2) {
250                                                 var type1 = typeof obj1;
251                                                 var type2 = typeof obj2;
253                                                 // == null also matches undefined
254                                                 if (obj1 === obj2 ||
255                                                                                 isNaN(obj1) || isNaN(obj2) ||
256                                                                                 obj1 == null || obj2 == null ||
257                                                                                 type1 !== "object" || type2 !== "object") {
259                                                                 return identical(obj1, obj2);
260                                                 }
262                                                 // Elements are only equal if identical(expected, actual)
263                                                 if (isElement(obj1) || isElement(obj2)) { return false; }
265                                                 var isDate1 = isDate(obj1), isDate2 = isDate(obj2);
266                                                 if (isDate1 || isDate2) {
267                                                                 if (!isDate1 || !isDate2 || obj1.getTime() !== obj2.getTime()) {
268                                                                                 return false;
269                                                                 }
270                                                 }
272                                                 if (obj1 instanceof RegExp && obj2 instanceof RegExp) {
273                                                                 if (obj1.toString() !== obj2.toString()) { return false; }
274                                                 }
276                                                 var class1 = getClass(obj1);
277                                                 var class2 = getClass(obj2);
278                                                 var keys1 = keys(obj1);
279                                                 var keys2 = keys(obj2);
281                                                 if (isArguments(obj1) || isArguments(obj2)) {
282                                                                 if (obj1.length !== obj2.length) { return false; }
283                                                 } else {
284                                                                 if (type1 !== type2 || class1 !== class2 ||
285                                                                                                 keys1.length !== keys2.length) {
286                                                                                 return false;
287                                                                 }
288                                                 }
290                                                 var key, i, l,
291                                                                 // following vars are used for the cyclic logic
292                                                                 value1, value2,
293                                                                 isObject1, isObject2,
294                                                                 index1, index2,
295                                                                 newPath1, newPath2;
297                                                 for (i = 0, l = keys1.length; i < l; i++) {
298                                                                 key = keys1[i];
299                                                                 if (!o.hasOwnProperty.call(obj2, key)) {
300                                                                                 return false;
301                                                                 }
303                                                                 // Start of the cyclic logic
305                                                                 value1 = obj1[key];
306                                                                 value2 = obj2[key];
308                                                                 isObject1 = isObject(value1);
309                                                                 isObject2 = isObject(value2);
311                                                                 // determine, if the objects were already visited
312                                                                 // (it's faster to check for isObject first, than to
313                                                                 // get -1 from getIndex for non objects)
314                                                                 index1 = isObject1 ? getIndex(objects1, value1) : -1;
315                                                                 index2 = isObject2 ? getIndex(objects2, value2) : -1;
317                                                                 // determine the new pathes of the objects
318                                                                 // - for non cyclic objects the current path will be extended
319                                                                 //   by current property name
320                                                                 // - for cyclic objects the stored path is taken
321                                                                 newPath1 = index1 !== -1
322                                                                                 ? paths1[index1]
323                                                                                 : path1 + '[' + JSON.stringify(key) + ']';
324                                                                 newPath2 = index2 !== -1
325                                                                                 ? paths2[index2]
326                                                                                 : path2 + '[' + JSON.stringify(key) + ']';
328                                                                 // stop recursion if current objects are already compared
329                                                                 if (compared[newPath1 + newPath2]) {
330                                                                                 return true;
331                                                                 }
333                                                                 // remember the current objects and their pathes
334                                                                 if (index1 === -1 && isObject1) {
335                                                                                 objects1.push(value1);
336                                                                                 paths1.push(newPath1);
337                                                                 }
338                                                                 if (index2 === -1 && isObject2) {
339                                                                                 objects2.push(value2);
340                                                                                 paths2.push(newPath2);
341                                                                 }
343                                                                 // remember that the current objects are already compared
344                                                                 if (isObject1 && isObject2) {
345                                                                                 compared[newPath1 + newPath2] = true;
346                                                                 }
348                                                                 // End of cyclic logic
350                                                                 // neither value1 nor value2 is a cycle
351                                                                 // continue with next level
352                                                                 if (!deepEqual(value1, value2, newPath1, newPath2)) {
353                                                                                 return false;
354                                                                 }
355                                                 }
357                                                 return true;
359                                 }(obj1, obj2, '$1', '$2'));
360                 }
362                 var match;
364                 function arrayContains(array, subset) {
365                                 if (subset.length === 0) { return true; }
366                                 var i, l, j, k;
367                                 for (i = 0, l = array.length; i < l; ++i) {
368                                                 if (match(array[i], subset[0])) {
369                                                                 for (j = 0, k = subset.length; j < k; ++j) {
370                                                                                 if (!match(array[i + j], subset[j])) { return false; }
371                                                                 }
372                                                                 return true;
373                                                 }
374                                 }
375                                 return false;
376                 }
378                 /**
379                  * @name samsam.match
380                  * @param Object object
381                  * @param Object matcher
382                  *
383                  * Compare arbitrary value ``object`` with matcher.
384                  */
385                 match = function match(object, matcher) {
386                                 if (matcher && typeof matcher.test === "function") {
387                                                 return matcher.test(object);
388                                 }
390                                 if (typeof matcher === "function") {
391                                                 return matcher(object) === true;
392                                 }
394                                 if (typeof matcher === "string") {
395                                                 matcher = matcher.toLowerCase();
396                                                 var notNull = typeof object === "string" || !!object;
397                                                 return notNull &&
398                                                                 (String(object)).toLowerCase().indexOf(matcher) >= 0;
399                                 }
401                                 if (typeof matcher === "number") {
402                                                 return matcher === object;
403                                 }
405                                 if (typeof matcher === "boolean") {
406                                                 return matcher === object;
407                                 }
409                                 if (typeof(matcher) === "undefined") {
410                                                 return typeof(object) === "undefined";
411                                 }
413                                 if (matcher === null) {
414                                                 return object === null;
415                                 }
417                                 if (getClass(object) === "Array" && getClass(matcher) === "Array") {
418                                                 return arrayContains(object, matcher);
419                                 }
421                                 if (matcher && typeof matcher === "object") {
422                                                 if (matcher === object) {
423                                                                 return true;
424                                                 }
425                                                 var prop;
426                                                 for (prop in matcher) {
427                                                                 var value = object[prop];
428                                                                 if (typeof value === "undefined" &&
429                                                                                                 typeof object.getAttribute === "function") {
430                                                                                 value = object.getAttribute(prop);
431                                                                 }
432                                                                 if (matcher[prop] === null || typeof matcher[prop] === 'undefined') {
433                                                                                 if (value !== matcher[prop]) {
434                                                                                                 return false;
435                                                                                 }
436                                                                 } else if (typeof  value === "undefined" || !match(value, matcher[prop])) {
437                                                                                 return false;
438                                                                 }
439                                                 }
440                                                 return true;
441                                 }
443                                 throw new Error("Matcher was not a string, a number, a " +
444                                                                                                 "function, a boolean or an object");
445                 };
447                 return {
448                                 isArguments: isArguments,
449                                 isElement: isElement,
450                                 isDate: isDate,
451                                 isNegZero: isNegZero,
452                                 identical: identical,
453                                 deepEqual: deepEqualCyclic,
454                                 match: match,
455                                 keys: keys
456                 };
458 ((typeof define === "function" && define.amd && function (m) {
459                 define("formatio", ["samsam"], m);
460 }) || (typeof module === "object" && function (m) {
461                 module.exports = m(require("samsam"));
462 }) || function (m) { this.formatio = m(this.samsam); }
463 )(function (samsam) {
465                 var formatio = {
466                                 excludeConstructors: ["Object", /^.$/],
467                                 quoteStrings: true,
468                                 limitChildrenCount: 0
469                 };
471                 var hasOwn = Object.prototype.hasOwnProperty;
473                 var specialObjects = [];
474                 if (typeof global !== "undefined") {
475                                 specialObjects.push({ object: global, value: "[object global]" });
476                 }
477                 if (typeof document !== "undefined") {
478                                 specialObjects.push({
479                                                 object: document,
480                                                 value: "[object HTMLDocument]"
481                                 });
482                 }
483                 if (typeof window !== "undefined") {
484                                 specialObjects.push({ object: window, value: "[object Window]" });
485                 }
487                 function functionName(func) {
488                                 if (!func) { return ""; }
489                                 if (func.displayName) { return func.displayName; }
490                                 if (func.name) { return func.name; }
491                                 var matches = func.toString().match(/function\s+([^\(]+)/m);
492                                 return (matches && matches[1]) || "";
493                 }
495                 function constructorName(f, object) {
496                                 var name = functionName(object && object.constructor);
497                                 var excludes = f.excludeConstructors ||
498                                                                 formatio.excludeConstructors || [];
500                                 var i, l;
501                                 for (i = 0, l = excludes.length; i < l; ++i) {
502                                                 if (typeof excludes[i] === "string" && excludes[i] === name) {
503                                                                 return "";
504                                                 } else if (excludes[i].test && excludes[i].test(name)) {
505                                                                 return "";
506                                                 }
507                                 }
509                                 return name;
510                 }
512                 function isCircular(object, objects) {
513                                 if (typeof object !== "object") { return false; }
514                                 var i, l;
515                                 for (i = 0, l = objects.length; i < l; ++i) {
516                                                 if (objects[i] === object) { return true; }
517                                 }
518                                 return false;
519                 }
521                 function ascii(f, object, processed, indent) {
522                                 if (typeof object === "string") {
523                                                 var qs = f.quoteStrings;
524                                                 var quote = typeof qs !== "boolean" || qs;
525                                                 return processed || quote ? '"' + object + '"' : object;
526                                 }
528                                 if (typeof object === "function" && !(object instanceof RegExp)) {
529                                                 return ascii.func(object);
530                                 }
532                                 processed = processed || [];
534                                 if (isCircular(object, processed)) { return "[Circular]"; }
536                                 if (Object.prototype.toString.call(object) === "[object Array]") {
537                                                 return ascii.array.call(f, object, processed);
538                                 }
540                                 if (!object) { return String((1/object) === -Infinity ? "-0" : object); }
541                                 if (samsam.isElement(object)) { return ascii.element(object); }
543                                 if (typeof object.toString === "function" &&
544                                                                 object.toString !== Object.prototype.toString) {
545                                                 return object.toString();
546                                 }
548                                 var i, l;
549                                 for (i = 0, l = specialObjects.length; i < l; i++) {
550                                                 if (object === specialObjects[i].object) {
551                                                                 return specialObjects[i].value;
552                                                 }
553                                 }
555                                 return ascii.object.call(f, object, processed, indent);
556                 }
558                 ascii.func = function (func) {
559                                 return "function " + functionName(func) + "() {}";
560                 };
562                 ascii.array = function (array, processed) {
563                                 processed = processed || [];
564                                 processed.push(array);
565                                 var pieces = [];
566                                 var i, l;
567                                 l = (this.limitChildrenCount > 0) ?
568                                                 Math.min(this.limitChildrenCount, array.length) : array.length;
570                                 for (i = 0; i < l; ++i) {
571                                                 pieces.push(ascii(this, array[i], processed));
572                                 }
574                                 if(l < array.length)
575                                                 pieces.push("[... " + (array.length - l) + " more elements]");
577                                 return "[" + pieces.join(", ") + "]";
578                 };
580                 ascii.object = function (object, processed, indent) {
581                                 processed = processed || [];
582                                 processed.push(object);
583                                 indent = indent || 0;
584                                 var pieces = [], properties = samsam.keys(object).sort();
585                                 var length = 3;
586                                 var prop, str, obj, i, k, l;
587                                 l = (this.limitChildrenCount > 0) ?
588                                                 Math.min(this.limitChildrenCount, properties.length) : properties.length;
590                                 for (i = 0; i < l; ++i) {
591                                                 prop = properties[i];
592                                                 obj = object[prop];
594                                                 if (isCircular(obj, processed)) {
595                                                                 str = "[Circular]";
596                                                 } else {
597                                                                 str = ascii(this, obj, processed, indent + 2);
598                                                 }
600                                                 str = (/\s/.test(prop) ? '"' + prop + '"' : prop) + ": " + str;
601                                                 length += str.length;
602                                                 pieces.push(str);
603                                 }
605                                 var cons = constructorName(this, object);
606                                 var prefix = cons ? "[" + cons + "] " : "";
607                                 var is = "";
608                                 for (i = 0, k = indent; i < k; ++i) { is += " "; }
610                                 if(l < properties.length)
611                                                 pieces.push("[... " + (properties.length - l) + " more elements]");
613                                 if (length + indent > 80) {
614                                                 return prefix + "{\n  " + is + pieces.join(",\n  " + is) + "\n" +
615                                                                 is + "}";
616                                 }
617                                 return prefix + "{ " + pieces.join(", ") + " }";
618                 };
620                 ascii.element = function (element) {
621                                 var tagName = element.tagName.toLowerCase();
622                                 var attrs = element.attributes, attr, pairs = [], attrName, i, l, val;
624                                 for (i = 0, l = attrs.length; i < l; ++i) {
625                                                 attr = attrs.item(i);
626                                                 attrName = attr.nodeName.toLowerCase().replace("html:", "");
627                                                 val = attr.nodeValue;
628                                                 if (attrName !== "contenteditable" || val !== "inherit") {
629                                                                 if (!!val) { pairs.push(attrName + "=\"" + val + "\""); }
630                                                 }
631                                 }
633                                 var formatted = "<" + tagName + (pairs.length > 0 ? " " : "");
634                                 var content = element.innerHTML;
636                                 if (content.length > 20) {
637                                                 content = content.substr(0, 20) + "[...]";
638                                 }
640                                 var res = formatted + pairs.join(" ") + ">" + content +
641                                                                 "</" + tagName + ">";
643                                 return res.replace(/ contentEditable="inherit"/, "");
644                 };
646                 function Formatio(options) {
647                                 for (var opt in options) {
648                                                 this[opt] = options[opt];
649                                 }
650                 }
652                 Formatio.prototype = {
653                                 functionName: functionName,
655                                 configure: function (options) {
656                                                 return new Formatio(options);
657                                 },
659                                 constructorName: function (object) {
660                                                 return constructorName(this, object);
661                                 },
663                                 ascii: function (object, processed, indent) {
664                                                 return ascii(this, object, processed, indent);
665                                 }
666                 };
668                 return Formatio.prototype;
670 !function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.lolex=e()}}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
671 (function (global){
672 /*jslint eqeqeq: false, plusplus: false, evil: true, onevar: false, browser: true, forin: false*/
673 /*global global*/
675  * @author Christian Johansen (christian@cjohansen.no) and contributors
676  * @license BSD
678  * Copyright (c) 2010-2014 Christian Johansen
679  */
681 // node expects setTimeout/setInterval to return a fn object w/ .ref()/.unref()
682 // browsers, a number.
683 // see https://github.com/cjohansen/Sinon.JS/pull/436
684 var timeoutResult = setTimeout(function() {}, 0);
685 var addTimerReturnsObject = typeof timeoutResult === "object";
686 clearTimeout(timeoutResult);
688 var NativeDate = Date;
689 var id = 1;
692  * Parse strings like "01:10:00" (meaning 1 hour, 10 minutes, 0 seconds) into
693  * number of milliseconds. This is used to support human-readable strings passed
694  * to clock.tick()
695  */
696 function parseTime(str) {
697                 if (!str) {
698                                 return 0;
699                 }
701                 var strings = str.split(":");
702                 var l = strings.length, i = l;
703                 var ms = 0, parsed;
705                 if (l > 3 || !/^(\d\d:){0,2}\d\d?$/.test(str)) {
706                                 throw new Error("tick only understands numbers and 'h:m:s'");
707                 }
709                 while (i--) {
710                                 parsed = parseInt(strings[i], 10);
712                                 if (parsed >= 60) {
713                                                 throw new Error("Invalid time " + str);
714                                 }
716                                 ms += parsed * Math.pow(60, (l - i - 1));
717                 }
719                 return ms * 1000;
723  * Used to grok the `now` parameter to createClock.
724  */
725 function getEpoch(epoch) {
726                 if (!epoch) { return 0; }
727                 if (typeof epoch.getTime === "function") { return epoch.getTime(); }
728                 if (typeof epoch === "number") { return epoch; }
729                 throw new TypeError("now should be milliseconds since UNIX epoch");
732 function inRange(from, to, timer) {
733                 return timer && timer.callAt >= from && timer.callAt <= to;
736 function mirrorDateProperties(target, source) {
737                 if (source.now) {
738                                 target.now = function now() {
739                                                 return target.clock.now;
740                                 };
741                 } else {
742                                 delete target.now;
743                 }
745                 if (source.toSource) {
746                                 target.toSource = function toSource() {
747                                                 return source.toSource();
748                                 };
749                 } else {
750                                 delete target.toSource;
751                 }
753                 target.toString = function toString() {
754                                 return source.toString();
755                 };
757                 target.prototype = source.prototype;
758                 target.parse = source.parse;
759                 target.UTC = source.UTC;
760                 target.prototype.toUTCString = source.prototype.toUTCString;
762                 for (var prop in source) {
763                                 if (source.hasOwnProperty(prop)) {
764                                                 target[prop] = source[prop];
765                                 }
766                 }
768                 return target;
771 function createDate() {
772                 function ClockDate(year, month, date, hour, minute, second, ms) {
773                                 // Defensive and verbose to avoid potential harm in passing
774                                 // explicit undefined when user does not pass argument
775                                 switch (arguments.length) {
776                                 case 0:
777                                                 return new NativeDate(ClockDate.clock.now);
778                                 case 1:
779                                                 return new NativeDate(year);
780                                 case 2:
781                                                 return new NativeDate(year, month);
782                                 case 3:
783                                                 return new NativeDate(year, month, date);
784                                 case 4:
785                                                 return new NativeDate(year, month, date, hour);
786                                 case 5:
787                                                 return new NativeDate(year, month, date, hour, minute);
788                                 case 6:
789                                                 return new NativeDate(year, month, date, hour, minute, second);
790                                 default:
791                                                 return new NativeDate(year, month, date, hour, minute, second, ms);
792                                 }
793                 }
795                 return mirrorDateProperties(ClockDate, NativeDate);
798 function addTimer(clock, timer) {
799                 if (typeof timer.func === "undefined") {
800                                 throw new Error("Callback must be provided to timer calls");
801                 }
803                 if (!clock.timers) {
804                                 clock.timers = {};
805                 }
807                 timer.id = id++;
808                 timer.createdAt = clock.now;
809                 timer.callAt = clock.now + (timer.delay || 0);
811                 clock.timers[timer.id] = timer;
813                 if (addTimerReturnsObject) {
814                                 return {
815                                                 id: timer.id,
816                                                 ref: function() {},
817                                                 unref: function() {}
818                                 };
819                 }
820                 else {
821                                 return timer.id;
822                 }
825 function firstTimerInRange(clock, from, to) {
826                 var timers = clock.timers, timer = null;
828                 for (var id in timers) {
829                                 if (!inRange(from, to, timers[id])) {
830                                                 continue;
831                                 }
833                                 if (!timer || ~compareTimers(timer, timers[id])) {
834                                                 timer = timers[id];
835                                 }
836                 }
838                 return timer;
841 function compareTimers(a, b) {
842                 // Sort first by absolute timing
843                 if (a.callAt < b.callAt) {
844                                 return -1;
845                 }
846                 if (a.callAt > b.callAt) {
847                                 return 1;
848                 }
850                 // Sort next by immediate, immediate timers take precedence
851                 if (a.immediate && !b.immediate) {
852                                 return -1;
853                 }
854                 if (!a.immediate && b.immediate) {
855                                 return 1;
856                 }
858                 // Sort next by creation time, earlier-created timers take precedence
859                 if (a.createdAt < b.createdAt) {
860                                 return -1;
861                 }
862                 if (a.createdAt > b.createdAt) {
863                                 return 1;
864                 }
866                 // Sort next by id, lower-id timers take precedence
867                 if (a.id < b.id) {
868                                 return -1;
869                 }
870                 if (a.id > b.id) {
871                                 return 1;
872                 }
874                 // As timer ids are unique, no fallback `0` is necessary
877 function callTimer(clock, timer) {
878                 if (typeof timer.interval == "number") {
879                                 clock.timers[timer.id].callAt += timer.interval;
880                 } else {
881                                 delete clock.timers[timer.id];
882                 }
884                 try {
885                                 if (typeof timer.func == "function") {
886                                                 timer.func.apply(null, timer.args);
887                                 } else {
888                                                 eval(timer.func);
889                                 }
890                 } catch (e) {
891                                 var exception = e;
892                 }
894                 if (!clock.timers[timer.id]) {
895                                 if (exception) {
896                                                 throw exception;
897                                 }
898                                 return;
899                 }
901                 if (exception) {
902                                 throw exception;
903                 }
906 function uninstall(clock, target) {
907                 var method;
909                 for (var i = 0, l = clock.methods.length; i < l; i++) {
910                                 method = clock.methods[i];
912                                 if (target[method].hadOwnProperty) {
913                                                 target[method] = clock["_" + method];
914                                 } else {
915                                                 try {
916                                                                 delete target[method];
917                                                 } catch (e) {}
918                                 }
919                 }
921                 // Prevent multiple executions which will completely remove these props
922                 clock.methods = [];
925 function hijackMethod(target, method, clock) {
926                 clock[method].hadOwnProperty = Object.prototype.hasOwnProperty.call(target, method);
927                 clock["_" + method] = target[method];
929                 if (method == "Date") {
930                                 var date = mirrorDateProperties(clock[method], target[method]);
931                                 target[method] = date;
932                 } else {
933                                 target[method] = function () {
934                                                 return clock[method].apply(clock, arguments);
935                                 };
937                                 for (var prop in clock[method]) {
938                                                 if (clock[method].hasOwnProperty(prop)) {
939                                                                 target[method][prop] = clock[method][prop];
940                                                 }
941                                 }
942                 }
944                 target[method].clock = clock;
947 var timers = {
948                 setTimeout: setTimeout,
949                 clearTimeout: clearTimeout,
950                 setImmediate: (typeof setImmediate !== "undefined" ? setImmediate : undefined),
951                 clearImmediate: (typeof clearImmediate !== "undefined" ? clearImmediate: undefined),
952                 setInterval: setInterval,
953                 clearInterval: clearInterval,
954                 Date: Date
957 var keys = Object.keys || function (obj) {
958                 var ks = [];
959                 for (var key in obj) {
960                                 ks.push(key);
961                 }
962                 return ks;
965 exports.timers = timers;
967 var createClock = exports.createClock = function (now) {
968                 var clock = {
969                                 now: getEpoch(now),
970                                 timeouts: {},
971                                 Date: createDate()
972                 };
974                 clock.Date.clock = clock;
976                 clock.setTimeout = function setTimeout(func, timeout) {
977                                 return addTimer(clock, {
978                                                 func: func,
979                                                 args: Array.prototype.slice.call(arguments, 2),
980                                                 delay: timeout
981                                 });
982                 };
984                 clock.clearTimeout = function clearTimeout(timerId) {
985                                 if (!timerId) {
986                                                 // null appears to be allowed in most browsers, and appears to be
987                                                 // relied upon by some libraries, like Bootstrap carousel
988                                                 return;
989                                 }
990                                 if (!clock.timers) {
991                                                 clock.timers = [];
992                                 }
993                                 // in Node, timerId is an object with .ref()/.unref(), and
994                                 // its .id field is the actual timer id.
995                                 if (typeof timerId === "object") {
996                                                 timerId = timerId.id
997                                 }
998                                 if (timerId in clock.timers) {
999                                                 delete clock.timers[timerId];
1000                                 }
1001                 };
1003                 clock.setInterval = function setInterval(func, timeout) {
1004                                 return addTimer(clock, {
1005                                                 func: func,
1006                                                 args: Array.prototype.slice.call(arguments, 2),
1007                                                 delay: timeout,
1008                                                 interval: timeout
1009                                 });
1010                 };
1012                 clock.clearInterval = function clearInterval(timerId) {
1013                                 clock.clearTimeout(timerId);
1014                 };
1016                 clock.setImmediate = function setImmediate(func) {
1017                                 return addTimer(clock, {
1018                                                 func: func,
1019                                                 args: Array.prototype.slice.call(arguments, 1),
1020                                                 immediate: true
1021                                 });
1022                 };
1024                 clock.clearImmediate = function clearImmediate(timerId) {
1025                                 clock.clearTimeout(timerId);
1026                 };
1028                 clock.tick = function tick(ms) {
1029                                 ms = typeof ms == "number" ? ms : parseTime(ms);
1030                                 var tickFrom = clock.now, tickTo = clock.now + ms, previous = clock.now;
1031                                 var timer = firstTimerInRange(clock, tickFrom, tickTo);
1033                                 var firstException;
1034                                 while (timer && tickFrom <= tickTo) {
1035                                                 if (clock.timers[timer.id]) {
1036                                                                 tickFrom = clock.now = timer.callAt;
1037                                                                 try {
1038                                                                                 callTimer(clock, timer);
1039                                                                 } catch (e) {
1040                                                                                 firstException = firstException || e;
1041                                                                 }
1042                                                 }
1044                                                 timer = firstTimerInRange(clock, previous, tickTo);
1045                                                 previous = tickFrom;
1046                                 }
1048                                 clock.now = tickTo;
1050                                 if (firstException) {
1051                                                 throw firstException;
1052                                 }
1054                                 return clock.now;
1055                 };
1057                 clock.reset = function reset() {
1058                                 clock.timers = {};
1059                 };
1061                 return clock;
1064 exports.install = function install(target, now, toFake) {
1065                 if (typeof target === "number") {
1066                                 toFake = now;
1067                                 now = target;
1068                                 target = null;
1069                 }
1071                 if (!target) {
1072                                 target = global;
1073                 }
1075                 var clock = createClock(now);
1077                 clock.uninstall = function () {
1078                                 uninstall(clock, target);
1079                 };
1081                 clock.methods = toFake || [];
1083                 if (clock.methods.length === 0) {
1084                                 clock.methods = keys(timers);
1085                 }
1087                 for (var i = 0, l = clock.methods.length; i < l; i++) {
1088                                 hijackMethod(target, clock.methods[i], clock);
1089                 }
1091                 return clock;
1094 }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
1095 },{}]},{},[1])(1)
1097         })();
1098         var define;
1100  * Sinon core utilities. For internal use only.
1102  * @author Christian Johansen (christian@cjohansen.no)
1103  * @license BSD
1105  * Copyright (c) 2010-2013 Christian Johansen
1106  */
1108 var sinon = (function () {
1109 "use strict";
1111                 var sinon;
1112                 var isNode = typeof module !== "undefined" && module.exports && typeof require === "function";
1113                 var isAMD = typeof define === "function" && typeof define.amd === "object" && define.amd;
1115                 function loadDependencies(require, exports, module) {
1116                                 sinon = module.exports = require("./sinon/util/core");
1117                                 require("./sinon/extend");
1118                                 require("./sinon/typeOf");
1119                                 require("./sinon/times_in_words");
1120                                 require("./sinon/spy");
1121                                 require("./sinon/call");
1122                                 require("./sinon/behavior");
1123                                 require("./sinon/stub");
1124                                 require("./sinon/mock");
1125                                 require("./sinon/collection");
1126                                 require("./sinon/assert");
1127                                 require("./sinon/sandbox");
1128                                 require("./sinon/test");
1129                                 require("./sinon/test_case");
1130                                 require("./sinon/match");
1131                                 require("./sinon/format");
1132                                 require("./sinon/log_error");
1133                 }
1135                 if (isAMD) {
1136                                 define(loadDependencies);
1137                 } else if (isNode) {
1138                                 loadDependencies(require, module.exports, module);
1139                                 sinon = module.exports;
1140                 } else {
1141                                 sinon = {};
1142                 }
1144                 return sinon;
1145 }());
1148  * @depend ../../sinon.js
1149  */
1151  * Sinon core utilities. For internal use only.
1153  * @author Christian Johansen (christian@cjohansen.no)
1154  * @license BSD
1156  * Copyright (c) 2010-2013 Christian Johansen
1157  */
1159 (function (sinon) {
1160                 var div = typeof document != "undefined" && document.createElement("div");
1161                 var hasOwn = Object.prototype.hasOwnProperty;
1163                 function isDOMNode(obj) {
1164                                 var success = false;
1166                                 try {
1167                                                 obj.appendChild(div);
1168                                                 success = div.parentNode == obj;
1169                                 } catch (e) {
1170                                                 return false;
1171                                 } finally {
1172                                                 try {
1173                                                                 obj.removeChild(div);
1174                                                 } catch (e) {
1175                                                                 // Remove failed, not much we can do about that
1176                                                 }
1177                                 }
1179                                 return success;
1180                 }
1182                 function isElement(obj) {
1183                                 return div && obj && obj.nodeType === 1 && isDOMNode(obj);
1184                 }
1186                 function isFunction(obj) {
1187                                 return typeof obj === "function" || !!(obj && obj.constructor && obj.call && obj.apply);
1188                 }
1190                 function isReallyNaN(val) {
1191                                 return typeof val === "number" && isNaN(val);
1192                 }
1194                 function mirrorProperties(target, source) {
1195                                 for (var prop in source) {
1196                                                 if (!hasOwn.call(target, prop)) {
1197                                                                 target[prop] = source[prop];
1198                                                 }
1199                                 }
1200                 }
1202                 function isRestorable(obj) {
1203                                 return typeof obj === "function" && typeof obj.restore === "function" && obj.restore.sinon;
1204                 }
1206                 // Cheap way to detect if we have ES5 support.
1207                 var hasES5Support = "keys" in Object;
1209                 function makeApi(sinon) {
1210                                 sinon.wrapMethod = function wrapMethod(object, property, method) {
1211                                                 if (!object) {
1212                                                                 throw new TypeError("Should wrap property of object");
1213                                                 }
1215                                                 if (typeof method != "function" && typeof method != "object") {
1216                                                                 throw new TypeError("Method wrapper should be a function or a property descriptor");
1217                                                 }
1219                                                 function checkWrappedMethod(wrappedMethod) {
1220                                                                 if (!isFunction(wrappedMethod)) {
1221                                                                                 error = new TypeError("Attempted to wrap " + (typeof wrappedMethod) + " property " +
1222                                                                                                                                                                 property + " as function");
1223                                                                 } else if (wrappedMethod.restore && wrappedMethod.restore.sinon) {
1224                                                                                 error = new TypeError("Attempted to wrap " + property + " which is already wrapped");
1225                                                                 } else if (wrappedMethod.calledBefore) {
1226                                                                                 var verb = !!wrappedMethod.returns ? "stubbed" : "spied on";
1227                                                                                 error = new TypeError("Attempted to wrap " + property + " which is already " + verb);
1228                                                                 }
1230                                                                 if (error) {
1231                                                                                 if (wrappedMethod && wrappedMethod.stackTrace) {
1232                                                                                                 error.stack += "\n--------------\n" + wrappedMethod.stackTrace;
1233                                                                                 }
1234                                                                                 throw error;
1235                                                                 }
1236                                                 }
1238                                                 var error, wrappedMethod;
1240                                                 // IE 8 does not support hasOwnProperty on the window object and Firefox has a problem
1241                                                 // when using hasOwn.call on objects from other frames.
1242                                                 var owned = object.hasOwnProperty ? object.hasOwnProperty(property) : hasOwn.call(object, property);
1244                                                 if (hasES5Support) {
1245                                                                 var methodDesc = (typeof method == "function") ? {value: method} : method,
1246                                                                                 wrappedMethodDesc = sinon.getPropertyDescriptor(object, property),
1247                                                                                 i;
1249                                                                 if (!wrappedMethodDesc) {
1250                                                                                 error = new TypeError("Attempted to wrap " + (typeof wrappedMethod) + " property " +
1251                                                                                                                                                                 property + " as function");
1252                                                                 } else if (wrappedMethodDesc.restore && wrappedMethodDesc.restore.sinon) {
1253                                                                                 error = new TypeError("Attempted to wrap " + property + " which is already wrapped");
1254                                                                 }
1255                                                                 if (error) {
1256                                                                                 if (wrappedMethodDesc && wrappedMethodDesc.stackTrace) {
1257                                                                                                 error.stack += "\n--------------\n" + wrappedMethodDesc.stackTrace;
1258                                                                                 }
1259                                                                                 throw error;
1260                                                                 }
1262                                                                 var types = sinon.objectKeys(methodDesc);
1263                                                                 for (i = 0; i < types.length; i++) {
1264                                                                                 wrappedMethod = wrappedMethodDesc[types[i]];
1265                                                                                 checkWrappedMethod(wrappedMethod);
1266                                                                 }
1268                                                                 mirrorProperties(methodDesc, wrappedMethodDesc);
1269                                                                 for (i = 0; i < types.length; i++) {
1270                                                                                 mirrorProperties(methodDesc[types[i]], wrappedMethodDesc[types[i]]);
1271                                                                 }
1272                                                                 Object.defineProperty(object, property, methodDesc);
1273                                                 } else {
1274                                                                 wrappedMethod = object[property];
1275                                                                 checkWrappedMethod(wrappedMethod);
1276                                                                 object[property] = method;
1277                                                                 method.displayName = property;
1278                                                 }
1280                                                 method.displayName = property;
1282                                                 // Set up a stack trace which can be used later to find what line of
1283                                                 // code the original method was created on.
1284                                                 method.stackTrace = (new Error("Stack Trace for original")).stack;
1286                                                 method.restore = function () {
1287                                                                 // For prototype properties try to reset by delete first.
1288                                                                 // If this fails (ex: localStorage on mobile safari) then force a reset
1289                                                                 // via direct assignment.
1290                                                                 if (!owned) {
1291                                                                                 try {
1292                                                                                                 delete object[property];
1293                                                                                 } catch (e) {}
1294                                                                                 // For native code functions `delete` fails without throwing an error
1295                                                                                 // on Chrome < 43, PhantomJS, etc.
1296                                                                                 // Use strict equality comparison to check failures then force a reset
1297                                                                                 // via direct assignment.
1298                                                                                 if (object[property] === method) {
1299                                                                                                 object[property] = wrappedMethod;
1300                                                                                 }
1301                                                                 } else if (hasES5Support) {
1302                                                                                 Object.defineProperty(object, property, wrappedMethodDesc);
1303                                                                 }
1305                                                                 if (!hasES5Support && object[property] === method) {
1306                                                                                 object[property] = wrappedMethod;
1307                                                                 }
1308                                                 };
1310                                                 method.restore.sinon = true;
1312                                                 if (!hasES5Support) {
1313                                                                 mirrorProperties(method, wrappedMethod);
1314                                                 }
1316                                                 return method;
1317                                 };
1319                                 sinon.create = function create(proto) {
1320                                                 var F = function () {};
1321                                                 F.prototype = proto;
1322                                                 return new F();
1323                                 };
1325                                 sinon.deepEqual = function deepEqual(a, b) {
1326                                                 if (sinon.match && sinon.match.isMatcher(a)) {
1327                                                                 return a.test(b);
1328                                                 }
1330                                                 if (typeof a != "object" || typeof b != "object") {
1331                                                                 if (isReallyNaN(a) && isReallyNaN(b)) {
1332                                                                                 return true;
1333                                                                 } else {
1334                                                                                 return a === b;
1335                                                                 }
1336                                                 }
1338                                                 if (isElement(a) || isElement(b)) {
1339                                                                 return a === b;
1340                                                 }
1342                                                 if (a === b) {
1343                                                                 return true;
1344                                                 }
1346                                                 if ((a === null && b !== null) || (a !== null && b === null)) {
1347                                                                 return false;
1348                                                 }
1350                                                 if (a instanceof RegExp && b instanceof RegExp) {
1351                                                                 return (a.source === b.source) && (a.global === b.global) &&
1352                                                                                 (a.ignoreCase === b.ignoreCase) && (a.multiline === b.multiline);
1353                                                 }
1355                                                 var aString = Object.prototype.toString.call(a);
1356                                                 if (aString != Object.prototype.toString.call(b)) {
1357                                                                 return false;
1358                                                 }
1360                                                 if (aString == "[object Date]") {
1361                                                                 return a.valueOf() === b.valueOf();
1362                                                 }
1364                                                 var prop, aLength = 0, bLength = 0;
1366                                                 if (aString == "[object Array]" && a.length !== b.length) {
1367                                                                 return false;
1368                                                 }
1370                                                 for (prop in a) {
1371                                                                 aLength += 1;
1373                                                                 if (!(prop in b)) {
1374                                                                                 return false;
1375                                                                 }
1377                                                                 if (!deepEqual(a[prop], b[prop])) {
1378                                                                                 return false;
1379                                                                 }
1380                                                 }
1382                                                 for (prop in b) {
1383                                                                 bLength += 1;
1384                                                 }
1386                                                 return aLength == bLength;
1387                                 };
1389                                 sinon.functionName = function functionName(func) {
1390                                                 var name = func.displayName || func.name;
1392                                                 // Use function decomposition as a last resort to get function
1393                                                 // name. Does not rely on function decomposition to work - if it
1394                                                 // doesn't debugging will be slightly less informative
1395                                                 // (i.e. toString will say 'spy' rather than 'myFunc').
1396                                                 if (!name) {
1397                                                                 var matches = func.toString().match(/function ([^\s\(]+)/);
1398                                                                 name = matches && matches[1];
1399                                                 }
1401                                                 return name;
1402                                 };
1404                                 sinon.functionToString = function toString() {
1405                                                 if (this.getCall && this.callCount) {
1406                                                                 var thisValue, prop, i = this.callCount;
1408                                                                 while (i--) {
1409                                                                                 thisValue = this.getCall(i).thisValue;
1411                                                                                 for (prop in thisValue) {
1412                                                                                                 if (thisValue[prop] === this) {
1413                                                                                                                 return prop;
1414                                                                                                 }
1415                                                                                 }
1416                                                                 }
1417                                                 }
1419                                                 return this.displayName || "sinon fake";
1420                                 };
1422                                 sinon.objectKeys = function objectKeys(obj) {
1423                                                 if (obj !== Object(obj)) {
1424                                                                 throw new TypeError("sinon.objectKeys called on a non-object");
1425                                                 }
1427                                                 var keys = [];
1428                                                 var key;
1429                                                 for (key in obj) {
1430                                                                 if (hasOwn.call(obj, key)) {
1431                                                                                 keys.push(key);
1432                                                                 }
1433                                                 }
1435                                                 return keys;
1436                                 };
1438                                 sinon.getPropertyDescriptor = function getPropertyDescriptor(object, property) {
1439                                                 var proto = object, descriptor;
1440                                                 while (proto && !(descriptor = Object.getOwnPropertyDescriptor(proto, property))) {
1441                                                                 proto = Object.getPrototypeOf(proto);
1442                                                 }
1443                                                 return descriptor;
1444                                 }
1446                                 sinon.getConfig = function (custom) {
1447                                                 var config = {};
1448                                                 custom = custom || {};
1449                                                 var defaults = sinon.defaultConfig;
1451                                                 for (var prop in defaults) {
1452                                                                 if (defaults.hasOwnProperty(prop)) {
1453                                                                                 config[prop] = custom.hasOwnProperty(prop) ? custom[prop] : defaults[prop];
1454                                                                 }
1455                                                 }
1457                                                 return config;
1458                                 };
1460                                 sinon.defaultConfig = {
1461                                                 injectIntoThis: true,
1462                                                 injectInto: null,
1463                                                 properties: ["spy", "stub", "mock", "clock", "server", "requests"],
1464                                                 useFakeTimers: true,
1465                                                 useFakeServer: true
1466                                 };
1468                                 sinon.timesInWords = function timesInWords(count) {
1469                                                 return count == 1 && "once" ||
1470                                                                 count == 2 && "twice" ||
1471                                                                 count == 3 && "thrice" ||
1472                                                                 (count || 0) + " times";
1473                                 };
1475                                 sinon.calledInOrder = function (spies) {
1476                                                 for (var i = 1, l = spies.length; i < l; i++) {
1477                                                                 if (!spies[i - 1].calledBefore(spies[i]) || !spies[i].called) {
1478                                                                                 return false;
1479                                                                 }
1480                                                 }
1482                                                 return true;
1483                                 };
1485                                 sinon.orderByFirstCall = function (spies) {
1486                                                 return spies.sort(function (a, b) {
1487                                                                 // uuid, won't ever be equal
1488                                                                 var aCall = a.getCall(0);
1489                                                                 var bCall = b.getCall(0);
1490                                                                 var aId = aCall && aCall.callId || -1;
1491                                                                 var bId = bCall && bCall.callId || -1;
1493                                                                 return aId < bId ? -1 : 1;
1494                                                 });
1495                                 };
1497                                 sinon.createStubInstance = function (constructor) {
1498                                                 if (typeof constructor !== "function") {
1499                                                                 throw new TypeError("The constructor should be a function.");
1500                                                 }
1501                                                 return sinon.stub(sinon.create(constructor.prototype));
1502                                 };
1504                                 sinon.restore = function (object) {
1505                                                 if (object !== null && typeof object === "object") {
1506                                                                 for (var prop in object) {
1507                                                                                 if (isRestorable(object[prop])) {
1508                                                                                                 object[prop].restore();
1509                                                                                 }
1510                                                                 }
1511                                                 } else if (isRestorable(object)) {
1512                                                                 object.restore();
1513                                                 }
1514                                 };
1516                                 return sinon;
1517                 }
1519                 var isNode = typeof module !== "undefined" && module.exports && typeof require == "function";
1520                 var isAMD = typeof define === "function" && typeof define.amd === "object" && define.amd;
1522                 function loadDependencies(require, exports) {
1523                                 makeApi(exports);
1524                 }
1526                 if (isAMD) {
1527                                 define(loadDependencies);
1528                 } else if (isNode) {
1529                                 loadDependencies(require, module.exports);
1530                 } else if (!sinon) {
1531                                 return;
1532                 } else {
1533                                 makeApi(sinon);
1534                 }
1535 }(typeof sinon == "object" && sinon || null));
1538  * @depend util/core.js
1539  */
1541 (function (sinon) {
1542                 function makeApi(sinon) {
1544                                 // Adapted from https://developer.mozilla.org/en/docs/ECMAScript_DontEnum_attribute#JScript_DontEnum_Bug
1545                                 var hasDontEnumBug = (function () {
1546                                                 var obj = {
1547                                                                 constructor: function () {
1548                                                                                 return "0";
1549                                                                 },
1550                                                                 toString: function () {
1551                                                                                 return "1";
1552                                                                 },
1553                                                                 valueOf: function () {
1554                                                                                 return "2";
1555                                                                 },
1556                                                                 toLocaleString: function () {
1557                                                                                 return "3";
1558                                                                 },
1559                                                                 prototype: function () {
1560                                                                                 return "4";
1561                                                                 },
1562                                                                 isPrototypeOf: function () {
1563                                                                                 return "5";
1564                                                                 },
1565                                                                 propertyIsEnumerable: function () {
1566                                                                                 return "6";
1567                                                                 },
1568                                                                 hasOwnProperty: function () {
1569                                                                                 return "7";
1570                                                                 },
1571                                                                 length: function () {
1572                                                                                 return "8";
1573                                                                 },
1574                                                                 unique: function () {
1575                                                                                 return "9"
1576                                                                 }
1577                                                 };
1579                                                 var result = [];
1580                                                 for (var prop in obj) {
1581                                                                 result.push(obj[prop]());
1582                                                 }
1583                                                 return result.join("") !== "0123456789";
1584                                 })();
1586                                 /* Public: Extend target in place with all (own) properties from sources in-order. Thus, last source will
1587                                  *         override properties in previous sources.
1588                                  *
1589                                  * target - The Object to extend
1590                                  * sources - Objects to copy properties from.
1591                                  *
1592                                  * Returns the extended target
1593                                  */
1594                                 function extend(target /*, sources */) {
1595                                                 var sources = Array.prototype.slice.call(arguments, 1),
1596                                                                 source, i, prop;
1598                                                 for (i = 0; i < sources.length; i++) {
1599                                                                 source = sources[i];
1601                                                                 for (prop in source) {
1602                                                                                 if (source.hasOwnProperty(prop)) {
1603                                                                                                 target[prop] = source[prop];
1604                                                                                 }
1605                                                                 }
1607                                                                 // Make sure we copy (own) toString method even when in JScript with DontEnum bug
1608                                                                 // See https://developer.mozilla.org/en/docs/ECMAScript_DontEnum_attribute#JScript_DontEnum_Bug
1609                                                                 if (hasDontEnumBug && source.hasOwnProperty("toString") && source.toString !== target.toString) {
1610                                                                                 target.toString = source.toString;
1611                                                                 }
1612                                                 }
1614                                                 return target;
1615                                 };
1617                                 sinon.extend = extend;
1618                                 return sinon.extend;
1619                 }
1621                 function loadDependencies(require, exports, module) {
1622                                 var sinon = require("./util/core");
1623                                 module.exports = makeApi(sinon);
1624                 }
1626                 var isNode = typeof module !== "undefined" && module.exports && typeof require == "function";
1627                 var isAMD = typeof define === "function" && typeof define.amd === "object" && define.amd;
1629                 if (isAMD) {
1630                                 define(loadDependencies);
1631                 } else if (isNode) {
1632                                 loadDependencies(require, module.exports, module);
1633                 } else if (!sinon) {
1634                                 return;
1635                 } else {
1636                                 makeApi(sinon);
1637                 }
1638 }(typeof sinon == "object" && sinon || null));
1641  * @depend util/core.js
1642  */
1644 (function (sinon) {
1645                 function makeApi(sinon) {
1647                                 function timesInWords(count) {
1648                                                 switch (count) {
1649                                                                 case 1:
1650                                                                                 return "once";
1651                                                                 case 2:
1652                                                                                 return "twice";
1653                                                                 case 3:
1654                                                                                 return "thrice";
1655                                                                 default:
1656                                                                                 return (count || 0) + " times";
1657                                                 }
1658                                 }
1660                                 sinon.timesInWords = timesInWords;
1661                                 return sinon.timesInWords;
1662                 }
1664                 function loadDependencies(require, exports, module) {
1665                                 var sinon = require("./util/core");
1666                                 module.exports = makeApi(sinon);
1667                 }
1669                 var isNode = typeof module !== "undefined" && module.exports && typeof require == "function";
1670                 var isAMD = typeof define === "function" && typeof define.amd === "object" && define.amd;
1672                 if (isAMD) {
1673                                 define(loadDependencies);
1674                 } else if (isNode) {
1675                                 loadDependencies(require, module.exports, module);
1676                 } else if (!sinon) {
1677                                 return;
1678                 } else {
1679                                 makeApi(sinon);
1680                 }
1681 }(typeof sinon == "object" && sinon || null));
1684  * @depend util/core.js
1685  */
1687  * Format functions
1689  * @author Christian Johansen (christian@cjohansen.no)
1690  * @license BSD
1692  * Copyright (c) 2010-2014 Christian Johansen
1693  */
1695 (function (sinon, formatio) {
1696                 function makeApi(sinon) {
1697                                 function typeOf(value) {
1698                                                 if (value === null) {
1699                                                                 return "null";
1700                                                 } else if (value === undefined) {
1701                                                                 return "undefined";
1702                                                 }
1703                                                 var string = Object.prototype.toString.call(value);
1704                                                 return string.substring(8, string.length - 1).toLowerCase();
1705                                 };
1707                                 sinon.typeOf = typeOf;
1708                                 return sinon.typeOf;
1709                 }
1711                 function loadDependencies(require, exports, module) {
1712                                 var sinon = require("./util/core");
1713                                 module.exports = makeApi(sinon);
1714                 }
1716                 var isNode = typeof module !== "undefined" && module.exports && typeof require == "function";
1717                 var isAMD = typeof define === "function" && typeof define.amd === "object" && define.amd;
1719                 if (isAMD) {
1720                                 define(loadDependencies);
1721                 } else if (isNode) {
1722                                 loadDependencies(require, module.exports, module);
1723                 } else if (!sinon) {
1724                                 return;
1725                 } else {
1726                                 makeApi(sinon);
1727                 }
1729                 (typeof sinon == "object" && sinon || null),
1730                 (typeof formatio == "object" && formatio)
1734  * @depend util/core.js
1735  * @depend typeOf.js
1736  */
1737 /*jslint eqeqeq: false, onevar: false, plusplus: false*/
1738 /*global module, require, sinon*/
1740  * Match functions
1742  * @author Maximilian Antoni (mail@maxantoni.de)
1743  * @license BSD
1745  * Copyright (c) 2012 Maximilian Antoni
1746  */
1748 (function (sinon) {
1749                 function makeApi(sinon) {
1750                                 function assertType(value, type, name) {
1751                                                 var actual = sinon.typeOf(value);
1752                                                 if (actual !== type) {
1753                                                                 throw new TypeError("Expected type of " + name + " to be " +
1754                                                                                 type + ", but was " + actual);
1755                                                 }
1756                                 }
1758                                 var matcher = {
1759                                                 toString: function () {
1760                                                                 return this.message;
1761                                                 }
1762                                 };
1764                                 function isMatcher(object) {
1765                                                 return matcher.isPrototypeOf(object);
1766                                 }
1768                                 function matchObject(expectation, actual) {
1769                                                 if (actual === null || actual === undefined) {
1770                                                                 return false;
1771                                                 }
1772                                                 for (var key in expectation) {
1773                                                                 if (expectation.hasOwnProperty(key)) {
1774                                                                                 var exp = expectation[key];
1775                                                                                 var act = actual[key];
1776                                                                                 if (match.isMatcher(exp)) {
1777                                                                                                 if (!exp.test(act)) {
1778                                                                                                                 return false;
1779                                                                                                 }
1780                                                                                 } else if (sinon.typeOf(exp) === "object") {
1781                                                                                                 if (!matchObject(exp, act)) {
1782                                                                                                                 return false;
1783                                                                                                 }
1784                                                                                 } else if (!sinon.deepEqual(exp, act)) {
1785                                                                                                 return false;
1786                                                                                 }
1787                                                                 }
1788                                                 }
1789                                                 return true;
1790                                 }
1792                                 matcher.or = function (m2) {
1793                                                 if (!arguments.length) {
1794                                                                 throw new TypeError("Matcher expected");
1795                                                 } else if (!isMatcher(m2)) {
1796                                                                 m2 = match(m2);
1797                                                 }
1798                                                 var m1 = this;
1799                                                 var or = sinon.create(matcher);
1800                                                 or.test = function (actual) {
1801                                                                 return m1.test(actual) || m2.test(actual);
1802                                                 };
1803                                                 or.message = m1.message + ".or(" + m2.message + ")";
1804                                                 return or;
1805                                 };
1807                                 matcher.and = function (m2) {
1808                                                 if (!arguments.length) {
1809                                                                 throw new TypeError("Matcher expected");
1810                                                 } else if (!isMatcher(m2)) {
1811                                                                 m2 = match(m2);
1812                                                 }
1813                                                 var m1 = this;
1814                                                 var and = sinon.create(matcher);
1815                                                 and.test = function (actual) {
1816                                                                 return m1.test(actual) && m2.test(actual);
1817                                                 };
1818                                                 and.message = m1.message + ".and(" + m2.message + ")";
1819                                                 return and;
1820                                 };
1822                                 var match = function (expectation, message) {
1823                                                 var m = sinon.create(matcher);
1824                                                 var type = sinon.typeOf(expectation);
1825                                                 switch (type) {
1826                                                 case "object":
1827                                                                 if (typeof expectation.test === "function") {
1828                                                                                 m.test = function (actual) {
1829                                                                                                 return expectation.test(actual) === true;
1830                                                                                 };
1831                                                                                 m.message = "match(" + sinon.functionName(expectation.test) + ")";
1832                                                                                 return m;
1833                                                                 }
1834                                                                 var str = [];
1835                                                                 for (var key in expectation) {
1836                                                                                 if (expectation.hasOwnProperty(key)) {
1837                                                                                                 str.push(key + ": " + expectation[key]);
1838                                                                                 }
1839                                                                 }
1840                                                                 m.test = function (actual) {
1841                                                                                 return matchObject(expectation, actual);
1842                                                                 };
1843                                                                 m.message = "match(" + str.join(", ") + ")";
1844                                                                 break;
1845                                                 case "number":
1846                                                                 m.test = function (actual) {
1847                                                                                 return expectation == actual;
1848                                                                 };
1849                                                                 break;
1850                                                 case "string":
1851                                                                 m.test = function (actual) {
1852                                                                                 if (typeof actual !== "string") {
1853                                                                                                 return false;
1854                                                                                 }
1855                                                                                 return actual.indexOf(expectation) !== -1;
1856                                                                 };
1857                                                                 m.message = "match(\"" + expectation + "\")";
1858                                                                 break;
1859                                                 case "regexp":
1860                                                                 m.test = function (actual) {
1861                                                                                 if (typeof actual !== "string") {
1862                                                                                                 return false;
1863                                                                                 }
1864                                                                                 return expectation.test(actual);
1865                                                                 };
1866                                                                 break;
1867                                                 case "function":
1868                                                                 m.test = expectation;
1869                                                                 if (message) {
1870                                                                                 m.message = message;
1871                                                                 } else {
1872                                                                                 m.message = "match(" + sinon.functionName(expectation) + ")";
1873                                                                 }
1874                                                                 break;
1875                                                 default:
1876                                                                 m.test = function (actual) {
1877                                                                                 return sinon.deepEqual(expectation, actual);
1878                                                                 };
1879                                                 }
1880                                                 if (!m.message) {
1881                                                                 m.message = "match(" + expectation + ")";
1882                                                 }
1883                                                 return m;
1884                                 };
1886                                 match.isMatcher = isMatcher;
1888                                 match.any = match(function () {
1889                                                 return true;
1890                                 }, "any");
1892                                 match.defined = match(function (actual) {
1893                                                 return actual !== null && actual !== undefined;
1894                                 }, "defined");
1896                                 match.truthy = match(function (actual) {
1897                                                 return !!actual;
1898                                 }, "truthy");
1900                                 match.falsy = match(function (actual) {
1901                                                 return !actual;
1902                                 }, "falsy");
1904                                 match.same = function (expectation) {
1905                                                 return match(function (actual) {
1906                                                                 return expectation === actual;
1907                                                 }, "same(" + expectation + ")");
1908                                 };
1910                                 match.typeOf = function (type) {
1911                                                 assertType(type, "string", "type");
1912                                                 return match(function (actual) {
1913                                                                 return sinon.typeOf(actual) === type;
1914                                                 }, "typeOf(\"" + type + "\")");
1915                                 };
1917                                 match.instanceOf = function (type) {
1918                                                 assertType(type, "function", "type");
1919                                                 return match(function (actual) {
1920                                                                 return actual instanceof type;
1921                                                 }, "instanceOf(" + sinon.functionName(type) + ")");
1922                                 };
1924                                 function createPropertyMatcher(propertyTest, messagePrefix) {
1925                                                 return function (property, value) {
1926                                                                 assertType(property, "string", "property");
1927                                                                 var onlyProperty = arguments.length === 1;
1928                                                                 var message = messagePrefix + "(\"" + property + "\"";
1929                                                                 if (!onlyProperty) {
1930                                                                                 message += ", " + value;
1931                                                                 }
1932                                                                 message += ")";
1933                                                                 return match(function (actual) {
1934                                                                                 if (actual === undefined || actual === null ||
1935                                                                                                                 !propertyTest(actual, property)) {
1936                                                                                                 return false;
1937                                                                                 }
1938                                                                                 return onlyProperty || sinon.deepEqual(value, actual[property]);
1939                                                                 }, message);
1940                                                 };
1941                                 }
1943                                 match.has = createPropertyMatcher(function (actual, property) {
1944                                                 if (typeof actual === "object") {
1945                                                                 return property in actual;
1946                                                 }
1947                                                 return actual[property] !== undefined;
1948                                 }, "has");
1950                                 match.hasOwn = createPropertyMatcher(function (actual, property) {
1951                                                 return actual.hasOwnProperty(property);
1952                                 }, "hasOwn");
1954                                 match.bool = match.typeOf("boolean");
1955                                 match.number = match.typeOf("number");
1956                                 match.string = match.typeOf("string");
1957                                 match.object = match.typeOf("object");
1958                                 match.func = match.typeOf("function");
1959                                 match.array = match.typeOf("array");
1960                                 match.regexp = match.typeOf("regexp");
1961                                 match.date = match.typeOf("date");
1963                                 sinon.match = match;
1964                                 return match;
1965                 }
1967                 var isNode = typeof module !== "undefined" && module.exports && typeof require == "function";
1968                 var isAMD = typeof define === "function" && typeof define.amd === "object" && define.amd;
1970                 function loadDependencies(require, exports, module) {
1971                                 var sinon = require("./util/core");
1972                                 require("./typeOf");
1973                                 module.exports = makeApi(sinon);
1974                 }
1976                 if (isAMD) {
1977                                 define(loadDependencies);
1978                 } else if (isNode) {
1979                                 loadDependencies(require, module.exports, module);
1980                 } else if (!sinon) {
1981                                 return;
1982                 } else {
1983                                 makeApi(sinon);
1984                 }
1985 }(typeof sinon == "object" && sinon || null));
1988  * @depend util/core.js
1989  */
1991  * Format functions
1993  * @author Christian Johansen (christian@cjohansen.no)
1994  * @license BSD
1996  * Copyright (c) 2010-2014 Christian Johansen
1997  */
1999 (function (sinon, formatio) {
2000                 function makeApi(sinon) {
2001                                 function valueFormatter(value) {
2002                                                 return "" + value;
2003                                 }
2005                                 function getFormatioFormatter() {
2006                                                 var formatter = formatio.configure({
2007                                                                                 quoteStrings: false,
2008                                                                                 limitChildrenCount: 250
2009                                                                 });
2011                                                 function format() {
2012                                                                 return formatter.ascii.apply(formatter, arguments);
2013                                                 };
2015                                                 return format;
2016                                 }
2018                                 function getNodeFormatter(value) {
2019                                                 function format(value) {
2020                                                                 return typeof value == "object" && value.toString === Object.prototype.toString ? util.inspect(value) : value;
2021                                                 };
2023                                                 try {
2024                                                                 var util = require("util");
2025                                                 } catch (e) {
2026                                                                 /* Node, but no util module - would be very old, but better safe than sorry */
2027                                                 }
2029                                                 return util ? format : valueFormatter;
2030                                 }
2032                                 var isNode = typeof module !== "undefined" && module.exports && typeof require == "function",
2033                                                 formatter;
2035                                 if (isNode) {
2036                                                 try {
2037                                                                 formatio = require("formatio");
2038                                                 } catch (e) {}
2039                                 }
2041                                 if (formatio) {
2042                                                 formatter = getFormatioFormatter()
2043                                 } else if (isNode) {
2044                                                 formatter = getNodeFormatter();
2045                                 } else {
2046                                                 formatter = valueFormatter;
2047                                 }
2049                                 sinon.format = formatter;
2050                                 return sinon.format;
2051                 }
2053                 function loadDependencies(require, exports, module) {
2054                                 var sinon = require("./util/core");
2055                                 module.exports = makeApi(sinon);
2056                 }
2058                 var isNode = typeof module !== "undefined" && module.exports && typeof require == "function";
2059                 var isAMD = typeof define === "function" && typeof define.amd === "object" && define.amd;
2061                 if (isAMD) {
2062                                 define(loadDependencies);
2063                 } else if (isNode) {
2064                                 loadDependencies(require, module.exports, module);
2065                 } else if (!sinon) {
2066                                 return;
2067                 } else {
2068                                 makeApi(sinon);
2069                 }
2071                 (typeof sinon == "object" && sinon || null),
2072                 (typeof formatio == "object" && formatio)
2076         * @depend util/core.js
2077         * @depend match.js
2078         * @depend format.js
2079         */
2081         * Spy calls
2082         *
2083         * @author Christian Johansen (christian@cjohansen.no)
2084         * @author Maximilian Antoni (mail@maxantoni.de)
2085         * @license BSD
2086         *
2087         * Copyright (c) 2010-2013 Christian Johansen
2088         * Copyright (c) 2013 Maximilian Antoni
2089         */
2091 (function (sinon) {
2092                 function makeApi(sinon) {
2093                                 function throwYieldError(proxy, text, args) {
2094                                                 var msg = sinon.functionName(proxy) + text;
2095                                                 if (args.length) {
2096                                                                 msg += " Received [" + slice.call(args).join(", ") + "]";
2097                                                 }
2098                                                 throw new Error(msg);
2099                                 }
2101                                 var slice = Array.prototype.slice;
2103                                 var callProto = {
2104                                                 calledOn: function calledOn(thisValue) {
2105                                                                 if (sinon.match && sinon.match.isMatcher(thisValue)) {
2106                                                                                 return thisValue.test(this.thisValue);
2107                                                                 }
2108                                                                 return this.thisValue === thisValue;
2109                                                 },
2111                                                 calledWith: function calledWith() {
2112                                                                 var l = arguments.length;
2113                                                                 if (l > this.args.length) {
2114                                                                                 return false;
2115                                                                 }
2116                                                                 for (var i = 0; i < l; i += 1) {
2117                                                                                 if (!sinon.deepEqual(arguments[i], this.args[i])) {
2118                                                                                                 return false;
2119                                                                                 }
2120                                                                 }
2122                                                                 return true;
2123                                                 },
2125                                                 calledWithMatch: function calledWithMatch() {
2126                                                                 var l = arguments.length;
2127                                                                 if (l > this.args.length) {
2128                                                                                 return false;
2129                                                                 }
2130                                                                 for (var i = 0; i < l; i += 1) {
2131                                                                                 var actual = this.args[i];
2132                                                                                 var expectation = arguments[i];
2133                                                                                 if (!sinon.match || !sinon.match(expectation).test(actual)) {
2134                                                                                                 return false;
2135                                                                                 }
2136                                                                 }
2137                                                                 return true;
2138                                                 },
2140                                                 calledWithExactly: function calledWithExactly() {
2141                                                                 return arguments.length == this.args.length &&
2142                                                                                 this.calledWith.apply(this, arguments);
2143                                                 },
2145                                                 notCalledWith: function notCalledWith() {
2146                                                                 return !this.calledWith.apply(this, arguments);
2147                                                 },
2149                                                 notCalledWithMatch: function notCalledWithMatch() {
2150                                                                 return !this.calledWithMatch.apply(this, arguments);
2151                                                 },
2153                                                 returned: function returned(value) {
2154                                                                 return sinon.deepEqual(value, this.returnValue);
2155                                                 },
2157                                                 threw: function threw(error) {
2158                                                                 if (typeof error === "undefined" || !this.exception) {
2159                                                                                 return !!this.exception;
2160                                                                 }
2162                                                                 return this.exception === error || this.exception.name === error;
2163                                                 },
2165                                                 calledWithNew: function calledWithNew() {
2166                                                                 return this.proxy.prototype && this.thisValue instanceof this.proxy;
2167                                                 },
2169                                                 calledBefore: function (other) {
2170                                                                 return this.callId < other.callId;
2171                                                 },
2173                                                 calledAfter: function (other) {
2174                                                                 return this.callId > other.callId;
2175                                                 },
2177                                                 callArg: function (pos) {
2178                                                                 this.args[pos]();
2179                                                 },
2181                                                 callArgOn: function (pos, thisValue) {
2182                                                                 this.args[pos].apply(thisValue);
2183                                                 },
2185                                                 callArgWith: function (pos) {
2186                                                                 this.callArgOnWith.apply(this, [pos, null].concat(slice.call(arguments, 1)));
2187                                                 },
2189                                                 callArgOnWith: function (pos, thisValue) {
2190                                                                 var args = slice.call(arguments, 2);
2191                                                                 this.args[pos].apply(thisValue, args);
2192                                                 },
2194                                                 yield: function () {
2195                                                                 this.yieldOn.apply(this, [null].concat(slice.call(arguments, 0)));
2196                                                 },
2198                                                 yieldOn: function (thisValue) {
2199                                                                 var args = this.args;
2200                                                                 for (var i = 0, l = args.length; i < l; ++i) {
2201                                                                                 if (typeof args[i] === "function") {
2202                                                                                                 args[i].apply(thisValue, slice.call(arguments, 1));
2203                                                                                                 return;
2204                                                                                 }
2205                                                                 }
2206                                                                 throwYieldError(this.proxy, " cannot yield since no callback was passed.", args);
2207                                                 },
2209                                                 yieldTo: function (prop) {
2210                                                                 this.yieldToOn.apply(this, [prop, null].concat(slice.call(arguments, 1)));
2211                                                 },
2213                                                 yieldToOn: function (prop, thisValue) {
2214                                                                 var args = this.args;
2215                                                                 for (var i = 0, l = args.length; i < l; ++i) {
2216                                                                                 if (args[i] && typeof args[i][prop] === "function") {
2217                                                                                                 args[i][prop].apply(thisValue, slice.call(arguments, 2));
2218                                                                                                 return;
2219                                                                                 }
2220                                                                 }
2221                                                                 throwYieldError(this.proxy, " cannot yield to '" + prop +
2222                                                                                 "' since no callback was passed.", args);
2223                                                 },
2225                                                 toString: function () {
2226                                                                 var callStr = this.proxy.toString() + "(";
2227                                                                 var args = [];
2229                                                                 for (var i = 0, l = this.args.length; i < l; ++i) {
2230                                                                                 args.push(sinon.format(this.args[i]));
2231                                                                 }
2233                                                                 callStr = callStr + args.join(", ") + ")";
2235                                                                 if (typeof this.returnValue != "undefined") {
2236                                                                                 callStr += " => " + sinon.format(this.returnValue);
2237                                                                 }
2239                                                                 if (this.exception) {
2240                                                                                 callStr += " !" + this.exception.name;
2242                                                                                 if (this.exception.message) {
2243                                                                                                 callStr += "(" + this.exception.message + ")";
2244                                                                                 }
2245                                                                 }
2247                                                                 return callStr;
2248                                                 }
2249                                 };
2251                                 callProto.invokeCallback = callProto.yield;
2253                                 function createSpyCall(spy, thisValue, args, returnValue, exception, id) {
2254                                                 if (typeof id !== "number") {
2255                                                                 throw new TypeError("Call id is not a number");
2256                                                 }
2257                                                 var proxyCall = sinon.create(callProto);
2258                                                 proxyCall.proxy = spy;
2259                                                 proxyCall.thisValue = thisValue;
2260                                                 proxyCall.args = args;
2261                                                 proxyCall.returnValue = returnValue;
2262                                                 proxyCall.exception = exception;
2263                                                 proxyCall.callId = id;
2265                                                 return proxyCall;
2266                                 }
2267                                 createSpyCall.toString = callProto.toString; // used by mocks
2269                                 sinon.spyCall = createSpyCall;
2270                                 return createSpyCall;
2271                 }
2273                 var isNode = typeof module !== "undefined" && module.exports && typeof require == "function";
2274                 var isAMD = typeof define === "function" && typeof define.amd === "object" && define.amd;
2276                 function loadDependencies(require, exports, module) {
2277                                 var sinon = require("./util/core");
2278                                 require("./match");
2279                                 require("./format");
2280                                 module.exports = makeApi(sinon);
2281                 }
2283                 if (isAMD) {
2284                                 define(loadDependencies);
2285                 } else if (isNode) {
2286                                 loadDependencies(require, module.exports, module);
2287                 } else if (!sinon) {
2288                                 return;
2289                 } else {
2290                                 makeApi(sinon);
2291                 }
2292 }(typeof sinon == "object" && sinon || null));
2295         * @depend times_in_words.js
2296         * @depend util/core.js
2297         * @depend extend.js
2298         * @depend call.js
2299         * @depend format.js
2300         */
2302         * Spy functions
2303         *
2304         * @author Christian Johansen (christian@cjohansen.no)
2305         * @license BSD
2306         *
2307         * Copyright (c) 2010-2013 Christian Johansen
2308         */
2310 (function (sinon) {
2312                 function makeApi(sinon) {
2313                                 var push = Array.prototype.push;
2314                                 var slice = Array.prototype.slice;
2315                                 var callId = 0;
2317                                 function spy(object, property, types) {
2318                                                 if (!property && typeof object == "function") {
2319                                                                 return spy.create(object);
2320                                                 }
2322                                                 if (!object && !property) {
2323                                                                 return spy.create(function () { });
2324                                                 }
2326                                                 if (types) {
2327                                                                 var methodDesc = sinon.getPropertyDescriptor(object, property);
2328                                                                 for (var i = 0; i < types.length; i++) {
2329                                                                                 methodDesc[types[i]] = spy.create(methodDesc[types[i]]);
2330                                                                 }
2331                                                                 return sinon.wrapMethod(object, property, methodDesc);
2332                                                 } else {
2333                                                                 var method = object[property];
2334                                                                 return sinon.wrapMethod(object, property, spy.create(method));
2335                                                 }
2336                                 }
2338                                 function matchingFake(fakes, args, strict) {
2339                                                 if (!fakes) {
2340                                                                 return;
2341                                                 }
2343                                                 for (var i = 0, l = fakes.length; i < l; i++) {
2344                                                                 if (fakes[i].matches(args, strict)) {
2345                                                                                 return fakes[i];
2346                                                                 }
2347                                                 }
2348                                 }
2350                                 function incrementCallCount() {
2351                                                 this.called = true;
2352                                                 this.callCount += 1;
2353                                                 this.notCalled = false;
2354                                                 this.calledOnce = this.callCount == 1;
2355                                                 this.calledTwice = this.callCount == 2;
2356                                                 this.calledThrice = this.callCount == 3;
2357                                 }
2359                                 function createCallProperties() {
2360                                                 this.firstCall = this.getCall(0);
2361                                                 this.secondCall = this.getCall(1);
2362                                                 this.thirdCall = this.getCall(2);
2363                                                 this.lastCall = this.getCall(this.callCount - 1);
2364                                 }
2366                                 var vars = "a,b,c,d,e,f,g,h,i,j,k,l";
2367                                 function createProxy(func, proxyLength) {
2368                                                 // Retain the function length:
2369                                                 var p;
2370                                                 if (proxyLength) {
2371                                                                 eval("p = (function proxy(" + vars.substring(0, proxyLength * 2 - 1) +
2372                                                                                 ") { return p.invoke(func, this, slice.call(arguments)); });");
2373                                                 } else {
2374                                                                 p = function proxy() {
2375                                                                                 return p.invoke(func, this, slice.call(arguments));
2376                                                                 };
2377                                                 }
2378                                                 return p;
2379                                 }
2381                                 var uuid = 0;
2383                                 // Public API
2384                                 var spyApi = {
2385                                                 reset: function () {
2386                                                                 if (this.invoking) {
2387                                                                                 var err = new Error("Cannot reset Sinon function while invoking it. " +
2388                                                                                                                                                                 "Move the call to .reset outside of the callback.");
2389                                                                                 err.name = "InvalidResetException";
2390                                                                                 throw err;
2391                                                                 }
2393                                                                 this.called = false;
2394                                                                 this.notCalled = true;
2395                                                                 this.calledOnce = false;
2396                                                                 this.calledTwice = false;
2397                                                                 this.calledThrice = false;
2398                                                                 this.callCount = 0;
2399                                                                 this.firstCall = null;
2400                                                                 this.secondCall = null;
2401                                                                 this.thirdCall = null;
2402                                                                 this.lastCall = null;
2403                                                                 this.args = [];
2404                                                                 this.returnValues = [];
2405                                                                 this.thisValues = [];
2406                                                                 this.exceptions = [];
2407                                                                 this.callIds = [];
2408                                                                 if (this.fakes) {
2409                                                                                 for (var i = 0; i < this.fakes.length; i++) {
2410                                                                                                 this.fakes[i].reset();
2411                                                                                 }
2412                                                                 }
2414                                                                 return this;
2415                                                 },
2417                                                 create: function create(func, spyLength) {
2418                                                                 var name;
2420                                                                 if (typeof func != "function") {
2421                                                                                 func = function () { };
2422                                                                 } else {
2423                                                                                 name = sinon.functionName(func);
2424                                                                 }
2426                                                                 if (!spyLength) {
2427                                                                                 spyLength = func.length;
2428                                                                 }
2430                                                                 var proxy = createProxy(func, spyLength);
2432                                                                 sinon.extend(proxy, spy);
2433                                                                 delete proxy.create;
2434                                                                 sinon.extend(proxy, func);
2436                                                                 proxy.reset();
2437                                                                 proxy.prototype = func.prototype;
2438                                                                 proxy.displayName = name || "spy";
2439                                                                 proxy.toString = sinon.functionToString;
2440                                                                 proxy.instantiateFake = sinon.spy.create;
2441                                                                 proxy.id = "spy#" + uuid++;
2443                                                                 return proxy;
2444                                                 },
2446                                                 invoke: function invoke(func, thisValue, args) {
2447                                                                 var matching = matchingFake(this.fakes, args);
2448                                                                 var exception, returnValue;
2450                                                                 incrementCallCount.call(this);
2451                                                                 push.call(this.thisValues, thisValue);
2452                                                                 push.call(this.args, args);
2453                                                                 push.call(this.callIds, callId++);
2455                                                                 // Make call properties available from within the spied function:
2456                                                                 createCallProperties.call(this);
2458                                                                 try {
2459                                                                                 this.invoking = true;
2461                                                                                 if (matching) {
2462                                                                                                 returnValue = matching.invoke(func, thisValue, args);
2463                                                                                 } else {
2464                                                                                                 returnValue = (this.func || func).apply(thisValue, args);
2465                                                                                 }
2467                                                                                 var thisCall = this.getCall(this.callCount - 1);
2468                                                                                 if (thisCall.calledWithNew() && typeof returnValue !== "object") {
2469                                                                                                 returnValue = thisValue;
2470                                                                                 }
2471                                                                 } catch (e) {
2472                                                                                 exception = e;
2473                                                                 } finally {
2474                                                                                 delete this.invoking;
2475                                                                 }
2477                                                                 push.call(this.exceptions, exception);
2478                                                                 push.call(this.returnValues, returnValue);
2480                                                                 // Make return value and exception available in the calls:
2481                                                                 createCallProperties.call(this);
2483                                                                 if (exception !== undefined) {
2484                                                                                 throw exception;
2485                                                                 }
2487                                                                 return returnValue;
2488                                                 },
2490                                                 named: function named(name) {
2491                                                                 this.displayName = name;
2492                                                                 return this;
2493                                                 },
2495                                                 getCall: function getCall(i) {
2496                                                                 if (i < 0 || i >= this.callCount) {
2497                                                                                 return null;
2498                                                                 }
2500                                                                 return sinon.spyCall(this, this.thisValues[i], this.args[i],
2501                                                                                                                                                                 this.returnValues[i], this.exceptions[i],
2502                                                                                                                                                                 this.callIds[i]);
2503                                                 },
2505                                                 getCalls: function () {
2506                                                                 var calls = [];
2507                                                                 var i;
2509                                                                 for (i = 0; i < this.callCount; i++) {
2510                                                                                 calls.push(this.getCall(i));
2511                                                                 }
2513                                                                 return calls;
2514                                                 },
2516                                                 calledBefore: function calledBefore(spyFn) {
2517                                                                 if (!this.called) {
2518                                                                                 return false;
2519                                                                 }
2521                                                                 if (!spyFn.called) {
2522                                                                                 return true;
2523                                                                 }
2525                                                                 return this.callIds[0] < spyFn.callIds[spyFn.callIds.length - 1];
2526                                                 },
2528                                                 calledAfter: function calledAfter(spyFn) {
2529                                                                 if (!this.called || !spyFn.called) {
2530                                                                                 return false;
2531                                                                 }
2533                                                                 return this.callIds[this.callCount - 1] > spyFn.callIds[spyFn.callCount - 1];
2534                                                 },
2536                                                 withArgs: function () {
2537                                                                 var args = slice.call(arguments);
2539                                                                 if (this.fakes) {
2540                                                                                 var match = matchingFake(this.fakes, args, true);
2542                                                                                 if (match) {
2543                                                                                                 return match;
2544                                                                                 }
2545                                                                 } else {
2546                                                                                 this.fakes = [];
2547                                                                 }
2549                                                                 var original = this;
2550                                                                 var fake = this.instantiateFake();
2551                                                                 fake.matchingAguments = args;
2552                                                                 fake.parent = this;
2553                                                                 push.call(this.fakes, fake);
2555                                                                 fake.withArgs = function () {
2556                                                                                 return original.withArgs.apply(original, arguments);
2557                                                                 };
2559                                                                 for (var i = 0; i < this.args.length; i++) {
2560                                                                                 if (fake.matches(this.args[i])) {
2561                                                                                                 incrementCallCount.call(fake);
2562                                                                                                 push.call(fake.thisValues, this.thisValues[i]);
2563                                                                                                 push.call(fake.args, this.args[i]);
2564                                                                                                 push.call(fake.returnValues, this.returnValues[i]);
2565                                                                                                 push.call(fake.exceptions, this.exceptions[i]);
2566                                                                                                 push.call(fake.callIds, this.callIds[i]);
2567                                                                                 }
2568                                                                 }
2569                                                                 createCallProperties.call(fake);
2571                                                                 return fake;
2572                                                 },
2574                                                 matches: function (args, strict) {
2575                                                                 var margs = this.matchingAguments;
2577                                                                 if (margs.length <= args.length &&
2578                                                                                 sinon.deepEqual(margs, args.slice(0, margs.length))) {
2579                                                                                 return !strict || margs.length == args.length;
2580                                                                 }
2581                                                 },
2583                                                 printf: function (format) {
2584                                                                 var spy = this;
2585                                                                 var args = slice.call(arguments, 1);
2586                                                                 var formatter;
2588                                                                 return (format || "").replace(/%(.)/g, function (match, specifyer) {
2589                                                                                 formatter = spyApi.formatters[specifyer];
2591                                                                                 if (typeof formatter == "function") {
2592                                                                                                 return formatter.call(null, spy, args);
2593                                                                                 } else if (!isNaN(parseInt(specifyer, 10))) {
2594                                                                                                 return sinon.format(args[specifyer - 1]);
2595                                                                                 }
2597                                                                                 return "%" + specifyer;
2598                                                                 });
2599                                                 }
2600                                 };
2602                                 function delegateToCalls(method, matchAny, actual, notCalled) {
2603                                                 spyApi[method] = function () {
2604                                                                 if (!this.called) {
2605                                                                                 if (notCalled) {
2606                                                                                                 return notCalled.apply(this, arguments);
2607                                                                                 }
2608                                                                                 return false;
2609                                                                 }
2611                                                                 var currentCall;
2612                                                                 var matches = 0;
2614                                                                 for (var i = 0, l = this.callCount; i < l; i += 1) {
2615                                                                                 currentCall = this.getCall(i);
2617                                                                                 if (currentCall[actual || method].apply(currentCall, arguments)) {
2618                                                                                                 matches += 1;
2620                                                                                                 if (matchAny) {
2621                                                                                                                 return true;
2622                                                                                                 }
2623                                                                                 }
2624                                                                 }
2626                                                                 return matches === this.callCount;
2627                                                 };
2628                                 }
2630                                 delegateToCalls("calledOn", true);
2631                                 delegateToCalls("alwaysCalledOn", false, "calledOn");
2632                                 delegateToCalls("calledWith", true);
2633                                 delegateToCalls("calledWithMatch", true);
2634                                 delegateToCalls("alwaysCalledWith", false, "calledWith");
2635                                 delegateToCalls("alwaysCalledWithMatch", false, "calledWithMatch");
2636                                 delegateToCalls("calledWithExactly", true);
2637                                 delegateToCalls("alwaysCalledWithExactly", false, "calledWithExactly");
2638                                 delegateToCalls("neverCalledWith", false, "notCalledWith",
2639                                                 function () { return true; });
2640                                 delegateToCalls("neverCalledWithMatch", false, "notCalledWithMatch",
2641                                                 function () { return true; });
2642                                 delegateToCalls("threw", true);
2643                                 delegateToCalls("alwaysThrew", false, "threw");
2644                                 delegateToCalls("returned", true);
2645                                 delegateToCalls("alwaysReturned", false, "returned");
2646                                 delegateToCalls("calledWithNew", true);
2647                                 delegateToCalls("alwaysCalledWithNew", false, "calledWithNew");
2648                                 delegateToCalls("callArg", false, "callArgWith", function () {
2649                                                 throw new Error(this.toString() + " cannot call arg since it was not yet invoked.");
2650                                 });
2651                                 spyApi.callArgWith = spyApi.callArg;
2652                                 delegateToCalls("callArgOn", false, "callArgOnWith", function () {
2653                                                 throw new Error(this.toString() + " cannot call arg since it was not yet invoked.");
2654                                 });
2655                                 spyApi.callArgOnWith = spyApi.callArgOn;
2656                                 delegateToCalls("yield", false, "yield", function () {
2657                                                 throw new Error(this.toString() + " cannot yield since it was not yet invoked.");
2658                                 });
2659                                 // "invokeCallback" is an alias for "yield" since "yield" is invalid in strict mode.
2660                                 spyApi.invokeCallback = spyApi.yield;
2661                                 delegateToCalls("yieldOn", false, "yieldOn", function () {
2662                                                 throw new Error(this.toString() + " cannot yield since it was not yet invoked.");
2663                                 });
2664                                 delegateToCalls("yieldTo", false, "yieldTo", function (property) {
2665                                                 throw new Error(this.toString() + " cannot yield to '" + property +
2666                                                                 "' since it was not yet invoked.");
2667                                 });
2668                                 delegateToCalls("yieldToOn", false, "yieldToOn", function (property) {
2669                                                 throw new Error(this.toString() + " cannot yield to '" + property +
2670                                                                 "' since it was not yet invoked.");
2671                                 });
2673                                 spyApi.formatters = {
2674                                                 c: function (spy) {
2675                                                                 return sinon.timesInWords(spy.callCount);
2676                                                 },
2678                                                 n: function (spy) {
2679                                                                 return spy.toString();
2680                                                 },
2682                                                 C: function (spy) {
2683                                                                 var calls = [];
2685                                                                 for (var i = 0, l = spy.callCount; i < l; ++i) {
2686                                                                                 var stringifiedCall = "    " + spy.getCall(i).toString();
2687                                                                                 if (/\n/.test(calls[i - 1])) {
2688                                                                                                 stringifiedCall = "\n" + stringifiedCall;
2689                                                                                 }
2690                                                                                 push.call(calls, stringifiedCall);
2691                                                                 }
2693                                                                 return calls.length > 0 ? "\n" + calls.join("\n") : "";
2694                                                 },
2696                                                 t: function (spy) {
2697                                                                 var objects = [];
2699                                                                 for (var i = 0, l = spy.callCount; i < l; ++i) {
2700                                                                                 push.call(objects, sinon.format(spy.thisValues[i]));
2701                                                                 }
2703                                                                 return objects.join(", ");
2704                                                 },
2706                                                 "*": function (spy, args) {
2707                                                                 var formatted = [];
2709                                                                 for (var i = 0, l = args.length; i < l; ++i) {
2710                                                                                 push.call(formatted, sinon.format(args[i]));
2711                                                                 }
2713                                                                 return formatted.join(", ");
2714                                                 }
2715                                 };
2717                                 sinon.extend(spy, spyApi);
2719                                 spy.spyCall = sinon.spyCall;
2720                                 sinon.spy = spy;
2722                                 return spy;
2723                 }
2725                 var isNode = typeof module !== "undefined" && module.exports && typeof require == "function";
2726                 var isAMD = typeof define === "function" && typeof define.amd === "object" && define.amd;
2728                 function loadDependencies(require, exports, module) {
2729                                 var sinon = require("./util/core");
2730                                 require("./call");
2731                                 require("./extend");
2732                                 require("./times_in_words");
2733                                 require("./format");
2734                                 module.exports = makeApi(sinon);
2735                 }
2737                 if (isAMD) {
2738                                 define(loadDependencies);
2739                 } else if (isNode) {
2740                                 loadDependencies(require, module.exports, module);
2741                 } else if (!sinon) {
2742                                 return;
2743                 } else {
2744                                 makeApi(sinon);
2745                 }
2746 }(typeof sinon == "object" && sinon || null));
2749  * @depend util/core.js
2750  * @depend extend.js
2751  */
2753  * Stub behavior
2755  * @author Christian Johansen (christian@cjohansen.no)
2756  * @author Tim Fischbach (mail@timfischbach.de)
2757  * @license BSD
2759  * Copyright (c) 2010-2013 Christian Johansen
2760  */
2762 (function (sinon) {
2763                 var slice = Array.prototype.slice;
2764                 var join = Array.prototype.join;
2765                 var useLeftMostCallback = -1;
2766                 var useRightMostCallback = -2;
2768                 var nextTick = (function () {
2769                                 if (typeof process === "object" && typeof process.nextTick === "function") {
2770                                                 return process.nextTick;
2771                                 } else if (typeof setImmediate === "function") {
2772                                                 return setImmediate;
2773                                 } else {
2774                                                 return function (callback) {
2775                                                                 setTimeout(callback, 0);
2776                                                 };
2777                                 }
2778                 })();
2780                 function throwsException(error, message) {
2781                                 if (typeof error == "string") {
2782                                                 this.exception = new Error(message || "");
2783                                                 this.exception.name = error;
2784                                 } else if (!error) {
2785                                                 this.exception = new Error("Error");
2786                                 } else {
2787                                                 this.exception = error;
2788                                 }
2790                                 return this;
2791                 }
2793                 function getCallback(behavior, args) {
2794                                 var callArgAt = behavior.callArgAt;
2796                                 if (callArgAt >= 0) {
2797                                                 return args[callArgAt];
2798                                 }
2800                                 var argumentList;
2802                                 if (callArgAt === useLeftMostCallback) {
2803                                                 argumentList = args;
2804                                 }
2806                                 if (callArgAt === useRightMostCallback) {
2807                                                 argumentList = slice.call(args).reverse();
2808                                 }
2810                                 var callArgProp = behavior.callArgProp;
2812                                 for (var i = 0, l = argumentList.length; i < l; ++i) {
2813                                                 if (!callArgProp && typeof argumentList[i] == "function") {
2814                                                                 return argumentList[i];
2815                                                 }
2817                                                 if (callArgProp && argumentList[i] &&
2818                                                                 typeof argumentList[i][callArgProp] == "function") {
2819                                                                 return argumentList[i][callArgProp];
2820                                                 }
2821                                 }
2823                                 return null;
2824                 }
2826                 function makeApi(sinon) {
2827                                 function getCallbackError(behavior, func, args) {
2828                                                 if (behavior.callArgAt < 0) {
2829                                                                 var msg;
2831                                                                 if (behavior.callArgProp) {
2832                                                                                 msg = sinon.functionName(behavior.stub) +
2833                                                                                                 " expected to yield to '" + behavior.callArgProp +
2834                                                                                                 "', but no object with such a property was passed.";
2835                                                                 } else {
2836                                                                                 msg = sinon.functionName(behavior.stub) +
2837                                                                                                 " expected to yield, but no callback was passed.";
2838                                                                 }
2840                                                                 if (args.length > 0) {
2841                                                                                 msg += " Received [" + join.call(args, ", ") + "]";
2842                                                                 }
2844                                                                 return msg;
2845                                                 }
2847                                                 return "argument at index " + behavior.callArgAt + " is not a function: " + func;
2848                                 }
2850                                 function callCallback(behavior, args) {
2851                                                 if (typeof behavior.callArgAt == "number") {
2852                                                                 var func = getCallback(behavior, args);
2854                                                                 if (typeof func != "function") {
2855                                                                                 throw new TypeError(getCallbackError(behavior, func, args));
2856                                                                 }
2858                                                                 if (behavior.callbackAsync) {
2859                                                                                 nextTick(function () {
2860                                                                                                 func.apply(behavior.callbackContext, behavior.callbackArguments);
2861                                                                                 });
2862                                                                 } else {
2863                                                                                 func.apply(behavior.callbackContext, behavior.callbackArguments);
2864                                                                 }
2865                                                 }
2866                                 }
2868                                 var proto = {
2869                                                 create: function create(stub) {
2870                                                                 var behavior = sinon.extend({}, sinon.behavior);
2871                                                                 delete behavior.create;
2872                                                                 behavior.stub = stub;
2874                                                                 return behavior;
2875                                                 },
2877                                                 isPresent: function isPresent() {
2878                                                                 return (typeof this.callArgAt == "number" ||
2879                                                                                                 this.exception ||
2880                                                                                                 typeof this.returnArgAt == "number" ||
2881                                                                                                 this.returnThis ||
2882                                                                                                 this.returnValueDefined);
2883                                                 },
2885                                                 invoke: function invoke(context, args) {
2886                                                                 callCallback(this, args);
2888                                                                 if (this.exception) {
2889                                                                                 throw this.exception;
2890                                                                 } else if (typeof this.returnArgAt == "number") {
2891                                                                                 return args[this.returnArgAt];
2892                                                                 } else if (this.returnThis) {
2893                                                                                 return context;
2894                                                                 }
2896                                                                 return this.returnValue;
2897                                                 },
2899                                                 onCall: function onCall(index) {
2900                                                                 return this.stub.onCall(index);
2901                                                 },
2903                                                 onFirstCall: function onFirstCall() {
2904                                                                 return this.stub.onFirstCall();
2905                                                 },
2907                                                 onSecondCall: function onSecondCall() {
2908                                                                 return this.stub.onSecondCall();
2909                                                 },
2911                                                 onThirdCall: function onThirdCall() {
2912                                                                 return this.stub.onThirdCall();
2913                                                 },
2915                                                 withArgs: function withArgs(/* arguments */) {
2916                                                                 throw new Error("Defining a stub by invoking \"stub.onCall(...).withArgs(...)\" is not supported. " +
2917                                                                                                                                 "Use \"stub.withArgs(...).onCall(...)\" to define sequential behavior for calls with certain arguments.");
2918                                                 },
2920                                                 callsArg: function callsArg(pos) {
2921                                                                 if (typeof pos != "number") {
2922                                                                                 throw new TypeError("argument index is not number");
2923                                                                 }
2925                                                                 this.callArgAt = pos;
2926                                                                 this.callbackArguments = [];
2927                                                                 this.callbackContext = undefined;
2928                                                                 this.callArgProp = undefined;
2929                                                                 this.callbackAsync = false;
2931                                                                 return this;
2932                                                 },
2934                                                 callsArgOn: function callsArgOn(pos, context) {
2935                                                                 if (typeof pos != "number") {
2936                                                                                 throw new TypeError("argument index is not number");
2937                                                                 }
2938                                                                 if (typeof context != "object") {
2939                                                                                 throw new TypeError("argument context is not an object");
2940                                                                 }
2942                                                                 this.callArgAt = pos;
2943                                                                 this.callbackArguments = [];
2944                                                                 this.callbackContext = context;
2945                                                                 this.callArgProp = undefined;
2946                                                                 this.callbackAsync = false;
2948                                                                 return this;
2949                                                 },
2951                                                 callsArgWith: function callsArgWith(pos) {
2952                                                                 if (typeof pos != "number") {
2953                                                                                 throw new TypeError("argument index is not number");
2954                                                                 }
2956                                                                 this.callArgAt = pos;
2957                                                                 this.callbackArguments = slice.call(arguments, 1);
2958                                                                 this.callbackContext = undefined;
2959                                                                 this.callArgProp = undefined;
2960                                                                 this.callbackAsync = false;
2962                                                                 return this;
2963                                                 },
2965                                                 callsArgOnWith: function callsArgWith(pos, context) {
2966                                                                 if (typeof pos != "number") {
2967                                                                                 throw new TypeError("argument index is not number");
2968                                                                 }
2969                                                                 if (typeof context != "object") {
2970                                                                                 throw new TypeError("argument context is not an object");
2971                                                                 }
2973                                                                 this.callArgAt = pos;
2974                                                                 this.callbackArguments = slice.call(arguments, 2);
2975                                                                 this.callbackContext = context;
2976                                                                 this.callArgProp = undefined;
2977                                                                 this.callbackAsync = false;
2979                                                                 return this;
2980                                                 },
2982                                                 yields: function () {
2983                                                                 this.callArgAt = useLeftMostCallback;
2984                                                                 this.callbackArguments = slice.call(arguments, 0);
2985                                                                 this.callbackContext = undefined;
2986                                                                 this.callArgProp = undefined;
2987                                                                 this.callbackAsync = false;
2989                                                                 return this;
2990                                                 },
2992                                                 yieldsRight: function () {
2993                                                                 this.callArgAt = useRightMostCallback;
2994                                                                 this.callbackArguments = slice.call(arguments, 0);
2995                                                                 this.callbackContext = undefined;
2996                                                                 this.callArgProp = undefined;
2997                                                                 this.callbackAsync = false;
2999                                                                 return this;
3000                                                 },
3002                                                 yieldsOn: function (context) {
3003                                                                 if (typeof context != "object") {
3004                                                                                 throw new TypeError("argument context is not an object");
3005                                                                 }
3007                                                                 this.callArgAt = useLeftMostCallback;
3008                                                                 this.callbackArguments = slice.call(arguments, 1);
3009                                                                 this.callbackContext = context;
3010                                                                 this.callArgProp = undefined;
3011                                                                 this.callbackAsync = false;
3013                                                                 return this;
3014                                                 },
3016                                                 yieldsTo: function (prop) {
3017                                                                 this.callArgAt = useLeftMostCallback;
3018                                                                 this.callbackArguments = slice.call(arguments, 1);
3019                                                                 this.callbackContext = undefined;
3020                                                                 this.callArgProp = prop;
3021                                                                 this.callbackAsync = false;
3023                                                                 return this;
3024                                                 },
3026                                                 yieldsToOn: function (prop, context) {
3027                                                                 if (typeof context != "object") {
3028                                                                                 throw new TypeError("argument context is not an object");
3029                                                                 }
3031                                                                 this.callArgAt = useLeftMostCallback;
3032                                                                 this.callbackArguments = slice.call(arguments, 2);
3033                                                                 this.callbackContext = context;
3034                                                                 this.callArgProp = prop;
3035                                                                 this.callbackAsync = false;
3037                                                                 return this;
3038                                                 },
3040                                                 throws: throwsException,
3041                                                 throwsException: throwsException,
3043                                                 returns: function returns(value) {
3044                                                                 this.returnValue = value;
3045                                                                 this.returnValueDefined = true;
3047                                                                 return this;
3048                                                 },
3050                                                 returnsArg: function returnsArg(pos) {
3051                                                                 if (typeof pos != "number") {
3052                                                                                 throw new TypeError("argument index is not number");
3053                                                                 }
3055                                                                 this.returnArgAt = pos;
3057                                                                 return this;
3058                                                 },
3060                                                 returnsThis: function returnsThis() {
3061                                                                 this.returnThis = true;
3063                                                                 return this;
3064                                                 }
3065                                 };
3067                                 // create asynchronous versions of callsArg* and yields* methods
3068                                 for (var method in proto) {
3069                                                 // need to avoid creating anotherasync versions of the newly added async methods
3070                                                 if (proto.hasOwnProperty(method) &&
3071                                                                 method.match(/^(callsArg|yields)/) &&
3072                                                                 !method.match(/Async/)) {
3073                                                                 proto[method + "Async"] = (function (syncFnName) {
3074                                                                                 return function () {
3075                                                                                                 var result = this[syncFnName].apply(this, arguments);
3076                                                                                                 this.callbackAsync = true;
3077                                                                                                 return result;
3078                                                                                 };
3079                                                                 })(method);
3080                                                 }
3081                                 }
3083                                 sinon.behavior = proto;
3084                                 return proto;
3085                 }
3087                 var isNode = typeof module !== "undefined" && module.exports && typeof require == "function";
3088                 var isAMD = typeof define === "function" && typeof define.amd === "object" && define.amd;
3090                 function loadDependencies(require, exports, module) {
3091                                 var sinon = require("./util/core");
3092                                 require("./extend");
3093                                 module.exports = makeApi(sinon);
3094                 }
3096                 if (isAMD) {
3097                                 define(loadDependencies);
3098                 } else if (isNode) {
3099                                 loadDependencies(require, module.exports, module);
3100                 } else if (!sinon) {
3101                                 return;
3102                 } else {
3103                                 makeApi(sinon);
3104                 }
3105 }(typeof sinon == "object" && sinon || null));
3108  * @depend util/core.js
3109  * @depend extend.js
3110  * @depend spy.js
3111  * @depend behavior.js
3112  */
3114  * Stub functions
3116  * @author Christian Johansen (christian@cjohansen.no)
3117  * @license BSD
3119  * Copyright (c) 2010-2013 Christian Johansen
3120  */
3122 (function (sinon) {
3123                 function makeApi(sinon) {
3124                                 function stub(object, property, func) {
3125                                                 if (!!func && typeof func != "function" && typeof func != "object") {
3126                                                                 throw new TypeError("Custom stub should be a function or a property descriptor");
3127                                                 }
3129                                                 var wrapper;
3131                                                 if (func) {
3132                                                                 if (typeof func == "function") {
3133                                                                                 wrapper = sinon.spy && sinon.spy.create ? sinon.spy.create(func) : func;
3134                                                                 } else {
3135                                                                                 wrapper = func;
3136                                                                                 if (sinon.spy && sinon.spy.create) {
3137                                                                                                 var types = sinon.objectKeys(wrapper);
3138                                                                                                 for (var i = 0; i < types.length; i++) {
3139                                                                                                                 wrapper[types[i]] = sinon.spy.create(wrapper[types[i]]);
3140                                                                                                 }
3141                                                                                 }
3142                                                                 }
3143                                                 } else {
3144                                                                 var stubLength = 0;
3145                                                                 if (typeof object == "object" && typeof object[property] == "function") {
3146                                                                                 stubLength = object[property].length;
3147                                                                 }
3148                                                                 wrapper = stub.create(stubLength);
3149                                                 }
3151                                                 if (!object && typeof property === "undefined") {
3152                                                                 return sinon.stub.create();
3153                                                 }
3155                                                 if (typeof property === "undefined" && typeof object == "object") {
3156                                                                 for (var prop in object) {
3157                                                                                 if (typeof object[prop] === "function") {
3158                                                                                                 stub(object, prop);
3159                                                                                 }
3160                                                                 }
3162                                                                 return object;
3163                                                 }
3165                                                 return sinon.wrapMethod(object, property, wrapper);
3166                                 }
3168                                 function getDefaultBehavior(stub) {
3169                                                 return stub.defaultBehavior || getParentBehaviour(stub) || sinon.behavior.create(stub);
3170                                 }
3172                                 function getParentBehaviour(stub) {
3173                                                 return (stub.parent && getCurrentBehavior(stub.parent));
3174                                 }
3176                                 function getCurrentBehavior(stub) {
3177                                                 var behavior = stub.behaviors[stub.callCount - 1];
3178                                                 return behavior && behavior.isPresent() ? behavior : getDefaultBehavior(stub);
3179                                 }
3181                                 var uuid = 0;
3183                                 var proto = {
3184                                                 create: function create(stubLength) {
3185                                                                 var functionStub = function () {
3186                                                                                 return getCurrentBehavior(functionStub).invoke(this, arguments);
3187                                                                 };
3189                                                                 functionStub.id = "stub#" + uuid++;
3190                                                                 var orig = functionStub;
3191                                                                 functionStub = sinon.spy.create(functionStub, stubLength);
3192                                                                 functionStub.func = orig;
3194                                                                 sinon.extend(functionStub, stub);
3195                                                                 functionStub.instantiateFake = sinon.stub.create;
3196                                                                 functionStub.displayName = "stub";
3197                                                                 functionStub.toString = sinon.functionToString;
3199                                                                 functionStub.defaultBehavior = null;
3200                                                                 functionStub.behaviors = [];
3202                                                                 return functionStub;
3203                                                 },
3205                                                 resetBehavior: function () {
3206                                                                 var i;
3208                                                                 this.defaultBehavior = null;
3209                                                                 this.behaviors = [];
3211                                                                 delete this.returnValue;
3212                                                                 delete this.returnArgAt;
3213                                                                 this.returnThis = false;
3215                                                                 if (this.fakes) {
3216                                                                                 for (i = 0; i < this.fakes.length; i++) {
3217                                                                                                 this.fakes[i].resetBehavior();
3218                                                                                 }
3219                                                                 }
3220                                                 },
3222                                                 onCall: function onCall(index) {
3223                                                                 if (!this.behaviors[index]) {
3224                                                                                 this.behaviors[index] = sinon.behavior.create(this);
3225                                                                 }
3227                                                                 return this.behaviors[index];
3228                                                 },
3230                                                 onFirstCall: function onFirstCall() {
3231                                                                 return this.onCall(0);
3232                                                 },
3234                                                 onSecondCall: function onSecondCall() {
3235                                                                 return this.onCall(1);
3236                                                 },
3238                                                 onThirdCall: function onThirdCall() {
3239                                                                 return this.onCall(2);
3240                                                 }
3241                                 };
3243                                 for (var method in sinon.behavior) {
3244                                                 if (sinon.behavior.hasOwnProperty(method) &&
3245                                                                 !proto.hasOwnProperty(method) &&
3246                                                                 method != "create" &&
3247                                                                 method != "withArgs" &&
3248                                                                 method != "invoke") {
3249                                                                 proto[method] = (function (behaviorMethod) {
3250                                                                                 return function () {
3251                                                                                                 this.defaultBehavior = this.defaultBehavior || sinon.behavior.create(this);
3252                                                                                                 this.defaultBehavior[behaviorMethod].apply(this.defaultBehavior, arguments);
3253                                                                                                 return this;
3254                                                                                 };
3255                                                                 }(method));
3256                                                 }
3257                                 }
3259                                 sinon.extend(stub, proto);
3260                                 sinon.stub = stub;
3262                                 return stub;
3263                 }
3265                 var isNode = typeof module !== "undefined" && module.exports && typeof require == "function";
3266                 var isAMD = typeof define === "function" && typeof define.amd === "object" && define.amd;
3268                 function loadDependencies(require, exports, module) {
3269                                 var sinon = require("./util/core");
3270                                 require("./behavior");
3271                                 require("./spy");
3272                                 require("./extend");
3273                                 module.exports = makeApi(sinon);
3274                 }
3276                 if (isAMD) {
3277                                 define(loadDependencies);
3278                 } else if (isNode) {
3279                                 loadDependencies(require, module.exports, module);
3280                 } else if (!sinon) {
3281                                 return;
3282                 } else {
3283                                 makeApi(sinon);
3284                 }
3285 }(typeof sinon == "object" && sinon || null));
3288  * @depend times_in_words.js
3289  * @depend util/core.js
3290  * @depend call.js
3291  * @depend extend.js
3292  * @depend match.js
3293  * @depend spy.js
3294  * @depend stub.js
3295  * @depend format.js
3296  */
3298  * Mock functions.
3300  * @author Christian Johansen (christian@cjohansen.no)
3301  * @license BSD
3303  * Copyright (c) 2010-2013 Christian Johansen
3304  */
3306 (function (sinon) {
3307                 function makeApi(sinon) {
3308                                 var push = [].push;
3309                                 var match = sinon.match;
3311                                 function mock(object) {
3312                                                 if (!object) {
3313                                                                 return sinon.expectation.create("Anonymous mock");
3314                                                 }
3316                                                 return mock.create(object);
3317                                 }
3319                                 function each(collection, callback) {
3320                                                 if (!collection) {
3321                                                                 return;
3322                                                 }
3324                                                 for (var i = 0, l = collection.length; i < l; i += 1) {
3325                                                                 callback(collection[i]);
3326                                                 }
3327                                 }
3329                                 sinon.extend(mock, {
3330                                                 create: function create(object) {
3331                                                                 if (!object) {
3332                                                                                 throw new TypeError("object is null");
3333                                                                 }
3335                                                                 var mockObject = sinon.extend({}, mock);
3336                                                                 mockObject.object = object;
3337                                                                 delete mockObject.create;
3339                                                                 return mockObject;
3340                                                 },
3342                                                 expects: function expects(method) {
3343                                                                 if (!method) {
3344                                                                                 throw new TypeError("method is falsy");
3345                                                                 }
3347                                                                 if (!this.expectations) {
3348                                                                                 this.expectations = {};
3349                                                                                 this.proxies = [];
3350                                                                 }
3352                                                                 if (!this.expectations[method]) {
3353                                                                                 this.expectations[method] = [];
3354                                                                                 var mockObject = this;
3356                                                                                 sinon.wrapMethod(this.object, method, function () {
3357                                                                                                 return mockObject.invokeMethod(method, this, arguments);
3358                                                                                 });
3360                                                                                 push.call(this.proxies, method);
3361                                                                 }
3363                                                                 var expectation = sinon.expectation.create(method);
3364                                                                 push.call(this.expectations[method], expectation);
3366                                                                 return expectation;
3367                                                 },
3369                                                 restore: function restore() {
3370                                                                 var object = this.object;
3372                                                                 each(this.proxies, function (proxy) {
3373                                                                                 if (typeof object[proxy].restore == "function") {
3374                                                                                                 object[proxy].restore();
3375                                                                                 }
3376                                                                 });
3377                                                 },
3379                                                 verify: function verify() {
3380                                                                 var expectations = this.expectations || {};
3381                                                                 var messages = [], met = [];
3383                                                                 each(this.proxies, function (proxy) {
3384                                                                                 each(expectations[proxy], function (expectation) {
3385                                                                                                 if (!expectation.met()) {
3386                                                                                                                 push.call(messages, expectation.toString());
3387                                                                                                 } else {
3388                                                                                                                 push.call(met, expectation.toString());
3389                                                                                                 }
3390                                                                                 });
3391                                                                 });
3393                                                                 this.restore();
3395                                                                 if (messages.length > 0) {
3396                                                                                 sinon.expectation.fail(messages.concat(met).join("\n"));
3397                                                                 } else if (met.length > 0) {
3398                                                                                 sinon.expectation.pass(messages.concat(met).join("\n"));
3399                                                                 }
3401                                                                 return true;
3402                                                 },
3404                                                 invokeMethod: function invokeMethod(method, thisValue, args) {
3405                                                                 var expectations = this.expectations && this.expectations[method];
3406                                                                 var length = expectations && expectations.length || 0, i;
3408                                                                 for (i = 0; i < length; i += 1) {
3409                                                                                 if (!expectations[i].met() &&
3410                                                                                                 expectations[i].allowsCall(thisValue, args)) {
3411                                                                                                 return expectations[i].apply(thisValue, args);
3412                                                                                 }
3413                                                                 }
3415                                                                 var messages = [], available, exhausted = 0;
3417                                                                 for (i = 0; i < length; i += 1) {
3418                                                                                 if (expectations[i].allowsCall(thisValue, args)) {
3419                                                                                                 available = available || expectations[i];
3420                                                                                 } else {
3421                                                                                                 exhausted += 1;
3422                                                                                 }
3423                                                                                 push.call(messages, "    " + expectations[i].toString());
3424                                                                 }
3426                                                                 if (exhausted === 0) {
3427                                                                                 return available.apply(thisValue, args);
3428                                                                 }
3430                                                                 messages.unshift("Unexpected call: " + sinon.spyCall.toString.call({
3431                                                                                 proxy: method,
3432                                                                                 args: args
3433                                                                 }));
3435                                                                 sinon.expectation.fail(messages.join("\n"));
3436                                                 }
3437                                 });
3439                                 var times = sinon.timesInWords;
3440                                 var slice = Array.prototype.slice;
3442                                 function callCountInWords(callCount) {
3443                                                 if (callCount == 0) {
3444                                                                 return "never called";
3445                                                 } else {
3446                                                                 return "called " + times(callCount);
3447                                                 }
3448                                 }
3450                                 function expectedCallCountInWords(expectation) {
3451                                                 var min = expectation.minCalls;
3452                                                 var max = expectation.maxCalls;
3454                                                 if (typeof min == "number" && typeof max == "number") {
3455                                                                 var str = times(min);
3457                                                                 if (min != max) {
3458                                                                                 str = "at least " + str + " and at most " + times(max);
3459                                                                 }
3461                                                                 return str;
3462                                                 }
3464                                                 if (typeof min == "number") {
3465                                                                 return "at least " + times(min);
3466                                                 }
3468                                                 return "at most " + times(max);
3469                                 }
3471                                 function receivedMinCalls(expectation) {
3472                                                 var hasMinLimit = typeof expectation.minCalls == "number";
3473                                                 return !hasMinLimit || expectation.callCount >= expectation.minCalls;
3474                                 }
3476                                 function receivedMaxCalls(expectation) {
3477                                                 if (typeof expectation.maxCalls != "number") {
3478                                                                 return false;
3479                                                 }
3481                                                 return expectation.callCount == expectation.maxCalls;
3482                                 }
3484                                 function verifyMatcher(possibleMatcher, arg) {
3485                                                 if (match && match.isMatcher(possibleMatcher)) {
3486                                                                 return possibleMatcher.test(arg);
3487                                                 } else {
3488                                                                 return true;
3489                                                 }
3490                                 }
3492                                 sinon.expectation = {
3493                                                 minCalls: 1,
3494                                                 maxCalls: 1,
3496                                                 create: function create(methodName) {
3497                                                                 var expectation = sinon.extend(sinon.stub.create(), sinon.expectation);
3498                                                                 delete expectation.create;
3499                                                                 expectation.method = methodName;
3501                                                                 return expectation;
3502                                                 },
3504                                                 invoke: function invoke(func, thisValue, args) {
3505                                                                 this.verifyCallAllowed(thisValue, args);
3507                                                                 return sinon.spy.invoke.apply(this, arguments);
3508                                                 },
3510                                                 atLeast: function atLeast(num) {
3511                                                                 if (typeof num != "number") {
3512                                                                                 throw new TypeError("'" + num + "' is not number");
3513                                                                 }
3515                                                                 if (!this.limitsSet) {
3516                                                                                 this.maxCalls = null;
3517                                                                                 this.limitsSet = true;
3518                                                                 }
3520                                                                 this.minCalls = num;
3522                                                                 return this;
3523                                                 },
3525                                                 atMost: function atMost(num) {
3526                                                                 if (typeof num != "number") {
3527                                                                                 throw new TypeError("'" + num + "' is not number");
3528                                                                 }
3530                                                                 if (!this.limitsSet) {
3531                                                                                 this.minCalls = null;
3532                                                                                 this.limitsSet = true;
3533                                                                 }
3535                                                                 this.maxCalls = num;
3537                                                                 return this;
3538                                                 },
3540                                                 never: function never() {
3541                                                                 return this.exactly(0);
3542                                                 },
3544                                                 once: function once() {
3545                                                                 return this.exactly(1);
3546                                                 },
3548                                                 twice: function twice() {
3549                                                                 return this.exactly(2);
3550                                                 },
3552                                                 thrice: function thrice() {
3553                                                                 return this.exactly(3);
3554                                                 },
3556                                                 exactly: function exactly(num) {
3557                                                                 if (typeof num != "number") {
3558                                                                                 throw new TypeError("'" + num + "' is not a number");
3559                                                                 }
3561                                                                 this.atLeast(num);
3562                                                                 return this.atMost(num);
3563                                                 },
3565                                                 met: function met() {
3566                                                                 return !this.failed && receivedMinCalls(this);
3567                                                 },
3569                                                 verifyCallAllowed: function verifyCallAllowed(thisValue, args) {
3570                                                                 if (receivedMaxCalls(this)) {
3571                                                                                 this.failed = true;
3572                                                                                 sinon.expectation.fail(this.method + " already called " + times(this.maxCalls));
3573                                                                 }
3575                                                                 if ("expectedThis" in this && this.expectedThis !== thisValue) {
3576                                                                                 sinon.expectation.fail(this.method + " called with " + thisValue + " as thisValue, expected " +
3577                                                                                                 this.expectedThis);
3578                                                                 }
3580                                                                 if (!("expectedArguments" in this)) {
3581                                                                                 return;
3582                                                                 }
3584                                                                 if (!args) {
3585                                                                                 sinon.expectation.fail(this.method + " received no arguments, expected " +
3586                                                                                                 sinon.format(this.expectedArguments));
3587                                                                 }
3589                                                                 if (args.length < this.expectedArguments.length) {
3590                                                                                 sinon.expectation.fail(this.method + " received too few arguments (" + sinon.format(args) +
3591                                                                                                 "), expected " + sinon.format(this.expectedArguments));
3592                                                                 }
3594                                                                 if (this.expectsExactArgCount &&
3595                                                                                 args.length != this.expectedArguments.length) {
3596                                                                                 sinon.expectation.fail(this.method + " received too many arguments (" + sinon.format(args) +
3597                                                                                                 "), expected " + sinon.format(this.expectedArguments));
3598                                                                 }
3600                                                                 for (var i = 0, l = this.expectedArguments.length; i < l; i += 1) {
3602                                                                                 if (!verifyMatcher(this.expectedArguments[i], args[i])) {
3603                                                                                                 sinon.expectation.fail(this.method + " received wrong arguments " + sinon.format(args) +
3604                                                                                                                 ", didn't match " + this.expectedArguments.toString());
3605                                                                                 }
3607                                                                                 if (!sinon.deepEqual(this.expectedArguments[i], args[i])) {
3608                                                                                                 sinon.expectation.fail(this.method + " received wrong arguments " + sinon.format(args) +
3609                                                                                                                 ", expected " + sinon.format(this.expectedArguments));
3610                                                                                 }
3611                                                                 }
3612                                                 },
3614                                                 allowsCall: function allowsCall(thisValue, args) {
3615                                                                 if (this.met() && receivedMaxCalls(this)) {
3616                                                                                 return false;
3617                                                                 }
3619                                                                 if ("expectedThis" in this && this.expectedThis !== thisValue) {
3620                                                                                 return false;
3621                                                                 }
3623                                                                 if (!("expectedArguments" in this)) {
3624                                                                                 return true;
3625                                                                 }
3627                                                                 args = args || [];
3629                                                                 if (args.length < this.expectedArguments.length) {
3630                                                                                 return false;
3631                                                                 }
3633                                                                 if (this.expectsExactArgCount &&
3634                                                                                 args.length != this.expectedArguments.length) {
3635                                                                                 return false;
3636                                                                 }
3638                                                                 for (var i = 0, l = this.expectedArguments.length; i < l; i += 1) {
3639                                                                                 if (!verifyMatcher(this.expectedArguments[i], args[i])) {
3640                                                                                                 return false;
3641                                                                                 }
3643                                                                                 if (!sinon.deepEqual(this.expectedArguments[i], args[i])) {
3644                                                                                                 return false;
3645                                                                                 }
3646                                                                 }
3648                                                                 return true;
3649                                                 },
3651                                                 withArgs: function withArgs() {
3652                                                                 this.expectedArguments = slice.call(arguments);
3653                                                                 return this;
3654                                                 },
3656                                                 withExactArgs: function withExactArgs() {
3657                                                                 this.withArgs.apply(this, arguments);
3658                                                                 this.expectsExactArgCount = true;
3659                                                                 return this;
3660                                                 },
3662                                                 on: function on(thisValue) {
3663                                                                 this.expectedThis = thisValue;
3664                                                                 return this;
3665                                                 },
3667                                                 toString: function () {
3668                                                                 var args = (this.expectedArguments || []).slice();
3670                                                                 if (!this.expectsExactArgCount) {
3671                                                                                 push.call(args, "[...]");
3672                                                                 }
3674                                                                 var callStr = sinon.spyCall.toString.call({
3675                                                                                 proxy: this.method || "anonymous mock expectation",
3676                                                                                 args: args
3677                                                                 });
3679                                                                 var message = callStr.replace(", [...", "[, ...") + " " +
3680                                                                                 expectedCallCountInWords(this);
3682                                                                 if (this.met()) {
3683                                                                                 return "Expectation met: " + message;
3684                                                                 }
3686                                                                 return "Expected " + message + " (" +
3687                                                                                 callCountInWords(this.callCount) + ")";
3688                                                 },
3690                                                 verify: function verify() {
3691                                                                 if (!this.met()) {
3692                                                                                 sinon.expectation.fail(this.toString());
3693                                                                 } else {
3694                                                                                 sinon.expectation.pass(this.toString());
3695                                                                 }
3697                                                                 return true;
3698                                                 },
3700                                                 pass: function pass(message) {
3701                                                                 sinon.assert.pass(message);
3702                                                 },
3704                                                 fail: function fail(message) {
3705                                                                 var exception = new Error(message);
3706                                                                 exception.name = "ExpectationError";
3708                                                                 throw exception;
3709                                                 }
3710                                 };
3712                                 sinon.mock = mock;
3713                                 return mock;
3714                 }
3716                 var isNode = typeof module !== "undefined" && module.exports && typeof require == "function";
3717                 var isAMD = typeof define === "function" && typeof define.amd === "object" && define.amd;
3719                 function loadDependencies(require, exports, module) {
3720                                 var sinon = require("./util/core");
3721                                 require("./times_in_words");
3722                                 require("./call");
3723                                 require("./extend");
3724                                 require("./match");
3725                                 require("./spy");
3726                                 require("./stub");
3727                                 require("./format");
3729                                 module.exports = makeApi(sinon);
3730                 }
3732                 if (isAMD) {
3733                                 define(loadDependencies);
3734                 } else if (isNode) {
3735                                 loadDependencies(require, module.exports, module);
3736                 } else if (!sinon) {
3737                                 return;
3738                 } else {
3739                                 makeApi(sinon);
3740                 }
3741 }(typeof sinon == "object" && sinon || null));
3744  * @depend util/core.js
3745  * @depend spy.js
3746  * @depend stub.js
3747  * @depend mock.js
3748  */
3750  * Collections of stubs, spies and mocks.
3752  * @author Christian Johansen (christian@cjohansen.no)
3753  * @license BSD
3755  * Copyright (c) 2010-2013 Christian Johansen
3756  */
3758 (function (sinon) {
3759                 var push = [].push;
3760                 var hasOwnProperty = Object.prototype.hasOwnProperty;
3762                 function getFakes(fakeCollection) {
3763                                 if (!fakeCollection.fakes) {
3764                                                 fakeCollection.fakes = [];
3765                                 }
3767                                 return fakeCollection.fakes;
3768                 }
3770                 function each(fakeCollection, method) {
3771                                 var fakes = getFakes(fakeCollection);
3773                                 for (var i = 0, l = fakes.length; i < l; i += 1) {
3774                                                 if (typeof fakes[i][method] == "function") {
3775                                                                 fakes[i][method]();
3776                                                 }
3777                                 }
3778                 }
3780                 function compact(fakeCollection) {
3781                                 var fakes = getFakes(fakeCollection);
3782                                 var i = 0;
3783                                 while (i < fakes.length) {
3784                                                 fakes.splice(i, 1);
3785                                 }
3786                 }
3788                 function makeApi(sinon) {
3789                                 var collection = {
3790                                                 verify: function resolve() {
3791                                                                 each(this, "verify");
3792                                                 },
3794                                                 restore: function restore() {
3795                                                                 each(this, "restore");
3796                                                                 compact(this);
3797                                                 },
3799                                                 reset: function restore() {
3800                                                                 each(this, "reset");
3801                                                 },
3803                                                 verifyAndRestore: function verifyAndRestore() {
3804                                                                 var exception;
3806                                                                 try {
3807                                                                                 this.verify();
3808                                                                 } catch (e) {
3809                                                                                 exception = e;
3810                                                                 }
3812                                                                 this.restore();
3814                                                                 if (exception) {
3815                                                                                 throw exception;
3816                                                                 }
3817                                                 },
3819                                                 add: function add(fake) {
3820                                                                 push.call(getFakes(this), fake);
3821                                                                 return fake;
3822                                                 },
3824                                                 spy: function spy() {
3825                                                                 return this.add(sinon.spy.apply(sinon, arguments));
3826                                                 },
3828                                                 stub: function stub(object, property, value) {
3829                                                                 if (property) {
3830                                                                                 var original = object[property];
3832                                                                                 if (typeof original != "function") {
3833                                                                                                 if (!hasOwnProperty.call(object, property)) {
3834                                                                                                                 throw new TypeError("Cannot stub non-existent own property " + property);
3835                                                                                                 }
3837                                                                                                 object[property] = value;
3839                                                                                                 return this.add({
3840                                                                                                                 restore: function () {
3841                                                                                                                                 object[property] = original;
3842                                                                                                                 }
3843                                                                                                 });
3844                                                                                 }
3845                                                                 }
3846                                                                 if (!property && !!object && typeof object == "object") {
3847                                                                                 var stubbedObj = sinon.stub.apply(sinon, arguments);
3849                                                                                 for (var prop in stubbedObj) {
3850                                                                                                 if (typeof stubbedObj[prop] === "function") {
3851                                                                                                                 this.add(stubbedObj[prop]);
3852                                                                                                 }
3853                                                                                 }
3855                                                                                 return stubbedObj;
3856                                                                 }
3858                                                                 return this.add(sinon.stub.apply(sinon, arguments));
3859                                                 },
3861                                                 mock: function mock() {
3862                                                                 return this.add(sinon.mock.apply(sinon, arguments));
3863                                                 },
3865                                                 inject: function inject(obj) {
3866                                                                 var col = this;
3868                                                                 obj.spy = function () {
3869                                                                                 return col.spy.apply(col, arguments);
3870                                                                 };
3872                                                                 obj.stub = function () {
3873                                                                                 return col.stub.apply(col, arguments);
3874                                                                 };
3876                                                                 obj.mock = function () {
3877                                                                                 return col.mock.apply(col, arguments);
3878                                                                 };
3880                                                                 return obj;
3881                                                 }
3882                                 };
3884                                 sinon.collection = collection;
3885                                 return collection;
3886                 }
3888                 var isNode = typeof module !== "undefined" && module.exports && typeof require == "function";
3889                 var isAMD = typeof define === "function" && typeof define.amd === "object" && define.amd;
3891                 function loadDependencies(require, exports, module) {
3892                                 var sinon = require("./util/core");
3893                                 require("./mock");
3894                                 require("./spy");
3895                                 require("./stub");
3896                                 module.exports = makeApi(sinon);
3897                 }
3899                 if (isAMD) {
3900                                 define(loadDependencies);
3901                 } else if (isNode) {
3902                                 loadDependencies(require, module.exports, module);
3903                 } else if (!sinon) {
3904                                 return;
3905                 } else {
3906                                 makeApi(sinon);
3907                 }
3908 }(typeof sinon == "object" && sinon || null));
3910 /*global lolex */
3913  * Fake timer API
3914  * setTimeout
3915  * setInterval
3916  * clearTimeout
3917  * clearInterval
3918  * tick
3919  * reset
3920  * Date
3922  * Inspired by jsUnitMockTimeOut from JsUnit
3924  * @author Christian Johansen (christian@cjohansen.no)
3925  * @license BSD
3927  * Copyright (c) 2010-2013 Christian Johansen
3928  */
3930 if (typeof sinon == "undefined") {
3931                 var sinon = {};
3934 (function (global) {
3935                 function makeApi(sinon, lol) {
3936                                 var llx = typeof lolex !== "undefined" ? lolex : lol;
3938                                 sinon.useFakeTimers = function () {
3939                                                 var now, methods = Array.prototype.slice.call(arguments);
3941                                                 if (typeof methods[0] === "string") {
3942                                                                 now = 0;
3943                                                 } else {
3944                                                                 now = methods.shift();
3945                                                 }
3947                                                 var clock = llx.install(now || 0, methods);
3948                                                 clock.restore = clock.uninstall;
3949                                                 return clock;
3950                                 };
3952                                 sinon.clock = {
3953                                                 create: function (now) {
3954                                                                 return llx.createClock(now);
3955                                                 }
3956                                 };
3958                                 sinon.timers = {
3959                                                 setTimeout: setTimeout,
3960                                                 clearTimeout: clearTimeout,
3961                                                 setImmediate: (typeof setImmediate !== "undefined" ? setImmediate : undefined),
3962                                                 clearImmediate: (typeof clearImmediate !== "undefined" ? clearImmediate : undefined),
3963                                                 setInterval: setInterval,
3964                                                 clearInterval: clearInterval,
3965                                                 Date: Date
3966                                 };
3967                 }
3969                 var isNode = typeof module !== "undefined" && module.exports && typeof require == "function";
3970                 var isAMD = typeof define === "function" && typeof define.amd === "object" && define.amd;
3972                 function loadDependencies(require, epxorts, module, lolex) {
3973                                 var sinon = require("./core");
3974                                 makeApi(sinon, lolex);
3975                                 module.exports = sinon;
3976                 }
3978                 if (isAMD) {
3979                                 define(loadDependencies);
3980                 } else if (isNode) {
3981                                 loadDependencies(require, module.exports, module, require("lolex"));
3982                 } else {
3983                                 makeApi(sinon);
3984                 }
3985 }(typeof global != "undefined" && typeof global !== "function" ? global : this));
3988  * Minimal Event interface implementation
3990  * Original implementation by Sven Fuchs: https://gist.github.com/995028
3991  * Modifications and tests by Christian Johansen.
3993  * @author Sven Fuchs (svenfuchs@artweb-design.de)
3994  * @author Christian Johansen (christian@cjohansen.no)
3995  * @license BSD
3997  * Copyright (c) 2011 Sven Fuchs, Christian Johansen
3998  */
4000 if (typeof sinon == "undefined") {
4001                 this.sinon = {};
4004 (function () {
4005                 var push = [].push;
4007                 function makeApi(sinon) {
4008                                 sinon.Event = function Event(type, bubbles, cancelable, target) {
4009                                                 this.initEvent(type, bubbles, cancelable, target);
4010                                 };
4012                                 sinon.Event.prototype = {
4013                                                 initEvent: function (type, bubbles, cancelable, target) {
4014                                                                 this.type = type;
4015                                                                 this.bubbles = bubbles;
4016                                                                 this.cancelable = cancelable;
4017                                                                 this.target = target;
4018                                                 },
4020                                                 stopPropagation: function () {},
4022                                                 preventDefault: function () {
4023                                                                 this.defaultPrevented = true;
4024                                                 }
4025                                 };
4027                                 sinon.ProgressEvent = function ProgressEvent(type, progressEventRaw, target) {
4028                                                 this.initEvent(type, false, false, target);
4029                                                 this.loaded = progressEventRaw.loaded || null;
4030                                                 this.total = progressEventRaw.total || null;
4031                                                 this.lengthComputable = !!progressEventRaw.total;
4032                                 };
4034                                 sinon.ProgressEvent.prototype = new sinon.Event();
4036                                 sinon.ProgressEvent.prototype.constructor =  sinon.ProgressEvent;
4038                                 sinon.CustomEvent = function CustomEvent(type, customData, target) {
4039                                                 this.initEvent(type, false, false, target);
4040                                                 this.detail = customData.detail || null;
4041                                 };
4043                                 sinon.CustomEvent.prototype = new sinon.Event();
4045                                 sinon.CustomEvent.prototype.constructor =  sinon.CustomEvent;
4047                                 sinon.EventTarget = {
4048                                                 addEventListener: function addEventListener(event, listener) {
4049                                                                 this.eventListeners = this.eventListeners || {};
4050                                                                 this.eventListeners[event] = this.eventListeners[event] || [];
4051                                                                 push.call(this.eventListeners[event], listener);
4052                                                 },
4054                                                 removeEventListener: function removeEventListener(event, listener) {
4055                                                                 var listeners = this.eventListeners && this.eventListeners[event] || [];
4057                                                                 for (var i = 0, l = listeners.length; i < l; ++i) {
4058                                                                                 if (listeners[i] == listener) {
4059                                                                                                 return listeners.splice(i, 1);
4060                                                                                 }
4061                                                                 }
4062                                                 },
4064                                                 dispatchEvent: function dispatchEvent(event) {
4065                                                                 var type = event.type;
4066                                                                 var listeners = this.eventListeners && this.eventListeners[type] || [];
4068                                                                 for (var i = 0; i < listeners.length; i++) {
4069                                                                                 if (typeof listeners[i] == "function") {
4070                                                                                                 listeners[i].call(this, event);
4071                                                                                 } else {
4072                                                                                                 listeners[i].handleEvent(event);
4073                                                                                 }
4074                                                                 }
4076                                                                 return !!event.defaultPrevented;
4077                                                 }
4078                                 };
4079                 }
4081                 var isNode = typeof module !== "undefined" && module.exports && typeof require == "function";
4082                 var isAMD = typeof define === "function" && typeof define.amd === "object" && define.amd;
4084                 function loadDependencies(require) {
4085                                 var sinon = require("./core");
4086                                 makeApi(sinon);
4087                 }
4089                 if (isAMD) {
4090                                 define(loadDependencies);
4091                 } else if (isNode) {
4092                                 loadDependencies(require);
4093                 } else {
4094                                 makeApi(sinon);
4095                 }
4096 }());
4099  * @depend util/core.js
4100  */
4102  * Logs errors
4104  * @author Christian Johansen (christian@cjohansen.no)
4105  * @license BSD
4107  * Copyright (c) 2010-2014 Christian Johansen
4108  */
4110 (function (sinon) {
4111                 // cache a reference to setTimeout, so that our reference won't be stubbed out
4112                 // when using fake timers and errors will still get logged
4113                 // https://github.com/cjohansen/Sinon.JS/issues/381
4114                 var realSetTimeout = setTimeout;
4116                 function makeApi(sinon) {
4118                                 function log() {}
4120                                 function logError(label, err) {
4121                                                 var msg = label + " threw exception: ";
4123                                                 sinon.log(msg + "[" + err.name + "] " + err.message);
4125                                                 if (err.stack) {
4126                                                                 sinon.log(err.stack);
4127                                                 }
4129                                                 logError.setTimeout(function () {
4130                                                                 err.message = msg + err.message;
4131                                                                 throw err;
4132                                                 }, 0);
4133                                 };
4135                                 // wrap realSetTimeout with something we can stub in tests
4136                                 logError.setTimeout = function (func, timeout) {
4137                                                 realSetTimeout(func, timeout);
4138                                 }
4140                                 var exports = {};
4141                                 exports.log = sinon.log = log;
4142                                 exports.logError = sinon.logError = logError;
4144                                 return exports;
4145                 }
4147                 function loadDependencies(require, exports, module) {
4148                                 var sinon = require("./util/core");
4149                                 module.exports = makeApi(sinon);
4150                 }
4152                 var isNode = typeof module !== "undefined" && module.exports && typeof require == "function";
4153                 var isAMD = typeof define === "function" && typeof define.amd === "object" && define.amd;
4155                 if (isAMD) {
4156                                 define(loadDependencies);
4157                 } else if (isNode) {
4158                                 loadDependencies(require, module.exports, module);
4159                 } else if (!sinon) {
4160                                 return;
4161                 } else {
4162                                 makeApi(sinon);
4163                 }
4164 }(typeof sinon == "object" && sinon || null));
4167  * @depend core.js
4168  * @depend ../extend.js
4169  * @depend event.js
4170  * @depend ../log_error.js
4171  */
4173  * Fake XDomainRequest object
4174  */
4176 if (typeof sinon == "undefined") {
4177                 this.sinon = {};
4180 // wrapper for global
4181 (function (global) {
4182                 var xdr = { XDomainRequest: global.XDomainRequest };
4183                 xdr.GlobalXDomainRequest = global.XDomainRequest;
4184                 xdr.supportsXDR = typeof xdr.GlobalXDomainRequest != "undefined";
4185                 xdr.workingXDR = xdr.supportsXDR ? xdr.GlobalXDomainRequest :  false;
4187                 function makeApi(sinon) {
4188                                 sinon.xdr = xdr;
4190                                 function FakeXDomainRequest() {
4191                                                 this.readyState = FakeXDomainRequest.UNSENT;
4192                                                 this.requestBody = null;
4193                                                 this.requestHeaders = {};
4194                                                 this.status = 0;
4195                                                 this.timeout = null;
4197                                                 if (typeof FakeXDomainRequest.onCreate == "function") {
4198                                                                 FakeXDomainRequest.onCreate(this);
4199                                                 }
4200                                 }
4202                                 function verifyState(xdr) {
4203                                                 if (xdr.readyState !== FakeXDomainRequest.OPENED) {
4204                                                                 throw new Error("INVALID_STATE_ERR");
4205                                                 }
4207                                                 if (xdr.sendFlag) {
4208                                                                 throw new Error("INVALID_STATE_ERR");
4209                                                 }
4210                                 }
4212                                 function verifyRequestSent(xdr) {
4213                                                 if (xdr.readyState == FakeXDomainRequest.UNSENT) {
4214                                                                 throw new Error("Request not sent");
4215                                                 }
4216                                                 if (xdr.readyState == FakeXDomainRequest.DONE) {
4217                                                                 throw new Error("Request done");
4218                                                 }
4219                                 }
4221                                 function verifyResponseBodyType(body) {
4222                                                 if (typeof body != "string") {
4223                                                                 var error = new Error("Attempted to respond to fake XDomainRequest with " +
4224                                                                                                                                                 body + ", which is not a string.");
4225                                                                 error.name = "InvalidBodyException";
4226                                                                 throw error;
4227                                                 }
4228                                 }
4230                                 sinon.extend(FakeXDomainRequest.prototype, sinon.EventTarget, {
4231                                                 open: function open(method, url) {
4232                                                                 this.method = method;
4233                                                                 this.url = url;
4235                                                                 this.responseText = null;
4236                                                                 this.sendFlag = false;
4238                                                                 this.readyStateChange(FakeXDomainRequest.OPENED);
4239                                                 },
4241                                                 readyStateChange: function readyStateChange(state) {
4242                                                                 this.readyState = state;
4243                                                                 var eventName = "";
4244                                                                 switch (this.readyState) {
4245                                                                 case FakeXDomainRequest.UNSENT:
4246                                                                                 break;
4247                                                                 case FakeXDomainRequest.OPENED:
4248                                                                                 break;
4249                                                                 case FakeXDomainRequest.LOADING:
4250                                                                                 if (this.sendFlag) {
4251                                                                                                 //raise the progress event
4252                                                                                                 eventName = "onprogress";
4253                                                                                 }
4254                                                                                 break;
4255                                                                 case FakeXDomainRequest.DONE:
4256                                                                                 if (this.isTimeout) {
4257                                                                                                 eventName = "ontimeout"
4258                                                                                 } else if (this.errorFlag || (this.status < 200 || this.status > 299)) {
4259                                                                                                 eventName = "onerror";
4260                                                                                 } else {
4261                                                                                                 eventName = "onload"
4262                                                                                 }
4263                                                                                 break;
4264                                                                 }
4266                                                                 // raising event (if defined)
4267                                                                 if (eventName) {
4268                                                                                 if (typeof this[eventName] == "function") {
4269                                                                                                 try {
4270                                                                                                                 this[eventName]();
4271                                                                                                 } catch (e) {
4272                                                                                                                 sinon.logError("Fake XHR " + eventName + " handler", e);
4273                                                                                                 }
4274                                                                                 }
4275                                                                 }
4276                                                 },
4278                                                 send: function send(data) {
4279                                                                 verifyState(this);
4281                                                                 if (!/^(get|head)$/i.test(this.method)) {
4282                                                                                 this.requestBody = data;
4283                                                                 }
4284                                                                 this.requestHeaders["Content-Type"] = "text/plain;charset=utf-8";
4286                                                                 this.errorFlag = false;
4287                                                                 this.sendFlag = true;
4288                                                                 this.readyStateChange(FakeXDomainRequest.OPENED);
4290                                                                 if (typeof this.onSend == "function") {
4291                                                                                 this.onSend(this);
4292                                                                 }
4293                                                 },
4295                                                 abort: function abort() {
4296                                                                 this.aborted = true;
4297                                                                 this.responseText = null;
4298                                                                 this.errorFlag = true;
4300                                                                 if (this.readyState > sinon.FakeXDomainRequest.UNSENT && this.sendFlag) {
4301                                                                                 this.readyStateChange(sinon.FakeXDomainRequest.DONE);
4302                                                                                 this.sendFlag = false;
4303                                                                 }
4304                                                 },
4306                                                 setResponseBody: function setResponseBody(body) {
4307                                                                 verifyRequestSent(this);
4308                                                                 verifyResponseBodyType(body);
4310                                                                 var chunkSize = this.chunkSize || 10;
4311                                                                 var index = 0;
4312                                                                 this.responseText = "";
4314                                                                 do {
4315                                                                                 this.readyStateChange(FakeXDomainRequest.LOADING);
4316                                                                                 this.responseText += body.substring(index, index + chunkSize);
4317                                                                                 index += chunkSize;
4318                                                                 } while (index < body.length);
4320                                                                 this.readyStateChange(FakeXDomainRequest.DONE);
4321                                                 },
4323                                                 respond: function respond(status, contentType, body) {
4324                                                                 // content-type ignored, since XDomainRequest does not carry this
4325                                                                 // we keep the same syntax for respond(...) as for FakeXMLHttpRequest to ease
4326                                                                 // test integration across browsers
4327                                                                 this.status = typeof status == "number" ? status : 200;
4328                                                                 this.setResponseBody(body || "");
4329                                                 },
4331                                                 simulatetimeout: function simulatetimeout() {
4332                                                                 this.status = 0;
4333                                                                 this.isTimeout = true;
4334                                                                 // Access to this should actually throw an error
4335                                                                 this.responseText = undefined;
4336                                                                 this.readyStateChange(FakeXDomainRequest.DONE);
4337                                                 }
4338                                 });
4340                                 sinon.extend(FakeXDomainRequest, {
4341                                                 UNSENT: 0,
4342                                                 OPENED: 1,
4343                                                 LOADING: 3,
4344                                                 DONE: 4
4345                                 });
4347                                 sinon.useFakeXDomainRequest = function useFakeXDomainRequest() {
4348                                                 sinon.FakeXDomainRequest.restore = function restore(keepOnCreate) {
4349                                                                 if (xdr.supportsXDR) {
4350                                                                                 global.XDomainRequest = xdr.GlobalXDomainRequest;
4351                                                                 }
4353                                                                 delete sinon.FakeXDomainRequest.restore;
4355                                                                 if (keepOnCreate !== true) {
4356                                                                                 delete sinon.FakeXDomainRequest.onCreate;
4357                                                                 }
4358                                                 };
4359                                                 if (xdr.supportsXDR) {
4360                                                                 global.XDomainRequest = sinon.FakeXDomainRequest;
4361                                                 }
4362                                                 return sinon.FakeXDomainRequest;
4363                                 };
4365                                 sinon.FakeXDomainRequest = FakeXDomainRequest;
4366                 }
4368                 var isNode = typeof module !== "undefined" && module.exports && typeof require == "function";
4369                 var isAMD = typeof define === "function" && typeof define.amd === "object" && define.amd;
4371                 function loadDependencies(require, exports, module) {
4372                                 var sinon = require("./core");
4373                                 require("../extend");
4374                                 require("./event");
4375                                 require("../log_error");
4376                                 makeApi(sinon);
4377                                 module.exports = sinon;
4378                 }
4380                 if (isAMD) {
4381                                 define(loadDependencies);
4382                 } else if (isNode) {
4383                                 loadDependencies(require, module.exports, module);
4384                 } else {
4385                                 makeApi(sinon);
4386                 }
4387 })(this);
4390  * @depend core.js
4391  * @depend ../extend.js
4392  * @depend event.js
4393  * @depend ../log_error.js
4394  */
4396  * Fake XMLHttpRequest object
4398  * @author Christian Johansen (christian@cjohansen.no)
4399  * @license BSD
4401  * Copyright (c) 2010-2013 Christian Johansen
4402  */
4404 (function (global) {
4406                 var supportsProgress = typeof ProgressEvent !== "undefined";
4407                 var supportsCustomEvent = typeof CustomEvent !== "undefined";
4408                 var sinonXhr = { XMLHttpRequest: global.XMLHttpRequest };
4409                 sinonXhr.GlobalXMLHttpRequest = global.XMLHttpRequest;
4410                 sinonXhr.GlobalActiveXObject = global.ActiveXObject;
4411                 sinonXhr.supportsActiveX = typeof sinonXhr.GlobalActiveXObject != "undefined";
4412                 sinonXhr.supportsXHR = typeof sinonXhr.GlobalXMLHttpRequest != "undefined";
4413                 sinonXhr.workingXHR = sinonXhr.supportsXHR ? sinonXhr.GlobalXMLHttpRequest : sinonXhr.supportsActiveX
4414                                                                                                                                                  ? function () { return new sinonXhr.GlobalActiveXObject("MSXML2.XMLHTTP.3.0") } : false;
4415                 sinonXhr.supportsCORS = sinonXhr.supportsXHR && "withCredentials" in (new sinonXhr.GlobalXMLHttpRequest());
4417                 /*jsl:ignore*/
4418                 var unsafeHeaders = {
4419                                 "Accept-Charset": true,
4420                                 "Accept-Encoding": true,
4421                                 Connection: true,
4422                                 "Content-Length": true,
4423                                 Cookie: true,
4424                                 Cookie2: true,
4425                                 "Content-Transfer-Encoding": true,
4426                                 Date: true,
4427                                 Expect: true,
4428                                 Host: true,
4429                                 "Keep-Alive": true,
4430                                 Referer: true,
4431                                 TE: true,
4432                                 Trailer: true,
4433                                 "Transfer-Encoding": true,
4434                                 Upgrade: true,
4435                                 "User-Agent": true,
4436                                 Via: true
4437                 };
4438                 /*jsl:end*/
4440                 function FakeXMLHttpRequest() {
4441                                 this.readyState = FakeXMLHttpRequest.UNSENT;
4442                                 this.requestHeaders = {};
4443                                 this.requestBody = null;
4444                                 this.status = 0;
4445                                 this.statusText = "";
4446                                 this.upload = new UploadProgress();
4447                                 if (sinonXhr.supportsCORS) {
4448                                                 this.withCredentials = false;
4449                                 }
4451                                 var xhr = this;
4452                                 var events = ["loadstart", "load", "abort", "loadend"];
4454                                 function addEventListener(eventName) {
4455                                                 xhr.addEventListener(eventName, function (event) {
4456                                                                 var listener = xhr["on" + eventName];
4458                                                                 if (listener && typeof listener == "function") {
4459                                                                                 listener.call(this, event);
4460                                                                 }
4461                                                 });
4462                                 }
4464                                 for (var i = events.length - 1; i >= 0; i--) {
4465                                                 addEventListener(events[i]);
4466                                 }
4468                                 if (typeof FakeXMLHttpRequest.onCreate == "function") {
4469                                                 FakeXMLHttpRequest.onCreate(this);
4470                                 }
4471                 }
4473                 // An upload object is created for each
4474                 // FakeXMLHttpRequest and allows upload
4475                 // events to be simulated using uploadProgress
4476                 // and uploadError.
4477                 function UploadProgress() {
4478                                 this.eventListeners = {
4479                                                 progress: [],
4480                                                 load: [],
4481                                                 abort: [],
4482                                                 error: []
4483                                 }
4484                 }
4486                 UploadProgress.prototype.addEventListener = function addEventListener(event, listener) {
4487                                 this.eventListeners[event].push(listener);
4488                 };
4490                 UploadProgress.prototype.removeEventListener = function removeEventListener(event, listener) {
4491                                 var listeners = this.eventListeners[event] || [];
4493                                 for (var i = 0, l = listeners.length; i < l; ++i) {
4494                                                 if (listeners[i] == listener) {
4495                                                                 return listeners.splice(i, 1);
4496                                                 }
4497                                 }
4498                 };
4500                 UploadProgress.prototype.dispatchEvent = function dispatchEvent(event) {
4501                                 var listeners = this.eventListeners[event.type] || [];
4503                                 for (var i = 0, listener; (listener = listeners[i]) != null; i++) {
4504                                                 listener(event);
4505                                 }
4506                 };
4508                 function verifyState(xhr) {
4509                                 if (xhr.readyState !== FakeXMLHttpRequest.OPENED) {
4510                                                 throw new Error("INVALID_STATE_ERR");
4511                                 }
4513                                 if (xhr.sendFlag) {
4514                                                 throw new Error("INVALID_STATE_ERR");
4515                                 }
4516                 }
4518                 function getHeader(headers, header) {
4519                                 header = header.toLowerCase();
4521                                 for (var h in headers) {
4522                                                 if (h.toLowerCase() == header) {
4523                                                                 return h;
4524                                                 }
4525                                 }
4527                                 return null;
4528                 }
4530                 // filtering to enable a white-list version of Sinon FakeXhr,
4531                 // where whitelisted requests are passed through to real XHR
4532                 function each(collection, callback) {
4533                                 if (!collection) {
4534                                                 return;
4535                                 }
4537                                 for (var i = 0, l = collection.length; i < l; i += 1) {
4538                                                 callback(collection[i]);
4539                                 }
4540                 }
4541                 function some(collection, callback) {
4542                                 for (var index = 0; index < collection.length; index++) {
4543                                                 if (callback(collection[index]) === true) {
4544                                                                 return true;
4545                                                 }
4546                                 }
4547                                 return false;
4548                 }
4549                 // largest arity in XHR is 5 - XHR#open
4550                 var apply = function (obj, method, args) {
4551                                 switch (args.length) {
4552                                 case 0: return obj[method]();
4553                                 case 1: return obj[method](args[0]);
4554                                 case 2: return obj[method](args[0], args[1]);
4555                                 case 3: return obj[method](args[0], args[1], args[2]);
4556                                 case 4: return obj[method](args[0], args[1], args[2], args[3]);
4557                                 case 5: return obj[method](args[0], args[1], args[2], args[3], args[4]);
4558                                 }
4559                 };
4561                 FakeXMLHttpRequest.filters = [];
4562                 FakeXMLHttpRequest.addFilter = function addFilter(fn) {
4563                                 this.filters.push(fn)
4564                 };
4565                 var IE6Re = /MSIE 6/;
4566                 FakeXMLHttpRequest.defake = function defake(fakeXhr, xhrArgs) {
4567                                 var xhr = new sinonXhr.workingXHR();
4568                                 each([
4569                                                 "open",
4570                                                 "setRequestHeader",
4571                                                 "send",
4572                                                 "abort",
4573                                                 "getResponseHeader",
4574                                                 "getAllResponseHeaders",
4575                                                 "addEventListener",
4576                                                 "overrideMimeType",
4577                                                 "removeEventListener"
4578                                 ], function (method) {
4579                                                 fakeXhr[method] = function () {
4580                                                                 return apply(xhr, method, arguments);
4581                                                 };
4582                                 });
4584                                 var copyAttrs = function (args) {
4585                                                 each(args, function (attr) {
4586                                                                 try {
4587                                                                                 fakeXhr[attr] = xhr[attr]
4588                                                                 } catch (e) {
4589                                                                                 if (!IE6Re.test(navigator.userAgent)) {
4590                                                                                                 throw e;
4591                                                                                 }
4592                                                                 }
4593                                                 });
4594                                 };
4596                                 var stateChange = function stateChange() {
4597                                                 fakeXhr.readyState = xhr.readyState;
4598                                                 if (xhr.readyState >= FakeXMLHttpRequest.HEADERS_RECEIVED) {
4599                                                                 copyAttrs(["status", "statusText"]);
4600                                                 }
4601                                                 if (xhr.readyState >= FakeXMLHttpRequest.LOADING) {
4602                                                                 copyAttrs(["responseText", "response"]);
4603                                                 }
4604                                                 if (xhr.readyState === FakeXMLHttpRequest.DONE) {
4605                                                                 copyAttrs(["responseXML"]);
4606                                                 }
4607                                                 if (fakeXhr.onreadystatechange) {
4608                                                                 fakeXhr.onreadystatechange.call(fakeXhr, { target: fakeXhr });
4609                                                 }
4610                                 };
4612                                 if (xhr.addEventListener) {
4613                                                 for (var event in fakeXhr.eventListeners) {
4614                                                                 if (fakeXhr.eventListeners.hasOwnProperty(event)) {
4615                                                                                 each(fakeXhr.eventListeners[event], function (handler) {
4616                                                                                                 xhr.addEventListener(event, handler);
4617                                                                                 });
4618                                                                 }
4619                                                 }
4620                                                 xhr.addEventListener("readystatechange", stateChange);
4621                                 } else {
4622                                                 xhr.onreadystatechange = stateChange;
4623                                 }
4624                                 apply(xhr, "open", xhrArgs);
4625                 };
4626                 FakeXMLHttpRequest.useFilters = false;
4628                 function verifyRequestOpened(xhr) {
4629                                 if (xhr.readyState != FakeXMLHttpRequest.OPENED) {
4630                                                 throw new Error("INVALID_STATE_ERR - " + xhr.readyState);
4631                                 }
4632                 }
4634                 function verifyRequestSent(xhr) {
4635                                 if (xhr.readyState == FakeXMLHttpRequest.DONE) {
4636                                                 throw new Error("Request done");
4637                                 }
4638                 }
4640                 function verifyHeadersReceived(xhr) {
4641                                 if (xhr.async && xhr.readyState != FakeXMLHttpRequest.HEADERS_RECEIVED) {
4642                                                 throw new Error("No headers received");
4643                                 }
4644                 }
4646                 function verifyResponseBodyType(body) {
4647                                 if (typeof body != "string") {
4648                                                 var error = new Error("Attempted to respond to fake XMLHttpRequest with " +
4649                                                                                                                                  body + ", which is not a string.");
4650                                                 error.name = "InvalidBodyException";
4651                                                 throw error;
4652                                 }
4653                 }
4655                 FakeXMLHttpRequest.parseXML = function parseXML(text) {
4656                                 var xmlDoc;
4658                                 if (typeof DOMParser != "undefined") {
4659                                                 var parser = new DOMParser();
4660                                                 xmlDoc = parser.parseFromString(text, "text/xml");
4661                                 } else {
4662                                                 xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
4663                                                 xmlDoc.async = "false";
4664                                                 xmlDoc.loadXML(text);
4665                                 }
4667                                 return xmlDoc;
4668                 };
4670                 FakeXMLHttpRequest.statusCodes = {
4671                                 100: "Continue",
4672                                 101: "Switching Protocols",
4673                                 200: "OK",
4674                                 201: "Created",
4675                                 202: "Accepted",
4676                                 203: "Non-Authoritative Information",
4677                                 204: "No Content",
4678                                 205: "Reset Content",
4679                                 206: "Partial Content",
4680                                 207: "Multi-Status",
4681                                 300: "Multiple Choice",
4682                                 301: "Moved Permanently",
4683                                 302: "Found",
4684                                 303: "See Other",
4685                                 304: "Not Modified",
4686                                 305: "Use Proxy",
4687                                 307: "Temporary Redirect",
4688                                 400: "Bad Request",
4689                                 401: "Unauthorized",
4690                                 402: "Payment Required",
4691                                 403: "Forbidden",
4692                                 404: "Not Found",
4693                                 405: "Method Not Allowed",
4694                                 406: "Not Acceptable",
4695                                 407: "Proxy Authentication Required",
4696                                 408: "Request Timeout",
4697                                 409: "Conflict",
4698                                 410: "Gone",
4699                                 411: "Length Required",
4700                                 412: "Precondition Failed",
4701                                 413: "Request Entity Too Large",
4702                                 414: "Request-URI Too Long",
4703                                 415: "Unsupported Media Type",
4704                                 416: "Requested Range Not Satisfiable",
4705                                 417: "Expectation Failed",
4706                                 422: "Unprocessable Entity",
4707                                 500: "Internal Server Error",
4708                                 501: "Not Implemented",
4709                                 502: "Bad Gateway",
4710                                 503: "Service Unavailable",
4711                                 504: "Gateway Timeout",
4712                                 505: "HTTP Version Not Supported"
4713                 };
4715                 function makeApi(sinon) {
4716                                 sinon.xhr = sinonXhr;
4718                                 sinon.extend(FakeXMLHttpRequest.prototype, sinon.EventTarget, {
4719                                                 async: true,
4721                                                 open: function open(method, url, async, username, password) {
4722                                                                 this.method = method;
4723                                                                 this.url = url;
4724                                                                 this.async = typeof async == "boolean" ? async : true;
4725                                                                 this.username = username;
4726                                                                 this.password = password;
4727                                                                 this.responseText = null;
4728                                                                 this.responseXML = null;
4729                                                                 this.requestHeaders = {};
4730                                                                 this.sendFlag = false;
4732                                                                 if (FakeXMLHttpRequest.useFilters === true) {
4733                                                                                 var xhrArgs = arguments;
4734                                                                                 var defake = some(FakeXMLHttpRequest.filters, function (filter) {
4735                                                                                                 return filter.apply(this, xhrArgs)
4736                                                                                 });
4737                                                                                 if (defake) {
4738                                                                                                 return FakeXMLHttpRequest.defake(this, arguments);
4739                                                                                 }
4740                                                                 }
4741                                                                 this.readyStateChange(FakeXMLHttpRequest.OPENED);
4742                                                 },
4744                                                 readyStateChange: function readyStateChange(state) {
4745                                                                 this.readyState = state;
4747                                                                 if (typeof this.onreadystatechange == "function") {
4748                                                                                 try {
4749                                                                                                 this.onreadystatechange();
4750                                                                                 } catch (e) {
4751                                                                                                 sinon.logError("Fake XHR onreadystatechange handler", e);
4752                                                                                 }
4753                                                                 }
4755                                                                 this.dispatchEvent(new sinon.Event("readystatechange"));
4757                                                                 switch (this.readyState) {
4758                                                                                 case FakeXMLHttpRequest.DONE:
4759                                                                                                 this.dispatchEvent(new sinon.Event("load", false, false, this));
4760                                                                                                 this.dispatchEvent(new sinon.Event("loadend", false, false, this));
4761                                                                                                 this.upload.dispatchEvent(new sinon.Event("load", false, false, this));
4762                                                                                                 if (supportsProgress) {
4763                                                                                                                 this.upload.dispatchEvent(new sinon.ProgressEvent("progress", {loaded: 100, total: 100}));
4764                                                                                                                 this.dispatchEvent(new sinon.ProgressEvent("progress", {loaded: 100, total: 100}));
4765                                                                                                 }
4766                                                                                                 break;
4767                                                                 }
4768                                                 },
4770                                                 setRequestHeader: function setRequestHeader(header, value) {
4771                                                                 verifyState(this);
4773                                                                 if (unsafeHeaders[header] || /^(Sec-|Proxy-)/.test(header)) {
4774                                                                                 throw new Error("Refused to set unsafe header \"" + header + "\"");
4775                                                                 }
4777                                                                 if (this.requestHeaders[header]) {
4778                                                                                 this.requestHeaders[header] += "," + value;
4779                                                                 } else {
4780                                                                                 this.requestHeaders[header] = value;
4781                                                                 }
4782                                                 },
4784                                                 // Helps testing
4785                                                 setResponseHeaders: function setResponseHeaders(headers) {
4786                                                                 verifyRequestOpened(this);
4787                                                                 this.responseHeaders = {};
4789                                                                 for (var header in headers) {
4790                                                                                 if (headers.hasOwnProperty(header)) {
4791                                                                                                 this.responseHeaders[header] = headers[header];
4792                                                                                 }
4793                                                                 }
4795                                                                 if (this.async) {
4796                                                                                 this.readyStateChange(FakeXMLHttpRequest.HEADERS_RECEIVED);
4797                                                                 } else {
4798                                                                                 this.readyState = FakeXMLHttpRequest.HEADERS_RECEIVED;
4799                                                                 }
4800                                                 },
4802                                                 // Currently treats ALL data as a DOMString (i.e. no Document)
4803                                                 send: function send(data) {
4804                                                                 verifyState(this);
4806                                                                 if (!/^(get|head)$/i.test(this.method)) {
4807                                                                                 var contentType = getHeader(this.requestHeaders, "Content-Type");
4808                                                                                 if (this.requestHeaders[contentType]) {
4809                                                                                                 var value = this.requestHeaders[contentType].split(";");
4810                                                                                                 this.requestHeaders[contentType] = value[0] + ";charset=utf-8";
4811                                                                                 } else if (!(data instanceof FormData)) {
4812                                                                                                 this.requestHeaders["Content-Type"] = "text/plain;charset=utf-8";
4813                                                                                 }
4815                                                                                 this.requestBody = data;
4816                                                                 }
4818                                                                 this.errorFlag = false;
4819                                                                 this.sendFlag = this.async;
4820                                                                 this.readyStateChange(FakeXMLHttpRequest.OPENED);
4822                                                                 if (typeof this.onSend == "function") {
4823                                                                                 this.onSend(this);
4824                                                                 }
4826                                                                 this.dispatchEvent(new sinon.Event("loadstart", false, false, this));
4827                                                 },
4829                                                 abort: function abort() {
4830                                                                 this.aborted = true;
4831                                                                 this.responseText = null;
4832                                                                 this.errorFlag = true;
4833                                                                 this.requestHeaders = {};
4835                                                                 if (this.readyState > FakeXMLHttpRequest.UNSENT && this.sendFlag) {
4836                                                                                 this.readyStateChange(FakeXMLHttpRequest.DONE);
4837                                                                                 this.sendFlag = false;
4838                                                                 }
4840                                                                 this.readyState = FakeXMLHttpRequest.UNSENT;
4842                                                                 this.dispatchEvent(new sinon.Event("abort", false, false, this));
4844                                                                 this.upload.dispatchEvent(new sinon.Event("abort", false, false, this));
4846                                                                 if (typeof this.onerror === "function") {
4847                                                                                 this.onerror();
4848                                                                 }
4849                                                 },
4851                                                 getResponseHeader: function getResponseHeader(header) {
4852                                                                 if (this.readyState < FakeXMLHttpRequest.HEADERS_RECEIVED) {
4853                                                                                 return null;
4854                                                                 }
4856                                                                 if (/^Set-Cookie2?$/i.test(header)) {
4857                                                                                 return null;
4858                                                                 }
4860                                                                 header = getHeader(this.responseHeaders, header);
4862                                                                 return this.responseHeaders[header] || null;
4863                                                 },
4865                                                 getAllResponseHeaders: function getAllResponseHeaders() {
4866                                                                 if (this.readyState < FakeXMLHttpRequest.HEADERS_RECEIVED) {
4867                                                                                 return "";
4868                                                                 }
4870                                                                 var headers = "";
4872                                                                 for (var header in this.responseHeaders) {
4873                                                                                 if (this.responseHeaders.hasOwnProperty(header) &&
4874                                                                                                 !/^Set-Cookie2?$/i.test(header)) {
4875                                                                                                 headers += header + ": " + this.responseHeaders[header] + "\r\n";
4876                                                                                 }
4877                                                                 }
4879                                                                 return headers;
4880                                                 },
4882                                                 setResponseBody: function setResponseBody(body) {
4883                                                                 verifyRequestSent(this);
4884                                                                 verifyHeadersReceived(this);
4885                                                                 verifyResponseBodyType(body);
4887                                                                 var chunkSize = this.chunkSize || 10;
4888                                                                 var index = 0;
4889                                                                 this.responseText = "";
4891                                                                 do {
4892                                                                                 if (this.async) {
4893                                                                                                 this.readyStateChange(FakeXMLHttpRequest.LOADING);
4894                                                                                 }
4896                                                                                 this.responseText += body.substring(index, index + chunkSize);
4897                                                                                 index += chunkSize;
4898                                                                 } while (index < body.length);
4900                                                                 var type = this.getResponseHeader("Content-Type");
4902                                                                 if (this.responseText &&
4903                                                                                 (!type || /(text\/xml)|(application\/xml)|(\+xml)/.test(type))) {
4904                                                                                 try {
4905                                                                                                 this.responseXML = FakeXMLHttpRequest.parseXML(this.responseText);
4906                                                                                 } catch (e) {
4907                                                                                                 // Unable to parse XML - no biggie
4908                                                                                 }
4909                                                                 }
4911                                                                 this.readyStateChange(FakeXMLHttpRequest.DONE);
4912                                                 },
4914                                                 respond: function respond(status, headers, body) {
4915                                                                 this.status = typeof status == "number" ? status : 200;
4916                                                                 this.statusText = FakeXMLHttpRequest.statusCodes[this.status];
4917                                                                 this.setResponseHeaders(headers || {});
4918                                                                 this.setResponseBody(body || "");
4919                                                 },
4921                                                 uploadProgress: function uploadProgress(progressEventRaw) {
4922                                                                 if (supportsProgress) {
4923                                                                                 this.upload.dispatchEvent(new sinon.ProgressEvent("progress", progressEventRaw));
4924                                                                 }
4925                                                 },
4927                                                 downloadProgress: function downloadProgress(progressEventRaw) {
4928                                                                 if (supportsProgress) {
4929                                                                                 this.dispatchEvent(new sinon.ProgressEvent("progress", progressEventRaw));
4930                                                                 }
4931                                                 },
4933                                                 uploadError: function uploadError(error) {
4934                                                                 if (supportsCustomEvent) {
4935                                                                                 this.upload.dispatchEvent(new sinon.CustomEvent("error", {detail: error}));
4936                                                                 }
4937                                                 }
4938                                 });
4940                                 sinon.extend(FakeXMLHttpRequest, {
4941                                                 UNSENT: 0,
4942                                                 OPENED: 1,
4943                                                 HEADERS_RECEIVED: 2,
4944                                                 LOADING: 3,
4945                                                 DONE: 4
4946                                 });
4948                                 sinon.useFakeXMLHttpRequest = function () {
4949                                                 FakeXMLHttpRequest.restore = function restore(keepOnCreate) {
4950                                                                 if (sinonXhr.supportsXHR) {
4951                                                                                 global.XMLHttpRequest = sinonXhr.GlobalXMLHttpRequest;
4952                                                                 }
4954                                                                 if (sinonXhr.supportsActiveX) {
4955                                                                                 global.ActiveXObject = sinonXhr.GlobalActiveXObject;
4956                                                                 }
4958                                                                 delete FakeXMLHttpRequest.restore;
4960                                                                 if (keepOnCreate !== true) {
4961                                                                                 delete FakeXMLHttpRequest.onCreate;
4962                                                                 }
4963                                                 };
4964                                                 if (sinonXhr.supportsXHR) {
4965                                                                 global.XMLHttpRequest = FakeXMLHttpRequest;
4966                                                 }
4968                                                 if (sinonXhr.supportsActiveX) {
4969                                                                 global.ActiveXObject = function ActiveXObject(objId) {
4970                                                                                 if (objId == "Microsoft.XMLHTTP" || /^Msxml2\.XMLHTTP/i.test(objId)) {
4972                                                                                                 return new FakeXMLHttpRequest();
4973                                                                                 }
4975                                                                                 return new sinonXhr.GlobalActiveXObject(objId);
4976                                                                 };
4977                                                 }
4979                                                 return FakeXMLHttpRequest;
4980                                 };
4982                                 sinon.FakeXMLHttpRequest = FakeXMLHttpRequest;
4983                 }
4985                 var isNode = typeof module !== "undefined" && module.exports && typeof require == "function";
4986                 var isAMD = typeof define === "function" && typeof define.amd === "object" && define.amd;
4988                 function loadDependencies(require, exports, module) {
4989                                 var sinon = require("./core");
4990                                 require("../extend");
4991                                 require("./event");
4992                                 require("../log_error");
4993                                 makeApi(sinon);
4994                                 module.exports = sinon;
4995                 }
4997                 if (isAMD) {
4998                                 define(loadDependencies);
4999                 } else if (isNode) {
5000                                 loadDependencies(require, module.exports, module);
5001                 } else if (typeof sinon === "undefined") {
5002                                 return;
5003                 } else {
5004                                 makeApi(sinon);
5005                 }
5007 })(typeof global !== "undefined" ? global : this);
5010  * @depend fake_xdomain_request.js
5011  * @depend fake_xml_http_request.js
5012  * @depend ../format.js
5013  * @depend ../log_error.js
5014  */
5016  * The Sinon "server" mimics a web server that receives requests from
5017  * sinon.FakeXMLHttpRequest and provides an API to respond to those requests,
5018  * both synchronously and asynchronously. To respond synchronuously, canned
5019  * answers have to be provided upfront.
5021  * @author Christian Johansen (christian@cjohansen.no)
5022  * @license BSD
5024  * Copyright (c) 2010-2013 Christian Johansen
5025  */
5027 if (typeof sinon == "undefined") {
5028                 var sinon = {};
5031 (function () {
5032                 var push = [].push;
5033                 function F() {}
5035                 function create(proto) {
5036                                 F.prototype = proto;
5037                                 return new F();
5038                 }
5040                 function responseArray(handler) {
5041                                 var response = handler;
5043                                 if (Object.prototype.toString.call(handler) != "[object Array]") {
5044                                                 response = [200, {}, handler];
5045                                 }
5047                                 if (typeof response[2] != "string") {
5048                                                 throw new TypeError("Fake server response body should be string, but was " +
5049                                                                                                                                 typeof response[2]);
5050                                 }
5052                                 return response;
5053                 }
5055                 var wloc = typeof window !== "undefined" ? window.location : {};
5056                 var rCurrLoc = new RegExp("^" + wloc.protocol + "//" + wloc.host);
5058                 function matchOne(response, reqMethod, reqUrl) {
5059                                 var rmeth = response.method;
5060                                 var matchMethod = !rmeth || rmeth.toLowerCase() == reqMethod.toLowerCase();
5061                                 var url = response.url;
5062                                 var matchUrl = !url || url == reqUrl || (typeof url.test == "function" && url.test(reqUrl));
5064                                 return matchMethod && matchUrl;
5065                 }
5067                 function match(response, request) {
5068                                 var requestUrl = request.url;
5070                                 if (!/^https?:\/\//.test(requestUrl) || rCurrLoc.test(requestUrl)) {
5071                                                 requestUrl = requestUrl.replace(rCurrLoc, "");
5072                                 }
5074                                 if (matchOne(response, this.getHTTPMethod(request), requestUrl)) {
5075                                                 if (typeof response.response == "function") {
5076                                                                 var ru = response.url;
5077                                                                 var args = [request].concat(ru && typeof ru.exec == "function" ? ru.exec(requestUrl).slice(1) : []);
5078                                                                 return response.response.apply(response, args);
5079                                                 }
5081                                                 return true;
5082                                 }
5084                                 return false;
5085                 }
5087                 function makeApi(sinon) {
5088                                 sinon.fakeServer = {
5089                                                 create: function () {
5090                                                                 var server = create(this);
5091                                                                 if (!sinon.xhr.supportsCORS) {
5092                                                                                 this.xhr = sinon.useFakeXDomainRequest();
5093                                                                 } else {
5094                                                                                 this.xhr = sinon.useFakeXMLHttpRequest();
5095                                                                 }
5096                                                                 server.requests = [];
5098                                                                 this.xhr.onCreate = function (xhrObj) {
5099                                                                                 server.addRequest(xhrObj);
5100                                                                 };
5102                                                                 return server;
5103                                                 },
5105                                                 addRequest: function addRequest(xhrObj) {
5106                                                                 var server = this;
5107                                                                 push.call(this.requests, xhrObj);
5109                                                                 xhrObj.onSend = function () {
5110                                                                                 server.handleRequest(this);
5112                                                                                 if (server.respondImmediately) {
5113                                                                                                 server.respond();
5114                                                                                 } else if (server.autoRespond && !server.responding) {
5115                                                                                                 setTimeout(function () {
5116                                                                                                                 server.responding = false;
5117                                                                                                                 server.respond();
5118                                                                                                 }, server.autoRespondAfter || 10);
5120                                                                                                 server.responding = true;
5121                                                                                 }
5122                                                                 };
5123                                                 },
5125                                                 getHTTPMethod: function getHTTPMethod(request) {
5126                                                                 if (this.fakeHTTPMethods && /post/i.test(request.method)) {
5127                                                                                 var matches = (request.requestBody || "").match(/_method=([^\b;]+)/);
5128                                                                                 return !!matches ? matches[1] : request.method;
5129                                                                 }
5131                                                                 return request.method;
5132                                                 },
5134                                                 handleRequest: function handleRequest(xhr) {
5135                                                                 if (xhr.async) {
5136                                                                                 if (!this.queue) {
5137                                                                                                 this.queue = [];
5138                                                                                 }
5140                                                                                 push.call(this.queue, xhr);
5141                                                                 } else {
5142                                                                                 this.processRequest(xhr);
5143                                                                 }
5144                                                 },
5146                                                 log: function log(response, request) {
5147                                                                 var str;
5149                                                                 str =  "Request:\n"  + sinon.format(request)  + "\n\n";
5150                                                                 str += "Response:\n" + sinon.format(response) + "\n\n";
5152                                                                 sinon.log(str);
5153                                                 },
5155                                                 respondWith: function respondWith(method, url, body) {
5156                                                                 if (arguments.length == 1 && typeof method != "function") {
5157                                                                                 this.response = responseArray(method);
5158                                                                                 return;
5159                                                                 }
5161                                                                 if (!this.responses) { this.responses = []; }
5163                                                                 if (arguments.length == 1) {
5164                                                                                 body = method;
5165                                                                                 url = method = null;
5166                                                                 }
5168                                                                 if (arguments.length == 2) {
5169                                                                                 body = url;
5170                                                                                 url = method;
5171                                                                                 method = null;
5172                                                                 }
5174                                                                 push.call(this.responses, {
5175                                                                                 method: method,
5176                                                                                 url: url,
5177                                                                                 response: typeof body == "function" ? body : responseArray(body)
5178                                                                 });
5179                                                 },
5181                                                 respond: function respond() {
5182                                                                 if (arguments.length > 0) {
5183                                                                                 this.respondWith.apply(this, arguments);
5184                                                                 }
5186                                                                 var queue = this.queue || [];
5187                                                                 var requests = queue.splice(0, queue.length);
5188                                                                 var request;
5190                                                                 while (request = requests.shift()) {
5191                                                                                 this.processRequest(request);
5192                                                                 }
5193                                                 },
5195                                                 processRequest: function processRequest(request) {
5196                                                                 try {
5197                                                                                 if (request.aborted) {
5198                                                                                                 return;
5199                                                                                 }
5201                                                                                 var response = this.response || [404, {}, ""];
5203                                                                                 if (this.responses) {
5204                                                                                                 for (var l = this.responses.length, i = l - 1; i >= 0; i--) {
5205                                                                                                                 if (match.call(this, this.responses[i], request)) {
5206                                                                                                                                 response = this.responses[i].response;
5207                                                                                                                                 break;
5208                                                                                                                 }
5209                                                                                                 }
5210                                                                                 }
5212                                                                                 if (request.readyState != 4) {
5213                                                                                                 this.log(response, request);
5215                                                                                                 request.respond(response[0], response[1], response[2]);
5216                                                                                 }
5217                                                                 } catch (e) {
5218                                                                                 sinon.logError("Fake server request processing", e);
5219                                                                 }
5220                                                 },
5222                                                 restore: function restore() {
5223                                                                 return this.xhr.restore && this.xhr.restore.apply(this.xhr, arguments);
5224                                                 }
5225                                 };
5226                 }
5228                 var isNode = typeof module !== "undefined" && module.exports && typeof require == "function";
5229                 var isAMD = typeof define === "function" && typeof define.amd === "object" && define.amd;
5231                 function loadDependencies(require, exports, module) {
5232                                 var sinon = require("./core");
5233                                 require("./fake_xdomain_request");
5234                                 require("./fake_xml_http_request");
5235                                 require("../format");
5236                                 makeApi(sinon);
5237                                 module.exports = sinon;
5238                 }
5240                 if (isAMD) {
5241                                 define(loadDependencies);
5242                 } else if (isNode) {
5243                                 loadDependencies(require, module.exports, module);
5244                 } else {
5245                                 makeApi(sinon);
5246                 }
5247 }());
5250  * @depend fake_server.js
5251  * @depend fake_timers.js
5252  */
5254  * Add-on for sinon.fakeServer that automatically handles a fake timer along with
5255  * the FakeXMLHttpRequest. The direct inspiration for this add-on is jQuery
5256  * 1.3.x, which does not use xhr object's onreadystatehandler at all - instead,
5257  * it polls the object for completion with setInterval. Dispite the direct
5258  * motivation, there is nothing jQuery-specific in this file, so it can be used
5259  * in any environment where the ajax implementation depends on setInterval or
5260  * setTimeout.
5262  * @author Christian Johansen (christian@cjohansen.no)
5263  * @license BSD
5265  * Copyright (c) 2010-2013 Christian Johansen
5266  */
5268 (function () {
5269                 function makeApi(sinon) {
5270                                 function Server() {}
5271                                 Server.prototype = sinon.fakeServer;
5273                                 sinon.fakeServerWithClock = new Server();
5275                                 sinon.fakeServerWithClock.addRequest = function addRequest(xhr) {
5276                                                 if (xhr.async) {
5277                                                                 if (typeof setTimeout.clock == "object") {
5278                                                                                 this.clock = setTimeout.clock;
5279                                                                 } else {
5280                                                                                 this.clock = sinon.useFakeTimers();
5281                                                                                 this.resetClock = true;
5282                                                                 }
5284                                                                 if (!this.longestTimeout) {
5285                                                                                 var clockSetTimeout = this.clock.setTimeout;
5286                                                                                 var clockSetInterval = this.clock.setInterval;
5287                                                                                 var server = this;
5289                                                                                 this.clock.setTimeout = function (fn, timeout) {
5290                                                                                                 server.longestTimeout = Math.max(timeout, server.longestTimeout || 0);
5292                                                                                                 return clockSetTimeout.apply(this, arguments);
5293                                                                                 };
5295                                                                                 this.clock.setInterval = function (fn, timeout) {
5296                                                                                                 server.longestTimeout = Math.max(timeout, server.longestTimeout || 0);
5298                                                                                                 return clockSetInterval.apply(this, arguments);
5299                                                                                 };
5300                                                                 }
5301                                                 }
5303                                                 return sinon.fakeServer.addRequest.call(this, xhr);
5304                                 };
5306                                 sinon.fakeServerWithClock.respond = function respond() {
5307                                                 var returnVal = sinon.fakeServer.respond.apply(this, arguments);
5309                                                 if (this.clock) {
5310                                                                 this.clock.tick(this.longestTimeout || 0);
5311                                                                 this.longestTimeout = 0;
5313                                                                 if (this.resetClock) {
5314                                                                                 this.clock.restore();
5315                                                                                 this.resetClock = false;
5316                                                                 }
5317                                                 }
5319                                                 return returnVal;
5320                                 };
5322                                 sinon.fakeServerWithClock.restore = function restore() {
5323                                                 if (this.clock) {
5324                                                                 this.clock.restore();
5325                                                 }
5327                                                 return sinon.fakeServer.restore.apply(this, arguments);
5328                                 };
5329                 }
5331                 var isNode = typeof module !== "undefined" && module.exports && typeof require == "function";
5332                 var isAMD = typeof define === "function" && typeof define.amd === "object" && define.amd;
5334                 function loadDependencies(require) {
5335                                 var sinon = require("./core");
5336                                 require("./fake_server");
5337                                 require("./fake_timers");
5338                                 makeApi(sinon);
5339                 }
5341                 if (isAMD) {
5342                                 define(loadDependencies);
5343                 } else if (isNode) {
5344                                 loadDependencies(require);
5345                 } else {
5346                                 makeApi(sinon);
5347                 }
5348 }());
5351  * @depend util/core.js
5352  * @depend extend.js
5353  * @depend collection.js
5354  * @depend util/fake_timers.js
5355  * @depend util/fake_server_with_clock.js
5356  */
5358  * Manages fake collections as well as fake utilities such as Sinon's
5359  * timers and fake XHR implementation in one convenient object.
5361  * @author Christian Johansen (christian@cjohansen.no)
5362  * @license BSD
5364  * Copyright (c) 2010-2013 Christian Johansen
5365  */
5367 (function () {
5368                 function makeApi(sinon) {
5369                                 var push = [].push;
5371                                 function exposeValue(sandbox, config, key, value) {
5372                                                 if (!value) {
5373                                                                 return;
5374                                                 }
5376                                                 if (config.injectInto && !(key in config.injectInto)) {
5377                                                                 config.injectInto[key] = value;
5378                                                                 sandbox.injectedKeys.push(key);
5379                                                 } else {
5380                                                                 push.call(sandbox.args, value);
5381                                                 }
5382                                 }
5384                                 function prepareSandboxFromConfig(config) {
5385                                                 var sandbox = sinon.create(sinon.sandbox);
5387                                                 if (config.useFakeServer) {
5388                                                                 if (typeof config.useFakeServer == "object") {
5389                                                                                 sandbox.serverPrototype = config.useFakeServer;
5390                                                                 }
5392                                                                 sandbox.useFakeServer();
5393                                                 }
5395                                                 if (config.useFakeTimers) {
5396                                                                 if (typeof config.useFakeTimers == "object") {
5397                                                                                 sandbox.useFakeTimers.apply(sandbox, config.useFakeTimers);
5398                                                                 } else {
5399                                                                                 sandbox.useFakeTimers();
5400                                                                 }
5401                                                 }
5403                                                 return sandbox;
5404                                 }
5406                                 sinon.sandbox = sinon.extend(sinon.create(sinon.collection), {
5407                                                 useFakeTimers: function useFakeTimers() {
5408                                                                 this.clock = sinon.useFakeTimers.apply(sinon, arguments);
5410                                                                 return this.add(this.clock);
5411                                                 },
5413                                                 serverPrototype: sinon.fakeServer,
5415                                                 useFakeServer: function useFakeServer() {
5416                                                                 var proto = this.serverPrototype || sinon.fakeServer;
5418                                                                 if (!proto || !proto.create) {
5419                                                                                 return null;
5420                                                                 }
5422                                                                 this.server = proto.create();
5423                                                                 return this.add(this.server);
5424                                                 },
5426                                                 inject: function (obj) {
5427                                                                 sinon.collection.inject.call(this, obj);
5429                                                                 if (this.clock) {
5430                                                                                 obj.clock = this.clock;
5431                                                                 }
5433                                                                 if (this.server) {
5434                                                                                 obj.server = this.server;
5435                                                                                 obj.requests = this.server.requests;
5436                                                                 }
5438                                                                 obj.match = sinon.match;
5440                                                                 return obj;
5441                                                 },
5443                                                 restore: function () {
5444                                                                 sinon.collection.restore.apply(this, arguments);
5445                                                                 this.restoreContext();
5446                                                 },
5448                                                 restoreContext: function () {
5449                                                                 if (this.injectedKeys) {
5450                                                                                 for (var i = 0, j = this.injectedKeys.length; i < j; i++) {
5451                                                                                                 delete this.injectInto[this.injectedKeys[i]];
5452                                                                                 }
5453                                                                                 this.injectedKeys = [];
5454                                                                 }
5455                                                 },
5457                                                 create: function (config) {
5458                                                                 if (!config) {
5459                                                                                 return sinon.create(sinon.sandbox);
5460                                                                 }
5462                                                                 var sandbox = prepareSandboxFromConfig(config);
5463                                                                 sandbox.args = sandbox.args || [];
5464                                                                 sandbox.injectedKeys = [];
5465                                                                 sandbox.injectInto = config.injectInto;
5466                                                                 var prop, value, exposed = sandbox.inject({});
5468                                                                 if (config.properties) {
5469                                                                                 for (var i = 0, l = config.properties.length; i < l; i++) {
5470                                                                                                 prop = config.properties[i];
5471                                                                                                 value = exposed[prop] || prop == "sandbox" && sandbox;
5472                                                                                                 exposeValue(sandbox, config, prop, value);
5473                                                                                 }
5474                                                                 } else {
5475                                                                                 exposeValue(sandbox, config, "sandbox", value);
5476                                                                 }
5478                                                                 return sandbox;
5479                                                 },
5481                                                 match: sinon.match
5482                                 });
5484                                 sinon.sandbox.useFakeXMLHttpRequest = sinon.sandbox.useFakeServer;
5486                                 return sinon.sandbox;
5487                 }
5489                 var isNode = typeof module !== "undefined" && module.exports && typeof require == "function";
5490                 var isAMD = typeof define === "function" && typeof define.amd === "object" && define.amd;
5492                 function loadDependencies(require, exports, module) {
5493                                 var sinon = require("./util/core");
5494                                 require("./extend");
5495                                 require("./util/fake_server_with_clock");
5496                                 require("./util/fake_timers");
5497                                 require("./collection");
5498                                 module.exports = makeApi(sinon);
5499                 }
5501                 if (isAMD) {
5502                                 define(loadDependencies);
5503                 } else if (isNode) {
5504                                 loadDependencies(require, module.exports, module);
5505                 } else if (!sinon) {
5506                                 return;
5507                 } else {
5508                                 makeApi(sinon);
5509                 }
5510 }());
5513  * @depend util/core.js
5514  * @depend sandbox.js
5515  */
5517  * Test function, sandboxes fakes
5519  * @author Christian Johansen (christian@cjohansen.no)
5520  * @license BSD
5522  * Copyright (c) 2010-2013 Christian Johansen
5523  */
5525 (function (sinon) {
5526                 function makeApi(sinon) {
5527                                 var slice = Array.prototype.slice;
5529                                 function test(callback) {
5530                                                 var type = typeof callback;
5532                                                 if (type != "function") {
5533                                                                 throw new TypeError("sinon.test needs to wrap a test function, got " + type);
5534                                                 }
5536                                                 function sinonSandboxedTest() {
5537                                                                 var config = sinon.getConfig(sinon.config);
5538                                                                 config.injectInto = config.injectIntoThis && this || config.injectInto;
5539                                                                 var sandbox = sinon.sandbox.create(config);
5540                                                                 var args = slice.call(arguments);
5541                                                                 var oldDone = args.length && args[args.length - 1];
5542                                                                 var exception, result;
5544                                                                 if (typeof oldDone == "function") {
5545                                                                                 args[args.length - 1] = function sinonDone(result) {
5546                                                                                                 if (result) {
5547                                                                                                                 sandbox.restore();
5548                                                                                                                 throw exception;
5549                                                                                                 } else {
5550                                                                                                                 sandbox.verifyAndRestore();
5551                                                                                                 }
5552                                                                                                 oldDone(result);
5553                                                                                 };
5554                                                                 }
5556                                                                 try {
5557                                                                                 result = callback.apply(this, args.concat(sandbox.args));
5558                                                                 } catch (e) {
5559                                                                                 exception = e;
5560                                                                 }
5562                                                                 if (typeof oldDone != "function") {
5563                                                                                 if (typeof exception !== "undefined") {
5564                                                                                                 sandbox.restore();
5565                                                                                                 throw exception;
5566                                                                                 } else {
5567                                                                                                 sandbox.verifyAndRestore();
5568                                                                                 }
5569                                                                 }
5571                                                                 return result;
5572                                                 }
5574                                                 if (callback.length) {
5575                                                                 return function sinonAsyncSandboxedTest(callback) {
5576                                                                                 return sinonSandboxedTest.apply(this, arguments);
5577                                                                 };
5578                                                 }
5580                                                 return sinonSandboxedTest;
5581                                 }
5583                                 test.config = {
5584                                                 injectIntoThis: true,
5585                                                 injectInto: null,
5586                                                 properties: ["spy", "stub", "mock", "clock", "server", "requests"],
5587                                                 useFakeTimers: true,
5588                                                 useFakeServer: true
5589                                 };
5591                                 sinon.test = test;
5592                                 return test;
5593                 }
5595                 var isNode = typeof module !== "undefined" && module.exports && typeof require == "function";
5596                 var isAMD = typeof define === "function" && typeof define.amd === "object" && define.amd;
5598                 function loadDependencies(require, exports, module) {
5599                                 var sinon = require("./util/core");
5600                                 require("./sandbox");
5601                                 module.exports = makeApi(sinon);
5602                 }
5604                 if (isAMD) {
5605                                 define(loadDependencies);
5606                 } else if (isNode) {
5607                                 loadDependencies(require, module.exports, module);
5608                 } else if (sinon) {
5609                                 makeApi(sinon);
5610                 }
5611 }(typeof sinon == "object" && sinon || null));
5614  * @depend util/core.js
5615  * @depend test.js
5616  */
5618  * Test case, sandboxes all test functions
5620  * @author Christian Johansen (christian@cjohansen.no)
5621  * @license BSD
5623  * Copyright (c) 2010-2013 Christian Johansen
5624  */
5626 (function (sinon) {
5627                 function createTest(property, setUp, tearDown) {
5628                                 return function () {
5629                                                 if (setUp) {
5630                                                                 setUp.apply(this, arguments);
5631                                                 }
5633                                                 var exception, result;
5635                                                 try {
5636                                                                 result = property.apply(this, arguments);
5637                                                 } catch (e) {
5638                                                                 exception = e;
5639                                                 }
5641                                                 if (tearDown) {
5642                                                                 tearDown.apply(this, arguments);
5643                                                 }
5645                                                 if (exception) {
5646                                                                 throw exception;
5647                                                 }
5649                                                 return result;
5650                                 };
5651                 }
5653                 function makeApi(sinon) {
5654                                 function testCase(tests, prefix) {
5655                                                 /*jsl:ignore*/
5656                                                 if (!tests || typeof tests != "object") {
5657                                                                 throw new TypeError("sinon.testCase needs an object with test functions");
5658                                                 }
5659                                                 /*jsl:end*/
5661                                                 prefix = prefix || "test";
5662                                                 var rPrefix = new RegExp("^" + prefix);
5663                                                 var methods = {}, testName, property, method;
5664                                                 var setUp = tests.setUp;
5665                                                 var tearDown = tests.tearDown;
5667                                                 for (testName in tests) {
5668                                                                 if (tests.hasOwnProperty(testName)) {
5669                                                                                 property = tests[testName];
5671                                                                                 if (/^(setUp|tearDown)$/.test(testName)) {
5672                                                                                                 continue;
5673                                                                                 }
5675                                                                                 if (typeof property == "function" && rPrefix.test(testName)) {
5676                                                                                                 method = property;
5678                                                                                                 if (setUp || tearDown) {
5679                                                                                                                 method = createTest(property, setUp, tearDown);
5680                                                                                                 }
5682                                                                                                 methods[testName] = sinon.test(method);
5683                                                                                 } else {
5684                                                                                                 methods[testName] = tests[testName];
5685                                                                                 }
5686                                                                 }
5687                                                 }
5689                                                 return methods;
5690                                 }
5692                                 sinon.testCase = testCase;
5693                                 return testCase;
5694                 }
5696                 var isNode = typeof module !== "undefined" && module.exports && typeof require == "function";
5697                 var isAMD = typeof define === "function" && typeof define.amd === "object" && define.amd;
5699                 function loadDependencies(require, exports, module) {
5700                                 var sinon = require("./util/core");
5701                                 require("./test");
5702                                 module.exports = makeApi(sinon);
5703                 }
5705                 if (isAMD) {
5706                                 define(loadDependencies);
5707                 } else if (isNode) {
5708                                 loadDependencies(require, module.exports, module);
5709                 } else if (!sinon) {
5710                                 return;
5711                 } else {
5712                                 makeApi(sinon);
5713                 }
5714 }(typeof sinon == "object" && sinon || null));
5717  * @depend times_in_words.js
5718  * @depend util/core.js
5719  * @depend match.js
5720  * @depend format.js
5721  */
5723  * Assertions matching the test spy retrieval interface.
5725  * @author Christian Johansen (christian@cjohansen.no)
5726  * @license BSD
5728  * Copyright (c) 2010-2013 Christian Johansen
5729  */
5731 (function (sinon, global) {
5732                 var slice = Array.prototype.slice;
5734                 function makeApi(sinon) {
5735                                 var assert;
5737                                 function verifyIsStub() {
5738                                                 var method;
5740                                                 for (var i = 0, l = arguments.length; i < l; ++i) {
5741                                                                 method = arguments[i];
5743                                                                 if (!method) {
5744                                                                                 assert.fail("fake is not a spy");
5745                                                                 }
5747                                                                 if (method.proxy) {
5748                                                                                 verifyIsStub(method.proxy);
5749                                                                 } else {
5750                                                                                 if (typeof method != "function") {
5751                                                                                                 assert.fail(method + " is not a function");
5752                                                                                 }
5754                                                                                 if (typeof method.getCall != "function") {
5755                                                                                                 assert.fail(method + " is not stubbed");
5756                                                                                 }
5757                                                                 }
5759                                                 }
5760                                 }
5762                                 function failAssertion(object, msg) {
5763                                                 object = object || global;
5764                                                 var failMethod = object.fail || assert.fail;
5765                                                 failMethod.call(object, msg);
5766                                 }
5768                                 function mirrorPropAsAssertion(name, method, message) {
5769                                                 if (arguments.length == 2) {
5770                                                                 message = method;
5771                                                                 method = name;
5772                                                 }
5774                                                 assert[name] = function (fake) {
5775                                                                 verifyIsStub(fake);
5777                                                                 var args = slice.call(arguments, 1);
5778                                                                 var failed = false;
5780                                                                 if (typeof method == "function") {
5781                                                                                 failed = !method(fake);
5782                                                                 } else {
5783                                                                                 failed = typeof fake[method] == "function" ?
5784                                                                                                 !fake[method].apply(fake, args) : !fake[method];
5785                                                                 }
5787                                                                 if (failed) {
5788                                                                                 failAssertion(this, (fake.printf || fake.proxy.printf).apply(fake, [message].concat(args)));
5789                                                                 } else {
5790                                                                                 assert.pass(name);
5791                                                                 }
5792                                                 };
5793                                 }
5795                                 function exposedName(prefix, prop) {
5796                                                 return !prefix || /^fail/.test(prop) ? prop :
5797                                                                 prefix + prop.slice(0, 1).toUpperCase() + prop.slice(1);
5798                                 }
5800                                 assert = {
5801                                                 failException: "AssertError",
5803                                                 fail: function fail(message) {
5804                                                                 var error = new Error(message);
5805                                                                 error.name = this.failException || assert.failException;
5807                                                                 throw error;
5808                                                 },
5810                                                 pass: function pass(assertion) {},
5812                                                 callOrder: function assertCallOrder() {
5813                                                                 verifyIsStub.apply(null, arguments);
5814                                                                 var expected = "", actual = "";
5816                                                                 if (!sinon.calledInOrder(arguments)) {
5817                                                                                 try {
5818                                                                                                 expected = [].join.call(arguments, ", ");
5819                                                                                                 var calls = slice.call(arguments);
5820                                                                                                 var i = calls.length;
5821                                                                                                 while (i) {
5822                                                                                                                 if (!calls[--i].called) {
5823                                                                                                                                 calls.splice(i, 1);
5824                                                                                                                 }
5825                                                                                                 }
5826                                                                                                 actual = sinon.orderByFirstCall(calls).join(", ");
5827                                                                                 } catch (e) {
5828                                                                                                 // If this fails, we'll just fall back to the blank string
5829                                                                                 }
5831                                                                                 failAssertion(this, "expected " + expected + " to be " +
5832                                                                                                                                 "called in order but were called as " + actual);
5833                                                                 } else {
5834                                                                                 assert.pass("callOrder");
5835                                                                 }
5836                                                 },
5838                                                 callCount: function assertCallCount(method, count) {
5839                                                                 verifyIsStub(method);
5841                                                                 if (method.callCount != count) {
5842                                                                                 var msg = "expected %n to be called " + sinon.timesInWords(count) +
5843                                                                                                 " but was called %c%C";
5844                                                                                 failAssertion(this, method.printf(msg));
5845                                                                 } else {
5846                                                                                 assert.pass("callCount");
5847                                                                 }
5848                                                 },
5850                                                 expose: function expose(target, options) {
5851                                                                 if (!target) {
5852                                                                                 throw new TypeError("target is null or undefined");
5853                                                                 }
5855                                                                 var o = options || {};
5856                                                                 var prefix = typeof o.prefix == "undefined" && "assert" || o.prefix;
5857                                                                 var includeFail = typeof o.includeFail == "undefined" || !!o.includeFail;
5859                                                                 for (var method in this) {
5860                                                                                 if (method != "expose" && (includeFail || !/^(fail)/.test(method))) {
5861                                                                                                 target[exposedName(prefix, method)] = this[method];
5862                                                                                 }
5863                                                                 }
5865                                                                 return target;
5866                                                 },
5868                                                 match: function match(actual, expectation) {
5869                                                                 var matcher = sinon.match(expectation);
5870                                                                 if (matcher.test(actual)) {
5871                                                                                 assert.pass("match");
5872                                                                 } else {
5873                                                                                 var formatted = [
5874                                                                                                 "expected value to match",
5875                                                                                                 "    expected = " + sinon.format(expectation),
5876                                                                                                 "    actual = " + sinon.format(actual)
5877                                                                                 ]
5878                                                                                 failAssertion(this, formatted.join("\n"));
5879                                                                 }
5880                                                 }
5881                                 };
5883                                 mirrorPropAsAssertion("called", "expected %n to have been called at least once but was never called");
5884                                 mirrorPropAsAssertion("notCalled", function (spy) { return !spy.called; },
5885                                                                                                                 "expected %n to not have been called but was called %c%C");
5886                                 mirrorPropAsAssertion("calledOnce", "expected %n to be called once but was called %c%C");
5887                                 mirrorPropAsAssertion("calledTwice", "expected %n to be called twice but was called %c%C");
5888                                 mirrorPropAsAssertion("calledThrice", "expected %n to be called thrice but was called %c%C");
5889                                 mirrorPropAsAssertion("calledOn", "expected %n to be called with %1 as this but was called with %t");
5890                                 mirrorPropAsAssertion("alwaysCalledOn", "expected %n to always be called with %1 as this but was called with %t");
5891                                 mirrorPropAsAssertion("calledWithNew", "expected %n to be called with new");
5892                                 mirrorPropAsAssertion("alwaysCalledWithNew", "expected %n to always be called with new");
5893                                 mirrorPropAsAssertion("calledWith", "expected %n to be called with arguments %*%C");
5894                                 mirrorPropAsAssertion("calledWithMatch", "expected %n to be called with match %*%C");
5895                                 mirrorPropAsAssertion("alwaysCalledWith", "expected %n to always be called with arguments %*%C");
5896                                 mirrorPropAsAssertion("alwaysCalledWithMatch", "expected %n to always be called with match %*%C");
5897                                 mirrorPropAsAssertion("calledWithExactly", "expected %n to be called with exact arguments %*%C");
5898                                 mirrorPropAsAssertion("alwaysCalledWithExactly", "expected %n to always be called with exact arguments %*%C");
5899                                 mirrorPropAsAssertion("neverCalledWith", "expected %n to never be called with arguments %*%C");
5900                                 mirrorPropAsAssertion("neverCalledWithMatch", "expected %n to never be called with match %*%C");
5901                                 mirrorPropAsAssertion("threw", "%n did not throw exception%C");
5902                                 mirrorPropAsAssertion("alwaysThrew", "%n did not always throw exception%C");
5904                                 sinon.assert = assert;
5905                                 return assert;
5906                 }
5908                 var isNode = typeof module !== "undefined" && module.exports && typeof require == "function";
5909                 var isAMD = typeof define === "function" && typeof define.amd === "object" && define.amd;
5911                 function loadDependencies(require, exports, module) {
5912                                 var sinon = require("./util/core");
5913                                 require("./match");
5914                                 require("./format");
5915                                 module.exports = makeApi(sinon);
5916                 }
5918                 if (isAMD) {
5919                                 define(loadDependencies);
5920                 } else if (isNode) {
5921                                 loadDependencies(require, module.exports, module);
5922                 } else if (!sinon) {
5923                                 return;
5924                 } else {
5925                                 makeApi(sinon);
5926                 }
5928 }(typeof sinon == "object" && sinon || null, typeof window != "undefined" ? window : (typeof self != "undefined") ? self : global));
5930         return sinon;
5931 }));