Merge "Special:Upload should not crash on failing previews"
[mediawiki.git] / resources / lib / sinonjs / sinon-1.17.3.js
blobd77b3175874fa227f516e9b1e17f4e8a52e93012
1 /**
2  * Sinon.JS 1.17.3, 2016/01/27
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   'use strict';
38   if (typeof define === 'function' && define.amd) {
39     define('sinon', [], function () {
40       return (root.sinon = factory());
41     });
42   } else if (typeof exports === 'object') {
43     module.exports = factory();
44   } else {
45     root.sinon = factory();
46   }
47 }(this, function () {
48   'use strict';
49   var samsam, formatio, lolex;
50   (function () {
51                 function define(mod, deps, fn) {
52                   if (mod == "samsam") {
53                     samsam = deps();
54                   } else if (typeof deps === "function" && mod.length === 0) {
55                     lolex = deps();
56                   } else if (typeof fn === "function") {
57                     formatio = fn(samsam);
58                   }
59                 }
60     define.amd = {};
61 ((typeof define === "function" && define.amd && function (m) { define("samsam", m); }) ||
62  (typeof module === "object" &&
63       function (m) { module.exports = m(); }) || // Node
64  function (m) { this.samsam = m(); } // Browser globals
65 )(function () {
66     var o = Object.prototype;
67     var div = typeof document !== "undefined" && document.createElement("div");
69     function isNaN(value) {
70         // Unlike global isNaN, this avoids type coercion
71         // typeof check avoids IE host object issues, hat tip to
72         // lodash
73         var val = value; // JsLint thinks value !== value is "weird"
74         return typeof value === "number" && value !== val;
75     }
77     function getClass(value) {
78         // Returns the internal [[Class]] by calling Object.prototype.toString
79         // with the provided value as this. Return value is a string, naming the
80         // internal class, e.g. "Array"
81         return o.toString.call(value).split(/[ \]]/)[1];
82     }
84     /**
85      * @name samsam.isArguments
86      * @param Object object
87      *
88      * Returns ``true`` if ``object`` is an ``arguments`` object,
89      * ``false`` otherwise.
90      */
91     function isArguments(object) {
92         if (getClass(object) === 'Arguments') { return true; }
93         if (typeof object !== "object" || typeof object.length !== "number" ||
94                 getClass(object) === "Array") {
95             return false;
96         }
97         if (typeof object.callee == "function") { return true; }
98         try {
99             object[object.length] = 6;
100             delete object[object.length];
101         } catch (e) {
102             return true;
103         }
104         return false;
105     }
107     /**
108      * @name samsam.isElement
109      * @param Object object
110      *
111      * Returns ``true`` if ``object`` is a DOM element node. Unlike
112      * Underscore.js/lodash, this function will return ``false`` if ``object``
113      * is an *element-like* object, i.e. a regular object with a ``nodeType``
114      * property that holds the value ``1``.
115      */
116     function isElement(object) {
117         if (!object || object.nodeType !== 1 || !div) { return false; }
118         try {
119             object.appendChild(div);
120             object.removeChild(div);
121         } catch (e) {
122             return false;
123         }
124         return true;
125     }
127     /**
128      * @name samsam.keys
129      * @param Object object
130      *
131      * Return an array of own property names.
132      */
133     function keys(object) {
134         var ks = [], prop;
135         for (prop in object) {
136             if (o.hasOwnProperty.call(object, prop)) { ks.push(prop); }
137         }
138         return ks;
139     }
141     /**
142      * @name samsam.isDate
143      * @param Object value
144      *
145      * Returns true if the object is a ``Date``, or *date-like*. Duck typing
146      * of date objects work by checking that the object has a ``getTime``
147      * function whose return value equals the return value from the object's
148      * ``valueOf``.
149      */
150     function isDate(value) {
151         return typeof value.getTime == "function" &&
152             value.getTime() == value.valueOf();
153     }
155     /**
156      * @name samsam.isNegZero
157      * @param Object value
158      *
159      * Returns ``true`` if ``value`` is ``-0``.
160      */
161     function isNegZero(value) {
162         return value === 0 && 1 / value === -Infinity;
163     }
165     /**
166      * @name samsam.equal
167      * @param Object obj1
168      * @param Object obj2
169      *
170      * Returns ``true`` if two objects are strictly equal. Compared to
171      * ``===`` there are two exceptions:
172      *
173      *   - NaN is considered equal to NaN
174      *   - -0 and +0 are not considered equal
175      */
176     function identical(obj1, obj2) {
177         if (obj1 === obj2 || (isNaN(obj1) && isNaN(obj2))) {
178             return obj1 !== 0 || isNegZero(obj1) === isNegZero(obj2);
179         }
180     }
183     /**
184      * @name samsam.deepEqual
185      * @param Object obj1
186      * @param Object obj2
187      *
188      * Deep equal comparison. Two values are "deep equal" if:
189      *
190      *   - They are equal, according to samsam.identical
191      *   - They are both date objects representing the same time
192      *   - They are both arrays containing elements that are all deepEqual
193      *   - They are objects with the same set of properties, and each property
194      *     in ``obj1`` is deepEqual to the corresponding property in ``obj2``
195      *
196      * Supports cyclic objects.
197      */
198     function deepEqualCyclic(obj1, obj2) {
200         // used for cyclic comparison
201         // contain already visited objects
202         var objects1 = [],
203             objects2 = [],
204         // contain pathes (position in the object structure)
205         // of the already visited objects
206         // indexes same as in objects arrays
207             paths1 = [],
208             paths2 = [],
209         // contains combinations of already compared objects
210         // in the manner: { "$1['ref']$2['ref']": true }
211             compared = {};
213         /**
214          * used to check, if the value of a property is an object
215          * (cyclic logic is only needed for objects)
216          * only needed for cyclic logic
217          */
218         function isObject(value) {
220             if (typeof value === 'object' && value !== null &&
221                     !(value instanceof Boolean) &&
222                     !(value instanceof Date)    &&
223                     !(value instanceof Number)  &&
224                     !(value instanceof RegExp)  &&
225                     !(value instanceof String)) {
227                 return true;
228             }
230             return false;
231         }
233         /**
234          * returns the index of the given object in the
235          * given objects array, -1 if not contained
236          * only needed for cyclic logic
237          */
238         function getIndex(objects, obj) {
240             var i;
241             for (i = 0; i < objects.length; i++) {
242                 if (objects[i] === obj) {
243                     return i;
244                 }
245             }
247             return -1;
248         }
250         // does the recursion for the deep equal check
251         return (function deepEqual(obj1, obj2, path1, path2) {
252             var type1 = typeof obj1;
253             var type2 = typeof obj2;
255             // == null also matches undefined
256             if (obj1 === obj2 ||
257                     isNaN(obj1) || isNaN(obj2) ||
258                     obj1 == null || obj2 == null ||
259                     type1 !== "object" || type2 !== "object") {
261                 return identical(obj1, obj2);
262             }
264             // Elements are only equal if identical(expected, actual)
265             if (isElement(obj1) || isElement(obj2)) { return false; }
267             var isDate1 = isDate(obj1), isDate2 = isDate(obj2);
268             if (isDate1 || isDate2) {
269                 if (!isDate1 || !isDate2 || obj1.getTime() !== obj2.getTime()) {
270                     return false;
271                 }
272             }
274             if (obj1 instanceof RegExp && obj2 instanceof RegExp) {
275                 if (obj1.toString() !== obj2.toString()) { return false; }
276             }
278             var class1 = getClass(obj1);
279             var class2 = getClass(obj2);
280             var keys1 = keys(obj1);
281             var keys2 = keys(obj2);
283             if (isArguments(obj1) || isArguments(obj2)) {
284                 if (obj1.length !== obj2.length) { return false; }
285             } else {
286                 if (type1 !== type2 || class1 !== class2 ||
287                         keys1.length !== keys2.length) {
288                     return false;
289                 }
290             }
292             var key, i, l,
293                 // following vars are used for the cyclic logic
294                 value1, value2,
295                 isObject1, isObject2,
296                 index1, index2,
297                 newPath1, newPath2;
299             for (i = 0, l = keys1.length; i < l; i++) {
300                 key = keys1[i];
301                 if (!o.hasOwnProperty.call(obj2, key)) {
302                     return false;
303                 }
305                 // Start of the cyclic logic
307                 value1 = obj1[key];
308                 value2 = obj2[key];
310                 isObject1 = isObject(value1);
311                 isObject2 = isObject(value2);
313                 // determine, if the objects were already visited
314                 // (it's faster to check for isObject first, than to
315                 // get -1 from getIndex for non objects)
316                 index1 = isObject1 ? getIndex(objects1, value1) : -1;
317                 index2 = isObject2 ? getIndex(objects2, value2) : -1;
319                 // determine the new pathes of the objects
320                 // - for non cyclic objects the current path will be extended
321                 //   by current property name
322                 // - for cyclic objects the stored path is taken
323                 newPath1 = index1 !== -1
324                     ? paths1[index1]
325                     : path1 + '[' + JSON.stringify(key) + ']';
326                 newPath2 = index2 !== -1
327                     ? paths2[index2]
328                     : path2 + '[' + JSON.stringify(key) + ']';
330                 // stop recursion if current objects are already compared
331                 if (compared[newPath1 + newPath2]) {
332                     return true;
333                 }
335                 // remember the current objects and their pathes
336                 if (index1 === -1 && isObject1) {
337                     objects1.push(value1);
338                     paths1.push(newPath1);
339                 }
340                 if (index2 === -1 && isObject2) {
341                     objects2.push(value2);
342                     paths2.push(newPath2);
343                 }
345                 // remember that the current objects are already compared
346                 if (isObject1 && isObject2) {
347                     compared[newPath1 + newPath2] = true;
348                 }
350                 // End of cyclic logic
352                 // neither value1 nor value2 is a cycle
353                 // continue with next level
354                 if (!deepEqual(value1, value2, newPath1, newPath2)) {
355                     return false;
356                 }
357             }
359             return true;
361         }(obj1, obj2, '$1', '$2'));
362     }
364     var match;
366     function arrayContains(array, subset) {
367         if (subset.length === 0) { return true; }
368         var i, l, j, k;
369         for (i = 0, l = array.length; i < l; ++i) {
370             if (match(array[i], subset[0])) {
371                 for (j = 0, k = subset.length; j < k; ++j) {
372                     if (!match(array[i + j], subset[j])) { return false; }
373                 }
374                 return true;
375             }
376         }
377         return false;
378     }
380     /**
381      * @name samsam.match
382      * @param Object object
383      * @param Object matcher
384      *
385      * Compare arbitrary value ``object`` with matcher.
386      */
387     match = function match(object, matcher) {
388         if (matcher && typeof matcher.test === "function") {
389             return matcher.test(object);
390         }
392         if (typeof matcher === "function") {
393             return matcher(object) === true;
394         }
396         if (typeof matcher === "string") {
397             matcher = matcher.toLowerCase();
398             var notNull = typeof object === "string" || !!object;
399             return notNull &&
400                 (String(object)).toLowerCase().indexOf(matcher) >= 0;
401         }
403         if (typeof matcher === "number") {
404             return matcher === object;
405         }
407         if (typeof matcher === "boolean") {
408             return matcher === object;
409         }
411         if (typeof(matcher) === "undefined") {
412             return typeof(object) === "undefined";
413         }
415         if (matcher === null) {
416             return object === null;
417         }
419         if (getClass(object) === "Array" && getClass(matcher) === "Array") {
420             return arrayContains(object, matcher);
421         }
423         if (matcher && typeof matcher === "object") {
424             if (matcher === object) {
425                 return true;
426             }
427             var prop;
428             for (prop in matcher) {
429                 var value = object[prop];
430                 if (typeof value === "undefined" &&
431                         typeof object.getAttribute === "function") {
432                     value = object.getAttribute(prop);
433                 }
434                 if (matcher[prop] === null || typeof matcher[prop] === 'undefined') {
435                     if (value !== matcher[prop]) {
436                         return false;
437                     }
438                 } else if (typeof  value === "undefined" || !match(value, matcher[prop])) {
439                     return false;
440                 }
441             }
442             return true;
443         }
445         throw new Error("Matcher was not a string, a number, a " +
446                         "function, a boolean or an object");
447     };
449     return {
450         isArguments: isArguments,
451         isElement: isElement,
452         isDate: isDate,
453         isNegZero: isNegZero,
454         identical: identical,
455         deepEqual: deepEqualCyclic,
456         match: match,
457         keys: keys
458     };
460 ((typeof define === "function" && define.amd && function (m) {
461     define("formatio", ["samsam"], m);
462 }) || (typeof module === "object" && function (m) {
463     module.exports = m(require("samsam"));
464 }) || function (m) { this.formatio = m(this.samsam); }
465 )(function (samsam) {
466     
467     var formatio = {
468         excludeConstructors: ["Object", /^.$/],
469         quoteStrings: true,
470         limitChildrenCount: 0
471     };
473     var hasOwn = Object.prototype.hasOwnProperty;
475     var specialObjects = [];
476     if (typeof global !== "undefined") {
477         specialObjects.push({ object: global, value: "[object global]" });
478     }
479     if (typeof document !== "undefined") {
480         specialObjects.push({
481             object: document,
482             value: "[object HTMLDocument]"
483         });
484     }
485     if (typeof window !== "undefined") {
486         specialObjects.push({ object: window, value: "[object Window]" });
487     }
489     function functionName(func) {
490         if (!func) { return ""; }
491         if (func.displayName) { return func.displayName; }
492         if (func.name) { return func.name; }
493         var matches = func.toString().match(/function\s+([^\(]+)/m);
494         return (matches && matches[1]) || "";
495     }
497     function constructorName(f, object) {
498         var name = functionName(object && object.constructor);
499         var excludes = f.excludeConstructors ||
500                 formatio.excludeConstructors || [];
502         var i, l;
503         for (i = 0, l = excludes.length; i < l; ++i) {
504             if (typeof excludes[i] === "string" && excludes[i] === name) {
505                 return "";
506             } else if (excludes[i].test && excludes[i].test(name)) {
507                 return "";
508             }
509         }
511         return name;
512     }
514     function isCircular(object, objects) {
515         if (typeof object !== "object") { return false; }
516         var i, l;
517         for (i = 0, l = objects.length; i < l; ++i) {
518             if (objects[i] === object) { return true; }
519         }
520         return false;
521     }
523     function ascii(f, object, processed, indent) {
524         if (typeof object === "string") {
525             var qs = f.quoteStrings;
526             var quote = typeof qs !== "boolean" || qs;
527             return processed || quote ? '"' + object + '"' : object;
528         }
530         if (typeof object === "function" && !(object instanceof RegExp)) {
531             return ascii.func(object);
532         }
534         processed = processed || [];
536         if (isCircular(object, processed)) { return "[Circular]"; }
538         if (Object.prototype.toString.call(object) === "[object Array]") {
539             return ascii.array.call(f, object, processed);
540         }
542         if (!object) { return String((1/object) === -Infinity ? "-0" : object); }
543         if (samsam.isElement(object)) { return ascii.element(object); }
545         if (typeof object.toString === "function" &&
546                 object.toString !== Object.prototype.toString) {
547             return object.toString();
548         }
550         var i, l;
551         for (i = 0, l = specialObjects.length; i < l; i++) {
552             if (object === specialObjects[i].object) {
553                 return specialObjects[i].value;
554             }
555         }
557         return ascii.object.call(f, object, processed, indent);
558     }
560     ascii.func = function (func) {
561         return "function " + functionName(func) + "() {}";
562     };
564     ascii.array = function (array, processed) {
565         processed = processed || [];
566         processed.push(array);
567         var pieces = [];
568         var i, l;
569         l = (this.limitChildrenCount > 0) ? 
570             Math.min(this.limitChildrenCount, array.length) : array.length;
572         for (i = 0; i < l; ++i) {
573             pieces.push(ascii(this, array[i], processed));
574         }
576         if(l < array.length)
577             pieces.push("[... " + (array.length - l) + " more elements]");
579         return "[" + pieces.join(", ") + "]";
580     };
582     ascii.object = function (object, processed, indent) {
583         processed = processed || [];
584         processed.push(object);
585         indent = indent || 0;
586         var pieces = [], properties = samsam.keys(object).sort();
587         var length = 3;
588         var prop, str, obj, i, k, l;
589         l = (this.limitChildrenCount > 0) ? 
590             Math.min(this.limitChildrenCount, properties.length) : properties.length;
592         for (i = 0; i < l; ++i) {
593             prop = properties[i];
594             obj = object[prop];
596             if (isCircular(obj, processed)) {
597                 str = "[Circular]";
598             } else {
599                 str = ascii(this, obj, processed, indent + 2);
600             }
602             str = (/\s/.test(prop) ? '"' + prop + '"' : prop) + ": " + str;
603             length += str.length;
604             pieces.push(str);
605         }
607         var cons = constructorName(this, object);
608         var prefix = cons ? "[" + cons + "] " : "";
609         var is = "";
610         for (i = 0, k = indent; i < k; ++i) { is += " "; }
612         if(l < properties.length)
613             pieces.push("[... " + (properties.length - l) + " more elements]");
615         if (length + indent > 80) {
616             return prefix + "{\n  " + is + pieces.join(",\n  " + is) + "\n" +
617                 is + "}";
618         }
619         return prefix + "{ " + pieces.join(", ") + " }";
620     };
622     ascii.element = function (element) {
623         var tagName = element.tagName.toLowerCase();
624         var attrs = element.attributes, attr, pairs = [], attrName, i, l, val;
626         for (i = 0, l = attrs.length; i < l; ++i) {
627             attr = attrs.item(i);
628             attrName = attr.nodeName.toLowerCase().replace("html:", "");
629             val = attr.nodeValue;
630             if (attrName !== "contenteditable" || val !== "inherit") {
631                 if (!!val) { pairs.push(attrName + "=\"" + val + "\""); }
632             }
633         }
635         var formatted = "<" + tagName + (pairs.length > 0 ? " " : "");
636         var content = element.innerHTML;
638         if (content.length > 20) {
639             content = content.substr(0, 20) + "[...]";
640         }
642         var res = formatted + pairs.join(" ") + ">" + content +
643                 "</" + tagName + ">";
645         return res.replace(/ contentEditable="inherit"/, "");
646     };
648     function Formatio(options) {
649         for (var opt in options) {
650             this[opt] = options[opt];
651         }
652     }
654     Formatio.prototype = {
655         functionName: functionName,
657         configure: function (options) {
658             return new Formatio(options);
659         },
661         constructorName: function (object) {
662             return constructorName(this, object);
663         },
665         ascii: function (object, processed, indent) {
666             return ascii(this, object, processed, indent);
667         }
668     };
670     return Formatio.prototype;
672 !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){
673 (function (global){
674 /*global global, window*/
676  * @author Christian Johansen (christian@cjohansen.no) and contributors
677  * @license BSD
679  * Copyright (c) 2010-2014 Christian Johansen
680  */
682 (function (global) {
683     
684     // Make properties writable in IE, as per
685     // http://www.adequatelygood.com/Replacing-setTimeout-Globally.html
686     // JSLint being anal
687     var glbl = global;
689     global.setTimeout = glbl.setTimeout;
690     global.clearTimeout = glbl.clearTimeout;
691     global.setInterval = glbl.setInterval;
692     global.clearInterval = glbl.clearInterval;
693     global.Date = glbl.Date;
695     // setImmediate is not a standard function
696     // avoid adding the prop to the window object if not present
697     if('setImmediate' in global) {
698         global.setImmediate = glbl.setImmediate;
699         global.clearImmediate = glbl.clearImmediate;
700     }
702     // node expects setTimeout/setInterval to return a fn object w/ .ref()/.unref()
703     // browsers, a number.
704     // see https://github.com/cjohansen/Sinon.JS/pull/436
706     var NOOP = function () { return undefined; };
707     var timeoutResult = setTimeout(NOOP, 0);
708     var addTimerReturnsObject = typeof timeoutResult === "object";
709     clearTimeout(timeoutResult);
711     var NativeDate = Date;
712     var uniqueTimerId = 1;
714     /**
715      * Parse strings like "01:10:00" (meaning 1 hour, 10 minutes, 0 seconds) into
716      * number of milliseconds. This is used to support human-readable strings passed
717      * to clock.tick()
718      */
719     function parseTime(str) {
720         if (!str) {
721             return 0;
722         }
724         var strings = str.split(":");
725         var l = strings.length, i = l;
726         var ms = 0, parsed;
728         if (l > 3 || !/^(\d\d:){0,2}\d\d?$/.test(str)) {
729             throw new Error("tick only understands numbers, 'm:s' and 'h:m:s'. Each part must be two digits");
730         }
732         while (i--) {
733             parsed = parseInt(strings[i], 10);
735             if (parsed >= 60) {
736                 throw new Error("Invalid time " + str);
737             }
739             ms += parsed * Math.pow(60, (l - i - 1));
740         }
742         return ms * 1000;
743     }
745     /**
746      * Used to grok the `now` parameter to createClock.
747      */
748     function getEpoch(epoch) {
749         if (!epoch) { return 0; }
750         if (typeof epoch.getTime === "function") { return epoch.getTime(); }
751         if (typeof epoch === "number") { return epoch; }
752         throw new TypeError("now should be milliseconds since UNIX epoch");
753     }
755     function inRange(from, to, timer) {
756         return timer && timer.callAt >= from && timer.callAt <= to;
757     }
759     function mirrorDateProperties(target, source) {
760         var prop;
761         for (prop in source) {
762             if (source.hasOwnProperty(prop)) {
763                 target[prop] = source[prop];
764             }
765         }
767         // set special now implementation
768         if (source.now) {
769             target.now = function now() {
770                 return target.clock.now;
771             };
772         } else {
773             delete target.now;
774         }
776         // set special toSource implementation
777         if (source.toSource) {
778             target.toSource = function toSource() {
779                 return source.toSource();
780             };
781         } else {
782             delete target.toSource;
783         }
785         // set special toString implementation
786         target.toString = function toString() {
787             return source.toString();
788         };
790         target.prototype = source.prototype;
791         target.parse = source.parse;
792         target.UTC = source.UTC;
793         target.prototype.toUTCString = source.prototype.toUTCString;
795         return target;
796     }
798     function createDate() {
799         function ClockDate(year, month, date, hour, minute, second, ms) {
800             // Defensive and verbose to avoid potential harm in passing
801             // explicit undefined when user does not pass argument
802             switch (arguments.length) {
803             case 0:
804                 return new NativeDate(ClockDate.clock.now);
805             case 1:
806                 return new NativeDate(year);
807             case 2:
808                 return new NativeDate(year, month);
809             case 3:
810                 return new NativeDate(year, month, date);
811             case 4:
812                 return new NativeDate(year, month, date, hour);
813             case 5:
814                 return new NativeDate(year, month, date, hour, minute);
815             case 6:
816                 return new NativeDate(year, month, date, hour, minute, second);
817             default:
818                 return new NativeDate(year, month, date, hour, minute, second, ms);
819             }
820         }
822         return mirrorDateProperties(ClockDate, NativeDate);
823     }
825     function addTimer(clock, timer) {
826         if (timer.func === undefined) {
827             throw new Error("Callback must be provided to timer calls");
828         }
830         if (!clock.timers) {
831             clock.timers = {};
832         }
834         timer.id = uniqueTimerId++;
835         timer.createdAt = clock.now;
836         timer.callAt = clock.now + (timer.delay || (clock.duringTick ? 1 : 0));
838         clock.timers[timer.id] = timer;
840         if (addTimerReturnsObject) {
841             return {
842                 id: timer.id,
843                 ref: NOOP,
844                 unref: NOOP
845             };
846         }
848         return timer.id;
849     }
852     function compareTimers(a, b) {
853         // Sort first by absolute timing
854         if (a.callAt < b.callAt) {
855             return -1;
856         }
857         if (a.callAt > b.callAt) {
858             return 1;
859         }
861         // Sort next by immediate, immediate timers take precedence
862         if (a.immediate && !b.immediate) {
863             return -1;
864         }
865         if (!a.immediate && b.immediate) {
866             return 1;
867         }
869         // Sort next by creation time, earlier-created timers take precedence
870         if (a.createdAt < b.createdAt) {
871             return -1;
872         }
873         if (a.createdAt > b.createdAt) {
874             return 1;
875         }
877         // Sort next by id, lower-id timers take precedence
878         if (a.id < b.id) {
879             return -1;
880         }
881         if (a.id > b.id) {
882             return 1;
883         }
885         // As timer ids are unique, no fallback `0` is necessary
886     }
888     function firstTimerInRange(clock, from, to) {
889         var timers = clock.timers,
890             timer = null,
891             id,
892             isInRange;
894         for (id in timers) {
895             if (timers.hasOwnProperty(id)) {
896                 isInRange = inRange(from, to, timers[id]);
898                 if (isInRange && (!timer || compareTimers(timer, timers[id]) === 1)) {
899                     timer = timers[id];
900                 }
901             }
902         }
904         return timer;
905     }
907     function firstTimer(clock) {
908         var timers = clock.timers,
909             timer = null,
910             id;
912         for (id in timers) {
913             if (timers.hasOwnProperty(id)) {
914                 if (!timer || compareTimers(timer, timers[id]) === 1) {
915                     timer = timers[id];
916                 }
917             }
918         }
920         return timer;
921     }
923     function callTimer(clock, timer) {
924         var exception;
926         if (typeof timer.interval === "number") {
927             clock.timers[timer.id].callAt += timer.interval;
928         } else {
929             delete clock.timers[timer.id];
930         }
932         try {
933             if (typeof timer.func === "function") {
934                 timer.func.apply(null, timer.args);
935             } else {
936                 eval(timer.func);
937             }
938         } catch (e) {
939             exception = e;
940         }
942         if (!clock.timers[timer.id]) {
943             if (exception) {
944                 throw exception;
945             }
946             return;
947         }
949         if (exception) {
950             throw exception;
951         }
952     }
954     function timerType(timer) {
955         if (timer.immediate) {
956             return "Immediate";
957         } else if (typeof timer.interval !== "undefined") {
958             return "Interval";
959         } else {
960             return "Timeout";
961         }
962     }
964     function clearTimer(clock, timerId, ttype) {
965         if (!timerId) {
966             // null appears to be allowed in most browsers, and appears to be
967             // relied upon by some libraries, like Bootstrap carousel
968             return;
969         }
971         if (!clock.timers) {
972             clock.timers = [];
973         }
975         // in Node, timerId is an object with .ref()/.unref(), and
976         // its .id field is the actual timer id.
977         if (typeof timerId === "object") {
978             timerId = timerId.id;
979         }
981         if (clock.timers.hasOwnProperty(timerId)) {
982             // check that the ID matches a timer of the correct type
983             var timer = clock.timers[timerId];
984             if (timerType(timer) === ttype) {
985                 delete clock.timers[timerId];
986             } else {
987                                 throw new Error("Cannot clear timer: timer created with set" + ttype + "() but cleared with clear" + timerType(timer) + "()");
988                         }
989         }
990     }
992     function uninstall(clock, target) {
993         var method,
994             i,
995             l;
997         for (i = 0, l = clock.methods.length; i < l; i++) {
998             method = clock.methods[i];
1000             if (target[method].hadOwnProperty) {
1001                 target[method] = clock["_" + method];
1002             } else {
1003                 try {
1004                     delete target[method];
1005                 } catch (ignore) {}
1006             }
1007         }
1009         // Prevent multiple executions which will completely remove these props
1010         clock.methods = [];
1011     }
1013     function hijackMethod(target, method, clock) {
1014         var prop;
1016         clock[method].hadOwnProperty = Object.prototype.hasOwnProperty.call(target, method);
1017         clock["_" + method] = target[method];
1019         if (method === "Date") {
1020             var date = mirrorDateProperties(clock[method], target[method]);
1021             target[method] = date;
1022         } else {
1023             target[method] = function () {
1024                 return clock[method].apply(clock, arguments);
1025             };
1027             for (prop in clock[method]) {
1028                 if (clock[method].hasOwnProperty(prop)) {
1029                     target[method][prop] = clock[method][prop];
1030                 }
1031             }
1032         }
1034         target[method].clock = clock;
1035     }
1037     var timers = {
1038         setTimeout: setTimeout,
1039         clearTimeout: clearTimeout,
1040         setImmediate: global.setImmediate,
1041         clearImmediate: global.clearImmediate,
1042         setInterval: setInterval,
1043         clearInterval: clearInterval,
1044         Date: Date
1045     };
1047     var keys = Object.keys || function (obj) {
1048         var ks = [],
1049             key;
1051         for (key in obj) {
1052             if (obj.hasOwnProperty(key)) {
1053                 ks.push(key);
1054             }
1055         }
1057         return ks;
1058     };
1060     exports.timers = timers;
1062     function createClock(now) {
1063         var clock = {
1064             now: getEpoch(now),
1065             timeouts: {},
1066             Date: createDate()
1067         };
1069         clock.Date.clock = clock;
1071         clock.setTimeout = function setTimeout(func, timeout) {
1072             return addTimer(clock, {
1073                 func: func,
1074                 args: Array.prototype.slice.call(arguments, 2),
1075                 delay: timeout
1076             });
1077         };
1079         clock.clearTimeout = function clearTimeout(timerId) {
1080             return clearTimer(clock, timerId, "Timeout");
1081         };
1083         clock.setInterval = function setInterval(func, timeout) {
1084             return addTimer(clock, {
1085                 func: func,
1086                 args: Array.prototype.slice.call(arguments, 2),
1087                 delay: timeout,
1088                 interval: timeout
1089             });
1090         };
1092         clock.clearInterval = function clearInterval(timerId) {
1093             return clearTimer(clock, timerId, "Interval");
1094         };
1096         clock.setImmediate = function setImmediate(func) {
1097             return addTimer(clock, {
1098                 func: func,
1099                 args: Array.prototype.slice.call(arguments, 1),
1100                 immediate: true
1101             });
1102         };
1104         clock.clearImmediate = function clearImmediate(timerId) {
1105             return clearTimer(clock, timerId, "Immediate");
1106         };
1108         clock.tick = function tick(ms) {
1109             ms = typeof ms === "number" ? ms : parseTime(ms);
1110             var tickFrom = clock.now, tickTo = clock.now + ms, previous = clock.now;
1111             var timer = firstTimerInRange(clock, tickFrom, tickTo);
1112             var oldNow;
1114             clock.duringTick = true;
1116             var firstException;
1117             while (timer && tickFrom <= tickTo) {
1118                 if (clock.timers[timer.id]) {
1119                     tickFrom = clock.now = timer.callAt;
1120                     try {
1121                         oldNow = clock.now;
1122                         callTimer(clock, timer);
1123                         // compensate for any setSystemTime() call during timer callback
1124                         if (oldNow !== clock.now) {
1125                             tickFrom += clock.now - oldNow;
1126                             tickTo += clock.now - oldNow;
1127                             previous += clock.now - oldNow;
1128                         }
1129                     } catch (e) {
1130                         firstException = firstException || e;
1131                     }
1132                 }
1134                 timer = firstTimerInRange(clock, previous, tickTo);
1135                 previous = tickFrom;
1136             }
1138             clock.duringTick = false;
1139             clock.now = tickTo;
1141             if (firstException) {
1142                 throw firstException;
1143             }
1145             return clock.now;
1146         };
1148         clock.next = function next() {
1149             var timer = firstTimer(clock);
1150             if (!timer) {
1151                 return clock.now;
1152             }
1154             clock.duringTick = true;
1155             try {
1156                 clock.now = timer.callAt;
1157                 callTimer(clock, timer);
1158                 return clock.now;
1159             } finally {
1160                 clock.duringTick = false;
1161             }
1162         };
1164         clock.reset = function reset() {
1165             clock.timers = {};
1166         };
1168         clock.setSystemTime = function setSystemTime(now) {
1169             // determine time difference
1170             var newNow = getEpoch(now);
1171             var difference = newNow - clock.now;
1173             // update 'system clock'
1174             clock.now = newNow;
1176             // update timers and intervals to keep them stable
1177             for (var id in clock.timers) {
1178                 if (clock.timers.hasOwnProperty(id)) {
1179                     var timer = clock.timers[id];
1180                     timer.createdAt += difference;
1181                     timer.callAt += difference;
1182                 }
1183             }
1184         };
1186         return clock;
1187     }
1188     exports.createClock = createClock;
1190     exports.install = function install(target, now, toFake) {
1191         var i,
1192             l;
1194         if (typeof target === "number") {
1195             toFake = now;
1196             now = target;
1197             target = null;
1198         }
1200         if (!target) {
1201             target = global;
1202         }
1204         var clock = createClock(now);
1206         clock.uninstall = function () {
1207             uninstall(clock, target);
1208         };
1210         clock.methods = toFake || [];
1212         if (clock.methods.length === 0) {
1213             clock.methods = keys(timers);
1214         }
1216         for (i = 0, l = clock.methods.length; i < l; i++) {
1217             hijackMethod(target, clock.methods[i], clock);
1218         }
1220         return clock;
1221     };
1223 }(global || this));
1225 }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
1226 },{}]},{},[1])(1)
1228   })();
1229   var define;
1231  * Sinon core utilities. For internal use only.
1233  * @author Christian Johansen (christian@cjohansen.no)
1234  * @license BSD
1236  * Copyright (c) 2010-2013 Christian Johansen
1237  */
1238 var sinon = (function () {
1239 "use strict";
1240  // eslint-disable-line no-unused-vars
1241     
1242     var sinonModule;
1243     var isNode = typeof module !== "undefined" && module.exports && typeof require === "function";
1244     var isAMD = typeof define === "function" && typeof define.amd === "object" && define.amd;
1246     function loadDependencies(require, exports, module) {
1247         sinonModule = module.exports = require("./sinon/util/core");
1248         require("./sinon/extend");
1249         require("./sinon/walk");
1250         require("./sinon/typeOf");
1251         require("./sinon/times_in_words");
1252         require("./sinon/spy");
1253         require("./sinon/call");
1254         require("./sinon/behavior");
1255         require("./sinon/stub");
1256         require("./sinon/mock");
1257         require("./sinon/collection");
1258         require("./sinon/assert");
1259         require("./sinon/sandbox");
1260         require("./sinon/test");
1261         require("./sinon/test_case");
1262         require("./sinon/match");
1263         require("./sinon/format");
1264         require("./sinon/log_error");
1265     }
1267     if (isAMD) {
1268         define(loadDependencies);
1269     } else if (isNode) {
1270         loadDependencies(require, module.exports, module);
1271         sinonModule = module.exports;
1272     } else {
1273         sinonModule = {};
1274     }
1276     return sinonModule;
1277 }());
1280  * @depend ../../sinon.js
1281  */
1283  * Sinon core utilities. For internal use only.
1285  * @author Christian Johansen (christian@cjohansen.no)
1286  * @license BSD
1288  * Copyright (c) 2010-2013 Christian Johansen
1289  */
1290 (function (sinonGlobal) {
1291     
1292     var div = typeof document !== "undefined" && document.createElement("div");
1293     var hasOwn = Object.prototype.hasOwnProperty;
1295     function isDOMNode(obj) {
1296         var success = false;
1298         try {
1299             obj.appendChild(div);
1300             success = div.parentNode === obj;
1301         } catch (e) {
1302             return false;
1303         } finally {
1304             try {
1305                 obj.removeChild(div);
1306             } catch (e) {
1307                 // Remove failed, not much we can do about that
1308             }
1309         }
1311         return success;
1312     }
1314     function isElement(obj) {
1315         return div && obj && obj.nodeType === 1 && isDOMNode(obj);
1316     }
1318     function isFunction(obj) {
1319         return typeof obj === "function" || !!(obj && obj.constructor && obj.call && obj.apply);
1320     }
1322     function isReallyNaN(val) {
1323         return typeof val === "number" && isNaN(val);
1324     }
1326     function mirrorProperties(target, source) {
1327         for (var prop in source) {
1328             if (!hasOwn.call(target, prop)) {
1329                 target[prop] = source[prop];
1330             }
1331         }
1332     }
1334     function isRestorable(obj) {
1335         return typeof obj === "function" && typeof obj.restore === "function" && obj.restore.sinon;
1336     }
1338     // Cheap way to detect if we have ES5 support.
1339     var hasES5Support = "keys" in Object;
1341     function makeApi(sinon) {
1342         sinon.wrapMethod = function wrapMethod(object, property, method) {
1343             if (!object) {
1344                 throw new TypeError("Should wrap property of object");
1345             }
1347             if (typeof method !== "function" && typeof method !== "object") {
1348                 throw new TypeError("Method wrapper should be a function or a property descriptor");
1349             }
1351             function checkWrappedMethod(wrappedMethod) {
1352                 var error;
1354                 if (!isFunction(wrappedMethod)) {
1355                     error = new TypeError("Attempted to wrap " + (typeof wrappedMethod) + " property " +
1356                                         property + " as function");
1357                 } else if (wrappedMethod.restore && wrappedMethod.restore.sinon) {
1358                     error = new TypeError("Attempted to wrap " + property + " which is already wrapped");
1359                 } else if (wrappedMethod.calledBefore) {
1360                     var verb = wrappedMethod.returns ? "stubbed" : "spied on";
1361                     error = new TypeError("Attempted to wrap " + property + " which is already " + verb);
1362                 }
1364                 if (error) {
1365                     if (wrappedMethod && wrappedMethod.stackTrace) {
1366                         error.stack += "\n--------------\n" + wrappedMethod.stackTrace;
1367                     }
1368                     throw error;
1369                 }
1370             }
1372             var error, wrappedMethod, i;
1374             // IE 8 does not support hasOwnProperty on the window object and Firefox has a problem
1375             // when using hasOwn.call on objects from other frames.
1376             var owned = object.hasOwnProperty ? object.hasOwnProperty(property) : hasOwn.call(object, property);
1378             if (hasES5Support) {
1379                 var methodDesc = (typeof method === "function") ? {value: method} : method;
1380                 var wrappedMethodDesc = sinon.getPropertyDescriptor(object, property);
1382                 if (!wrappedMethodDesc) {
1383                     error = new TypeError("Attempted to wrap " + (typeof wrappedMethod) + " property " +
1384                                         property + " as function");
1385                 } else if (wrappedMethodDesc.restore && wrappedMethodDesc.restore.sinon) {
1386                     error = new TypeError("Attempted to wrap " + property + " which is already wrapped");
1387                 }
1388                 if (error) {
1389                     if (wrappedMethodDesc && wrappedMethodDesc.stackTrace) {
1390                         error.stack += "\n--------------\n" + wrappedMethodDesc.stackTrace;
1391                     }
1392                     throw error;
1393                 }
1395                 var types = sinon.objectKeys(methodDesc);
1396                 for (i = 0; i < types.length; i++) {
1397                     wrappedMethod = wrappedMethodDesc[types[i]];
1398                     checkWrappedMethod(wrappedMethod);
1399                 }
1401                 mirrorProperties(methodDesc, wrappedMethodDesc);
1402                 for (i = 0; i < types.length; i++) {
1403                     mirrorProperties(methodDesc[types[i]], wrappedMethodDesc[types[i]]);
1404                 }
1405                 Object.defineProperty(object, property, methodDesc);
1406             } else {
1407                 wrappedMethod = object[property];
1408                 checkWrappedMethod(wrappedMethod);
1409                 object[property] = method;
1410                 method.displayName = property;
1411             }
1413             method.displayName = property;
1415             // Set up a stack trace which can be used later to find what line of
1416             // code the original method was created on.
1417             method.stackTrace = (new Error("Stack Trace for original")).stack;
1419             method.restore = function () {
1420                 // For prototype properties try to reset by delete first.
1421                 // If this fails (ex: localStorage on mobile safari) then force a reset
1422                 // via direct assignment.
1423                 if (!owned) {
1424                     // In some cases `delete` may throw an error
1425                     try {
1426                         delete object[property];
1427                     } catch (e) {} // eslint-disable-line no-empty
1428                     // For native code functions `delete` fails without throwing an error
1429                     // on Chrome < 43, PhantomJS, etc.
1430                 } else if (hasES5Support) {
1431                     Object.defineProperty(object, property, wrappedMethodDesc);
1432                 }
1434                 // Use strict equality comparison to check failures then force a reset
1435                 // via direct assignment.
1436                 if (object[property] === method) {
1437                     object[property] = wrappedMethod;
1438                 }
1439             };
1441             method.restore.sinon = true;
1443             if (!hasES5Support) {
1444                 mirrorProperties(method, wrappedMethod);
1445             }
1447             return method;
1448         };
1450         sinon.create = function create(proto) {
1451             var F = function () {};
1452             F.prototype = proto;
1453             return new F();
1454         };
1456         sinon.deepEqual = function deepEqual(a, b) {
1457             if (sinon.match && sinon.match.isMatcher(a)) {
1458                 return a.test(b);
1459             }
1461             if (typeof a !== "object" || typeof b !== "object") {
1462                 return isReallyNaN(a) && isReallyNaN(b) || a === b;
1463             }
1465             if (isElement(a) || isElement(b)) {
1466                 return a === b;
1467             }
1469             if (a === b) {
1470                 return true;
1471             }
1473             if ((a === null && b !== null) || (a !== null && b === null)) {
1474                 return false;
1475             }
1477             if (a instanceof RegExp && b instanceof RegExp) {
1478                 return (a.source === b.source) && (a.global === b.global) &&
1479                     (a.ignoreCase === b.ignoreCase) && (a.multiline === b.multiline);
1480             }
1482             var aString = Object.prototype.toString.call(a);
1483             if (aString !== Object.prototype.toString.call(b)) {
1484                 return false;
1485             }
1487             if (aString === "[object Date]") {
1488                 return a.valueOf() === b.valueOf();
1489             }
1491             var prop;
1492             var aLength = 0;
1493             var bLength = 0;
1495             if (aString === "[object Array]" && a.length !== b.length) {
1496                 return false;
1497             }
1499             for (prop in a) {
1500                 if (a.hasOwnProperty(prop)) {
1501                     aLength += 1;
1503                     if (!(prop in b)) {
1504                         return false;
1505                     }
1507                     if (!deepEqual(a[prop], b[prop])) {
1508                         return false;
1509                     }
1510                 }
1511             }
1513             for (prop in b) {
1514                 if (b.hasOwnProperty(prop)) {
1515                     bLength += 1;
1516                 }
1517             }
1519             return aLength === bLength;
1520         };
1522         sinon.functionName = function functionName(func) {
1523             var name = func.displayName || func.name;
1525             // Use function decomposition as a last resort to get function
1526             // name. Does not rely on function decomposition to work - if it
1527             // doesn't debugging will be slightly less informative
1528             // (i.e. toString will say 'spy' rather than 'myFunc').
1529             if (!name) {
1530                 var matches = func.toString().match(/function ([^\s\(]+)/);
1531                 name = matches && matches[1];
1532             }
1534             return name;
1535         };
1537         sinon.functionToString = function toString() {
1538             if (this.getCall && this.callCount) {
1539                 var thisValue,
1540                     prop;
1541                 var i = this.callCount;
1543                 while (i--) {
1544                     thisValue = this.getCall(i).thisValue;
1546                     for (prop in thisValue) {
1547                         if (thisValue[prop] === this) {
1548                             return prop;
1549                         }
1550                     }
1551                 }
1552             }
1554             return this.displayName || "sinon fake";
1555         };
1557         sinon.objectKeys = function objectKeys(obj) {
1558             if (obj !== Object(obj)) {
1559                 throw new TypeError("sinon.objectKeys called on a non-object");
1560             }
1562             var keys = [];
1563             var key;
1564             for (key in obj) {
1565                 if (hasOwn.call(obj, key)) {
1566                     keys.push(key);
1567                 }
1568             }
1570             return keys;
1571         };
1573         sinon.getPropertyDescriptor = function getPropertyDescriptor(object, property) {
1574             var proto = object;
1575             var descriptor;
1577             while (proto && !(descriptor = Object.getOwnPropertyDescriptor(proto, property))) {
1578                 proto = Object.getPrototypeOf(proto);
1579             }
1580             return descriptor;
1581         };
1583         sinon.getConfig = function (custom) {
1584             var config = {};
1585             custom = custom || {};
1586             var defaults = sinon.defaultConfig;
1588             for (var prop in defaults) {
1589                 if (defaults.hasOwnProperty(prop)) {
1590                     config[prop] = custom.hasOwnProperty(prop) ? custom[prop] : defaults[prop];
1591                 }
1592             }
1594             return config;
1595         };
1597         sinon.defaultConfig = {
1598             injectIntoThis: true,
1599             injectInto: null,
1600             properties: ["spy", "stub", "mock", "clock", "server", "requests"],
1601             useFakeTimers: true,
1602             useFakeServer: true
1603         };
1605         sinon.timesInWords = function timesInWords(count) {
1606             return count === 1 && "once" ||
1607                 count === 2 && "twice" ||
1608                 count === 3 && "thrice" ||
1609                 (count || 0) + " times";
1610         };
1612         sinon.calledInOrder = function (spies) {
1613             for (var i = 1, l = spies.length; i < l; i++) {
1614                 if (!spies[i - 1].calledBefore(spies[i]) || !spies[i].called) {
1615                     return false;
1616                 }
1617             }
1619             return true;
1620         };
1622         sinon.orderByFirstCall = function (spies) {
1623             return spies.sort(function (a, b) {
1624                 // uuid, won't ever be equal
1625                 var aCall = a.getCall(0);
1626                 var bCall = b.getCall(0);
1627                 var aId = aCall && aCall.callId || -1;
1628                 var bId = bCall && bCall.callId || -1;
1630                 return aId < bId ? -1 : 1;
1631             });
1632         };
1634         sinon.createStubInstance = function (constructor) {
1635             if (typeof constructor !== "function") {
1636                 throw new TypeError("The constructor should be a function.");
1637             }
1638             return sinon.stub(sinon.create(constructor.prototype));
1639         };
1641         sinon.restore = function (object) {
1642             if (object !== null && typeof object === "object") {
1643                 for (var prop in object) {
1644                     if (isRestorable(object[prop])) {
1645                         object[prop].restore();
1646                     }
1647                 }
1648             } else if (isRestorable(object)) {
1649                 object.restore();
1650             }
1651         };
1653         return sinon;
1654     }
1656     var isNode = typeof module !== "undefined" && module.exports && typeof require === "function";
1657     var isAMD = typeof define === "function" && typeof define.amd === "object" && define.amd;
1659     function loadDependencies(require, exports) {
1660         makeApi(exports);
1661     }
1663     if (isAMD) {
1664         define(loadDependencies);
1665         return;
1666     }
1668     if (isNode) {
1669         loadDependencies(require, module.exports, module);
1670         return;
1671     }
1673     if (sinonGlobal) {
1674         makeApi(sinonGlobal);
1675     }
1677     typeof sinon === "object" && sinon // eslint-disable-line no-undef
1681  * @depend util/core.js
1682  */
1683 (function (sinonGlobal) {
1684     
1685     function makeApi(sinon) {
1687         // Adapted from https://developer.mozilla.org/en/docs/ECMAScript_DontEnum_attribute#JScript_DontEnum_Bug
1688         var hasDontEnumBug = (function () {
1689             var obj = {
1690                 constructor: function () {
1691                     return "0";
1692                 },
1693                 toString: function () {
1694                     return "1";
1695                 },
1696                 valueOf: function () {
1697                     return "2";
1698                 },
1699                 toLocaleString: function () {
1700                     return "3";
1701                 },
1702                 prototype: function () {
1703                     return "4";
1704                 },
1705                 isPrototypeOf: function () {
1706                     return "5";
1707                 },
1708                 propertyIsEnumerable: function () {
1709                     return "6";
1710                 },
1711                 hasOwnProperty: function () {
1712                     return "7";
1713                 },
1714                 length: function () {
1715                     return "8";
1716                 },
1717                 unique: function () {
1718                     return "9";
1719                 }
1720             };
1722             var result = [];
1723             for (var prop in obj) {
1724                 if (obj.hasOwnProperty(prop)) {
1725                     result.push(obj[prop]());
1726                 }
1727             }
1728             return result.join("") !== "0123456789";
1729         })();
1731         /* Public: Extend target in place with all (own) properties from sources in-order. Thus, last source will
1732          *         override properties in previous sources.
1733          *
1734          * target - The Object to extend
1735          * sources - Objects to copy properties from.
1736          *
1737          * Returns the extended target
1738          */
1739         function extend(target /*, sources */) {
1740             var sources = Array.prototype.slice.call(arguments, 1);
1741             var source, i, prop;
1743             for (i = 0; i < sources.length; i++) {
1744                 source = sources[i];
1746                 for (prop in source) {
1747                     if (source.hasOwnProperty(prop)) {
1748                         target[prop] = source[prop];
1749                     }
1750                 }
1752                 // Make sure we copy (own) toString method even when in JScript with DontEnum bug
1753                 // See https://developer.mozilla.org/en/docs/ECMAScript_DontEnum_attribute#JScript_DontEnum_Bug
1754                 if (hasDontEnumBug && source.hasOwnProperty("toString") && source.toString !== target.toString) {
1755                     target.toString = source.toString;
1756                 }
1757             }
1759             return target;
1760         }
1762         sinon.extend = extend;
1763         return sinon.extend;
1764     }
1766     function loadDependencies(require, exports, module) {
1767         var sinon = require("./util/core");
1768         module.exports = makeApi(sinon);
1769     }
1771     var isNode = typeof module !== "undefined" && module.exports && typeof require === "function";
1772     var isAMD = typeof define === "function" && typeof define.amd === "object" && define.amd;
1774     if (isAMD) {
1775         define(loadDependencies);
1776         return;
1777     }
1779     if (isNode) {
1780         loadDependencies(require, module.exports, module);
1781         return;
1782     }
1784     if (sinonGlobal) {
1785         makeApi(sinonGlobal);
1786     }
1788     typeof sinon === "object" && sinon // eslint-disable-line no-undef
1792  * @depend util/core.js
1793  */
1794 (function (sinonGlobal) {
1795     
1796     function makeApi(sinon) {
1798         function timesInWords(count) {
1799             switch (count) {
1800                 case 1:
1801                     return "once";
1802                 case 2:
1803                     return "twice";
1804                 case 3:
1805                     return "thrice";
1806                 default:
1807                     return (count || 0) + " times";
1808             }
1809         }
1811         sinon.timesInWords = timesInWords;
1812         return sinon.timesInWords;
1813     }
1815     function loadDependencies(require, exports, module) {
1816         var core = require("./util/core");
1817         module.exports = makeApi(core);
1818     }
1820     var isNode = typeof module !== "undefined" && module.exports && typeof require === "function";
1821     var isAMD = typeof define === "function" && typeof define.amd === "object" && define.amd;
1823     if (isAMD) {
1824         define(loadDependencies);
1825         return;
1826     }
1828     if (isNode) {
1829         loadDependencies(require, module.exports, module);
1830         return;
1831     }
1833     if (sinonGlobal) {
1834         makeApi(sinonGlobal);
1835     }
1837     typeof sinon === "object" && sinon // eslint-disable-line no-undef
1841  * @depend util/core.js
1842  */
1844  * Format functions
1846  * @author Christian Johansen (christian@cjohansen.no)
1847  * @license BSD
1849  * Copyright (c) 2010-2014 Christian Johansen
1850  */
1851 (function (sinonGlobal) {
1852     
1853     function makeApi(sinon) {
1854         function typeOf(value) {
1855             if (value === null) {
1856                 return "null";
1857             } else if (value === undefined) {
1858                 return "undefined";
1859             }
1860             var string = Object.prototype.toString.call(value);
1861             return string.substring(8, string.length - 1).toLowerCase();
1862         }
1864         sinon.typeOf = typeOf;
1865         return sinon.typeOf;
1866     }
1868     function loadDependencies(require, exports, module) {
1869         var core = require("./util/core");
1870         module.exports = makeApi(core);
1871     }
1873     var isNode = typeof module !== "undefined" && module.exports && typeof require === "function";
1874     var isAMD = typeof define === "function" && typeof define.amd === "object" && define.amd;
1876     if (isAMD) {
1877         define(loadDependencies);
1878         return;
1879     }
1881     if (isNode) {
1882         loadDependencies(require, module.exports, module);
1883         return;
1884     }
1886     if (sinonGlobal) {
1887         makeApi(sinonGlobal);
1888     }
1890     typeof sinon === "object" && sinon // eslint-disable-line no-undef
1894  * @depend util/core.js
1895  * @depend typeOf.js
1896  */
1897 /*jslint eqeqeq: false, onevar: false, plusplus: false*/
1898 /*global module, require, sinon*/
1900  * Match functions
1902  * @author Maximilian Antoni (mail@maxantoni.de)
1903  * @license BSD
1905  * Copyright (c) 2012 Maximilian Antoni
1906  */
1907 (function (sinonGlobal) {
1908     
1909     function makeApi(sinon) {
1910         function assertType(value, type, name) {
1911             var actual = sinon.typeOf(value);
1912             if (actual !== type) {
1913                 throw new TypeError("Expected type of " + name + " to be " +
1914                     type + ", but was " + actual);
1915             }
1916         }
1918         var matcher = {
1919             toString: function () {
1920                 return this.message;
1921             }
1922         };
1924         function isMatcher(object) {
1925             return matcher.isPrototypeOf(object);
1926         }
1928         function matchObject(expectation, actual) {
1929             if (actual === null || actual === undefined) {
1930                 return false;
1931             }
1932             for (var key in expectation) {
1933                 if (expectation.hasOwnProperty(key)) {
1934                     var exp = expectation[key];
1935                     var act = actual[key];
1936                     if (isMatcher(exp)) {
1937                         if (!exp.test(act)) {
1938                             return false;
1939                         }
1940                     } else if (sinon.typeOf(exp) === "object") {
1941                         if (!matchObject(exp, act)) {
1942                             return false;
1943                         }
1944                     } else if (!sinon.deepEqual(exp, act)) {
1945                         return false;
1946                     }
1947                 }
1948             }
1949             return true;
1950         }
1952         function match(expectation, message) {
1953             var m = sinon.create(matcher);
1954             var type = sinon.typeOf(expectation);
1955             switch (type) {
1956             case "object":
1957                 if (typeof expectation.test === "function") {
1958                     m.test = function (actual) {
1959                         return expectation.test(actual) === true;
1960                     };
1961                     m.message = "match(" + sinon.functionName(expectation.test) + ")";
1962                     return m;
1963                 }
1964                 var str = [];
1965                 for (var key in expectation) {
1966                     if (expectation.hasOwnProperty(key)) {
1967                         str.push(key + ": " + expectation[key]);
1968                     }
1969                 }
1970                 m.test = function (actual) {
1971                     return matchObject(expectation, actual);
1972                 };
1973                 m.message = "match(" + str.join(", ") + ")";
1974                 break;
1975             case "number":
1976                 m.test = function (actual) {
1977                     // we need type coercion here
1978                     return expectation == actual; // eslint-disable-line eqeqeq
1979                 };
1980                 break;
1981             case "string":
1982                 m.test = function (actual) {
1983                     if (typeof actual !== "string") {
1984                         return false;
1985                     }
1986                     return actual.indexOf(expectation) !== -1;
1987                 };
1988                 m.message = "match(\"" + expectation + "\")";
1989                 break;
1990             case "regexp":
1991                 m.test = function (actual) {
1992                     if (typeof actual !== "string") {
1993                         return false;
1994                     }
1995                     return expectation.test(actual);
1996                 };
1997                 break;
1998             case "function":
1999                 m.test = expectation;
2000                 if (message) {
2001                     m.message = message;
2002                 } else {
2003                     m.message = "match(" + sinon.functionName(expectation) + ")";
2004                 }
2005                 break;
2006             default:
2007                 m.test = function (actual) {
2008                     return sinon.deepEqual(expectation, actual);
2009                 };
2010             }
2011             if (!m.message) {
2012                 m.message = "match(" + expectation + ")";
2013             }
2014             return m;
2015         }
2017         matcher.or = function (m2) {
2018             if (!arguments.length) {
2019                 throw new TypeError("Matcher expected");
2020             } else if (!isMatcher(m2)) {
2021                 m2 = match(m2);
2022             }
2023             var m1 = this;
2024             var or = sinon.create(matcher);
2025             or.test = function (actual) {
2026                 return m1.test(actual) || m2.test(actual);
2027             };
2028             or.message = m1.message + ".or(" + m2.message + ")";
2029             return or;
2030         };
2032         matcher.and = function (m2) {
2033             if (!arguments.length) {
2034                 throw new TypeError("Matcher expected");
2035             } else if (!isMatcher(m2)) {
2036                 m2 = match(m2);
2037             }
2038             var m1 = this;
2039             var and = sinon.create(matcher);
2040             and.test = function (actual) {
2041                 return m1.test(actual) && m2.test(actual);
2042             };
2043             and.message = m1.message + ".and(" + m2.message + ")";
2044             return and;
2045         };
2047         match.isMatcher = isMatcher;
2049         match.any = match(function () {
2050             return true;
2051         }, "any");
2053         match.defined = match(function (actual) {
2054             return actual !== null && actual !== undefined;
2055         }, "defined");
2057         match.truthy = match(function (actual) {
2058             return !!actual;
2059         }, "truthy");
2061         match.falsy = match(function (actual) {
2062             return !actual;
2063         }, "falsy");
2065         match.same = function (expectation) {
2066             return match(function (actual) {
2067                 return expectation === actual;
2068             }, "same(" + expectation + ")");
2069         };
2071         match.typeOf = function (type) {
2072             assertType(type, "string", "type");
2073             return match(function (actual) {
2074                 return sinon.typeOf(actual) === type;
2075             }, "typeOf(\"" + type + "\")");
2076         };
2078         match.instanceOf = function (type) {
2079             assertType(type, "function", "type");
2080             return match(function (actual) {
2081                 return actual instanceof type;
2082             }, "instanceOf(" + sinon.functionName(type) + ")");
2083         };
2085         function createPropertyMatcher(propertyTest, messagePrefix) {
2086             return function (property, value) {
2087                 assertType(property, "string", "property");
2088                 var onlyProperty = arguments.length === 1;
2089                 var message = messagePrefix + "(\"" + property + "\"";
2090                 if (!onlyProperty) {
2091                     message += ", " + value;
2092                 }
2093                 message += ")";
2094                 return match(function (actual) {
2095                     if (actual === undefined || actual === null ||
2096                             !propertyTest(actual, property)) {
2097                         return false;
2098                     }
2099                     return onlyProperty || sinon.deepEqual(value, actual[property]);
2100                 }, message);
2101             };
2102         }
2104         match.has = createPropertyMatcher(function (actual, property) {
2105             if (typeof actual === "object") {
2106                 return property in actual;
2107             }
2108             return actual[property] !== undefined;
2109         }, "has");
2111         match.hasOwn = createPropertyMatcher(function (actual, property) {
2112             return actual.hasOwnProperty(property);
2113         }, "hasOwn");
2115         match.bool = match.typeOf("boolean");
2116         match.number = match.typeOf("number");
2117         match.string = match.typeOf("string");
2118         match.object = match.typeOf("object");
2119         match.func = match.typeOf("function");
2120         match.array = match.typeOf("array");
2121         match.regexp = match.typeOf("regexp");
2122         match.date = match.typeOf("date");
2124         sinon.match = match;
2125         return match;
2126     }
2128     var isNode = typeof module !== "undefined" && module.exports && typeof require === "function";
2129     var isAMD = typeof define === "function" && typeof define.amd === "object" && define.amd;
2131     function loadDependencies(require, exports, module) {
2132         var sinon = require("./util/core");
2133         require("./typeOf");
2134         module.exports = makeApi(sinon);
2135     }
2137     if (isAMD) {
2138         define(loadDependencies);
2139         return;
2140     }
2142     if (isNode) {
2143         loadDependencies(require, module.exports, module);
2144         return;
2145     }
2147     if (sinonGlobal) {
2148         makeApi(sinonGlobal);
2149     }
2151     typeof sinon === "object" && sinon // eslint-disable-line no-undef
2155  * @depend util/core.js
2156  */
2158  * Format functions
2160  * @author Christian Johansen (christian@cjohansen.no)
2161  * @license BSD
2163  * Copyright (c) 2010-2014 Christian Johansen
2164  */
2165 (function (sinonGlobal, formatio) {
2166     
2167     function makeApi(sinon) {
2168         function valueFormatter(value) {
2169             return "" + value;
2170         }
2172         function getFormatioFormatter() {
2173             var formatter = formatio.configure({
2174                     quoteStrings: false,
2175                     limitChildrenCount: 250
2176                 });
2178             function format() {
2179                 return formatter.ascii.apply(formatter, arguments);
2180             }
2182             return format;
2183         }
2185         function getNodeFormatter() {
2186             try {
2187                 var util = require("util");
2188             } catch (e) {
2189                 /* Node, but no util module - would be very old, but better safe than sorry */
2190             }
2192             function format(v) {
2193                 var isObjectWithNativeToString = typeof v === "object" && v.toString === Object.prototype.toString;
2194                 return isObjectWithNativeToString ? util.inspect(v) : v;
2195             }
2197             return util ? format : valueFormatter;
2198         }
2200         var isNode = typeof module !== "undefined" && module.exports && typeof require === "function";
2201         var formatter;
2203         if (isNode) {
2204             try {
2205                 formatio = require("formatio");
2206             }
2207             catch (e) {} // eslint-disable-line no-empty
2208         }
2210         if (formatio) {
2211             formatter = getFormatioFormatter();
2212         } else if (isNode) {
2213             formatter = getNodeFormatter();
2214         } else {
2215             formatter = valueFormatter;
2216         }
2218         sinon.format = formatter;
2219         return sinon.format;
2220     }
2222     function loadDependencies(require, exports, module) {
2223         var sinon = require("./util/core");
2224         module.exports = makeApi(sinon);
2225     }
2227     var isNode = typeof module !== "undefined" && module.exports && typeof require === "function";
2228     var isAMD = typeof define === "function" && typeof define.amd === "object" && define.amd;
2230     if (isAMD) {
2231         define(loadDependencies);
2232         return;
2233     }
2235     if (isNode) {
2236         loadDependencies(require, module.exports, module);
2237         return;
2238     }
2240     if (sinonGlobal) {
2241         makeApi(sinonGlobal);
2242     }
2244     typeof sinon === "object" && sinon, // eslint-disable-line no-undef
2245     typeof formatio === "object" && formatio // eslint-disable-line no-undef
2249   * @depend util/core.js
2250   * @depend match.js
2251   * @depend format.js
2252   */
2254   * Spy calls
2255   *
2256   * @author Christian Johansen (christian@cjohansen.no)
2257   * @author Maximilian Antoni (mail@maxantoni.de)
2258   * @license BSD
2259   *
2260   * Copyright (c) 2010-2013 Christian Johansen
2261   * Copyright (c) 2013 Maximilian Antoni
2262   */
2263 (function (sinonGlobal) {
2264     
2265     var slice = Array.prototype.slice;
2267     function makeApi(sinon) {
2268         function throwYieldError(proxy, text, args) {
2269             var msg = sinon.functionName(proxy) + text;
2270             if (args.length) {
2271                 msg += " Received [" + slice.call(args).join(", ") + "]";
2272             }
2273             throw new Error(msg);
2274         }
2276         var callProto = {
2277             calledOn: function calledOn(thisValue) {
2278                 if (sinon.match && sinon.match.isMatcher(thisValue)) {
2279                     return thisValue.test(this.thisValue);
2280                 }
2281                 return this.thisValue === thisValue;
2282             },
2284             calledWith: function calledWith() {
2285                 var l = arguments.length;
2286                 if (l > this.args.length) {
2287                     return false;
2288                 }
2289                 for (var i = 0; i < l; i += 1) {
2290                     if (!sinon.deepEqual(arguments[i], this.args[i])) {
2291                         return false;
2292                     }
2293                 }
2295                 return true;
2296             },
2298             calledWithMatch: function calledWithMatch() {
2299                 var l = arguments.length;
2300                 if (l > this.args.length) {
2301                     return false;
2302                 }
2303                 for (var i = 0; i < l; i += 1) {
2304                     var actual = this.args[i];
2305                     var expectation = arguments[i];
2306                     if (!sinon.match || !sinon.match(expectation).test(actual)) {
2307                         return false;
2308                     }
2309                 }
2310                 return true;
2311             },
2313             calledWithExactly: function calledWithExactly() {
2314                 return arguments.length === this.args.length &&
2315                     this.calledWith.apply(this, arguments);
2316             },
2318             notCalledWith: function notCalledWith() {
2319                 return !this.calledWith.apply(this, arguments);
2320             },
2322             notCalledWithMatch: function notCalledWithMatch() {
2323                 return !this.calledWithMatch.apply(this, arguments);
2324             },
2326             returned: function returned(value) {
2327                 return sinon.deepEqual(value, this.returnValue);
2328             },
2330             threw: function threw(error) {
2331                 if (typeof error === "undefined" || !this.exception) {
2332                     return !!this.exception;
2333                 }
2335                 return this.exception === error || this.exception.name === error;
2336             },
2338             calledWithNew: function calledWithNew() {
2339                 return this.proxy.prototype && this.thisValue instanceof this.proxy;
2340             },
2342             calledBefore: function (other) {
2343                 return this.callId < other.callId;
2344             },
2346             calledAfter: function (other) {
2347                 return this.callId > other.callId;
2348             },
2350             callArg: function (pos) {
2351                 this.args[pos]();
2352             },
2354             callArgOn: function (pos, thisValue) {
2355                 this.args[pos].apply(thisValue);
2356             },
2358             callArgWith: function (pos) {
2359                 this.callArgOnWith.apply(this, [pos, null].concat(slice.call(arguments, 1)));
2360             },
2362             callArgOnWith: function (pos, thisValue) {
2363                 var args = slice.call(arguments, 2);
2364                 this.args[pos].apply(thisValue, args);
2365             },
2367             "yield": function () {
2368                 this.yieldOn.apply(this, [null].concat(slice.call(arguments, 0)));
2369             },
2371             yieldOn: function (thisValue) {
2372                 var args = this.args;
2373                 for (var i = 0, l = args.length; i < l; ++i) {
2374                     if (typeof args[i] === "function") {
2375                         args[i].apply(thisValue, slice.call(arguments, 1));
2376                         return;
2377                     }
2378                 }
2379                 throwYieldError(this.proxy, " cannot yield since no callback was passed.", args);
2380             },
2382             yieldTo: function (prop) {
2383                 this.yieldToOn.apply(this, [prop, null].concat(slice.call(arguments, 1)));
2384             },
2386             yieldToOn: function (prop, thisValue) {
2387                 var args = this.args;
2388                 for (var i = 0, l = args.length; i < l; ++i) {
2389                     if (args[i] && typeof args[i][prop] === "function") {
2390                         args[i][prop].apply(thisValue, slice.call(arguments, 2));
2391                         return;
2392                     }
2393                 }
2394                 throwYieldError(this.proxy, " cannot yield to '" + prop +
2395                     "' since no callback was passed.", args);
2396             },
2398             getStackFrames: function () {
2399                 // Omit the error message and the two top stack frames in sinon itself:
2400                 return this.stack && this.stack.split("\n").slice(3);
2401             },
2403             toString: function () {
2404                 var callStr = this.proxy ? this.proxy.toString() + "(" : "";
2405                 var args = [];
2407                 if (!this.args) {
2408                     return ":(";
2409                 }
2411                 for (var i = 0, l = this.args.length; i < l; ++i) {
2412                     args.push(sinon.format(this.args[i]));
2413                 }
2415                 callStr = callStr + args.join(", ") + ")";
2417                 if (typeof this.returnValue !== "undefined") {
2418                     callStr += " => " + sinon.format(this.returnValue);
2419                 }
2421                 if (this.exception) {
2422                     callStr += " !" + this.exception.name;
2424                     if (this.exception.message) {
2425                         callStr += "(" + this.exception.message + ")";
2426                     }
2427                 }
2428                 if (this.stack) {
2429                     callStr += this.getStackFrames()[0].replace(/^\s*(?:at\s+|@)?/, " at ");
2431                 }
2433                 return callStr;
2434             }
2435         };
2437         callProto.invokeCallback = callProto.yield;
2439         function createSpyCall(spy, thisValue, args, returnValue, exception, id, stack) {
2440             if (typeof id !== "number") {
2441                 throw new TypeError("Call id is not a number");
2442             }
2443             var proxyCall = sinon.create(callProto);
2444             proxyCall.proxy = spy;
2445             proxyCall.thisValue = thisValue;
2446             proxyCall.args = args;
2447             proxyCall.returnValue = returnValue;
2448             proxyCall.exception = exception;
2449             proxyCall.callId = id;
2450             proxyCall.stack = stack;
2452             return proxyCall;
2453         }
2454         createSpyCall.toString = callProto.toString; // used by mocks
2456         sinon.spyCall = createSpyCall;
2457         return createSpyCall;
2458     }
2460     var isNode = typeof module !== "undefined" && module.exports && typeof require === "function";
2461     var isAMD = typeof define === "function" && typeof define.amd === "object" && define.amd;
2463     function loadDependencies(require, exports, module) {
2464         var sinon = require("./util/core");
2465         require("./match");
2466         require("./format");
2467         module.exports = makeApi(sinon);
2468     }
2470     if (isAMD) {
2471         define(loadDependencies);
2472         return;
2473     }
2475     if (isNode) {
2476         loadDependencies(require, module.exports, module);
2477         return;
2478     }
2480     if (sinonGlobal) {
2481         makeApi(sinonGlobal);
2482     }
2484     typeof sinon === "object" && sinon // eslint-disable-line no-undef
2488   * @depend times_in_words.js
2489   * @depend util/core.js
2490   * @depend extend.js
2491   * @depend call.js
2492   * @depend format.js
2493   */
2495   * Spy functions
2496   *
2497   * @author Christian Johansen (christian@cjohansen.no)
2498   * @license BSD
2499   *
2500   * Copyright (c) 2010-2013 Christian Johansen
2501   */
2502 (function (sinonGlobal) {
2503     
2504     function makeApi(sinon) {
2505         var push = Array.prototype.push;
2506         var slice = Array.prototype.slice;
2507         var callId = 0;
2509         function spy(object, property, types) {
2510             if (!property && typeof object === "function") {
2511                 return spy.create(object);
2512             }
2514             if (!object && !property) {
2515                 return spy.create(function () { });
2516             }
2518             if (types) {
2519                 var methodDesc = sinon.getPropertyDescriptor(object, property);
2520                 for (var i = 0; i < types.length; i++) {
2521                     methodDesc[types[i]] = spy.create(methodDesc[types[i]]);
2522                 }
2523                 return sinon.wrapMethod(object, property, methodDesc);
2524             }
2526             return sinon.wrapMethod(object, property, spy.create(object[property]));
2527         }
2529         function matchingFake(fakes, args, strict) {
2530             if (!fakes) {
2531                 return undefined;
2532             }
2534             for (var i = 0, l = fakes.length; i < l; i++) {
2535                 if (fakes[i].matches(args, strict)) {
2536                     return fakes[i];
2537                 }
2538             }
2539         }
2541         function incrementCallCount() {
2542             this.called = true;
2543             this.callCount += 1;
2544             this.notCalled = false;
2545             this.calledOnce = this.callCount === 1;
2546             this.calledTwice = this.callCount === 2;
2547             this.calledThrice = this.callCount === 3;
2548         }
2550         function createCallProperties() {
2551             this.firstCall = this.getCall(0);
2552             this.secondCall = this.getCall(1);
2553             this.thirdCall = this.getCall(2);
2554             this.lastCall = this.getCall(this.callCount - 1);
2555         }
2557         var vars = "a,b,c,d,e,f,g,h,i,j,k,l";
2558         function createProxy(func, proxyLength) {
2559             // Retain the function length:
2560             var p;
2561             if (proxyLength) {
2562                 eval("p = (function proxy(" + vars.substring(0, proxyLength * 2 - 1) + // eslint-disable-line no-eval
2563                     ") { return p.invoke(func, this, slice.call(arguments)); });");
2564             } else {
2565                 p = function proxy() {
2566                     return p.invoke(func, this, slice.call(arguments));
2567                 };
2568             }
2569             p.isSinonProxy = true;
2570             return p;
2571         }
2573         var uuid = 0;
2575         // Public API
2576         var spyApi = {
2577             reset: function () {
2578                 if (this.invoking) {
2579                     var err = new Error("Cannot reset Sinon function while invoking it. " +
2580                                         "Move the call to .reset outside of the callback.");
2581                     err.name = "InvalidResetException";
2582                     throw err;
2583                 }
2585                 this.called = false;
2586                 this.notCalled = true;
2587                 this.calledOnce = false;
2588                 this.calledTwice = false;
2589                 this.calledThrice = false;
2590                 this.callCount = 0;
2591                 this.firstCall = null;
2592                 this.secondCall = null;
2593                 this.thirdCall = null;
2594                 this.lastCall = null;
2595                 this.args = [];
2596                 this.returnValues = [];
2597                 this.thisValues = [];
2598                 this.exceptions = [];
2599                 this.callIds = [];
2600                 this.stacks = [];
2601                 if (this.fakes) {
2602                     for (var i = 0; i < this.fakes.length; i++) {
2603                         this.fakes[i].reset();
2604                     }
2605                 }
2607                 return this;
2608             },
2610             create: function create(func, spyLength) {
2611                 var name;
2613                 if (typeof func !== "function") {
2614                     func = function () { };
2615                 } else {
2616                     name = sinon.functionName(func);
2617                 }
2619                 if (!spyLength) {
2620                     spyLength = func.length;
2621                 }
2623                 var proxy = createProxy(func, spyLength);
2625                 sinon.extend(proxy, spy);
2626                 delete proxy.create;
2627                 sinon.extend(proxy, func);
2629                 proxy.reset();
2630                 proxy.prototype = func.prototype;
2631                 proxy.displayName = name || "spy";
2632                 proxy.toString = sinon.functionToString;
2633                 proxy.instantiateFake = sinon.spy.create;
2634                 proxy.id = "spy#" + uuid++;
2636                 return proxy;
2637             },
2639             invoke: function invoke(func, thisValue, args) {
2640                 var matching = matchingFake(this.fakes, args);
2641                 var exception, returnValue;
2643                 incrementCallCount.call(this);
2644                 push.call(this.thisValues, thisValue);
2645                 push.call(this.args, args);
2646                 push.call(this.callIds, callId++);
2648                 // Make call properties available from within the spied function:
2649                 createCallProperties.call(this);
2651                 try {
2652                     this.invoking = true;
2654                     if (matching) {
2655                         returnValue = matching.invoke(func, thisValue, args);
2656                     } else {
2657                         returnValue = (this.func || func).apply(thisValue, args);
2658                     }
2660                     var thisCall = this.getCall(this.callCount - 1);
2661                     if (thisCall.calledWithNew() && typeof returnValue !== "object") {
2662                         returnValue = thisValue;
2663                     }
2664                 } catch (e) {
2665                     exception = e;
2666                 } finally {
2667                     delete this.invoking;
2668                 }
2670                 push.call(this.exceptions, exception);
2671                 push.call(this.returnValues, returnValue);
2672                 push.call(this.stacks, new Error().stack);
2674                 // Make return value and exception available in the calls:
2675                 createCallProperties.call(this);
2677                 if (exception !== undefined) {
2678                     throw exception;
2679                 }
2681                 return returnValue;
2682             },
2684             named: function named(name) {
2685                 this.displayName = name;
2686                 return this;
2687             },
2689             getCall: function getCall(i) {
2690                 if (i < 0 || i >= this.callCount) {
2691                     return null;
2692                 }
2694                 return sinon.spyCall(this, this.thisValues[i], this.args[i],
2695                                         this.returnValues[i], this.exceptions[i],
2696                                         this.callIds[i], this.stacks[i]);
2697             },
2699             getCalls: function () {
2700                 var calls = [];
2701                 var i;
2703                 for (i = 0; i < this.callCount; i++) {
2704                     calls.push(this.getCall(i));
2705                 }
2707                 return calls;
2708             },
2710             calledBefore: function calledBefore(spyFn) {
2711                 if (!this.called) {
2712                     return false;
2713                 }
2715                 if (!spyFn.called) {
2716                     return true;
2717                 }
2719                 return this.callIds[0] < spyFn.callIds[spyFn.callIds.length - 1];
2720             },
2722             calledAfter: function calledAfter(spyFn) {
2723                 if (!this.called || !spyFn.called) {
2724                     return false;
2725                 }
2727                 return this.callIds[this.callCount - 1] > spyFn.callIds[spyFn.callCount - 1];
2728             },
2730             withArgs: function () {
2731                 var args = slice.call(arguments);
2733                 if (this.fakes) {
2734                     var match = matchingFake(this.fakes, args, true);
2736                     if (match) {
2737                         return match;
2738                     }
2739                 } else {
2740                     this.fakes = [];
2741                 }
2743                 var original = this;
2744                 var fake = this.instantiateFake();
2745                 fake.matchingAguments = args;
2746                 fake.parent = this;
2747                 push.call(this.fakes, fake);
2749                 fake.withArgs = function () {
2750                     return original.withArgs.apply(original, arguments);
2751                 };
2753                 for (var i = 0; i < this.args.length; i++) {
2754                     if (fake.matches(this.args[i])) {
2755                         incrementCallCount.call(fake);
2756                         push.call(fake.thisValues, this.thisValues[i]);
2757                         push.call(fake.args, this.args[i]);
2758                         push.call(fake.returnValues, this.returnValues[i]);
2759                         push.call(fake.exceptions, this.exceptions[i]);
2760                         push.call(fake.callIds, this.callIds[i]);
2761                     }
2762                 }
2763                 createCallProperties.call(fake);
2765                 return fake;
2766             },
2768             matches: function (args, strict) {
2769                 var margs = this.matchingAguments;
2771                 if (margs.length <= args.length &&
2772                     sinon.deepEqual(margs, args.slice(0, margs.length))) {
2773                     return !strict || margs.length === args.length;
2774                 }
2775             },
2777             printf: function (format) {
2778                 var spyInstance = this;
2779                 var args = slice.call(arguments, 1);
2780                 var formatter;
2782                 return (format || "").replace(/%(.)/g, function (match, specifyer) {
2783                     formatter = spyApi.formatters[specifyer];
2785                     if (typeof formatter === "function") {
2786                         return formatter.call(null, spyInstance, args);
2787                     } else if (!isNaN(parseInt(specifyer, 10))) {
2788                         return sinon.format(args[specifyer - 1]);
2789                     }
2791                     return "%" + specifyer;
2792                 });
2793             }
2794         };
2796         function delegateToCalls(method, matchAny, actual, notCalled) {
2797             spyApi[method] = function () {
2798                 if (!this.called) {
2799                     if (notCalled) {
2800                         return notCalled.apply(this, arguments);
2801                     }
2802                     return false;
2803                 }
2805                 var currentCall;
2806                 var matches = 0;
2808                 for (var i = 0, l = this.callCount; i < l; i += 1) {
2809                     currentCall = this.getCall(i);
2811                     if (currentCall[actual || method].apply(currentCall, arguments)) {
2812                         matches += 1;
2814                         if (matchAny) {
2815                             return true;
2816                         }
2817                     }
2818                 }
2820                 return matches === this.callCount;
2821             };
2822         }
2824         delegateToCalls("calledOn", true);
2825         delegateToCalls("alwaysCalledOn", false, "calledOn");
2826         delegateToCalls("calledWith", true);
2827         delegateToCalls("calledWithMatch", true);
2828         delegateToCalls("alwaysCalledWith", false, "calledWith");
2829         delegateToCalls("alwaysCalledWithMatch", false, "calledWithMatch");
2830         delegateToCalls("calledWithExactly", true);
2831         delegateToCalls("alwaysCalledWithExactly", false, "calledWithExactly");
2832         delegateToCalls("neverCalledWith", false, "notCalledWith", function () {
2833             return true;
2834         });
2835         delegateToCalls("neverCalledWithMatch", false, "notCalledWithMatch", function () {
2836             return true;
2837         });
2838         delegateToCalls("threw", true);
2839         delegateToCalls("alwaysThrew", false, "threw");
2840         delegateToCalls("returned", true);
2841         delegateToCalls("alwaysReturned", false, "returned");
2842         delegateToCalls("calledWithNew", true);
2843         delegateToCalls("alwaysCalledWithNew", false, "calledWithNew");
2844         delegateToCalls("callArg", false, "callArgWith", function () {
2845             throw new Error(this.toString() + " cannot call arg since it was not yet invoked.");
2846         });
2847         spyApi.callArgWith = spyApi.callArg;
2848         delegateToCalls("callArgOn", false, "callArgOnWith", function () {
2849             throw new Error(this.toString() + " cannot call arg since it was not yet invoked.");
2850         });
2851         spyApi.callArgOnWith = spyApi.callArgOn;
2852         delegateToCalls("yield", false, "yield", function () {
2853             throw new Error(this.toString() + " cannot yield since it was not yet invoked.");
2854         });
2855         // "invokeCallback" is an alias for "yield" since "yield" is invalid in strict mode.
2856         spyApi.invokeCallback = spyApi.yield;
2857         delegateToCalls("yieldOn", false, "yieldOn", function () {
2858             throw new Error(this.toString() + " cannot yield since it was not yet invoked.");
2859         });
2860         delegateToCalls("yieldTo", false, "yieldTo", function (property) {
2861             throw new Error(this.toString() + " cannot yield to '" + property +
2862                 "' since it was not yet invoked.");
2863         });
2864         delegateToCalls("yieldToOn", false, "yieldToOn", function (property) {
2865             throw new Error(this.toString() + " cannot yield to '" + property +
2866                 "' since it was not yet invoked.");
2867         });
2869         spyApi.formatters = {
2870             c: function (spyInstance) {
2871                 return sinon.timesInWords(spyInstance.callCount);
2872             },
2874             n: function (spyInstance) {
2875                 return spyInstance.toString();
2876             },
2878             C: function (spyInstance) {
2879                 var calls = [];
2881                 for (var i = 0, l = spyInstance.callCount; i < l; ++i) {
2882                     var stringifiedCall = "    " + spyInstance.getCall(i).toString();
2883                     if (/\n/.test(calls[i - 1])) {
2884                         stringifiedCall = "\n" + stringifiedCall;
2885                     }
2886                     push.call(calls, stringifiedCall);
2887                 }
2889                 return calls.length > 0 ? "\n" + calls.join("\n") : "";
2890             },
2892             t: function (spyInstance) {
2893                 var objects = [];
2895                 for (var i = 0, l = spyInstance.callCount; i < l; ++i) {
2896                     push.call(objects, sinon.format(spyInstance.thisValues[i]));
2897                 }
2899                 return objects.join(", ");
2900             },
2902             "*": function (spyInstance, args) {
2903                 var formatted = [];
2905                 for (var i = 0, l = args.length; i < l; ++i) {
2906                     push.call(formatted, sinon.format(args[i]));
2907                 }
2909                 return formatted.join(", ");
2910             }
2911         };
2913         sinon.extend(spy, spyApi);
2915         spy.spyCall = sinon.spyCall;
2916         sinon.spy = spy;
2918         return spy;
2919     }
2921     var isNode = typeof module !== "undefined" && module.exports && typeof require === "function";
2922     var isAMD = typeof define === "function" && typeof define.amd === "object" && define.amd;
2924     function loadDependencies(require, exports, module) {
2925         var core = require("./util/core");
2926         require("./call");
2927         require("./extend");
2928         require("./times_in_words");
2929         require("./format");
2930         module.exports = makeApi(core);
2931     }
2933     if (isAMD) {
2934         define(loadDependencies);
2935         return;
2936     }
2938     if (isNode) {
2939         loadDependencies(require, module.exports, module);
2940         return;
2941     }
2943     if (sinonGlobal) {
2944         makeApi(sinonGlobal);
2945     }
2947     typeof sinon === "object" && sinon // eslint-disable-line no-undef
2951  * @depend util/core.js
2952  * @depend extend.js
2953  */
2955  * Stub behavior
2957  * @author Christian Johansen (christian@cjohansen.no)
2958  * @author Tim Fischbach (mail@timfischbach.de)
2959  * @license BSD
2961  * Copyright (c) 2010-2013 Christian Johansen
2962  */
2963 (function (sinonGlobal) {
2964     
2965     var slice = Array.prototype.slice;
2966     var join = Array.prototype.join;
2967     var useLeftMostCallback = -1;
2968     var useRightMostCallback = -2;
2970     var nextTick = (function () {
2971         if (typeof process === "object" && typeof process.nextTick === "function") {
2972             return process.nextTick;
2973         }
2975         if (typeof setImmediate === "function") {
2976             return setImmediate;
2977         }
2979         return function (callback) {
2980             setTimeout(callback, 0);
2981         };
2982     })();
2984     function throwsException(error, message) {
2985         if (typeof error === "string") {
2986             this.exception = new Error(message || "");
2987             this.exception.name = error;
2988         } else if (!error) {
2989             this.exception = new Error("Error");
2990         } else {
2991             this.exception = error;
2992         }
2994         return this;
2995     }
2997     function getCallback(behavior, args) {
2998         var callArgAt = behavior.callArgAt;
3000         if (callArgAt >= 0) {
3001             return args[callArgAt];
3002         }
3004         var argumentList;
3006         if (callArgAt === useLeftMostCallback) {
3007             argumentList = args;
3008         }
3010         if (callArgAt === useRightMostCallback) {
3011             argumentList = slice.call(args).reverse();
3012         }
3014         var callArgProp = behavior.callArgProp;
3016         for (var i = 0, l = argumentList.length; i < l; ++i) {
3017             if (!callArgProp && typeof argumentList[i] === "function") {
3018                 return argumentList[i];
3019             }
3021             if (callArgProp && argumentList[i] &&
3022                 typeof argumentList[i][callArgProp] === "function") {
3023                 return argumentList[i][callArgProp];
3024             }
3025         }
3027         return null;
3028     }
3030     function makeApi(sinon) {
3031         function getCallbackError(behavior, func, args) {
3032             if (behavior.callArgAt < 0) {
3033                 var msg;
3035                 if (behavior.callArgProp) {
3036                     msg = sinon.functionName(behavior.stub) +
3037                         " expected to yield to '" + behavior.callArgProp +
3038                         "', but no object with such a property was passed.";
3039                 } else {
3040                     msg = sinon.functionName(behavior.stub) +
3041                         " expected to yield, but no callback was passed.";
3042                 }
3044                 if (args.length > 0) {
3045                     msg += " Received [" + join.call(args, ", ") + "]";
3046                 }
3048                 return msg;
3049             }
3051             return "argument at index " + behavior.callArgAt + " is not a function: " + func;
3052         }
3054         function callCallback(behavior, args) {
3055             if (typeof behavior.callArgAt === "number") {
3056                 var func = getCallback(behavior, args);
3058                 if (typeof func !== "function") {
3059                     throw new TypeError(getCallbackError(behavior, func, args));
3060                 }
3062                 if (behavior.callbackAsync) {
3063                     nextTick(function () {
3064                         func.apply(behavior.callbackContext, behavior.callbackArguments);
3065                     });
3066                 } else {
3067                     func.apply(behavior.callbackContext, behavior.callbackArguments);
3068                 }
3069             }
3070         }
3072         var proto = {
3073             create: function create(stub) {
3074                 var behavior = sinon.extend({}, sinon.behavior);
3075                 delete behavior.create;
3076                 behavior.stub = stub;
3078                 return behavior;
3079             },
3081             isPresent: function isPresent() {
3082                 return (typeof this.callArgAt === "number" ||
3083                         this.exception ||
3084                         typeof this.returnArgAt === "number" ||
3085                         this.returnThis ||
3086                         this.returnValueDefined);
3087             },
3089             invoke: function invoke(context, args) {
3090                 callCallback(this, args);
3092                 if (this.exception) {
3093                     throw this.exception;
3094                 } else if (typeof this.returnArgAt === "number") {
3095                     return args[this.returnArgAt];
3096                 } else if (this.returnThis) {
3097                     return context;
3098                 }
3100                 return this.returnValue;
3101             },
3103             onCall: function onCall(index) {
3104                 return this.stub.onCall(index);
3105             },
3107             onFirstCall: function onFirstCall() {
3108                 return this.stub.onFirstCall();
3109             },
3111             onSecondCall: function onSecondCall() {
3112                 return this.stub.onSecondCall();
3113             },
3115             onThirdCall: function onThirdCall() {
3116                 return this.stub.onThirdCall();
3117             },
3119             withArgs: function withArgs(/* arguments */) {
3120                 throw new Error(
3121                     "Defining a stub by invoking \"stub.onCall(...).withArgs(...)\" " +
3122                     "is not supported. Use \"stub.withArgs(...).onCall(...)\" " +
3123                     "to define sequential behavior for calls with certain arguments."
3124                 );
3125             },
3127             callsArg: function callsArg(pos) {
3128                 if (typeof pos !== "number") {
3129                     throw new TypeError("argument index is not number");
3130                 }
3132                 this.callArgAt = pos;
3133                 this.callbackArguments = [];
3134                 this.callbackContext = undefined;
3135                 this.callArgProp = undefined;
3136                 this.callbackAsync = false;
3138                 return this;
3139             },
3141             callsArgOn: function callsArgOn(pos, context) {
3142                 if (typeof pos !== "number") {
3143                     throw new TypeError("argument index is not number");
3144                 }
3145                 if (typeof context !== "object") {
3146                     throw new TypeError("argument context is not an object");
3147                 }
3149                 this.callArgAt = pos;
3150                 this.callbackArguments = [];
3151                 this.callbackContext = context;
3152                 this.callArgProp = undefined;
3153                 this.callbackAsync = false;
3155                 return this;
3156             },
3158             callsArgWith: function callsArgWith(pos) {
3159                 if (typeof pos !== "number") {
3160                     throw new TypeError("argument index is not number");
3161                 }
3163                 this.callArgAt = pos;
3164                 this.callbackArguments = slice.call(arguments, 1);
3165                 this.callbackContext = undefined;
3166                 this.callArgProp = undefined;
3167                 this.callbackAsync = false;
3169                 return this;
3170             },
3172             callsArgOnWith: function callsArgWith(pos, context) {
3173                 if (typeof pos !== "number") {
3174                     throw new TypeError("argument index is not number");
3175                 }
3176                 if (typeof context !== "object") {
3177                     throw new TypeError("argument context is not an object");
3178                 }
3180                 this.callArgAt = pos;
3181                 this.callbackArguments = slice.call(arguments, 2);
3182                 this.callbackContext = context;
3183                 this.callArgProp = undefined;
3184                 this.callbackAsync = false;
3186                 return this;
3187             },
3189             yields: function () {
3190                 this.callArgAt = useLeftMostCallback;
3191                 this.callbackArguments = slice.call(arguments, 0);
3192                 this.callbackContext = undefined;
3193                 this.callArgProp = undefined;
3194                 this.callbackAsync = false;
3196                 return this;
3197             },
3199             yieldsRight: function () {
3200                 this.callArgAt = useRightMostCallback;
3201                 this.callbackArguments = slice.call(arguments, 0);
3202                 this.callbackContext = undefined;
3203                 this.callArgProp = undefined;
3204                 this.callbackAsync = false;
3206                 return this;
3207             },
3209             yieldsOn: function (context) {
3210                 if (typeof context !== "object") {
3211                     throw new TypeError("argument context is not an object");
3212                 }
3214                 this.callArgAt = useLeftMostCallback;
3215                 this.callbackArguments = slice.call(arguments, 1);
3216                 this.callbackContext = context;
3217                 this.callArgProp = undefined;
3218                 this.callbackAsync = false;
3220                 return this;
3221             },
3223             yieldsTo: function (prop) {
3224                 this.callArgAt = useLeftMostCallback;
3225                 this.callbackArguments = slice.call(arguments, 1);
3226                 this.callbackContext = undefined;
3227                 this.callArgProp = prop;
3228                 this.callbackAsync = false;
3230                 return this;
3231             },
3233             yieldsToOn: function (prop, context) {
3234                 if (typeof context !== "object") {
3235                     throw new TypeError("argument context is not an object");
3236                 }
3238                 this.callArgAt = useLeftMostCallback;
3239                 this.callbackArguments = slice.call(arguments, 2);
3240                 this.callbackContext = context;
3241                 this.callArgProp = prop;
3242                 this.callbackAsync = false;
3244                 return this;
3245             },
3247             throws: throwsException,
3248             throwsException: throwsException,
3250             returns: function returns(value) {
3251                 this.returnValue = value;
3252                 this.returnValueDefined = true;
3253                 this.exception = undefined;
3255                 return this;
3256             },
3258             returnsArg: function returnsArg(pos) {
3259                 if (typeof pos !== "number") {
3260                     throw new TypeError("argument index is not number");
3261                 }
3263                 this.returnArgAt = pos;
3265                 return this;
3266             },
3268             returnsThis: function returnsThis() {
3269                 this.returnThis = true;
3271                 return this;
3272             }
3273         };
3275         function createAsyncVersion(syncFnName) {
3276             return function () {
3277                 var result = this[syncFnName].apply(this, arguments);
3278                 this.callbackAsync = true;
3279                 return result;
3280             };
3281         }
3283         // create asynchronous versions of callsArg* and yields* methods
3284         for (var method in proto) {
3285             // need to avoid creating anotherasync versions of the newly added async methods
3286             if (proto.hasOwnProperty(method) && method.match(/^(callsArg|yields)/) && !method.match(/Async/)) {
3287                 proto[method + "Async"] = createAsyncVersion(method);
3288             }
3289         }
3291         sinon.behavior = proto;
3292         return proto;
3293     }
3295     var isNode = typeof module !== "undefined" && module.exports && typeof require === "function";
3296     var isAMD = typeof define === "function" && typeof define.amd === "object" && define.amd;
3298     function loadDependencies(require, exports, module) {
3299         var sinon = require("./util/core");
3300         require("./extend");
3301         module.exports = makeApi(sinon);
3302     }
3304     if (isAMD) {
3305         define(loadDependencies);
3306         return;
3307     }
3309     if (isNode) {
3310         loadDependencies(require, module.exports, module);
3311         return;
3312     }
3314     if (sinonGlobal) {
3315         makeApi(sinonGlobal);
3316     }
3318     typeof sinon === "object" && sinon // eslint-disable-line no-undef
3322  * @depend util/core.js
3323  */
3324 (function (sinonGlobal) {
3325     
3326     function makeApi(sinon) {
3327         function walkInternal(obj, iterator, context, originalObj, seen) {
3328             var proto, prop;
3330             if (typeof Object.getOwnPropertyNames !== "function") {
3331                 // We explicitly want to enumerate through all of the prototype's properties
3332                 // in this case, therefore we deliberately leave out an own property check.
3333                 /* eslint-disable guard-for-in */
3334                 for (prop in obj) {
3335                     iterator.call(context, obj[prop], prop, obj);
3336                 }
3337                 /* eslint-enable guard-for-in */
3339                 return;
3340             }
3342             Object.getOwnPropertyNames(obj).forEach(function (k) {
3343                 if (!seen[k]) {
3344                     seen[k] = true;
3345                     var target = typeof Object.getOwnPropertyDescriptor(obj, k).get === "function" ?
3346                         originalObj : obj;
3347                     iterator.call(context, target[k], k, target);
3348                 }
3349             });
3351             proto = Object.getPrototypeOf(obj);
3352             if (proto) {
3353                 walkInternal(proto, iterator, context, originalObj, seen);
3354             }
3355         }
3357         /* Public: walks the prototype chain of an object and iterates over every own property
3358          * name encountered. The iterator is called in the same fashion that Array.prototype.forEach
3359          * works, where it is passed the value, key, and own object as the 1st, 2nd, and 3rd positional
3360          * argument, respectively. In cases where Object.getOwnPropertyNames is not available, walk will
3361          * default to using a simple for..in loop.
3362          *
3363          * obj - The object to walk the prototype chain for.
3364          * iterator - The function to be called on each pass of the walk.
3365          * context - (Optional) When given, the iterator will be called with this object as the receiver.
3366          */
3367         function walk(obj, iterator, context) {
3368             return walkInternal(obj, iterator, context, obj, {});
3369         }
3371         sinon.walk = walk;
3372         return sinon.walk;
3373     }
3375     function loadDependencies(require, exports, module) {
3376         var sinon = require("./util/core");
3377         module.exports = makeApi(sinon);
3378     }
3380     var isNode = typeof module !== "undefined" && module.exports && typeof require === "function";
3381     var isAMD = typeof define === "function" && typeof define.amd === "object" && define.amd;
3383     if (isAMD) {
3384         define(loadDependencies);
3385         return;
3386     }
3388     if (isNode) {
3389         loadDependencies(require, module.exports, module);
3390         return;
3391     }
3393     if (sinonGlobal) {
3394         makeApi(sinonGlobal);
3395     }
3397     typeof sinon === "object" && sinon // eslint-disable-line no-undef
3401  * @depend util/core.js
3402  * @depend extend.js
3403  * @depend spy.js
3404  * @depend behavior.js
3405  * @depend walk.js
3406  */
3408  * Stub functions
3410  * @author Christian Johansen (christian@cjohansen.no)
3411  * @license BSD
3413  * Copyright (c) 2010-2013 Christian Johansen
3414  */
3415 (function (sinonGlobal) {
3416     
3417     function makeApi(sinon) {
3418         function stub(object, property, func) {
3419             if (!!func && typeof func !== "function" && typeof func !== "object") {
3420                 throw new TypeError("Custom stub should be a function or a property descriptor");
3421             }
3423             var wrapper;
3425             if (func) {
3426                 if (typeof func === "function") {
3427                     wrapper = sinon.spy && sinon.spy.create ? sinon.spy.create(func) : func;
3428                 } else {
3429                     wrapper = func;
3430                     if (sinon.spy && sinon.spy.create) {
3431                         var types = sinon.objectKeys(wrapper);
3432                         for (var i = 0; i < types.length; i++) {
3433                             wrapper[types[i]] = sinon.spy.create(wrapper[types[i]]);
3434                         }
3435                     }
3436                 }
3437             } else {
3438                 var stubLength = 0;
3439                 if (typeof object === "object" && typeof object[property] === "function") {
3440                     stubLength = object[property].length;
3441                 }
3442                 wrapper = stub.create(stubLength);
3443             }
3445             if (!object && typeof property === "undefined") {
3446                 return sinon.stub.create();
3447             }
3449             if (typeof property === "undefined" && typeof object === "object") {
3450                 sinon.walk(object || {}, function (value, prop, propOwner) {
3451                     // we don't want to stub things like toString(), valueOf(), etc. so we only stub if the object
3452                     // is not Object.prototype
3453                     if (
3454                         propOwner !== Object.prototype &&
3455                         prop !== "constructor" &&
3456                         typeof sinon.getPropertyDescriptor(propOwner, prop).value === "function"
3457                     ) {
3458                         stub(object, prop);
3459                     }
3460                 });
3462                 return object;
3463             }
3465             return sinon.wrapMethod(object, property, wrapper);
3466         }
3469         /*eslint-disable no-use-before-define*/
3470         function getParentBehaviour(stubInstance) {
3471             return (stubInstance.parent && getCurrentBehavior(stubInstance.parent));
3472         }
3474         function getDefaultBehavior(stubInstance) {
3475             return stubInstance.defaultBehavior ||
3476                     getParentBehaviour(stubInstance) ||
3477                     sinon.behavior.create(stubInstance);
3478         }
3480         function getCurrentBehavior(stubInstance) {
3481             var behavior = stubInstance.behaviors[stubInstance.callCount - 1];
3482             return behavior && behavior.isPresent() ? behavior : getDefaultBehavior(stubInstance);
3483         }
3484         /*eslint-enable no-use-before-define*/
3486         var uuid = 0;
3488         var proto = {
3489             create: function create(stubLength) {
3490                 var functionStub = function () {
3491                     return getCurrentBehavior(functionStub).invoke(this, arguments);
3492                 };
3494                 functionStub.id = "stub#" + uuid++;
3495                 var orig = functionStub;
3496                 functionStub = sinon.spy.create(functionStub, stubLength);
3497                 functionStub.func = orig;
3499                 sinon.extend(functionStub, stub);
3500                 functionStub.instantiateFake = sinon.stub.create;
3501                 functionStub.displayName = "stub";
3502                 functionStub.toString = sinon.functionToString;
3504                 functionStub.defaultBehavior = null;
3505                 functionStub.behaviors = [];
3507                 return functionStub;
3508             },
3510             resetBehavior: function () {
3511                 var i;
3513                 this.defaultBehavior = null;
3514                 this.behaviors = [];
3516                 delete this.returnValue;
3517                 delete this.returnArgAt;
3518                 this.returnThis = false;
3520                 if (this.fakes) {
3521                     for (i = 0; i < this.fakes.length; i++) {
3522                         this.fakes[i].resetBehavior();
3523                     }
3524                 }
3525             },
3527             onCall: function onCall(index) {
3528                 if (!this.behaviors[index]) {
3529                     this.behaviors[index] = sinon.behavior.create(this);
3530                 }
3532                 return this.behaviors[index];
3533             },
3535             onFirstCall: function onFirstCall() {
3536                 return this.onCall(0);
3537             },
3539             onSecondCall: function onSecondCall() {
3540                 return this.onCall(1);
3541             },
3543             onThirdCall: function onThirdCall() {
3544                 return this.onCall(2);
3545             }
3546         };
3548         function createBehavior(behaviorMethod) {
3549             return function () {
3550                 this.defaultBehavior = this.defaultBehavior || sinon.behavior.create(this);
3551                 this.defaultBehavior[behaviorMethod].apply(this.defaultBehavior, arguments);
3552                 return this;
3553             };
3554         }
3556         for (var method in sinon.behavior) {
3557             if (sinon.behavior.hasOwnProperty(method) &&
3558                 !proto.hasOwnProperty(method) &&
3559                 method !== "create" &&
3560                 method !== "withArgs" &&
3561                 method !== "invoke") {
3562                 proto[method] = createBehavior(method);
3563             }
3564         }
3566         sinon.extend(stub, proto);
3567         sinon.stub = stub;
3569         return stub;
3570     }
3572     var isNode = typeof module !== "undefined" && module.exports && typeof require === "function";
3573     var isAMD = typeof define === "function" && typeof define.amd === "object" && define.amd;
3575     function loadDependencies(require, exports, module) {
3576         var core = require("./util/core");
3577         require("./behavior");
3578         require("./spy");
3579         require("./extend");
3580         module.exports = makeApi(core);
3581     }
3583     if (isAMD) {
3584         define(loadDependencies);
3585         return;
3586     }
3588     if (isNode) {
3589         loadDependencies(require, module.exports, module);
3590         return;
3591     }
3593     if (sinonGlobal) {
3594         makeApi(sinonGlobal);
3595     }
3597     typeof sinon === "object" && sinon // eslint-disable-line no-undef
3601  * @depend times_in_words.js
3602  * @depend util/core.js
3603  * @depend call.js
3604  * @depend extend.js
3605  * @depend match.js
3606  * @depend spy.js
3607  * @depend stub.js
3608  * @depend format.js
3609  */
3611  * Mock functions.
3613  * @author Christian Johansen (christian@cjohansen.no)
3614  * @license BSD
3616  * Copyright (c) 2010-2013 Christian Johansen
3617  */
3618 (function (sinonGlobal) {
3619     
3620     function makeApi(sinon) {
3621         var push = [].push;
3622         var match = sinon.match;
3624         function mock(object) {
3625             // if (typeof console !== undefined && console.warn) {
3626             //     console.warn("mock will be removed from Sinon.JS v2.0");
3627             // }
3629             if (!object) {
3630                 return sinon.expectation.create("Anonymous mock");
3631             }
3633             return mock.create(object);
3634         }
3636         function each(collection, callback) {
3637             if (!collection) {
3638                 return;
3639             }
3641             for (var i = 0, l = collection.length; i < l; i += 1) {
3642                 callback(collection[i]);
3643             }
3644         }
3646         function arrayEquals(arr1, arr2, compareLength) {
3647             if (compareLength && (arr1.length !== arr2.length)) {
3648                 return false;
3649             }
3651             for (var i = 0, l = arr1.length; i < l; i++) {
3652                 if (!sinon.deepEqual(arr1[i], arr2[i])) {
3653                     return false;
3654                 }
3655             }
3656             return true;
3657         }
3659         sinon.extend(mock, {
3660             create: function create(object) {
3661                 if (!object) {
3662                     throw new TypeError("object is null");
3663                 }
3665                 var mockObject = sinon.extend({}, mock);
3666                 mockObject.object = object;
3667                 delete mockObject.create;
3669                 return mockObject;
3670             },
3672             expects: function expects(method) {
3673                 if (!method) {
3674                     throw new TypeError("method is falsy");
3675                 }
3677                 if (!this.expectations) {
3678                     this.expectations = {};
3679                     this.proxies = [];
3680                 }
3682                 if (!this.expectations[method]) {
3683                     this.expectations[method] = [];
3684                     var mockObject = this;
3686                     sinon.wrapMethod(this.object, method, function () {
3687                         return mockObject.invokeMethod(method, this, arguments);
3688                     });
3690                     push.call(this.proxies, method);
3691                 }
3693                 var expectation = sinon.expectation.create(method);
3694                 push.call(this.expectations[method], expectation);
3696                 return expectation;
3697             },
3699             restore: function restore() {
3700                 var object = this.object;
3702                 each(this.proxies, function (proxy) {
3703                     if (typeof object[proxy].restore === "function") {
3704                         object[proxy].restore();
3705                     }
3706                 });
3707             },
3709             verify: function verify() {
3710                 var expectations = this.expectations || {};
3711                 var messages = [];
3712                 var met = [];
3714                 each(this.proxies, function (proxy) {
3715                     each(expectations[proxy], function (expectation) {
3716                         if (!expectation.met()) {
3717                             push.call(messages, expectation.toString());
3718                         } else {
3719                             push.call(met, expectation.toString());
3720                         }
3721                     });
3722                 });
3724                 this.restore();
3726                 if (messages.length > 0) {
3727                     sinon.expectation.fail(messages.concat(met).join("\n"));
3728                 } else if (met.length > 0) {
3729                     sinon.expectation.pass(messages.concat(met).join("\n"));
3730                 }
3732                 return true;
3733             },
3735             invokeMethod: function invokeMethod(method, thisValue, args) {
3736                 var expectations = this.expectations && this.expectations[method] ? this.expectations[method] : [];
3737                 var expectationsWithMatchingArgs = [];
3738                 var currentArgs = args || [];
3739                 var i, available;
3741                 for (i = 0; i < expectations.length; i += 1) {
3742                     var expectedArgs = expectations[i].expectedArguments || [];
3743                     if (arrayEquals(expectedArgs, currentArgs, expectations[i].expectsExactArgCount)) {
3744                         expectationsWithMatchingArgs.push(expectations[i]);
3745                     }
3746                 }
3748                 for (i = 0; i < expectationsWithMatchingArgs.length; i += 1) {
3749                     if (!expectationsWithMatchingArgs[i].met() &&
3750                         expectationsWithMatchingArgs[i].allowsCall(thisValue, args)) {
3751                         return expectationsWithMatchingArgs[i].apply(thisValue, args);
3752                     }
3753                 }
3755                 var messages = [];
3756                 var exhausted = 0;
3758                 for (i = 0; i < expectationsWithMatchingArgs.length; i += 1) {
3759                     if (expectationsWithMatchingArgs[i].allowsCall(thisValue, args)) {
3760                         available = available || expectationsWithMatchingArgs[i];
3761                     } else {
3762                         exhausted += 1;
3763                     }
3764                 }
3766                 if (available && exhausted === 0) {
3767                     return available.apply(thisValue, args);
3768                 }
3770                 for (i = 0; i < expectations.length; i += 1) {
3771                     push.call(messages, "    " + expectations[i].toString());
3772                 }
3774                 messages.unshift("Unexpected call: " + sinon.spyCall.toString.call({
3775                     proxy: method,
3776                     args: args
3777                 }));
3779                 sinon.expectation.fail(messages.join("\n"));
3780             }
3781         });
3783         var times = sinon.timesInWords;
3784         var slice = Array.prototype.slice;
3786         function callCountInWords(callCount) {
3787             if (callCount === 0) {
3788                 return "never called";
3789             }
3791             return "called " + times(callCount);
3792         }
3794         function expectedCallCountInWords(expectation) {
3795             var min = expectation.minCalls;
3796             var max = expectation.maxCalls;
3798             if (typeof min === "number" && typeof max === "number") {
3799                 var str = times(min);
3801                 if (min !== max) {
3802                     str = "at least " + str + " and at most " + times(max);
3803                 }
3805                 return str;
3806             }
3808             if (typeof min === "number") {
3809                 return "at least " + times(min);
3810             }
3812             return "at most " + times(max);
3813         }
3815         function receivedMinCalls(expectation) {
3816             var hasMinLimit = typeof expectation.minCalls === "number";
3817             return !hasMinLimit || expectation.callCount >= expectation.minCalls;
3818         }
3820         function receivedMaxCalls(expectation) {
3821             if (typeof expectation.maxCalls !== "number") {
3822                 return false;
3823             }
3825             return expectation.callCount === expectation.maxCalls;
3826         }
3828         function verifyMatcher(possibleMatcher, arg) {
3829             var isMatcher = match && match.isMatcher(possibleMatcher);
3831             return isMatcher && possibleMatcher.test(arg) || true;
3832         }
3834         sinon.expectation = {
3835             minCalls: 1,
3836             maxCalls: 1,
3838             create: function create(methodName) {
3839                 var expectation = sinon.extend(sinon.stub.create(), sinon.expectation);
3840                 delete expectation.create;
3841                 expectation.method = methodName;
3843                 return expectation;
3844             },
3846             invoke: function invoke(func, thisValue, args) {
3847                 this.verifyCallAllowed(thisValue, args);
3849                 return sinon.spy.invoke.apply(this, arguments);
3850             },
3852             atLeast: function atLeast(num) {
3853                 if (typeof num !== "number") {
3854                     throw new TypeError("'" + num + "' is not number");
3855                 }
3857                 if (!this.limitsSet) {
3858                     this.maxCalls = null;
3859                     this.limitsSet = true;
3860                 }
3862                 this.minCalls = num;
3864                 return this;
3865             },
3867             atMost: function atMost(num) {
3868                 if (typeof num !== "number") {
3869                     throw new TypeError("'" + num + "' is not number");
3870                 }
3872                 if (!this.limitsSet) {
3873                     this.minCalls = null;
3874                     this.limitsSet = true;
3875                 }
3877                 this.maxCalls = num;
3879                 return this;
3880             },
3882             never: function never() {
3883                 return this.exactly(0);
3884             },
3886             once: function once() {
3887                 return this.exactly(1);
3888             },
3890             twice: function twice() {
3891                 return this.exactly(2);
3892             },
3894             thrice: function thrice() {
3895                 return this.exactly(3);
3896             },
3898             exactly: function exactly(num) {
3899                 if (typeof num !== "number") {
3900                     throw new TypeError("'" + num + "' is not a number");
3901                 }
3903                 this.atLeast(num);
3904                 return this.atMost(num);
3905             },
3907             met: function met() {
3908                 return !this.failed && receivedMinCalls(this);
3909             },
3911             verifyCallAllowed: function verifyCallAllowed(thisValue, args) {
3912                 if (receivedMaxCalls(this)) {
3913                     this.failed = true;
3914                     sinon.expectation.fail(this.method + " already called " + times(this.maxCalls));
3915                 }
3917                 if ("expectedThis" in this && this.expectedThis !== thisValue) {
3918                     sinon.expectation.fail(this.method + " called with " + thisValue + " as thisValue, expected " +
3919                         this.expectedThis);
3920                 }
3922                 if (!("expectedArguments" in this)) {
3923                     return;
3924                 }
3926                 if (!args) {
3927                     sinon.expectation.fail(this.method + " received no arguments, expected " +
3928                         sinon.format(this.expectedArguments));
3929                 }
3931                 if (args.length < this.expectedArguments.length) {
3932                     sinon.expectation.fail(this.method + " received too few arguments (" + sinon.format(args) +
3933                         "), expected " + sinon.format(this.expectedArguments));
3934                 }
3936                 if (this.expectsExactArgCount &&
3937                     args.length !== this.expectedArguments.length) {
3938                     sinon.expectation.fail(this.method + " received too many arguments (" + sinon.format(args) +
3939                         "), expected " + sinon.format(this.expectedArguments));
3940                 }
3942                 for (var i = 0, l = this.expectedArguments.length; i < l; i += 1) {
3944                     if (!verifyMatcher(this.expectedArguments[i], args[i])) {
3945                         sinon.expectation.fail(this.method + " received wrong arguments " + sinon.format(args) +
3946                             ", didn't match " + this.expectedArguments.toString());
3947                     }
3949                     if (!sinon.deepEqual(this.expectedArguments[i], args[i])) {
3950                         sinon.expectation.fail(this.method + " received wrong arguments " + sinon.format(args) +
3951                             ", expected " + sinon.format(this.expectedArguments));
3952                     }
3953                 }
3954             },
3956             allowsCall: function allowsCall(thisValue, args) {
3957                 if (this.met() && receivedMaxCalls(this)) {
3958                     return false;
3959                 }
3961                 if ("expectedThis" in this && this.expectedThis !== thisValue) {
3962                     return false;
3963                 }
3965                 if (!("expectedArguments" in this)) {
3966                     return true;
3967                 }
3969                 args = args || [];
3971                 if (args.length < this.expectedArguments.length) {
3972                     return false;
3973                 }
3975                 if (this.expectsExactArgCount &&
3976                     args.length !== this.expectedArguments.length) {
3977                     return false;
3978                 }
3980                 for (var i = 0, l = this.expectedArguments.length; i < l; i += 1) {
3981                     if (!verifyMatcher(this.expectedArguments[i], args[i])) {
3982                         return false;
3983                     }
3985                     if (!sinon.deepEqual(this.expectedArguments[i], args[i])) {
3986                         return false;
3987                     }
3988                 }
3990                 return true;
3991             },
3993             withArgs: function withArgs() {
3994                 this.expectedArguments = slice.call(arguments);
3995                 return this;
3996             },
3998             withExactArgs: function withExactArgs() {
3999                 this.withArgs.apply(this, arguments);
4000                 this.expectsExactArgCount = true;
4001                 return this;
4002             },
4004             on: function on(thisValue) {
4005                 this.expectedThis = thisValue;
4006                 return this;
4007             },
4009             toString: function () {
4010                 var args = (this.expectedArguments || []).slice();
4012                 if (!this.expectsExactArgCount) {
4013                     push.call(args, "[...]");
4014                 }
4016                 var callStr = sinon.spyCall.toString.call({
4017                     proxy: this.method || "anonymous mock expectation",
4018                     args: args
4019                 });
4021                 var message = callStr.replace(", [...", "[, ...") + " " +
4022                     expectedCallCountInWords(this);
4024                 if (this.met()) {
4025                     return "Expectation met: " + message;
4026                 }
4028                 return "Expected " + message + " (" +
4029                     callCountInWords(this.callCount) + ")";
4030             },
4032             verify: function verify() {
4033                 if (!this.met()) {
4034                     sinon.expectation.fail(this.toString());
4035                 } else {
4036                     sinon.expectation.pass(this.toString());
4037                 }
4039                 return true;
4040             },
4042             pass: function pass(message) {
4043                 sinon.assert.pass(message);
4044             },
4046             fail: function fail(message) {
4047                 var exception = new Error(message);
4048                 exception.name = "ExpectationError";
4050                 throw exception;
4051             }
4052         };
4054         sinon.mock = mock;
4055         return mock;
4056     }
4058     var isNode = typeof module !== "undefined" && module.exports && typeof require === "function";
4059     var isAMD = typeof define === "function" && typeof define.amd === "object" && define.amd;
4061     function loadDependencies(require, exports, module) {
4062         var sinon = require("./util/core");
4063         require("./times_in_words");
4064         require("./call");
4065         require("./extend");
4066         require("./match");
4067         require("./spy");
4068         require("./stub");
4069         require("./format");
4071         module.exports = makeApi(sinon);
4072     }
4074     if (isAMD) {
4075         define(loadDependencies);
4076         return;
4077     }
4079     if (isNode) {
4080         loadDependencies(require, module.exports, module);
4081         return;
4082     }
4084     if (sinonGlobal) {
4085         makeApi(sinonGlobal);
4086     }
4088     typeof sinon === "object" && sinon // eslint-disable-line no-undef
4092  * @depend util/core.js
4093  * @depend spy.js
4094  * @depend stub.js
4095  * @depend mock.js
4096  */
4098  * Collections of stubs, spies and mocks.
4100  * @author Christian Johansen (christian@cjohansen.no)
4101  * @license BSD
4103  * Copyright (c) 2010-2013 Christian Johansen
4104  */
4105 (function (sinonGlobal) {
4106     
4107     var push = [].push;
4108     var hasOwnProperty = Object.prototype.hasOwnProperty;
4110     function getFakes(fakeCollection) {
4111         if (!fakeCollection.fakes) {
4112             fakeCollection.fakes = [];
4113         }
4115         return fakeCollection.fakes;
4116     }
4118     function each(fakeCollection, method) {
4119         var fakes = getFakes(fakeCollection);
4121         for (var i = 0, l = fakes.length; i < l; i += 1) {
4122             if (typeof fakes[i][method] === "function") {
4123                 fakes[i][method]();
4124             }
4125         }
4126     }
4128     function compact(fakeCollection) {
4129         var fakes = getFakes(fakeCollection);
4130         var i = 0;
4131         while (i < fakes.length) {
4132             fakes.splice(i, 1);
4133         }
4134     }
4136     function makeApi(sinon) {
4137         var collection = {
4138             verify: function resolve() {
4139                 each(this, "verify");
4140             },
4142             restore: function restore() {
4143                 each(this, "restore");
4144                 compact(this);
4145             },
4147             reset: function restore() {
4148                 each(this, "reset");
4149             },
4151             verifyAndRestore: function verifyAndRestore() {
4152                 var exception;
4154                 try {
4155                     this.verify();
4156                 } catch (e) {
4157                     exception = e;
4158                 }
4160                 this.restore();
4162                 if (exception) {
4163                     throw exception;
4164                 }
4165             },
4167             add: function add(fake) {
4168                 push.call(getFakes(this), fake);
4169                 return fake;
4170             },
4172             spy: function spy() {
4173                 return this.add(sinon.spy.apply(sinon, arguments));
4174             },
4176             stub: function stub(object, property, value) {
4177                 if (property) {
4178                     var original = object[property];
4180                     if (typeof original !== "function") {
4181                         if (!hasOwnProperty.call(object, property)) {
4182                             throw new TypeError("Cannot stub non-existent own property " + property);
4183                         }
4185                         object[property] = value;
4187                         return this.add({
4188                             restore: function () {
4189                                 object[property] = original;
4190                             }
4191                         });
4192                     }
4193                 }
4194                 if (!property && !!object && typeof object === "object") {
4195                     var stubbedObj = sinon.stub.apply(sinon, arguments);
4197                     for (var prop in stubbedObj) {
4198                         if (typeof stubbedObj[prop] === "function") {
4199                             this.add(stubbedObj[prop]);
4200                         }
4201                     }
4203                     return stubbedObj;
4204                 }
4206                 return this.add(sinon.stub.apply(sinon, arguments));
4207             },
4209             mock: function mock() {
4210                 return this.add(sinon.mock.apply(sinon, arguments));
4211             },
4213             inject: function inject(obj) {
4214                 var col = this;
4216                 obj.spy = function () {
4217                     return col.spy.apply(col, arguments);
4218                 };
4220                 obj.stub = function () {
4221                     return col.stub.apply(col, arguments);
4222                 };
4224                 obj.mock = function () {
4225                     return col.mock.apply(col, arguments);
4226                 };
4228                 return obj;
4229             }
4230         };
4232         sinon.collection = collection;
4233         return collection;
4234     }
4236     var isNode = typeof module !== "undefined" && module.exports && typeof require === "function";
4237     var isAMD = typeof define === "function" && typeof define.amd === "object" && define.amd;
4239     function loadDependencies(require, exports, module) {
4240         var sinon = require("./util/core");
4241         require("./mock");
4242         require("./spy");
4243         require("./stub");
4244         module.exports = makeApi(sinon);
4245     }
4247     if (isAMD) {
4248         define(loadDependencies);
4249         return;
4250     }
4252     if (isNode) {
4253         loadDependencies(require, module.exports, module);
4254         return;
4255     }
4257     if (sinonGlobal) {
4258         makeApi(sinonGlobal);
4259     }
4261     typeof sinon === "object" && sinon // eslint-disable-line no-undef
4265  * Fake timer API
4266  * setTimeout
4267  * setInterval
4268  * clearTimeout
4269  * clearInterval
4270  * tick
4271  * reset
4272  * Date
4274  * Inspired by jsUnitMockTimeOut from JsUnit
4276  * @author Christian Johansen (christian@cjohansen.no)
4277  * @license BSD
4279  * Copyright (c) 2010-2013 Christian Johansen
4280  */
4281 (function () {
4282     
4283     function makeApi(s, lol) {
4284         /*global lolex */
4285         var llx = typeof lolex !== "undefined" ? lolex : lol;
4287         s.useFakeTimers = function () {
4288             var now;
4289             var methods = Array.prototype.slice.call(arguments);
4291             if (typeof methods[0] === "string") {
4292                 now = 0;
4293             } else {
4294                 now = methods.shift();
4295             }
4297             var clock = llx.install(now || 0, methods);
4298             clock.restore = clock.uninstall;
4299             return clock;
4300         };
4302         s.clock = {
4303             create: function (now) {
4304                 return llx.createClock(now);
4305             }
4306         };
4308         s.timers = {
4309             setTimeout: setTimeout,
4310             clearTimeout: clearTimeout,
4311             setImmediate: (typeof setImmediate !== "undefined" ? setImmediate : undefined),
4312             clearImmediate: (typeof clearImmediate !== "undefined" ? clearImmediate : undefined),
4313             setInterval: setInterval,
4314             clearInterval: clearInterval,
4315             Date: Date
4316         };
4317     }
4319     var isNode = typeof module !== "undefined" && module.exports && typeof require === "function";
4320     var isAMD = typeof define === "function" && typeof define.amd === "object" && define.amd;
4322     function loadDependencies(require, epxorts, module, lolex) {
4323         var core = require("./core");
4324         makeApi(core, lolex);
4325         module.exports = core;
4326     }
4328     if (isAMD) {
4329         define(loadDependencies);
4330     } else if (isNode) {
4331         loadDependencies(require, module.exports, module, require("lolex"));
4332     } else {
4333         makeApi(sinon); // eslint-disable-line no-undef
4334     }
4335 }());
4338  * Minimal Event interface implementation
4340  * Original implementation by Sven Fuchs: https://gist.github.com/995028
4341  * Modifications and tests by Christian Johansen.
4343  * @author Sven Fuchs (svenfuchs@artweb-design.de)
4344  * @author Christian Johansen (christian@cjohansen.no)
4345  * @license BSD
4347  * Copyright (c) 2011 Sven Fuchs, Christian Johansen
4348  */
4349 if (typeof sinon === "undefined") {
4350     this.sinon = {};
4353 (function () {
4354     
4355     var push = [].push;
4357     function makeApi(sinon) {
4358         sinon.Event = function Event(type, bubbles, cancelable, target) {
4359             this.initEvent(type, bubbles, cancelable, target);
4360         };
4362         sinon.Event.prototype = {
4363             initEvent: function (type, bubbles, cancelable, target) {
4364                 this.type = type;
4365                 this.bubbles = bubbles;
4366                 this.cancelable = cancelable;
4367                 this.target = target;
4368             },
4370             stopPropagation: function () {},
4372             preventDefault: function () {
4373                 this.defaultPrevented = true;
4374             }
4375         };
4377         sinon.ProgressEvent = function ProgressEvent(type, progressEventRaw, target) {
4378             this.initEvent(type, false, false, target);
4379             this.loaded = progressEventRaw.loaded || null;
4380             this.total = progressEventRaw.total || null;
4381             this.lengthComputable = !!progressEventRaw.total;
4382         };
4384         sinon.ProgressEvent.prototype = new sinon.Event();
4386         sinon.ProgressEvent.prototype.constructor = sinon.ProgressEvent;
4388         sinon.CustomEvent = function CustomEvent(type, customData, target) {
4389             this.initEvent(type, false, false, target);
4390             this.detail = customData.detail || null;
4391         };
4393         sinon.CustomEvent.prototype = new sinon.Event();
4395         sinon.CustomEvent.prototype.constructor = sinon.CustomEvent;
4397         sinon.EventTarget = {
4398             addEventListener: function addEventListener(event, listener) {
4399                 this.eventListeners = this.eventListeners || {};
4400                 this.eventListeners[event] = this.eventListeners[event] || [];
4401                 push.call(this.eventListeners[event], listener);
4402             },
4404             removeEventListener: function removeEventListener(event, listener) {
4405                 var listeners = this.eventListeners && this.eventListeners[event] || [];
4407                 for (var i = 0, l = listeners.length; i < l; ++i) {
4408                     if (listeners[i] === listener) {
4409                         return listeners.splice(i, 1);
4410                     }
4411                 }
4412             },
4414             dispatchEvent: function dispatchEvent(event) {
4415                 var type = event.type;
4416                 var listeners = this.eventListeners && this.eventListeners[type] || [];
4418                 for (var i = 0; i < listeners.length; i++) {
4419                     if (typeof listeners[i] === "function") {
4420                         listeners[i].call(this, event);
4421                     } else {
4422                         listeners[i].handleEvent(event);
4423                     }
4424                 }
4426                 return !!event.defaultPrevented;
4427             }
4428         };
4429     }
4431     var isNode = typeof module !== "undefined" && module.exports && typeof require === "function";
4432     var isAMD = typeof define === "function" && typeof define.amd === "object" && define.amd;
4434     function loadDependencies(require) {
4435         var sinon = require("./core");
4436         makeApi(sinon);
4437     }
4439     if (isAMD) {
4440         define(loadDependencies);
4441     } else if (isNode) {
4442         loadDependencies(require);
4443     } else {
4444         makeApi(sinon); // eslint-disable-line no-undef
4445     }
4446 }());
4449  * @depend util/core.js
4450  */
4452  * Logs errors
4454  * @author Christian Johansen (christian@cjohansen.no)
4455  * @license BSD
4457  * Copyright (c) 2010-2014 Christian Johansen
4458  */
4459 (function (sinonGlobal) {
4460     
4461     // cache a reference to setTimeout, so that our reference won't be stubbed out
4462     // when using fake timers and errors will still get logged
4463     // https://github.com/cjohansen/Sinon.JS/issues/381
4464     var realSetTimeout = setTimeout;
4466     function makeApi(sinon) {
4468         function log() {}
4470         function logError(label, err) {
4471             var msg = label + " threw exception: ";
4473             function throwLoggedError() {
4474                 err.message = msg + err.message;
4475                 throw err;
4476             }
4478             sinon.log(msg + "[" + err.name + "] " + err.message);
4480             if (err.stack) {
4481                 sinon.log(err.stack);
4482             }
4484             if (logError.useImmediateExceptions) {
4485                 throwLoggedError();
4486             } else {
4487                 logError.setTimeout(throwLoggedError, 0);
4488             }
4489         }
4491         // When set to true, any errors logged will be thrown immediately;
4492         // If set to false, the errors will be thrown in separate execution frame.
4493         logError.useImmediateExceptions = false;
4495         // wrap realSetTimeout with something we can stub in tests
4496         logError.setTimeout = function (func, timeout) {
4497             realSetTimeout(func, timeout);
4498         };
4500         var exports = {};
4501         exports.log = sinon.log = log;
4502         exports.logError = sinon.logError = logError;
4504         return exports;
4505     }
4507     function loadDependencies(require, exports, module) {
4508         var sinon = require("./util/core");
4509         module.exports = makeApi(sinon);
4510     }
4512     var isNode = typeof module !== "undefined" && module.exports && typeof require === "function";
4513     var isAMD = typeof define === "function" && typeof define.amd === "object" && define.amd;
4515     if (isAMD) {
4516         define(loadDependencies);
4517         return;
4518     }
4520     if (isNode) {
4521         loadDependencies(require, module.exports, module);
4522         return;
4523     }
4525     if (sinonGlobal) {
4526         makeApi(sinonGlobal);
4527     }
4529     typeof sinon === "object" && sinon // eslint-disable-line no-undef
4533  * @depend core.js
4534  * @depend ../extend.js
4535  * @depend event.js
4536  * @depend ../log_error.js
4537  */
4539  * Fake XDomainRequest object
4540  */
4543  * Returns the global to prevent assigning values to 'this' when this is undefined.
4544  * This can occur when files are interpreted by node in strict mode.
4545  * @private
4546  */
4547 function getGlobal() {
4548     
4549     return typeof window !== "undefined" ? window : global;
4552 if (typeof sinon === "undefined") {
4553     if (typeof this === "undefined") {
4554         getGlobal().sinon = {};
4555     } else {
4556         this.sinon = {};
4557     }
4560 // wrapper for global
4561 (function (global) {
4562     
4563     var xdr = { XDomainRequest: global.XDomainRequest };
4564     xdr.GlobalXDomainRequest = global.XDomainRequest;
4565     xdr.supportsXDR = typeof xdr.GlobalXDomainRequest !== "undefined";
4566     xdr.workingXDR = xdr.supportsXDR ? xdr.GlobalXDomainRequest : false;
4568     function makeApi(sinon) {
4569         sinon.xdr = xdr;
4571         function FakeXDomainRequest() {
4572             this.readyState = FakeXDomainRequest.UNSENT;
4573             this.requestBody = null;
4574             this.requestHeaders = {};
4575             this.status = 0;
4576             this.timeout = null;
4578             if (typeof FakeXDomainRequest.onCreate === "function") {
4579                 FakeXDomainRequest.onCreate(this);
4580             }
4581         }
4583         function verifyState(x) {
4584             if (x.readyState !== FakeXDomainRequest.OPENED) {
4585                 throw new Error("INVALID_STATE_ERR");
4586             }
4588             if (x.sendFlag) {
4589                 throw new Error("INVALID_STATE_ERR");
4590             }
4591         }
4593         function verifyRequestSent(x) {
4594             if (x.readyState === FakeXDomainRequest.UNSENT) {
4595                 throw new Error("Request not sent");
4596             }
4597             if (x.readyState === FakeXDomainRequest.DONE) {
4598                 throw new Error("Request done");
4599             }
4600         }
4602         function verifyResponseBodyType(body) {
4603             if (typeof body !== "string") {
4604                 var error = new Error("Attempted to respond to fake XDomainRequest with " +
4605                                     body + ", which is not a string.");
4606                 error.name = "InvalidBodyException";
4607                 throw error;
4608             }
4609         }
4611         sinon.extend(FakeXDomainRequest.prototype, sinon.EventTarget, {
4612             open: function open(method, url) {
4613                 this.method = method;
4614                 this.url = url;
4616                 this.responseText = null;
4617                 this.sendFlag = false;
4619                 this.readyStateChange(FakeXDomainRequest.OPENED);
4620             },
4622             readyStateChange: function readyStateChange(state) {
4623                 this.readyState = state;
4624                 var eventName = "";
4625                 switch (this.readyState) {
4626                 case FakeXDomainRequest.UNSENT:
4627                     break;
4628                 case FakeXDomainRequest.OPENED:
4629                     break;
4630                 case FakeXDomainRequest.LOADING:
4631                     if (this.sendFlag) {
4632                         //raise the progress event
4633                         eventName = "onprogress";
4634                     }
4635                     break;
4636                 case FakeXDomainRequest.DONE:
4637                     if (this.isTimeout) {
4638                         eventName = "ontimeout";
4639                     } else if (this.errorFlag || (this.status < 200 || this.status > 299)) {
4640                         eventName = "onerror";
4641                     } else {
4642                         eventName = "onload";
4643                     }
4644                     break;
4645                 }
4647                 // raising event (if defined)
4648                 if (eventName) {
4649                     if (typeof this[eventName] === "function") {
4650                         try {
4651                             this[eventName]();
4652                         } catch (e) {
4653                             sinon.logError("Fake XHR " + eventName + " handler", e);
4654                         }
4655                     }
4656                 }
4657             },
4659             send: function send(data) {
4660                 verifyState(this);
4662                 if (!/^(get|head)$/i.test(this.method)) {
4663                     this.requestBody = data;
4664                 }
4665                 this.requestHeaders["Content-Type"] = "text/plain;charset=utf-8";
4667                 this.errorFlag = false;
4668                 this.sendFlag = true;
4669                 this.readyStateChange(FakeXDomainRequest.OPENED);
4671                 if (typeof this.onSend === "function") {
4672                     this.onSend(this);
4673                 }
4674             },
4676             abort: function abort() {
4677                 this.aborted = true;
4678                 this.responseText = null;
4679                 this.errorFlag = true;
4681                 if (this.readyState > sinon.FakeXDomainRequest.UNSENT && this.sendFlag) {
4682                     this.readyStateChange(sinon.FakeXDomainRequest.DONE);
4683                     this.sendFlag = false;
4684                 }
4685             },
4687             setResponseBody: function setResponseBody(body) {
4688                 verifyRequestSent(this);
4689                 verifyResponseBodyType(body);
4691                 var chunkSize = this.chunkSize || 10;
4692                 var index = 0;
4693                 this.responseText = "";
4695                 do {
4696                     this.readyStateChange(FakeXDomainRequest.LOADING);
4697                     this.responseText += body.substring(index, index + chunkSize);
4698                     index += chunkSize;
4699                 } while (index < body.length);
4701                 this.readyStateChange(FakeXDomainRequest.DONE);
4702             },
4704             respond: function respond(status, contentType, body) {
4705                 // content-type ignored, since XDomainRequest does not carry this
4706                 // we keep the same syntax for respond(...) as for FakeXMLHttpRequest to ease
4707                 // test integration across browsers
4708                 this.status = typeof status === "number" ? status : 200;
4709                 this.setResponseBody(body || "");
4710             },
4712             simulatetimeout: function simulatetimeout() {
4713                 this.status = 0;
4714                 this.isTimeout = true;
4715                 // Access to this should actually throw an error
4716                 this.responseText = undefined;
4717                 this.readyStateChange(FakeXDomainRequest.DONE);
4718             }
4719         });
4721         sinon.extend(FakeXDomainRequest, {
4722             UNSENT: 0,
4723             OPENED: 1,
4724             LOADING: 3,
4725             DONE: 4
4726         });
4728         sinon.useFakeXDomainRequest = function useFakeXDomainRequest() {
4729             sinon.FakeXDomainRequest.restore = function restore(keepOnCreate) {
4730                 if (xdr.supportsXDR) {
4731                     global.XDomainRequest = xdr.GlobalXDomainRequest;
4732                 }
4734                 delete sinon.FakeXDomainRequest.restore;
4736                 if (keepOnCreate !== true) {
4737                     delete sinon.FakeXDomainRequest.onCreate;
4738                 }
4739             };
4740             if (xdr.supportsXDR) {
4741                 global.XDomainRequest = sinon.FakeXDomainRequest;
4742             }
4743             return sinon.FakeXDomainRequest;
4744         };
4746         sinon.FakeXDomainRequest = FakeXDomainRequest;
4747     }
4749     var isNode = typeof module !== "undefined" && module.exports && typeof require === "function";
4750     var isAMD = typeof define === "function" && typeof define.amd === "object" && define.amd;
4752     function loadDependencies(require, exports, module) {
4753         var sinon = require("./core");
4754         require("../extend");
4755         require("./event");
4756         require("../log_error");
4757         makeApi(sinon);
4758         module.exports = sinon;
4759     }
4761     if (isAMD) {
4762         define(loadDependencies);
4763     } else if (isNode) {
4764         loadDependencies(require, module.exports, module);
4765     } else {
4766         makeApi(sinon); // eslint-disable-line no-undef
4767     }
4768 })(typeof global !== "undefined" ? global : self);
4771  * @depend core.js
4772  * @depend ../extend.js
4773  * @depend event.js
4774  * @depend ../log_error.js
4775  */
4777  * Fake XMLHttpRequest object
4779  * @author Christian Johansen (christian@cjohansen.no)
4780  * @license BSD
4782  * Copyright (c) 2010-2013 Christian Johansen
4783  */
4784 (function (sinonGlobal, global) {
4785     
4786     function getWorkingXHR(globalScope) {
4787         var supportsXHR = typeof globalScope.XMLHttpRequest !== "undefined";
4788         if (supportsXHR) {
4789             return globalScope.XMLHttpRequest;
4790         }
4792         var supportsActiveX = typeof globalScope.ActiveXObject !== "undefined";
4793         if (supportsActiveX) {
4794             return function () {
4795                 return new globalScope.ActiveXObject("MSXML2.XMLHTTP.3.0");
4796             };
4797         }
4799         return false;
4800     }
4802     var supportsProgress = typeof ProgressEvent !== "undefined";
4803     var supportsCustomEvent = typeof CustomEvent !== "undefined";
4804     var supportsFormData = typeof FormData !== "undefined";
4805     var supportsArrayBuffer = typeof ArrayBuffer !== "undefined";
4806     var supportsBlob = typeof Blob === "function";
4807     var sinonXhr = { XMLHttpRequest: global.XMLHttpRequest };
4808     sinonXhr.GlobalXMLHttpRequest = global.XMLHttpRequest;
4809     sinonXhr.GlobalActiveXObject = global.ActiveXObject;
4810     sinonXhr.supportsActiveX = typeof sinonXhr.GlobalActiveXObject !== "undefined";
4811     sinonXhr.supportsXHR = typeof sinonXhr.GlobalXMLHttpRequest !== "undefined";
4812     sinonXhr.workingXHR = getWorkingXHR(global);
4813     sinonXhr.supportsCORS = sinonXhr.supportsXHR && "withCredentials" in (new sinonXhr.GlobalXMLHttpRequest());
4815     var unsafeHeaders = {
4816         "Accept-Charset": true,
4817         "Accept-Encoding": true,
4818         Connection: true,
4819         "Content-Length": true,
4820         Cookie: true,
4821         Cookie2: true,
4822         "Content-Transfer-Encoding": true,
4823         Date: true,
4824         Expect: true,
4825         Host: true,
4826         "Keep-Alive": true,
4827         Referer: true,
4828         TE: true,
4829         Trailer: true,
4830         "Transfer-Encoding": true,
4831         Upgrade: true,
4832         "User-Agent": true,
4833         Via: true
4834     };
4836     // An upload object is created for each
4837     // FakeXMLHttpRequest and allows upload
4838     // events to be simulated using uploadProgress
4839     // and uploadError.
4840     function UploadProgress() {
4841         this.eventListeners = {
4842             progress: [],
4843             load: [],
4844             abort: [],
4845             error: []
4846         };
4847     }
4849     UploadProgress.prototype.addEventListener = function addEventListener(event, listener) {
4850         this.eventListeners[event].push(listener);
4851     };
4853     UploadProgress.prototype.removeEventListener = function removeEventListener(event, listener) {
4854         var listeners = this.eventListeners[event] || [];
4856         for (var i = 0, l = listeners.length; i < l; ++i) {
4857             if (listeners[i] === listener) {
4858                 return listeners.splice(i, 1);
4859             }
4860         }
4861     };
4863     UploadProgress.prototype.dispatchEvent = function dispatchEvent(event) {
4864         var listeners = this.eventListeners[event.type] || [];
4866         for (var i = 0, listener; (listener = listeners[i]) != null; i++) {
4867             listener(event);
4868         }
4869     };
4871     // Note that for FakeXMLHttpRequest to work pre ES5
4872     // we lose some of the alignment with the spec.
4873     // To ensure as close a match as possible,
4874     // set responseType before calling open, send or respond;
4875     function FakeXMLHttpRequest() {
4876         this.readyState = FakeXMLHttpRequest.UNSENT;
4877         this.requestHeaders = {};
4878         this.requestBody = null;
4879         this.status = 0;
4880         this.statusText = "";
4881         this.upload = new UploadProgress();
4882         this.responseType = "";
4883         this.response = "";
4884         if (sinonXhr.supportsCORS) {
4885             this.withCredentials = false;
4886         }
4888         var xhr = this;
4889         var events = ["loadstart", "load", "abort", "loadend"];
4891         function addEventListener(eventName) {
4892             xhr.addEventListener(eventName, function (event) {
4893                 var listener = xhr["on" + eventName];
4895                 if (listener && typeof listener === "function") {
4896                     listener.call(this, event);
4897                 }
4898             });
4899         }
4901         for (var i = events.length - 1; i >= 0; i--) {
4902             addEventListener(events[i]);
4903         }
4905         if (typeof FakeXMLHttpRequest.onCreate === "function") {
4906             FakeXMLHttpRequest.onCreate(this);
4907         }
4908     }
4910     function verifyState(xhr) {
4911         if (xhr.readyState !== FakeXMLHttpRequest.OPENED) {
4912             throw new Error("INVALID_STATE_ERR");
4913         }
4915         if (xhr.sendFlag) {
4916             throw new Error("INVALID_STATE_ERR");
4917         }
4918     }
4920     function getHeader(headers, header) {
4921         header = header.toLowerCase();
4923         for (var h in headers) {
4924             if (h.toLowerCase() === header) {
4925                 return h;
4926             }
4927         }
4929         return null;
4930     }
4932     // filtering to enable a white-list version of Sinon FakeXhr,
4933     // where whitelisted requests are passed through to real XHR
4934     function each(collection, callback) {
4935         if (!collection) {
4936             return;
4937         }
4939         for (var i = 0, l = collection.length; i < l; i += 1) {
4940             callback(collection[i]);
4941         }
4942     }
4943     function some(collection, callback) {
4944         for (var index = 0; index < collection.length; index++) {
4945             if (callback(collection[index]) === true) {
4946                 return true;
4947             }
4948         }
4949         return false;
4950     }
4951     // largest arity in XHR is 5 - XHR#open
4952     var apply = function (obj, method, args) {
4953         switch (args.length) {
4954         case 0: return obj[method]();
4955         case 1: return obj[method](args[0]);
4956         case 2: return obj[method](args[0], args[1]);
4957         case 3: return obj[method](args[0], args[1], args[2]);
4958         case 4: return obj[method](args[0], args[1], args[2], args[3]);
4959         case 5: return obj[method](args[0], args[1], args[2], args[3], args[4]);
4960         }
4961     };
4963     FakeXMLHttpRequest.filters = [];
4964     FakeXMLHttpRequest.addFilter = function addFilter(fn) {
4965         this.filters.push(fn);
4966     };
4967     var IE6Re = /MSIE 6/;
4968     FakeXMLHttpRequest.defake = function defake(fakeXhr, xhrArgs) {
4969         var xhr = new sinonXhr.workingXHR(); // eslint-disable-line new-cap
4971         each([
4972             "open",
4973             "setRequestHeader",
4974             "send",
4975             "abort",
4976             "getResponseHeader",
4977             "getAllResponseHeaders",
4978             "addEventListener",
4979             "overrideMimeType",
4980             "removeEventListener"
4981         ], function (method) {
4982             fakeXhr[method] = function () {
4983                 return apply(xhr, method, arguments);
4984             };
4985         });
4987         var copyAttrs = function (args) {
4988             each(args, function (attr) {
4989                 try {
4990                     fakeXhr[attr] = xhr[attr];
4991                 } catch (e) {
4992                     if (!IE6Re.test(navigator.userAgent)) {
4993                         throw e;
4994                     }
4995                 }
4996             });
4997         };
4999         var stateChange = function stateChange() {
5000             fakeXhr.readyState = xhr.readyState;
5001             if (xhr.readyState >= FakeXMLHttpRequest.HEADERS_RECEIVED) {
5002                 copyAttrs(["status", "statusText"]);
5003             }
5004             if (xhr.readyState >= FakeXMLHttpRequest.LOADING) {
5005                 copyAttrs(["responseText", "response"]);
5006             }
5007             if (xhr.readyState === FakeXMLHttpRequest.DONE) {
5008                 copyAttrs(["responseXML"]);
5009             }
5010             if (fakeXhr.onreadystatechange) {
5011                 fakeXhr.onreadystatechange.call(fakeXhr, { target: fakeXhr });
5012             }
5013         };
5015         if (xhr.addEventListener) {
5016             for (var event in fakeXhr.eventListeners) {
5017                 if (fakeXhr.eventListeners.hasOwnProperty(event)) {
5019                     /*eslint-disable no-loop-func*/
5020                     each(fakeXhr.eventListeners[event], function (handler) {
5021                         xhr.addEventListener(event, handler);
5022                     });
5023                     /*eslint-enable no-loop-func*/
5024                 }
5025             }
5026             xhr.addEventListener("readystatechange", stateChange);
5027         } else {
5028             xhr.onreadystatechange = stateChange;
5029         }
5030         apply(xhr, "open", xhrArgs);
5031     };
5032     FakeXMLHttpRequest.useFilters = false;
5034     function verifyRequestOpened(xhr) {
5035         if (xhr.readyState !== FakeXMLHttpRequest.OPENED) {
5036             throw new Error("INVALID_STATE_ERR - " + xhr.readyState);
5037         }
5038     }
5040     function verifyRequestSent(xhr) {
5041         if (xhr.readyState === FakeXMLHttpRequest.DONE) {
5042             throw new Error("Request done");
5043         }
5044     }
5046     function verifyHeadersReceived(xhr) {
5047         if (xhr.async && xhr.readyState !== FakeXMLHttpRequest.HEADERS_RECEIVED) {
5048             throw new Error("No headers received");
5049         }
5050     }
5052     function verifyResponseBodyType(body) {
5053         if (typeof body !== "string") {
5054             var error = new Error("Attempted to respond to fake XMLHttpRequest with " +
5055                                  body + ", which is not a string.");
5056             error.name = "InvalidBodyException";
5057             throw error;
5058         }
5059     }
5061     function convertToArrayBuffer(body) {
5062         var buffer = new ArrayBuffer(body.length);
5063         var view = new Uint8Array(buffer);
5064         for (var i = 0; i < body.length; i++) {
5065             var charCode = body.charCodeAt(i);
5066             if (charCode >= 256) {
5067                 throw new TypeError("arraybuffer or blob responseTypes require binary string, " +
5068                                     "invalid character " + body[i] + " found.");
5069             }
5070             view[i] = charCode;
5071         }
5072         return buffer;
5073     }
5075     function isXmlContentType(contentType) {
5076         return !contentType || /(text\/xml)|(application\/xml)|(\+xml)/.test(contentType);
5077     }
5079     function convertResponseBody(responseType, contentType, body) {
5080         if (responseType === "" || responseType === "text") {
5081             return body;
5082         } else if (supportsArrayBuffer && responseType === "arraybuffer") {
5083             return convertToArrayBuffer(body);
5084         } else if (responseType === "json") {
5085             try {
5086                 return JSON.parse(body);
5087             } catch (e) {
5088                 // Return parsing failure as null
5089                 return null;
5090             }
5091         } else if (supportsBlob && responseType === "blob") {
5092             var blobOptions = {};
5093             if (contentType) {
5094                 blobOptions.type = contentType;
5095             }
5096             return new Blob([convertToArrayBuffer(body)], blobOptions);
5097         } else if (responseType === "document") {
5098             if (isXmlContentType(contentType)) {
5099                 return FakeXMLHttpRequest.parseXML(body);
5100             }
5101             return null;
5102         }
5103         throw new Error("Invalid responseType " + responseType);
5104     }
5106     function clearResponse(xhr) {
5107         if (xhr.responseType === "" || xhr.responseType === "text") {
5108             xhr.response = xhr.responseText = "";
5109         } else {
5110             xhr.response = xhr.responseText = null;
5111         }
5112         xhr.responseXML = null;
5113     }
5115     FakeXMLHttpRequest.parseXML = function parseXML(text) {
5116         // Treat empty string as parsing failure
5117         if (text !== "") {
5118             try {
5119                 if (typeof DOMParser !== "undefined") {
5120                     var parser = new DOMParser();
5121                     return parser.parseFromString(text, "text/xml");
5122                 }
5123                 var xmlDoc = new window.ActiveXObject("Microsoft.XMLDOM");
5124                 xmlDoc.async = "false";
5125                 xmlDoc.loadXML(text);
5126                 return xmlDoc;
5127             } catch (e) {
5128                 // Unable to parse XML - no biggie
5129             }
5130         }
5132         return null;
5133     };
5135     FakeXMLHttpRequest.statusCodes = {
5136         100: "Continue",
5137         101: "Switching Protocols",
5138         200: "OK",
5139         201: "Created",
5140         202: "Accepted",
5141         203: "Non-Authoritative Information",
5142         204: "No Content",
5143         205: "Reset Content",
5144         206: "Partial Content",
5145         207: "Multi-Status",
5146         300: "Multiple Choice",
5147         301: "Moved Permanently",
5148         302: "Found",
5149         303: "See Other",
5150         304: "Not Modified",
5151         305: "Use Proxy",
5152         307: "Temporary Redirect",
5153         400: "Bad Request",
5154         401: "Unauthorized",
5155         402: "Payment Required",
5156         403: "Forbidden",
5157         404: "Not Found",
5158         405: "Method Not Allowed",
5159         406: "Not Acceptable",
5160         407: "Proxy Authentication Required",
5161         408: "Request Timeout",
5162         409: "Conflict",
5163         410: "Gone",
5164         411: "Length Required",
5165         412: "Precondition Failed",
5166         413: "Request Entity Too Large",
5167         414: "Request-URI Too Long",
5168         415: "Unsupported Media Type",
5169         416: "Requested Range Not Satisfiable",
5170         417: "Expectation Failed",
5171         422: "Unprocessable Entity",
5172         500: "Internal Server Error",
5173         501: "Not Implemented",
5174         502: "Bad Gateway",
5175         503: "Service Unavailable",
5176         504: "Gateway Timeout",
5177         505: "HTTP Version Not Supported"
5178     };
5180     function makeApi(sinon) {
5181         sinon.xhr = sinonXhr;
5183         sinon.extend(FakeXMLHttpRequest.prototype, sinon.EventTarget, {
5184             async: true,
5186             open: function open(method, url, async, username, password) {
5187                 this.method = method;
5188                 this.url = url;
5189                 this.async = typeof async === "boolean" ? async : true;
5190                 this.username = username;
5191                 this.password = password;
5192                 clearResponse(this);
5193                 this.requestHeaders = {};
5194                 this.sendFlag = false;
5196                 if (FakeXMLHttpRequest.useFilters === true) {
5197                     var xhrArgs = arguments;
5198                     var defake = some(FakeXMLHttpRequest.filters, function (filter) {
5199                         return filter.apply(this, xhrArgs);
5200                     });
5201                     if (defake) {
5202                         return FakeXMLHttpRequest.defake(this, arguments);
5203                     }
5204                 }
5205                 this.readyStateChange(FakeXMLHttpRequest.OPENED);
5206             },
5208             readyStateChange: function readyStateChange(state) {
5209                 this.readyState = state;
5211                 var readyStateChangeEvent = new sinon.Event("readystatechange", false, false, this);
5213                 if (typeof this.onreadystatechange === "function") {
5214                     try {
5215                         this.onreadystatechange(readyStateChangeEvent);
5216                     } catch (e) {
5217                         sinon.logError("Fake XHR onreadystatechange handler", e);
5218                     }
5219                 }
5221                 switch (this.readyState) {
5222                     case FakeXMLHttpRequest.DONE:
5223                         if (supportsProgress) {
5224                             this.upload.dispatchEvent(new sinon.ProgressEvent("progress", {loaded: 100, total: 100}));
5225                             this.dispatchEvent(new sinon.ProgressEvent("progress", {loaded: 100, total: 100}));
5226                         }
5227                         this.upload.dispatchEvent(new sinon.Event("load", false, false, this));
5228                         this.dispatchEvent(new sinon.Event("load", false, false, this));
5229                         this.dispatchEvent(new sinon.Event("loadend", false, false, this));
5230                         break;
5231                 }
5233                 this.dispatchEvent(readyStateChangeEvent);
5234             },
5236             setRequestHeader: function setRequestHeader(header, value) {
5237                 verifyState(this);
5239                 if (unsafeHeaders[header] || /^(Sec-|Proxy-)/.test(header)) {
5240                     throw new Error("Refused to set unsafe header \"" + header + "\"");
5241                 }
5243                 if (this.requestHeaders[header]) {
5244                     this.requestHeaders[header] += "," + value;
5245                 } else {
5246                     this.requestHeaders[header] = value;
5247                 }
5248             },
5250             // Helps testing
5251             setResponseHeaders: function setResponseHeaders(headers) {
5252                 verifyRequestOpened(this);
5253                 this.responseHeaders = {};
5255                 for (var header in headers) {
5256                     if (headers.hasOwnProperty(header)) {
5257                         this.responseHeaders[header] = headers[header];
5258                     }
5259                 }
5261                 if (this.async) {
5262                     this.readyStateChange(FakeXMLHttpRequest.HEADERS_RECEIVED);
5263                 } else {
5264                     this.readyState = FakeXMLHttpRequest.HEADERS_RECEIVED;
5265                 }
5266             },
5268             // Currently treats ALL data as a DOMString (i.e. no Document)
5269             send: function send(data) {
5270                 verifyState(this);
5272                 if (!/^(get|head)$/i.test(this.method)) {
5273                     var contentType = getHeader(this.requestHeaders, "Content-Type");
5274                     if (this.requestHeaders[contentType]) {
5275                         var value = this.requestHeaders[contentType].split(";");
5276                         this.requestHeaders[contentType] = value[0] + ";charset=utf-8";
5277                     } else if (supportsFormData && !(data instanceof FormData)) {
5278                         this.requestHeaders["Content-Type"] = "text/plain;charset=utf-8";
5279                     }
5281                     this.requestBody = data;
5282                 }
5284                 this.errorFlag = false;
5285                 this.sendFlag = this.async;
5286                 clearResponse(this);
5287                 this.readyStateChange(FakeXMLHttpRequest.OPENED);
5289                 if (typeof this.onSend === "function") {
5290                     this.onSend(this);
5291                 }
5293                 this.dispatchEvent(new sinon.Event("loadstart", false, false, this));
5294             },
5296             abort: function abort() {
5297                 this.aborted = true;
5298                 clearResponse(this);
5299                 this.errorFlag = true;
5300                 this.requestHeaders = {};
5301                 this.responseHeaders = {};
5303                 if (this.readyState > FakeXMLHttpRequest.UNSENT && this.sendFlag) {
5304                     this.readyStateChange(FakeXMLHttpRequest.DONE);
5305                     this.sendFlag = false;
5306                 }
5308                 this.readyState = FakeXMLHttpRequest.UNSENT;
5310                 this.dispatchEvent(new sinon.Event("abort", false, false, this));
5312                 this.upload.dispatchEvent(new sinon.Event("abort", false, false, this));
5314                 if (typeof this.onerror === "function") {
5315                     this.onerror();
5316                 }
5317             },
5319             getResponseHeader: function getResponseHeader(header) {
5320                 if (this.readyState < FakeXMLHttpRequest.HEADERS_RECEIVED) {
5321                     return null;
5322                 }
5324                 if (/^Set-Cookie2?$/i.test(header)) {
5325                     return null;
5326                 }
5328                 header = getHeader(this.responseHeaders, header);
5330                 return this.responseHeaders[header] || null;
5331             },
5333             getAllResponseHeaders: function getAllResponseHeaders() {
5334                 if (this.readyState < FakeXMLHttpRequest.HEADERS_RECEIVED) {
5335                     return "";
5336                 }
5338                 var headers = "";
5340                 for (var header in this.responseHeaders) {
5341                     if (this.responseHeaders.hasOwnProperty(header) &&
5342                         !/^Set-Cookie2?$/i.test(header)) {
5343                         headers += header + ": " + this.responseHeaders[header] + "\r\n";
5344                     }
5345                 }
5347                 return headers;
5348             },
5350             setResponseBody: function setResponseBody(body) {
5351                 verifyRequestSent(this);
5352                 verifyHeadersReceived(this);
5353                 verifyResponseBodyType(body);
5354                 var contentType = this.getResponseHeader("Content-Type");
5356                 var isTextResponse = this.responseType === "" || this.responseType === "text";
5357                 clearResponse(this);
5358                 if (this.async) {
5359                     var chunkSize = this.chunkSize || 10;
5360                     var index = 0;
5362                     do {
5363                         this.readyStateChange(FakeXMLHttpRequest.LOADING);
5365                         if (isTextResponse) {
5366                             this.responseText = this.response += body.substring(index, index + chunkSize);
5367                         }
5368                         index += chunkSize;
5369                     } while (index < body.length);
5370                 }
5372                 this.response = convertResponseBody(this.responseType, contentType, body);
5373                 if (isTextResponse) {
5374                     this.responseText = this.response;
5375                 }
5377                 if (this.responseType === "document") {
5378                     this.responseXML = this.response;
5379                 } else if (this.responseType === "" && isXmlContentType(contentType)) {
5380                     this.responseXML = FakeXMLHttpRequest.parseXML(this.responseText);
5381                 }
5382                 this.readyStateChange(FakeXMLHttpRequest.DONE);
5383             },
5385             respond: function respond(status, headers, body) {
5386                 this.status = typeof status === "number" ? status : 200;
5387                 this.statusText = FakeXMLHttpRequest.statusCodes[this.status];
5388                 this.setResponseHeaders(headers || {});
5389                 this.setResponseBody(body || "");
5390             },
5392             uploadProgress: function uploadProgress(progressEventRaw) {
5393                 if (supportsProgress) {
5394                     this.upload.dispatchEvent(new sinon.ProgressEvent("progress", progressEventRaw));
5395                 }
5396             },
5398             downloadProgress: function downloadProgress(progressEventRaw) {
5399                 if (supportsProgress) {
5400                     this.dispatchEvent(new sinon.ProgressEvent("progress", progressEventRaw));
5401                 }
5402             },
5404             uploadError: function uploadError(error) {
5405                 if (supportsCustomEvent) {
5406                     this.upload.dispatchEvent(new sinon.CustomEvent("error", {detail: error}));
5407                 }
5408             }
5409         });
5411         sinon.extend(FakeXMLHttpRequest, {
5412             UNSENT: 0,
5413             OPENED: 1,
5414             HEADERS_RECEIVED: 2,
5415             LOADING: 3,
5416             DONE: 4
5417         });
5419         sinon.useFakeXMLHttpRequest = function () {
5420             FakeXMLHttpRequest.restore = function restore(keepOnCreate) {
5421                 if (sinonXhr.supportsXHR) {
5422                     global.XMLHttpRequest = sinonXhr.GlobalXMLHttpRequest;
5423                 }
5425                 if (sinonXhr.supportsActiveX) {
5426                     global.ActiveXObject = sinonXhr.GlobalActiveXObject;
5427                 }
5429                 delete FakeXMLHttpRequest.restore;
5431                 if (keepOnCreate !== true) {
5432                     delete FakeXMLHttpRequest.onCreate;
5433                 }
5434             };
5435             if (sinonXhr.supportsXHR) {
5436                 global.XMLHttpRequest = FakeXMLHttpRequest;
5437             }
5439             if (sinonXhr.supportsActiveX) {
5440                 global.ActiveXObject = function ActiveXObject(objId) {
5441                     if (objId === "Microsoft.XMLHTTP" || /^Msxml2\.XMLHTTP/i.test(objId)) {
5443                         return new FakeXMLHttpRequest();
5444                     }
5446                     return new sinonXhr.GlobalActiveXObject(objId);
5447                 };
5448             }
5450             return FakeXMLHttpRequest;
5451         };
5453         sinon.FakeXMLHttpRequest = FakeXMLHttpRequest;
5454     }
5456     var isNode = typeof module !== "undefined" && module.exports && typeof require === "function";
5457     var isAMD = typeof define === "function" && typeof define.amd === "object" && define.amd;
5459     function loadDependencies(require, exports, module) {
5460         var sinon = require("./core");
5461         require("../extend");
5462         require("./event");
5463         require("../log_error");
5464         makeApi(sinon);
5465         module.exports = sinon;
5466     }
5468     if (isAMD) {
5469         define(loadDependencies);
5470         return;
5471     }
5473     if (isNode) {
5474         loadDependencies(require, module.exports, module);
5475         return;
5476     }
5478     if (sinonGlobal) {
5479         makeApi(sinonGlobal);
5480     }
5482     typeof sinon === "object" && sinon, // eslint-disable-line no-undef
5483     typeof global !== "undefined" ? global : self
5487  * @depend fake_xdomain_request.js
5488  * @depend fake_xml_http_request.js
5489  * @depend ../format.js
5490  * @depend ../log_error.js
5491  */
5493  * The Sinon "server" mimics a web server that receives requests from
5494  * sinon.FakeXMLHttpRequest and provides an API to respond to those requests,
5495  * both synchronously and asynchronously. To respond synchronuously, canned
5496  * answers have to be provided upfront.
5498  * @author Christian Johansen (christian@cjohansen.no)
5499  * @license BSD
5501  * Copyright (c) 2010-2013 Christian Johansen
5502  */
5503 (function () {
5504     
5505     var push = [].push;
5507     function responseArray(handler) {
5508         var response = handler;
5510         if (Object.prototype.toString.call(handler) !== "[object Array]") {
5511             response = [200, {}, handler];
5512         }
5514         if (typeof response[2] !== "string") {
5515             throw new TypeError("Fake server response body should be string, but was " +
5516                                 typeof response[2]);
5517         }
5519         return response;
5520     }
5522     var wloc = typeof window !== "undefined" ? window.location : {};
5523     var rCurrLoc = new RegExp("^" + wloc.protocol + "//" + wloc.host);
5525     function matchOne(response, reqMethod, reqUrl) {
5526         var rmeth = response.method;
5527         var matchMethod = !rmeth || rmeth.toLowerCase() === reqMethod.toLowerCase();
5528         var url = response.url;
5529         var matchUrl = !url || url === reqUrl || (typeof url.test === "function" && url.test(reqUrl));
5531         return matchMethod && matchUrl;
5532     }
5534     function match(response, request) {
5535         var requestUrl = request.url;
5537         if (!/^https?:\/\//.test(requestUrl) || rCurrLoc.test(requestUrl)) {
5538             requestUrl = requestUrl.replace(rCurrLoc, "");
5539         }
5541         if (matchOne(response, this.getHTTPMethod(request), requestUrl)) {
5542             if (typeof response.response === "function") {
5543                 var ru = response.url;
5544                 var args = [request].concat(ru && typeof ru.exec === "function" ? ru.exec(requestUrl).slice(1) : []);
5545                 return response.response.apply(response, args);
5546             }
5548             return true;
5549         }
5551         return false;
5552     }
5554     function makeApi(sinon) {
5555         sinon.fakeServer = {
5556             create: function (config) {
5557                 var server = sinon.create(this);
5558                 server.configure(config);
5559                 if (!sinon.xhr.supportsCORS) {
5560                     this.xhr = sinon.useFakeXDomainRequest();
5561                 } else {
5562                     this.xhr = sinon.useFakeXMLHttpRequest();
5563                 }
5564                 server.requests = [];
5566                 this.xhr.onCreate = function (xhrObj) {
5567                     server.addRequest(xhrObj);
5568                 };
5570                 return server;
5571             },
5572             configure: function (config) {
5573                 var whitelist = {
5574                     "autoRespond": true,
5575                     "autoRespondAfter": true,
5576                     "respondImmediately": true,
5577                     "fakeHTTPMethods": true
5578                 };
5579                 var setting;
5581                 config = config || {};
5582                 for (setting in config) {
5583                     if (whitelist.hasOwnProperty(setting) && config.hasOwnProperty(setting)) {
5584                         this[setting] = config[setting];
5585                     }
5586                 }
5587             },
5588             addRequest: function addRequest(xhrObj) {
5589                 var server = this;
5590                 push.call(this.requests, xhrObj);
5592                 xhrObj.onSend = function () {
5593                     server.handleRequest(this);
5595                     if (server.respondImmediately) {
5596                         server.respond();
5597                     } else if (server.autoRespond && !server.responding) {
5598                         setTimeout(function () {
5599                             server.responding = false;
5600                             server.respond();
5601                         }, server.autoRespondAfter || 10);
5603                         server.responding = true;
5604                     }
5605                 };
5606             },
5608             getHTTPMethod: function getHTTPMethod(request) {
5609                 if (this.fakeHTTPMethods && /post/i.test(request.method)) {
5610                     var matches = (request.requestBody || "").match(/_method=([^\b;]+)/);
5611                     return matches ? matches[1] : request.method;
5612                 }
5614                 return request.method;
5615             },
5617             handleRequest: function handleRequest(xhr) {
5618                 if (xhr.async) {
5619                     if (!this.queue) {
5620                         this.queue = [];
5621                     }
5623                     push.call(this.queue, xhr);
5624                 } else {
5625                     this.processRequest(xhr);
5626                 }
5627             },
5629             log: function log(response, request) {
5630                 var str;
5632                 str = "Request:\n" + sinon.format(request) + "\n\n";
5633                 str += "Response:\n" + sinon.format(response) + "\n\n";
5635                 sinon.log(str);
5636             },
5638             respondWith: function respondWith(method, url, body) {
5639                 if (arguments.length === 1 && typeof method !== "function") {
5640                     this.response = responseArray(method);
5641                     return;
5642                 }
5644                 if (!this.responses) {
5645                     this.responses = [];
5646                 }
5648                 if (arguments.length === 1) {
5649                     body = method;
5650                     url = method = null;
5651                 }
5653                 if (arguments.length === 2) {
5654                     body = url;
5655                     url = method;
5656                     method = null;
5657                 }
5659                 push.call(this.responses, {
5660                     method: method,
5661                     url: url,
5662                     response: typeof body === "function" ? body : responseArray(body)
5663                 });
5664             },
5666             respond: function respond() {
5667                 if (arguments.length > 0) {
5668                     this.respondWith.apply(this, arguments);
5669                 }
5671                 var queue = this.queue || [];
5672                 var requests = queue.splice(0, queue.length);
5674                 for (var i = 0; i < requests.length; i++) {
5675                     this.processRequest(requests[i]);
5676                 }
5677             },
5679             processRequest: function processRequest(request) {
5680                 try {
5681                     if (request.aborted) {
5682                         return;
5683                     }
5685                     var response = this.response || [404, {}, ""];
5687                     if (this.responses) {
5688                         for (var l = this.responses.length, i = l - 1; i >= 0; i--) {
5689                             if (match.call(this, this.responses[i], request)) {
5690                                 response = this.responses[i].response;
5691                                 break;
5692                             }
5693                         }
5694                     }
5696                     if (request.readyState !== 4) {
5697                         this.log(response, request);
5699                         request.respond(response[0], response[1], response[2]);
5700                     }
5701                 } catch (e) {
5702                     sinon.logError("Fake server request processing", e);
5703                 }
5704             },
5706             restore: function restore() {
5707                 return this.xhr.restore && this.xhr.restore.apply(this.xhr, arguments);
5708             }
5709         };
5710     }
5712     var isNode = typeof module !== "undefined" && module.exports && typeof require === "function";
5713     var isAMD = typeof define === "function" && typeof define.amd === "object" && define.amd;
5715     function loadDependencies(require, exports, module) {
5716         var sinon = require("./core");
5717         require("./fake_xdomain_request");
5718         require("./fake_xml_http_request");
5719         require("../format");
5720         makeApi(sinon);
5721         module.exports = sinon;
5722     }
5724     if (isAMD) {
5725         define(loadDependencies);
5726     } else if (isNode) {
5727         loadDependencies(require, module.exports, module);
5728     } else {
5729         makeApi(sinon); // eslint-disable-line no-undef
5730     }
5731 }());
5734  * @depend fake_server.js
5735  * @depend fake_timers.js
5736  */
5738  * Add-on for sinon.fakeServer that automatically handles a fake timer along with
5739  * the FakeXMLHttpRequest. The direct inspiration for this add-on is jQuery
5740  * 1.3.x, which does not use xhr object's onreadystatehandler at all - instead,
5741  * it polls the object for completion with setInterval. Dispite the direct
5742  * motivation, there is nothing jQuery-specific in this file, so it can be used
5743  * in any environment where the ajax implementation depends on setInterval or
5744  * setTimeout.
5746  * @author Christian Johansen (christian@cjohansen.no)
5747  * @license BSD
5749  * Copyright (c) 2010-2013 Christian Johansen
5750  */
5751 (function () {
5752     
5753     function makeApi(sinon) {
5754         function Server() {}
5755         Server.prototype = sinon.fakeServer;
5757         sinon.fakeServerWithClock = new Server();
5759         sinon.fakeServerWithClock.addRequest = function addRequest(xhr) {
5760             if (xhr.async) {
5761                 if (typeof setTimeout.clock === "object") {
5762                     this.clock = setTimeout.clock;
5763                 } else {
5764                     this.clock = sinon.useFakeTimers();
5765                     this.resetClock = true;
5766                 }
5768                 if (!this.longestTimeout) {
5769                     var clockSetTimeout = this.clock.setTimeout;
5770                     var clockSetInterval = this.clock.setInterval;
5771                     var server = this;
5773                     this.clock.setTimeout = function (fn, timeout) {
5774                         server.longestTimeout = Math.max(timeout, server.longestTimeout || 0);
5776                         return clockSetTimeout.apply(this, arguments);
5777                     };
5779                     this.clock.setInterval = function (fn, timeout) {
5780                         server.longestTimeout = Math.max(timeout, server.longestTimeout || 0);
5782                         return clockSetInterval.apply(this, arguments);
5783                     };
5784                 }
5785             }
5787             return sinon.fakeServer.addRequest.call(this, xhr);
5788         };
5790         sinon.fakeServerWithClock.respond = function respond() {
5791             var returnVal = sinon.fakeServer.respond.apply(this, arguments);
5793             if (this.clock) {
5794                 this.clock.tick(this.longestTimeout || 0);
5795                 this.longestTimeout = 0;
5797                 if (this.resetClock) {
5798                     this.clock.restore();
5799                     this.resetClock = false;
5800                 }
5801             }
5803             return returnVal;
5804         };
5806         sinon.fakeServerWithClock.restore = function restore() {
5807             if (this.clock) {
5808                 this.clock.restore();
5809             }
5811             return sinon.fakeServer.restore.apply(this, arguments);
5812         };
5813     }
5815     var isNode = typeof module !== "undefined" && module.exports && typeof require === "function";
5816     var isAMD = typeof define === "function" && typeof define.amd === "object" && define.amd;
5818     function loadDependencies(require) {
5819         var sinon = require("./core");
5820         require("./fake_server");
5821         require("./fake_timers");
5822         makeApi(sinon);
5823     }
5825     if (isAMD) {
5826         define(loadDependencies);
5827     } else if (isNode) {
5828         loadDependencies(require);
5829     } else {
5830         makeApi(sinon); // eslint-disable-line no-undef
5831     }
5832 }());
5835  * @depend util/core.js
5836  * @depend extend.js
5837  * @depend collection.js
5838  * @depend util/fake_timers.js
5839  * @depend util/fake_server_with_clock.js
5840  */
5842  * Manages fake collections as well as fake utilities such as Sinon's
5843  * timers and fake XHR implementation in one convenient object.
5845  * @author Christian Johansen (christian@cjohansen.no)
5846  * @license BSD
5848  * Copyright (c) 2010-2013 Christian Johansen
5849  */
5850 (function (sinonGlobal) {
5851     
5852     function makeApi(sinon) {
5853         var push = [].push;
5855         function exposeValue(sandbox, config, key, value) {
5856             if (!value) {
5857                 return;
5858             }
5860             if (config.injectInto && !(key in config.injectInto)) {
5861                 config.injectInto[key] = value;
5862                 sandbox.injectedKeys.push(key);
5863             } else {
5864                 push.call(sandbox.args, value);
5865             }
5866         }
5868         function prepareSandboxFromConfig(config) {
5869             var sandbox = sinon.create(sinon.sandbox);
5871             if (config.useFakeServer) {
5872                 if (typeof config.useFakeServer === "object") {
5873                     sandbox.serverPrototype = config.useFakeServer;
5874                 }
5876                 sandbox.useFakeServer();
5877             }
5879             if (config.useFakeTimers) {
5880                 if (typeof config.useFakeTimers === "object") {
5881                     sandbox.useFakeTimers.apply(sandbox, config.useFakeTimers);
5882                 } else {
5883                     sandbox.useFakeTimers();
5884                 }
5885             }
5887             return sandbox;
5888         }
5890         sinon.sandbox = sinon.extend(sinon.create(sinon.collection), {
5891             useFakeTimers: function useFakeTimers() {
5892                 this.clock = sinon.useFakeTimers.apply(sinon, arguments);
5894                 return this.add(this.clock);
5895             },
5897             serverPrototype: sinon.fakeServer,
5899             useFakeServer: function useFakeServer() {
5900                 var proto = this.serverPrototype || sinon.fakeServer;
5902                 if (!proto || !proto.create) {
5903                     return null;
5904                 }
5906                 this.server = proto.create();
5907                 return this.add(this.server);
5908             },
5910             inject: function (obj) {
5911                 sinon.collection.inject.call(this, obj);
5913                 if (this.clock) {
5914                     obj.clock = this.clock;
5915                 }
5917                 if (this.server) {
5918                     obj.server = this.server;
5919                     obj.requests = this.server.requests;
5920                 }
5922                 obj.match = sinon.match;
5924                 return obj;
5925             },
5927             restore: function () {
5928                 sinon.collection.restore.apply(this, arguments);
5929                 this.restoreContext();
5930             },
5932             restoreContext: function () {
5933                 if (this.injectedKeys) {
5934                     for (var i = 0, j = this.injectedKeys.length; i < j; i++) {
5935                         delete this.injectInto[this.injectedKeys[i]];
5936                     }
5937                     this.injectedKeys = [];
5938                 }
5939             },
5941             create: function (config) {
5942                 if (!config) {
5943                     return sinon.create(sinon.sandbox);
5944                 }
5946                 var sandbox = prepareSandboxFromConfig(config);
5947                 sandbox.args = sandbox.args || [];
5948                 sandbox.injectedKeys = [];
5949                 sandbox.injectInto = config.injectInto;
5950                 var prop,
5951                     value;
5952                 var exposed = sandbox.inject({});
5954                 if (config.properties) {
5955                     for (var i = 0, l = config.properties.length; i < l; i++) {
5956                         prop = config.properties[i];
5957                         value = exposed[prop] || prop === "sandbox" && sandbox;
5958                         exposeValue(sandbox, config, prop, value);
5959                     }
5960                 } else {
5961                     exposeValue(sandbox, config, "sandbox", value);
5962                 }
5964                 return sandbox;
5965             },
5967             match: sinon.match
5968         });
5970         sinon.sandbox.useFakeXMLHttpRequest = sinon.sandbox.useFakeServer;
5972         return sinon.sandbox;
5973     }
5975     var isNode = typeof module !== "undefined" && module.exports && typeof require === "function";
5976     var isAMD = typeof define === "function" && typeof define.amd === "object" && define.amd;
5978     function loadDependencies(require, exports, module) {
5979         var sinon = require("./util/core");
5980         require("./extend");
5981         require("./util/fake_server_with_clock");
5982         require("./util/fake_timers");
5983         require("./collection");
5984         module.exports = makeApi(sinon);
5985     }
5987     if (isAMD) {
5988         define(loadDependencies);
5989         return;
5990     }
5992     if (isNode) {
5993         loadDependencies(require, module.exports, module);
5994         return;
5995     }
5997     if (sinonGlobal) {
5998         makeApi(sinonGlobal);
5999     }
6001     typeof sinon === "object" && sinon // eslint-disable-line no-undef
6005  * @depend util/core.js
6006  * @depend sandbox.js
6007  */
6009  * Test function, sandboxes fakes
6011  * @author Christian Johansen (christian@cjohansen.no)
6012  * @license BSD
6014  * Copyright (c) 2010-2013 Christian Johansen
6015  */
6016 (function (sinonGlobal) {
6017     
6018     function makeApi(sinon) {
6019         var slice = Array.prototype.slice;
6021         function test(callback) {
6022             var type = typeof callback;
6024             if (type !== "function") {
6025                 throw new TypeError("sinon.test needs to wrap a test function, got " + type);
6026             }
6028             function sinonSandboxedTest() {
6029                 var config = sinon.getConfig(sinon.config);
6030                 config.injectInto = config.injectIntoThis && this || config.injectInto;
6031                 var sandbox = sinon.sandbox.create(config);
6032                 var args = slice.call(arguments);
6033                 var oldDone = args.length && args[args.length - 1];
6034                 var exception, result;
6036                 if (typeof oldDone === "function") {
6037                     args[args.length - 1] = function sinonDone(res) {
6038                         if (res) {
6039                             sandbox.restore();
6040                         } else {
6041                             sandbox.verifyAndRestore();
6042                         }
6043                         oldDone(res);
6044                     };
6045                 }
6047                 try {
6048                     result = callback.apply(this, args.concat(sandbox.args));
6049                 } catch (e) {
6050                     exception = e;
6051                 }
6053                 if (typeof oldDone !== "function") {
6054                     if (typeof exception !== "undefined") {
6055                         sandbox.restore();
6056                         throw exception;
6057                     } else {
6058                         sandbox.verifyAndRestore();
6059                     }
6060                 }
6062                 return result;
6063             }
6065             if (callback.length) {
6066                 return function sinonAsyncSandboxedTest(done) { // eslint-disable-line no-unused-vars
6067                     return sinonSandboxedTest.apply(this, arguments);
6068                 };
6069             }
6071             return sinonSandboxedTest;
6072         }
6074         test.config = {
6075             injectIntoThis: true,
6076             injectInto: null,
6077             properties: ["spy", "stub", "mock", "clock", "server", "requests"],
6078             useFakeTimers: true,
6079             useFakeServer: true
6080         };
6082         sinon.test = test;
6083         return test;
6084     }
6086     var isNode = typeof module !== "undefined" && module.exports && typeof require === "function";
6087     var isAMD = typeof define === "function" && typeof define.amd === "object" && define.amd;
6089     function loadDependencies(require, exports, module) {
6090         var core = require("./util/core");
6091         require("./sandbox");
6092         module.exports = makeApi(core);
6093     }
6095     if (isAMD) {
6096         define(loadDependencies);
6097     } else if (isNode) {
6098         loadDependencies(require, module.exports, module);
6099     } else if (sinonGlobal) {
6100         makeApi(sinonGlobal);
6101     }
6102 }(typeof sinon === "object" && sinon || null)); // eslint-disable-line no-undef
6105  * @depend util/core.js
6106  * @depend test.js
6107  */
6109  * Test case, sandboxes all test functions
6111  * @author Christian Johansen (christian@cjohansen.no)
6112  * @license BSD
6114  * Copyright (c) 2010-2013 Christian Johansen
6115  */
6116 (function (sinonGlobal) {
6117     
6118     function createTest(property, setUp, tearDown) {
6119         return function () {
6120             if (setUp) {
6121                 setUp.apply(this, arguments);
6122             }
6124             var exception, result;
6126             try {
6127                 result = property.apply(this, arguments);
6128             } catch (e) {
6129                 exception = e;
6130             }
6132             if (tearDown) {
6133                 tearDown.apply(this, arguments);
6134             }
6136             if (exception) {
6137                 throw exception;
6138             }
6140             return result;
6141         };
6142     }
6144     function makeApi(sinon) {
6145         function testCase(tests, prefix) {
6146             if (!tests || typeof tests !== "object") {
6147                 throw new TypeError("sinon.testCase needs an object with test functions");
6148             }
6150             prefix = prefix || "test";
6151             var rPrefix = new RegExp("^" + prefix);
6152             var methods = {};
6153             var setUp = tests.setUp;
6154             var tearDown = tests.tearDown;
6155             var testName,
6156                 property,
6157                 method;
6159             for (testName in tests) {
6160                 if (tests.hasOwnProperty(testName) && !/^(setUp|tearDown)$/.test(testName)) {
6161                     property = tests[testName];
6163                     if (typeof property === "function" && rPrefix.test(testName)) {
6164                         method = property;
6166                         if (setUp || tearDown) {
6167                             method = createTest(property, setUp, tearDown);
6168                         }
6170                         methods[testName] = sinon.test(method);
6171                     } else {
6172                         methods[testName] = tests[testName];
6173                     }
6174                 }
6175             }
6177             return methods;
6178         }
6180         sinon.testCase = testCase;
6181         return testCase;
6182     }
6184     var isNode = typeof module !== "undefined" && module.exports && typeof require === "function";
6185     var isAMD = typeof define === "function" && typeof define.amd === "object" && define.amd;
6187     function loadDependencies(require, exports, module) {
6188         var core = require("./util/core");
6189         require("./test");
6190         module.exports = makeApi(core);
6191     }
6193     if (isAMD) {
6194         define(loadDependencies);
6195         return;
6196     }
6198     if (isNode) {
6199         loadDependencies(require, module.exports, module);
6200         return;
6201     }
6203     if (sinonGlobal) {
6204         makeApi(sinonGlobal);
6205     }
6207     typeof sinon === "object" && sinon // eslint-disable-line no-undef
6211  * @depend times_in_words.js
6212  * @depend util/core.js
6213  * @depend match.js
6214  * @depend format.js
6215  */
6217  * Assertions matching the test spy retrieval interface.
6219  * @author Christian Johansen (christian@cjohansen.no)
6220  * @license BSD
6222  * Copyright (c) 2010-2013 Christian Johansen
6223  */
6224 (function (sinonGlobal, global) {
6225     
6226     var slice = Array.prototype.slice;
6228     function makeApi(sinon) {
6229         var assert;
6231         function verifyIsStub() {
6232             var method;
6234             for (var i = 0, l = arguments.length; i < l; ++i) {
6235                 method = arguments[i];
6237                 if (!method) {
6238                     assert.fail("fake is not a spy");
6239                 }
6241                 if (method.proxy && method.proxy.isSinonProxy) {
6242                     verifyIsStub(method.proxy);
6243                 } else {
6244                     if (typeof method !== "function") {
6245                         assert.fail(method + " is not a function");
6246                     }
6248                     if (typeof method.getCall !== "function") {
6249                         assert.fail(method + " is not stubbed");
6250                     }
6251                 }
6253             }
6254         }
6256         function failAssertion(object, msg) {
6257             object = object || global;
6258             var failMethod = object.fail || assert.fail;
6259             failMethod.call(object, msg);
6260         }
6262         function mirrorPropAsAssertion(name, method, message) {
6263             if (arguments.length === 2) {
6264                 message = method;
6265                 method = name;
6266             }
6268             assert[name] = function (fake) {
6269                 verifyIsStub(fake);
6271                 var args = slice.call(arguments, 1);
6272                 var failed = false;
6274                 if (typeof method === "function") {
6275                     failed = !method(fake);
6276                 } else {
6277                     failed = typeof fake[method] === "function" ?
6278                         !fake[method].apply(fake, args) : !fake[method];
6279                 }
6281                 if (failed) {
6282                     failAssertion(this, (fake.printf || fake.proxy.printf).apply(fake, [message].concat(args)));
6283                 } else {
6284                     assert.pass(name);
6285                 }
6286             };
6287         }
6289         function exposedName(prefix, prop) {
6290             return !prefix || /^fail/.test(prop) ? prop :
6291                 prefix + prop.slice(0, 1).toUpperCase() + prop.slice(1);
6292         }
6294         assert = {
6295             failException: "AssertError",
6297             fail: function fail(message) {
6298                 var error = new Error(message);
6299                 error.name = this.failException || assert.failException;
6301                 throw error;
6302             },
6304             pass: function pass() {},
6306             callOrder: function assertCallOrder() {
6307                 verifyIsStub.apply(null, arguments);
6308                 var expected = "";
6309                 var actual = "";
6311                 if (!sinon.calledInOrder(arguments)) {
6312                     try {
6313                         expected = [].join.call(arguments, ", ");
6314                         var calls = slice.call(arguments);
6315                         var i = calls.length;
6316                         while (i) {
6317                             if (!calls[--i].called) {
6318                                 calls.splice(i, 1);
6319                             }
6320                         }
6321                         actual = sinon.orderByFirstCall(calls).join(", ");
6322                     } catch (e) {
6323                         // If this fails, we'll just fall back to the blank string
6324                     }
6326                     failAssertion(this, "expected " + expected + " to be " +
6327                                 "called in order but were called as " + actual);
6328                 } else {
6329                     assert.pass("callOrder");
6330                 }
6331             },
6333             callCount: function assertCallCount(method, count) {
6334                 verifyIsStub(method);
6336                 if (method.callCount !== count) {
6337                     var msg = "expected %n to be called " + sinon.timesInWords(count) +
6338                         " but was called %c%C";
6339                     failAssertion(this, method.printf(msg));
6340                 } else {
6341                     assert.pass("callCount");
6342                 }
6343             },
6345             expose: function expose(target, options) {
6346                 if (!target) {
6347                     throw new TypeError("target is null or undefined");
6348                 }
6350                 var o = options || {};
6351                 var prefix = typeof o.prefix === "undefined" && "assert" || o.prefix;
6352                 var includeFail = typeof o.includeFail === "undefined" || !!o.includeFail;
6354                 for (var method in this) {
6355                     if (method !== "expose" && (includeFail || !/^(fail)/.test(method))) {
6356                         target[exposedName(prefix, method)] = this[method];
6357                     }
6358                 }
6360                 return target;
6361             },
6363             match: function match(actual, expectation) {
6364                 var matcher = sinon.match(expectation);
6365                 if (matcher.test(actual)) {
6366                     assert.pass("match");
6367                 } else {
6368                     var formatted = [
6369                         "expected value to match",
6370                         "    expected = " + sinon.format(expectation),
6371                         "    actual = " + sinon.format(actual)
6372                     ];
6374                     failAssertion(this, formatted.join("\n"));
6375                 }
6376             }
6377         };
6379         mirrorPropAsAssertion("called", "expected %n to have been called at least once but was never called");
6380         mirrorPropAsAssertion("notCalled", function (spy) {
6381             return !spy.called;
6382         }, "expected %n to not have been called but was called %c%C");
6383         mirrorPropAsAssertion("calledOnce", "expected %n to be called once but was called %c%C");
6384         mirrorPropAsAssertion("calledTwice", "expected %n to be called twice but was called %c%C");
6385         mirrorPropAsAssertion("calledThrice", "expected %n to be called thrice but was called %c%C");
6386         mirrorPropAsAssertion("calledOn", "expected %n to be called with %1 as this but was called with %t");
6387         mirrorPropAsAssertion(
6388             "alwaysCalledOn",
6389             "expected %n to always be called with %1 as this but was called with %t"
6390         );
6391         mirrorPropAsAssertion("calledWithNew", "expected %n to be called with new");
6392         mirrorPropAsAssertion("alwaysCalledWithNew", "expected %n to always be called with new");
6393         mirrorPropAsAssertion("calledWith", "expected %n to be called with arguments %*%C");
6394         mirrorPropAsAssertion("calledWithMatch", "expected %n to be called with match %*%C");
6395         mirrorPropAsAssertion("alwaysCalledWith", "expected %n to always be called with arguments %*%C");
6396         mirrorPropAsAssertion("alwaysCalledWithMatch", "expected %n to always be called with match %*%C");
6397         mirrorPropAsAssertion("calledWithExactly", "expected %n to be called with exact arguments %*%C");
6398         mirrorPropAsAssertion("alwaysCalledWithExactly", "expected %n to always be called with exact arguments %*%C");
6399         mirrorPropAsAssertion("neverCalledWith", "expected %n to never be called with arguments %*%C");
6400         mirrorPropAsAssertion("neverCalledWithMatch", "expected %n to never be called with match %*%C");
6401         mirrorPropAsAssertion("threw", "%n did not throw exception%C");
6402         mirrorPropAsAssertion("alwaysThrew", "%n did not always throw exception%C");
6404         sinon.assert = assert;
6405         return assert;
6406     }
6408     var isNode = typeof module !== "undefined" && module.exports && typeof require === "function";
6409     var isAMD = typeof define === "function" && typeof define.amd === "object" && define.amd;
6411     function loadDependencies(require, exports, module) {
6412         var sinon = require("./util/core");
6413         require("./match");
6414         require("./format");
6415         module.exports = makeApi(sinon);
6416     }
6418     if (isAMD) {
6419         define(loadDependencies);
6420         return;
6421     }
6423     if (isNode) {
6424         loadDependencies(require, module.exports, module);
6425         return;
6426     }
6428     if (sinonGlobal) {
6429         makeApi(sinonGlobal);
6430     }
6432     typeof sinon === "object" && sinon, // eslint-disable-line no-undef
6433     typeof global !== "undefined" ? global : self
6436   return sinon;
6437 }));