Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(243)

Side by Side Diff: appengine/config_service/ui/bower_components/sinonjs/sinon.js

Issue 2923973003: Added base template for config ui. (Closed)
Patch Set: Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 /**
2 * Sinon.JS 1.17.1, 2015/09/26
3 *
4 * @author Christian Johansen (christian@cjohansen.no)
5 * @author Contributors: https://github.com/cjohansen/Sinon.JS/blob/master/AUTHO RS
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 modificati on,
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 notic e,
18 * this list of conditions and the following disclaimer in the documentati on
19 * and/or other materials provided with the distribution.
20 * * Neither the name of Christian Johansen nor the names of his contributor s
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" A ND
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 */
35
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");
68
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 }
76
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 }
83
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 }
106
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 }
126
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 }
140
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 }
154
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 }
164
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 }
181
182
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) {
199
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 = {};
212
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) {
219
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)) {
226
227 return true;
228 }
229
230 return false;
231 }
232
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) {
239
240 var i;
241 for (i = 0; i < objects.length; i++) {
242 if (objects[i] === obj) {
243 return i;
244 }
245 }
246
247 return -1;
248 }
249
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;
254
255 // == null also matches undefined
256 if (obj1 === obj2 ||
257 isNaN(obj1) || isNaN(obj2) ||
258 obj1 == null || obj2 == null ||
259 type1 !== "object" || type2 !== "object") {
260
261 return identical(obj1, obj2);
262 }
263
264 // Elements are only equal if identical(expected, actual)
265 if (isElement(obj1) || isElement(obj2)) { return false; }
266
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 }
273
274 if (obj1 instanceof RegExp && obj2 instanceof RegExp) {
275 if (obj1.toString() !== obj2.toString()) { return false; }
276 }
277
278 var class1 = getClass(obj1);
279 var class2 = getClass(obj2);
280 var keys1 = keys(obj1);
281 var keys2 = keys(obj2);
282
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 }
291
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;
298
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 }
304
305 // Start of the cyclic logic
306
307 value1 = obj1[key];
308 value2 = obj2[key];
309
310 isObject1 = isObject(value1);
311 isObject2 = isObject(value2);
312
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;
318
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) + ']';
329
330 // stop recursion if current objects are already compared
331 if (compared[newPath1 + newPath2]) {
332 return true;
333 }
334
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 }
344
345 // remember that the current objects are already compared
346 if (isObject1 && isObject2) {
347 compared[newPath1 + newPath2] = true;
348 }
349
350 // End of cyclic logic
351
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 }
358
359 return true;
360
361 }(obj1, obj2, '$1', '$2'));
362 }
363
364 var match;
365
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 }
379
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 }
391
392 if (typeof matcher === "function") {
393 return matcher(object) === true;
394 }
395
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 }
402
403 if (typeof matcher === "number") {
404 return matcher === object;
405 }
406
407 if (typeof matcher === "boolean") {
408 return matcher === object;
409 }
410
411 if (typeof(matcher) === "undefined") {
412 return typeof(object) === "undefined";
413 }
414
415 if (matcher === null) {
416 return object === null;
417 }
418
419 if (getClass(object) === "Array" && getClass(matcher) === "Array") {
420 return arrayContains(object, matcher);
421 }
422
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] === 'undefine d') {
435 if (value !== matcher[prop]) {
436 return false;
437 }
438 } else if (typeof value === "undefined" || !match(value, matche r[prop])) {
439 return false;
440 }
441 }
442 return true;
443 }
444
445 throw new Error("Matcher was not a string, a number, a " +
446 "function, a boolean or an object");
447 };
448
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 };
459 });
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 };
472
473 var hasOwn = Object.prototype.hasOwnProperty;
474
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 }
488
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 }
496
497 function constructorName(f, object) {
498 var name = functionName(object && object.constructor);
499 var excludes = f.excludeConstructors ||
500 formatio.excludeConstructors || [];
501
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 }
510
511 return name;
512 }
513
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 }
522
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 }
529
530 if (typeof object === "function" && !(object instanceof RegExp)) {
531 return ascii.func(object);
532 }
533
534 processed = processed || [];
535
536 if (isCircular(object, processed)) { return "[Circular]"; }
537
538 if (Object.prototype.toString.call(object) === "[object Array]") {
539 return ascii.array.call(f, object, processed);
540 }
541
542 if (!object) { return String((1/object) === -Infinity ? "-0" : object); }
543 if (samsam.isElement(object)) { return ascii.element(object); }
544
545 if (typeof object.toString === "function" &&
546 object.toString !== Object.prototype.toString) {
547 return object.toString();
548 }
549
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 }
556
557 return ascii.object.call(f, object, processed, indent);
558 }
559
560 ascii.func = function (func) {
561 return "function " + functionName(func) + "() {}";
562 };
563
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;
571
572 for (i = 0; i < l; ++i) {
573 pieces.push(ascii(this, array[i], processed));
574 }
575
576 if(l < array.length)
577 pieces.push("[... " + (array.length - l) + " more elements]");
578
579 return "[" + pieces.join(", ") + "]";
580 };
581
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.le ngth;
591
592 for (i = 0; i < l; ++i) {
593 prop = properties[i];
594 obj = object[prop];
595
596 if (isCircular(obj, processed)) {
597 str = "[Circular]";
598 } else {
599 str = ascii(this, obj, processed, indent + 2);
600 }
601
602 str = (/\s/.test(prop) ? '"' + prop + '"' : prop) + ": " + str;
603 length += str.length;
604 pieces.push(str);
605 }
606
607 var cons = constructorName(this, object);
608 var prefix = cons ? "[" + cons + "] " : "";
609 var is = "";
610 for (i = 0, k = indent; i < k; ++i) { is += " "; }
611
612 if(l < properties.length)
613 pieces.push("[... " + (properties.length - l) + " more elements]");
614
615 if (length + indent > 80) {
616 return prefix + "{\n " + is + pieces.join(",\n " + is) + "\n" +
617 is + "}";
618 }
619 return prefix + "{ " + pieces.join(", ") + " }";
620 };
621
622 ascii.element = function (element) {
623 var tagName = element.tagName.toLowerCase();
624 var attrs = element.attributes, attr, pairs = [], attrName, i, l, val;
625
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 }
634
635 var formatted = "<" + tagName + (pairs.length > 0 ? " " : "");
636 var content = element.innerHTML;
637
638 if (content.length > 20) {
639 content = content.substr(0, 20) + "[...]";
640 }
641
642 var res = formatted + pairs.join(" ") + ">" + content +
643 "</" + tagName + ">";
644
645 return res.replace(/ contentEditable="inherit"/, "");
646 };
647
648 function Formatio(options) {
649 for (var opt in options) {
650 this[opt] = options[opt];
651 }
652 }
653
654 Formatio.prototype = {
655 functionName: functionName,
656
657 configure: function (options) {
658 return new Formatio(options);
659 },
660
661 constructorName: function (object) {
662 return constructorName(this, object);
663 },
664
665 ascii: function (object, processed, indent) {
666 return ascii(this, object, processed, indent);
667 }
668 };
669
670 return Formatio.prototype;
671 });
672 !function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.expo rts=e();else if("function"==typeof define&&define.amd)define([],e);else{var f;"u ndefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined "!=typeof self&&(f=self),f.lolex=e()}}(function(){var define,module,exports;retu rn (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]={expo rts:{}};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,export s){
673 (function (global){
674 /*global global, window*/
675 /**
676 * @author Christian Johansen (christian@cjohansen.no) and contributors
677 * @license BSD
678 *
679 * Copyright (c) 2010-2014 Christian Johansen
680 */
681
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;
688
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;
694
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 }
701
702 // node expects setTimeout/setInterval to return a fn object w/ .ref()/.unre f()
703 // browsers, a number.
704 // see https://github.com/cjohansen/Sinon.JS/pull/436
705
706 var NOOP = function () { return undefined; };
707 var timeoutResult = setTimeout(NOOP, 0);
708 var addTimerReturnsObject = typeof timeoutResult === "object";
709 clearTimeout(timeoutResult);
710
711 var NativeDate = Date;
712 var uniqueTimerId = 1;
713
714 /**
715 * Parse strings like "01:10:00" (meaning 1 hour, 10 minutes, 0 seconds) int o
716 * number of milliseconds. This is used to support human-readable strings pa ssed
717 * to clock.tick()
718 */
719 function parseTime(str) {
720 if (!str) {
721 return 0;
722 }
723
724 var strings = str.split(":");
725 var l = strings.length, i = l;
726 var ms = 0, parsed;
727
728 if (l > 3 || !/^(\d\d:){0,2}\d\d?$/.test(str)) {
729 throw new Error("tick only understands numbers and 'h:m:s'");
730 }
731
732 while (i--) {
733 parsed = parseInt(strings[i], 10);
734
735 if (parsed >= 60) {
736 throw new Error("Invalid time " + str);
737 }
738
739 ms += parsed * Math.pow(60, (l - i - 1));
740 }
741
742 return ms * 1000;
743 }
744
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 }
754
755 function inRange(from, to, timer) {
756 return timer && timer.callAt >= from && timer.callAt <= to;
757 }
758
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 }
766
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 }
775
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 }
784
785 // set special toString implementation
786 target.toString = function toString() {
787 return source.toString();
788 };
789
790 target.prototype = source.prototype;
791 target.parse = source.parse;
792 target.UTC = source.UTC;
793 target.prototype.toUTCString = source.prototype.toUTCString;
794
795 return target;
796 }
797
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, m s);
819 }
820 }
821
822 return mirrorDateProperties(ClockDate, NativeDate);
823 }
824
825 function addTimer(clock, timer) {
826 if (timer.func === undefined) {
827 throw new Error("Callback must be provided to timer calls");
828 }
829
830 if (!clock.timers) {
831 clock.timers = {};
832 }
833
834 timer.id = uniqueTimerId++;
835 timer.createdAt = clock.now;
836 timer.callAt = clock.now + (timer.delay || (clock.duringTick ? 1 : 0));
837
838 clock.timers[timer.id] = timer;
839
840 if (addTimerReturnsObject) {
841 return {
842 id: timer.id,
843 ref: NOOP,
844 unref: NOOP
845 };
846 }
847
848 return timer.id;
849 }
850
851
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 }
860
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 }
868
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 }
876
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 }
884
885 // As timer ids are unique, no fallback `0` is necessary
886 }
887
888 function firstTimerInRange(clock, from, to) {
889 var timers = clock.timers,
890 timer = null,
891 id,
892 isInRange;
893
894 for (id in timers) {
895 if (timers.hasOwnProperty(id)) {
896 isInRange = inRange(from, to, timers[id]);
897
898 if (isInRange && (!timer || compareTimers(timer, timers[id]) === 1)) {
899 timer = timers[id];
900 }
901 }
902 }
903
904 return timer;
905 }
906
907 function callTimer(clock, timer) {
908 var exception;
909
910 if (typeof timer.interval === "number") {
911 clock.timers[timer.id].callAt += timer.interval;
912 } else {
913 delete clock.timers[timer.id];
914 }
915
916 try {
917 if (typeof timer.func === "function") {
918 timer.func.apply(null, timer.args);
919 } else {
920 eval(timer.func);
921 }
922 } catch (e) {
923 exception = e;
924 }
925
926 if (!clock.timers[timer.id]) {
927 if (exception) {
928 throw exception;
929 }
930 return;
931 }
932
933 if (exception) {
934 throw exception;
935 }
936 }
937
938 function timerType(timer) {
939 if (timer.immediate) {
940 return "Immediate";
941 } else if (typeof timer.interval !== "undefined") {
942 return "Interval";
943 } else {
944 return "Timeout";
945 }
946 }
947
948 function clearTimer(clock, timerId, ttype) {
949 if (!timerId) {
950 // null appears to be allowed in most browsers, and appears to be
951 // relied upon by some libraries, like Bootstrap carousel
952 return;
953 }
954
955 if (!clock.timers) {
956 clock.timers = [];
957 }
958
959 // in Node, timerId is an object with .ref()/.unref(), and
960 // its .id field is the actual timer id.
961 if (typeof timerId === "object") {
962 timerId = timerId.id;
963 }
964
965 if (clock.timers.hasOwnProperty(timerId)) {
966 // check that the ID matches a timer of the correct type
967 var timer = clock.timers[timerId];
968 if (timerType(timer) === ttype) {
969 delete clock.timers[timerId];
970 } else {
971 throw new Error("Cannot clear timer: timer creat ed with set" + ttype + "() but cleared with clear" + timerType(timer) + "()");
972 }
973 }
974 }
975
976 function uninstall(clock, target) {
977 var method,
978 i,
979 l;
980
981 for (i = 0, l = clock.methods.length; i < l; i++) {
982 method = clock.methods[i];
983
984 if (target[method].hadOwnProperty) {
985 target[method] = clock["_" + method];
986 } else {
987 try {
988 delete target[method];
989 } catch (ignore) {}
990 }
991 }
992
993 // Prevent multiple executions which will completely remove these props
994 clock.methods = [];
995 }
996
997 function hijackMethod(target, method, clock) {
998 var prop;
999
1000 clock[method].hadOwnProperty = Object.prototype.hasOwnProperty.call(targ et, method);
1001 clock["_" + method] = target[method];
1002
1003 if (method === "Date") {
1004 var date = mirrorDateProperties(clock[method], target[method]);
1005 target[method] = date;
1006 } else {
1007 target[method] = function () {
1008 return clock[method].apply(clock, arguments);
1009 };
1010
1011 for (prop in clock[method]) {
1012 if (clock[method].hasOwnProperty(prop)) {
1013 target[method][prop] = clock[method][prop];
1014 }
1015 }
1016 }
1017
1018 target[method].clock = clock;
1019 }
1020
1021 var timers = {
1022 setTimeout: setTimeout,
1023 clearTimeout: clearTimeout,
1024 setImmediate: global.setImmediate,
1025 clearImmediate: global.clearImmediate,
1026 setInterval: setInterval,
1027 clearInterval: clearInterval,
1028 Date: Date
1029 };
1030
1031 var keys = Object.keys || function (obj) {
1032 var ks = [],
1033 key;
1034
1035 for (key in obj) {
1036 if (obj.hasOwnProperty(key)) {
1037 ks.push(key);
1038 }
1039 }
1040
1041 return ks;
1042 };
1043
1044 exports.timers = timers;
1045
1046 function createClock(now) {
1047 var clock = {
1048 now: getEpoch(now),
1049 timeouts: {},
1050 Date: createDate()
1051 };
1052
1053 clock.Date.clock = clock;
1054
1055 clock.setTimeout = function setTimeout(func, timeout) {
1056 return addTimer(clock, {
1057 func: func,
1058 args: Array.prototype.slice.call(arguments, 2),
1059 delay: timeout
1060 });
1061 };
1062
1063 clock.clearTimeout = function clearTimeout(timerId) {
1064 return clearTimer(clock, timerId, "Timeout");
1065 };
1066
1067 clock.setInterval = function setInterval(func, timeout) {
1068 return addTimer(clock, {
1069 func: func,
1070 args: Array.prototype.slice.call(arguments, 2),
1071 delay: timeout,
1072 interval: timeout
1073 });
1074 };
1075
1076 clock.clearInterval = function clearInterval(timerId) {
1077 return clearTimer(clock, timerId, "Interval");
1078 };
1079
1080 clock.setImmediate = function setImmediate(func) {
1081 return addTimer(clock, {
1082 func: func,
1083 args: Array.prototype.slice.call(arguments, 1),
1084 immediate: true
1085 });
1086 };
1087
1088 clock.clearImmediate = function clearImmediate(timerId) {
1089 return clearTimer(clock, timerId, "Immediate");
1090 };
1091
1092 clock.tick = function tick(ms) {
1093 ms = typeof ms === "number" ? ms : parseTime(ms);
1094 var tickFrom = clock.now, tickTo = clock.now + ms, previous = clock. now;
1095 var timer = firstTimerInRange(clock, tickFrom, tickTo);
1096 var oldNow;
1097
1098 clock.duringTick = true;
1099
1100 var firstException;
1101 while (timer && tickFrom <= tickTo) {
1102 if (clock.timers[timer.id]) {
1103 tickFrom = clock.now = timer.callAt;
1104 try {
1105 oldNow = clock.now;
1106 callTimer(clock, timer);
1107 // compensate for any setSystemTime() call during timer callback
1108 if (oldNow !== clock.now) {
1109 tickFrom += clock.now - oldNow;
1110 tickTo += clock.now - oldNow;
1111 previous += clock.now - oldNow;
1112 }
1113 } catch (e) {
1114 firstException = firstException || e;
1115 }
1116 }
1117
1118 timer = firstTimerInRange(clock, previous, tickTo);
1119 previous = tickFrom;
1120 }
1121
1122 clock.duringTick = false;
1123 clock.now = tickTo;
1124
1125 if (firstException) {
1126 throw firstException;
1127 }
1128
1129 return clock.now;
1130 };
1131
1132 clock.reset = function reset() {
1133 clock.timers = {};
1134 };
1135
1136 clock.setSystemTime = function setSystemTime(now) {
1137 // determine time difference
1138 var newNow = getEpoch(now);
1139 var difference = newNow - clock.now;
1140
1141 // update 'system clock'
1142 clock.now = newNow;
1143
1144 // update timers and intervals to keep them stable
1145 for (var id in clock.timers) {
1146 if (clock.timers.hasOwnProperty(id)) {
1147 var timer = clock.timers[id];
1148 timer.createdAt += difference;
1149 timer.callAt += difference;
1150 }
1151 }
1152 };
1153
1154 return clock;
1155 }
1156 exports.createClock = createClock;
1157
1158 exports.install = function install(target, now, toFake) {
1159 var i,
1160 l;
1161
1162 if (typeof target === "number") {
1163 toFake = now;
1164 now = target;
1165 target = null;
1166 }
1167
1168 if (!target) {
1169 target = global;
1170 }
1171
1172 var clock = createClock(now);
1173
1174 clock.uninstall = function () {
1175 uninstall(clock, target);
1176 };
1177
1178 clock.methods = toFake || [];
1179
1180 if (clock.methods.length === 0) {
1181 clock.methods = keys(timers);
1182 }
1183
1184 for (i = 0, l = clock.methods.length; i < l; i++) {
1185 hijackMethod(target, clock.methods[i], clock);
1186 }
1187
1188 return clock;
1189 };
1190
1191 }(global || this));
1192
1193 }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined " ? self : typeof window !== "undefined" ? window : {})
1194 },{}]},{},[1])(1)
1195 });
1196 })();
1197 var define;
1198 /**
1199 * Sinon core utilities. For internal use only.
1200 *
1201 * @author Christian Johansen (christian@cjohansen.no)
1202 * @license BSD
1203 *
1204 * Copyright (c) 2010-2013 Christian Johansen
1205 */
1206 var sinon = (function () {
1207 "use strict";
1208 // eslint-disable-line no-unused-vars
1209
1210 var sinonModule;
1211 var isNode = typeof module !== "undefined" && module.exports && typeof requi re === "function";
1212 var isAMD = typeof define === "function" && typeof define.amd === "object" & & define.amd;
1213
1214 function loadDependencies(require, exports, module) {
1215 sinonModule = module.exports = require("./sinon/util/core");
1216 require("./sinon/extend");
1217 require("./sinon/walk");
1218 require("./sinon/typeOf");
1219 require("./sinon/times_in_words");
1220 require("./sinon/spy");
1221 require("./sinon/call");
1222 require("./sinon/behavior");
1223 require("./sinon/stub");
1224 require("./sinon/mock");
1225 require("./sinon/collection");
1226 require("./sinon/assert");
1227 require("./sinon/sandbox");
1228 require("./sinon/test");
1229 require("./sinon/test_case");
1230 require("./sinon/match");
1231 require("./sinon/format");
1232 require("./sinon/log_error");
1233 }
1234
1235 if (isAMD) {
1236 define(loadDependencies);
1237 } else if (isNode) {
1238 loadDependencies(require, module.exports, module);
1239 sinonModule = module.exports;
1240 } else {
1241 sinonModule = {};
1242 }
1243
1244 return sinonModule;
1245 }());
1246
1247 /**
1248 * @depend ../../sinon.js
1249 */
1250 /**
1251 * Sinon core utilities. For internal use only.
1252 *
1253 * @author Christian Johansen (christian@cjohansen.no)
1254 * @license BSD
1255 *
1256 * Copyright (c) 2010-2013 Christian Johansen
1257 */
1258 (function (sinonGlobal) {
1259
1260 var div = typeof document !== "undefined" && document.createElement("div");
1261 var hasOwn = Object.prototype.hasOwnProperty;
1262
1263 function isDOMNode(obj) {
1264 var success = false;
1265
1266 try {
1267 obj.appendChild(div);
1268 success = div.parentNode === obj;
1269 } catch (e) {
1270 return false;
1271 } finally {
1272 try {
1273 obj.removeChild(div);
1274 } catch (e) {
1275 // Remove failed, not much we can do about that
1276 }
1277 }
1278
1279 return success;
1280 }
1281
1282 function isElement(obj) {
1283 return div && obj && obj.nodeType === 1 && isDOMNode(obj);
1284 }
1285
1286 function isFunction(obj) {
1287 return typeof obj === "function" || !!(obj && obj.constructor && obj.cal l && obj.apply);
1288 }
1289
1290 function isReallyNaN(val) {
1291 return typeof val === "number" && isNaN(val);
1292 }
1293
1294 function mirrorProperties(target, source) {
1295 for (var prop in source) {
1296 if (!hasOwn.call(target, prop)) {
1297 target[prop] = source[prop];
1298 }
1299 }
1300 }
1301
1302 function isRestorable(obj) {
1303 return typeof obj === "function" && typeof obj.restore === "function" && obj.restore.sinon;
1304 }
1305
1306 // Cheap way to detect if we have ES5 support.
1307 var hasES5Support = "keys" in Object;
1308
1309 function makeApi(sinon) {
1310 sinon.wrapMethod = function wrapMethod(object, property, method) {
1311 if (!object) {
1312 throw new TypeError("Should wrap property of object");
1313 }
1314
1315 if (typeof method !== "function" && typeof method !== "object") {
1316 throw new TypeError("Method wrapper should be a function or a pr operty descriptor");
1317 }
1318
1319 function checkWrappedMethod(wrappedMethod) {
1320 var error;
1321
1322 if (!isFunction(wrappedMethod)) {
1323 error = new TypeError("Attempted to wrap " + (typeof wrapped Method) + " property " +
1324 property + " as function");
1325 } else if (wrappedMethod.restore && wrappedMethod.restore.sinon) {
1326 error = new TypeError("Attempted to wrap " + property + " wh ich is already wrapped");
1327 } else if (wrappedMethod.calledBefore) {
1328 var verb = wrappedMethod.returns ? "stubbed" : "spied on";
1329 error = new TypeError("Attempted to wrap " + property + " wh ich is already " + verb);
1330 }
1331
1332 if (error) {
1333 if (wrappedMethod && wrappedMethod.stackTrace) {
1334 error.stack += "\n--------------\n" + wrappedMethod.stac kTrace;
1335 }
1336 throw error;
1337 }
1338 }
1339
1340 var error, wrappedMethod, i;
1341
1342 // IE 8 does not support hasOwnProperty on the window object and Fir efox has a problem
1343 // when using hasOwn.call on objects from other frames.
1344 var owned = object.hasOwnProperty ? object.hasOwnProperty(property) : hasOwn.call(object, property);
1345
1346 if (hasES5Support) {
1347 var methodDesc = (typeof method === "function") ? {value: method } : method;
1348 var wrappedMethodDesc = sinon.getPropertyDescriptor(object, prop erty);
1349
1350 if (!wrappedMethodDesc) {
1351 error = new TypeError("Attempted to wrap " + (typeof wrapped Method) + " property " +
1352 property + " as function");
1353 } else if (wrappedMethodDesc.restore && wrappedMethodDesc.restor e.sinon) {
1354 error = new TypeError("Attempted to wrap " + property + " wh ich is already wrapped");
1355 }
1356 if (error) {
1357 if (wrappedMethodDesc && wrappedMethodDesc.stackTrace) {
1358 error.stack += "\n--------------\n" + wrappedMethodDesc. stackTrace;
1359 }
1360 throw error;
1361 }
1362
1363 var types = sinon.objectKeys(methodDesc);
1364 for (i = 0; i < types.length; i++) {
1365 wrappedMethod = wrappedMethodDesc[types[i]];
1366 checkWrappedMethod(wrappedMethod);
1367 }
1368
1369 mirrorProperties(methodDesc, wrappedMethodDesc);
1370 for (i = 0; i < types.length; i++) {
1371 mirrorProperties(methodDesc[types[i]], wrappedMethodDesc[typ es[i]]);
1372 }
1373 Object.defineProperty(object, property, methodDesc);
1374 } else {
1375 wrappedMethod = object[property];
1376 checkWrappedMethod(wrappedMethod);
1377 object[property] = method;
1378 method.displayName = property;
1379 }
1380
1381 method.displayName = property;
1382
1383 // Set up a stack trace which can be used later to find what line of
1384 // code the original method was created on.
1385 method.stackTrace = (new Error("Stack Trace for original")).stack;
1386
1387 method.restore = function () {
1388 // For prototype properties try to reset by delete first.
1389 // If this fails (ex: localStorage on mobile safari) then force a reset
1390 // via direct assignment.
1391 if (!owned) {
1392 // In some cases `delete` may throw an error
1393 try {
1394 delete object[property];
1395 } catch (e) {} // eslint-disable-line no-empty
1396 // For native code functions `delete` fails without throwing an error
1397 // on Chrome < 43, PhantomJS, etc.
1398 } else if (hasES5Support) {
1399 Object.defineProperty(object, property, wrappedMethodDesc);
1400 }
1401
1402 // Use strict equality comparison to check failures then force a reset
1403 // via direct assignment.
1404 if (object[property] === method) {
1405 object[property] = wrappedMethod;
1406 }
1407 };
1408
1409 method.restore.sinon = true;
1410
1411 if (!hasES5Support) {
1412 mirrorProperties(method, wrappedMethod);
1413 }
1414
1415 return method;
1416 };
1417
1418 sinon.create = function create(proto) {
1419 var F = function () {};
1420 F.prototype = proto;
1421 return new F();
1422 };
1423
1424 sinon.deepEqual = function deepEqual(a, b) {
1425 if (sinon.match && sinon.match.isMatcher(a)) {
1426 return a.test(b);
1427 }
1428
1429 if (typeof a !== "object" || typeof b !== "object") {
1430 return isReallyNaN(a) && isReallyNaN(b) || a === b;
1431 }
1432
1433 if (isElement(a) || isElement(b)) {
1434 return a === b;
1435 }
1436
1437 if (a === b) {
1438 return true;
1439 }
1440
1441 if ((a === null && b !== null) || (a !== null && b === null)) {
1442 return false;
1443 }
1444
1445 if (a instanceof RegExp && b instanceof RegExp) {
1446 return (a.source === b.source) && (a.global === b.global) &&
1447 (a.ignoreCase === b.ignoreCase) && (a.multiline === b.multil ine);
1448 }
1449
1450 var aString = Object.prototype.toString.call(a);
1451 if (aString !== Object.prototype.toString.call(b)) {
1452 return false;
1453 }
1454
1455 if (aString === "[object Date]") {
1456 return a.valueOf() === b.valueOf();
1457 }
1458
1459 var prop;
1460 var aLength = 0;
1461 var bLength = 0;
1462
1463 if (aString === "[object Array]" && a.length !== b.length) {
1464 return false;
1465 }
1466
1467 for (prop in a) {
1468 if (a.hasOwnProperty(prop)) {
1469 aLength += 1;
1470
1471 if (!(prop in b)) {
1472 return false;
1473 }
1474
1475 if (!deepEqual(a[prop], b[prop])) {
1476 return false;
1477 }
1478 }
1479 }
1480
1481 for (prop in b) {
1482 if (b.hasOwnProperty(prop)) {
1483 bLength += 1;
1484 }
1485 }
1486
1487 return aLength === bLength;
1488 };
1489
1490 sinon.functionName = function functionName(func) {
1491 var name = func.displayName || func.name;
1492
1493 // Use function decomposition as a last resort to get function
1494 // name. Does not rely on function decomposition to work - if it
1495 // doesn't debugging will be slightly less informative
1496 // (i.e. toString will say 'spy' rather than 'myFunc').
1497 if (!name) {
1498 var matches = func.toString().match(/function ([^\s\(]+)/);
1499 name = matches && matches[1];
1500 }
1501
1502 return name;
1503 };
1504
1505 sinon.functionToString = function toString() {
1506 if (this.getCall && this.callCount) {
1507 var thisValue,
1508 prop;
1509 var i = this.callCount;
1510
1511 while (i--) {
1512 thisValue = this.getCall(i).thisValue;
1513
1514 for (prop in thisValue) {
1515 if (thisValue[prop] === this) {
1516 return prop;
1517 }
1518 }
1519 }
1520 }
1521
1522 return this.displayName || "sinon fake";
1523 };
1524
1525 sinon.objectKeys = function objectKeys(obj) {
1526 if (obj !== Object(obj)) {
1527 throw new TypeError("sinon.objectKeys called on a non-object");
1528 }
1529
1530 var keys = [];
1531 var key;
1532 for (key in obj) {
1533 if (hasOwn.call(obj, key)) {
1534 keys.push(key);
1535 }
1536 }
1537
1538 return keys;
1539 };
1540
1541 sinon.getPropertyDescriptor = function getPropertyDescriptor(object, pro perty) {
1542 var proto = object;
1543 var descriptor;
1544
1545 while (proto && !(descriptor = Object.getOwnPropertyDescriptor(proto , property))) {
1546 proto = Object.getPrototypeOf(proto);
1547 }
1548 return descriptor;
1549 };
1550
1551 sinon.getConfig = function (custom) {
1552 var config = {};
1553 custom = custom || {};
1554 var defaults = sinon.defaultConfig;
1555
1556 for (var prop in defaults) {
1557 if (defaults.hasOwnProperty(prop)) {
1558 config[prop] = custom.hasOwnProperty(prop) ? custom[prop] : defaults[prop];
1559 }
1560 }
1561
1562 return config;
1563 };
1564
1565 sinon.defaultConfig = {
1566 injectIntoThis: true,
1567 injectInto: null,
1568 properties: ["spy", "stub", "mock", "clock", "server", "requests"],
1569 useFakeTimers: true,
1570 useFakeServer: true
1571 };
1572
1573 sinon.timesInWords = function timesInWords(count) {
1574 return count === 1 && "once" ||
1575 count === 2 && "twice" ||
1576 count === 3 && "thrice" ||
1577 (count || 0) + " times";
1578 };
1579
1580 sinon.calledInOrder = function (spies) {
1581 for (var i = 1, l = spies.length; i < l; i++) {
1582 if (!spies[i - 1].calledBefore(spies[i]) || !spies[i].called) {
1583 return false;
1584 }
1585 }
1586
1587 return true;
1588 };
1589
1590 sinon.orderByFirstCall = function (spies) {
1591 return spies.sort(function (a, b) {
1592 // uuid, won't ever be equal
1593 var aCall = a.getCall(0);
1594 var bCall = b.getCall(0);
1595 var aId = aCall && aCall.callId || -1;
1596 var bId = bCall && bCall.callId || -1;
1597
1598 return aId < bId ? -1 : 1;
1599 });
1600 };
1601
1602 sinon.createStubInstance = function (constructor) {
1603 if (typeof constructor !== "function") {
1604 throw new TypeError("The constructor should be a function.");
1605 }
1606 return sinon.stub(sinon.create(constructor.prototype));
1607 };
1608
1609 sinon.restore = function (object) {
1610 if (object !== null && typeof object === "object") {
1611 for (var prop in object) {
1612 if (isRestorable(object[prop])) {
1613 object[prop].restore();
1614 }
1615 }
1616 } else if (isRestorable(object)) {
1617 object.restore();
1618 }
1619 };
1620
1621 return sinon;
1622 }
1623
1624 var isNode = typeof module !== "undefined" && module.exports && typeof requi re === "function";
1625 var isAMD = typeof define === "function" && typeof define.amd === "object" & & define.amd;
1626
1627 function loadDependencies(require, exports) {
1628 makeApi(exports);
1629 }
1630
1631 if (isAMD) {
1632 define(loadDependencies);
1633 return;
1634 }
1635
1636 if (isNode) {
1637 loadDependencies(require, module.exports, module);
1638 return;
1639 }
1640
1641 if (sinonGlobal) {
1642 makeApi(sinonGlobal);
1643 }
1644 }(
1645 typeof sinon === "object" && sinon // eslint-disable-line no-undef
1646 ));
1647
1648 /**
1649 * @depend util/core.js
1650 */
1651 (function (sinonGlobal) {
1652
1653 function makeApi(sinon) {
1654
1655 // Adapted from https://developer.mozilla.org/en/docs/ECMAScript_DontEnu m_attribute#JScript_DontEnum_Bug
1656 var hasDontEnumBug = (function () {
1657 var obj = {
1658 constructor: function () {
1659 return "0";
1660 },
1661 toString: function () {
1662 return "1";
1663 },
1664 valueOf: function () {
1665 return "2";
1666 },
1667 toLocaleString: function () {
1668 return "3";
1669 },
1670 prototype: function () {
1671 return "4";
1672 },
1673 isPrototypeOf: function () {
1674 return "5";
1675 },
1676 propertyIsEnumerable: function () {
1677 return "6";
1678 },
1679 hasOwnProperty: function () {
1680 return "7";
1681 },
1682 length: function () {
1683 return "8";
1684 },
1685 unique: function () {
1686 return "9";
1687 }
1688 };
1689
1690 var result = [];
1691 for (var prop in obj) {
1692 if (obj.hasOwnProperty(prop)) {
1693 result.push(obj[prop]());
1694 }
1695 }
1696 return result.join("") !== "0123456789";
1697 })();
1698
1699 /* Public: Extend target in place with all (own) properties from sources in-order. Thus, last source will
1700 * override properties in previous sources.
1701 *
1702 * target - The Object to extend
1703 * sources - Objects to copy properties from.
1704 *
1705 * Returns the extended target
1706 */
1707 function extend(target /*, sources */) {
1708 var sources = Array.prototype.slice.call(arguments, 1);
1709 var source, i, prop;
1710
1711 for (i = 0; i < sources.length; i++) {
1712 source = sources[i];
1713
1714 for (prop in source) {
1715 if (source.hasOwnProperty(prop)) {
1716 target[prop] = source[prop];
1717 }
1718 }
1719
1720 // Make sure we copy (own) toString method even when in JScript with DontEnum bug
1721 // See https://developer.mozilla.org/en/docs/ECMAScript_DontEnum _attribute#JScript_DontEnum_Bug
1722 if (hasDontEnumBug && source.hasOwnProperty("toString") && sourc e.toString !== target.toString) {
1723 target.toString = source.toString;
1724 }
1725 }
1726
1727 return target;
1728 }
1729
1730 sinon.extend = extend;
1731 return sinon.extend;
1732 }
1733
1734 function loadDependencies(require, exports, module) {
1735 var sinon = require("./util/core");
1736 module.exports = makeApi(sinon);
1737 }
1738
1739 var isNode = typeof module !== "undefined" && module.exports && typeof requi re === "function";
1740 var isAMD = typeof define === "function" && typeof define.amd === "object" & & define.amd;
1741
1742 if (isAMD) {
1743 define(loadDependencies);
1744 return;
1745 }
1746
1747 if (isNode) {
1748 loadDependencies(require, module.exports, module);
1749 return;
1750 }
1751
1752 if (sinonGlobal) {
1753 makeApi(sinonGlobal);
1754 }
1755 }(
1756 typeof sinon === "object" && sinon // eslint-disable-line no-undef
1757 ));
1758
1759 /**
1760 * @depend util/core.js
1761 */
1762 (function (sinonGlobal) {
1763
1764 function makeApi(sinon) {
1765
1766 function timesInWords(count) {
1767 switch (count) {
1768 case 1:
1769 return "once";
1770 case 2:
1771 return "twice";
1772 case 3:
1773 return "thrice";
1774 default:
1775 return (count || 0) + " times";
1776 }
1777 }
1778
1779 sinon.timesInWords = timesInWords;
1780 return sinon.timesInWords;
1781 }
1782
1783 function loadDependencies(require, exports, module) {
1784 var core = require("./util/core");
1785 module.exports = makeApi(core);
1786 }
1787
1788 var isNode = typeof module !== "undefined" && module.exports && typeof requi re === "function";
1789 var isAMD = typeof define === "function" && typeof define.amd === "object" & & define.amd;
1790
1791 if (isAMD) {
1792 define(loadDependencies);
1793 return;
1794 }
1795
1796 if (isNode) {
1797 loadDependencies(require, module.exports, module);
1798 return;
1799 }
1800
1801 if (sinonGlobal) {
1802 makeApi(sinonGlobal);
1803 }
1804 }(
1805 typeof sinon === "object" && sinon // eslint-disable-line no-undef
1806 ));
1807
1808 /**
1809 * @depend util/core.js
1810 */
1811 /**
1812 * Format functions
1813 *
1814 * @author Christian Johansen (christian@cjohansen.no)
1815 * @license BSD
1816 *
1817 * Copyright (c) 2010-2014 Christian Johansen
1818 */
1819 (function (sinonGlobal) {
1820
1821 function makeApi(sinon) {
1822 function typeOf(value) {
1823 if (value === null) {
1824 return "null";
1825 } else if (value === undefined) {
1826 return "undefined";
1827 }
1828 var string = Object.prototype.toString.call(value);
1829 return string.substring(8, string.length - 1).toLowerCase();
1830 }
1831
1832 sinon.typeOf = typeOf;
1833 return sinon.typeOf;
1834 }
1835
1836 function loadDependencies(require, exports, module) {
1837 var core = require("./util/core");
1838 module.exports = makeApi(core);
1839 }
1840
1841 var isNode = typeof module !== "undefined" && module.exports && typeof requi re === "function";
1842 var isAMD = typeof define === "function" && typeof define.amd === "object" & & define.amd;
1843
1844 if (isAMD) {
1845 define(loadDependencies);
1846 return;
1847 }
1848
1849 if (isNode) {
1850 loadDependencies(require, module.exports, module);
1851 return;
1852 }
1853
1854 if (sinonGlobal) {
1855 makeApi(sinonGlobal);
1856 }
1857 }(
1858 typeof sinon === "object" && sinon // eslint-disable-line no-undef
1859 ));
1860
1861 /**
1862 * @depend util/core.js
1863 * @depend typeOf.js
1864 */
1865 /*jslint eqeqeq: false, onevar: false, plusplus: false*/
1866 /*global module, require, sinon*/
1867 /**
1868 * Match functions
1869 *
1870 * @author Maximilian Antoni (mail@maxantoni.de)
1871 * @license BSD
1872 *
1873 * Copyright (c) 2012 Maximilian Antoni
1874 */
1875 (function (sinonGlobal) {
1876
1877 function makeApi(sinon) {
1878 function assertType(value, type, name) {
1879 var actual = sinon.typeOf(value);
1880 if (actual !== type) {
1881 throw new TypeError("Expected type of " + name + " to be " +
1882 type + ", but was " + actual);
1883 }
1884 }
1885
1886 var matcher = {
1887 toString: function () {
1888 return this.message;
1889 }
1890 };
1891
1892 function isMatcher(object) {
1893 return matcher.isPrototypeOf(object);
1894 }
1895
1896 function matchObject(expectation, actual) {
1897 if (actual === null || actual === undefined) {
1898 return false;
1899 }
1900 for (var key in expectation) {
1901 if (expectation.hasOwnProperty(key)) {
1902 var exp = expectation[key];
1903 var act = actual[key];
1904 if (isMatcher(exp)) {
1905 if (!exp.test(act)) {
1906 return false;
1907 }
1908 } else if (sinon.typeOf(exp) === "object") {
1909 if (!matchObject(exp, act)) {
1910 return false;
1911 }
1912 } else if (!sinon.deepEqual(exp, act)) {
1913 return false;
1914 }
1915 }
1916 }
1917 return true;
1918 }
1919
1920 function match(expectation, message) {
1921 var m = sinon.create(matcher);
1922 var type = sinon.typeOf(expectation);
1923 switch (type) {
1924 case "object":
1925 if (typeof expectation.test === "function") {
1926 m.test = function (actual) {
1927 return expectation.test(actual) === true;
1928 };
1929 m.message = "match(" + sinon.functionName(expectation.test) + ")";
1930 return m;
1931 }
1932 var str = [];
1933 for (var key in expectation) {
1934 if (expectation.hasOwnProperty(key)) {
1935 str.push(key + ": " + expectation[key]);
1936 }
1937 }
1938 m.test = function (actual) {
1939 return matchObject(expectation, actual);
1940 };
1941 m.message = "match(" + str.join(", ") + ")";
1942 break;
1943 case "number":
1944 m.test = function (actual) {
1945 // we need type coercion here
1946 return expectation == actual; // eslint-disable-line eqeqeq
1947 };
1948 break;
1949 case "string":
1950 m.test = function (actual) {
1951 if (typeof actual !== "string") {
1952 return false;
1953 }
1954 return actual.indexOf(expectation) !== -1;
1955 };
1956 m.message = "match(\"" + expectation + "\")";
1957 break;
1958 case "regexp":
1959 m.test = function (actual) {
1960 if (typeof actual !== "string") {
1961 return false;
1962 }
1963 return expectation.test(actual);
1964 };
1965 break;
1966 case "function":
1967 m.test = expectation;
1968 if (message) {
1969 m.message = message;
1970 } else {
1971 m.message = "match(" + sinon.functionName(expectation) + ")" ;
1972 }
1973 break;
1974 default:
1975 m.test = function (actual) {
1976 return sinon.deepEqual(expectation, actual);
1977 };
1978 }
1979 if (!m.message) {
1980 m.message = "match(" + expectation + ")";
1981 }
1982 return m;
1983 }
1984
1985 matcher.or = function (m2) {
1986 if (!arguments.length) {
1987 throw new TypeError("Matcher expected");
1988 } else if (!isMatcher(m2)) {
1989 m2 = match(m2);
1990 }
1991 var m1 = this;
1992 var or = sinon.create(matcher);
1993 or.test = function (actual) {
1994 return m1.test(actual) || m2.test(actual);
1995 };
1996 or.message = m1.message + ".or(" + m2.message + ")";
1997 return or;
1998 };
1999
2000 matcher.and = function (m2) {
2001 if (!arguments.length) {
2002 throw new TypeError("Matcher expected");
2003 } else if (!isMatcher(m2)) {
2004 m2 = match(m2);
2005 }
2006 var m1 = this;
2007 var and = sinon.create(matcher);
2008 and.test = function (actual) {
2009 return m1.test(actual) && m2.test(actual);
2010 };
2011 and.message = m1.message + ".and(" + m2.message + ")";
2012 return and;
2013 };
2014
2015 match.isMatcher = isMatcher;
2016
2017 match.any = match(function () {
2018 return true;
2019 }, "any");
2020
2021 match.defined = match(function (actual) {
2022 return actual !== null && actual !== undefined;
2023 }, "defined");
2024
2025 match.truthy = match(function (actual) {
2026 return !!actual;
2027 }, "truthy");
2028
2029 match.falsy = match(function (actual) {
2030 return !actual;
2031 }, "falsy");
2032
2033 match.same = function (expectation) {
2034 return match(function (actual) {
2035 return expectation === actual;
2036 }, "same(" + expectation + ")");
2037 };
2038
2039 match.typeOf = function (type) {
2040 assertType(type, "string", "type");
2041 return match(function (actual) {
2042 return sinon.typeOf(actual) === type;
2043 }, "typeOf(\"" + type + "\")");
2044 };
2045
2046 match.instanceOf = function (type) {
2047 assertType(type, "function", "type");
2048 return match(function (actual) {
2049 return actual instanceof type;
2050 }, "instanceOf(" + sinon.functionName(type) + ")");
2051 };
2052
2053 function createPropertyMatcher(propertyTest, messagePrefix) {
2054 return function (property, value) {
2055 assertType(property, "string", "property");
2056 var onlyProperty = arguments.length === 1;
2057 var message = messagePrefix + "(\"" + property + "\"";
2058 if (!onlyProperty) {
2059 message += ", " + value;
2060 }
2061 message += ")";
2062 return match(function (actual) {
2063 if (actual === undefined || actual === null ||
2064 !propertyTest(actual, property)) {
2065 return false;
2066 }
2067 return onlyProperty || sinon.deepEqual(value, actual[propert y]);
2068 }, message);
2069 };
2070 }
2071
2072 match.has = createPropertyMatcher(function (actual, property) {
2073 if (typeof actual === "object") {
2074 return property in actual;
2075 }
2076 return actual[property] !== undefined;
2077 }, "has");
2078
2079 match.hasOwn = createPropertyMatcher(function (actual, property) {
2080 return actual.hasOwnProperty(property);
2081 }, "hasOwn");
2082
2083 match.bool = match.typeOf("boolean");
2084 match.number = match.typeOf("number");
2085 match.string = match.typeOf("string");
2086 match.object = match.typeOf("object");
2087 match.func = match.typeOf("function");
2088 match.array = match.typeOf("array");
2089 match.regexp = match.typeOf("regexp");
2090 match.date = match.typeOf("date");
2091
2092 sinon.match = match;
2093 return match;
2094 }
2095
2096 var isNode = typeof module !== "undefined" && module.exports && typeof requi re === "function";
2097 var isAMD = typeof define === "function" && typeof define.amd === "object" & & define.amd;
2098
2099 function loadDependencies(require, exports, module) {
2100 var sinon = require("./util/core");
2101 require("./typeOf");
2102 module.exports = makeApi(sinon);
2103 }
2104
2105 if (isAMD) {
2106 define(loadDependencies);
2107 return;
2108 }
2109
2110 if (isNode) {
2111 loadDependencies(require, module.exports, module);
2112 return;
2113 }
2114
2115 if (sinonGlobal) {
2116 makeApi(sinonGlobal);
2117 }
2118 }(
2119 typeof sinon === "object" && sinon // eslint-disable-line no-undef
2120 ));
2121
2122 /**
2123 * @depend util/core.js
2124 */
2125 /**
2126 * Format functions
2127 *
2128 * @author Christian Johansen (christian@cjohansen.no)
2129 * @license BSD
2130 *
2131 * Copyright (c) 2010-2014 Christian Johansen
2132 */
2133 (function (sinonGlobal, formatio) {
2134
2135 function makeApi(sinon) {
2136 function valueFormatter(value) {
2137 return "" + value;
2138 }
2139
2140 function getFormatioFormatter() {
2141 var formatter = formatio.configure({
2142 quoteStrings: false,
2143 limitChildrenCount: 250
2144 });
2145
2146 function format() {
2147 return formatter.ascii.apply(formatter, arguments);
2148 }
2149
2150 return format;
2151 }
2152
2153 function getNodeFormatter() {
2154 try {
2155 var util = require("util");
2156 } catch (e) {
2157 /* Node, but no util module - would be very old, but better safe than sorry */
2158 }
2159
2160 function format(v) {
2161 var isObjectWithNativeToString = typeof v === "object" && v.toSt ring === Object.prototype.toString;
2162 return isObjectWithNativeToString ? util.inspect(v) : v;
2163 }
2164
2165 return util ? format : valueFormatter;
2166 }
2167
2168 var isNode = typeof module !== "undefined" && module.exports && typeof r equire === "function";
2169 var formatter;
2170
2171 if (isNode) {
2172 try {
2173 formatio = require("formatio");
2174 }
2175 catch (e) {} // eslint-disable-line no-empty
2176 }
2177
2178 if (formatio) {
2179 formatter = getFormatioFormatter();
2180 } else if (isNode) {
2181 formatter = getNodeFormatter();
2182 } else {
2183 formatter = valueFormatter;
2184 }
2185
2186 sinon.format = formatter;
2187 return sinon.format;
2188 }
2189
2190 function loadDependencies(require, exports, module) {
2191 var sinon = require("./util/core");
2192 module.exports = makeApi(sinon);
2193 }
2194
2195 var isNode = typeof module !== "undefined" && module.exports && typeof requi re === "function";
2196 var isAMD = typeof define === "function" && typeof define.amd === "object" & & define.amd;
2197
2198 if (isAMD) {
2199 define(loadDependencies);
2200 return;
2201 }
2202
2203 if (isNode) {
2204 loadDependencies(require, module.exports, module);
2205 return;
2206 }
2207
2208 if (sinonGlobal) {
2209 makeApi(sinonGlobal);
2210 }
2211 }(
2212 typeof sinon === "object" && sinon, // eslint-disable-line no-undef
2213 typeof formatio === "object" && formatio // eslint-disable-line no-undef
2214 ));
2215
2216 /**
2217 * @depend util/core.js
2218 * @depend match.js
2219 * @depend format.js
2220 */
2221 /**
2222 * Spy calls
2223 *
2224 * @author Christian Johansen (christian@cjohansen.no)
2225 * @author Maximilian Antoni (mail@maxantoni.de)
2226 * @license BSD
2227 *
2228 * Copyright (c) 2010-2013 Christian Johansen
2229 * Copyright (c) 2013 Maximilian Antoni
2230 */
2231 (function (sinonGlobal) {
2232
2233 var slice = Array.prototype.slice;
2234
2235 function makeApi(sinon) {
2236 function throwYieldError(proxy, text, args) {
2237 var msg = sinon.functionName(proxy) + text;
2238 if (args.length) {
2239 msg += " Received [" + slice.call(args).join(", ") + "]";
2240 }
2241 throw new Error(msg);
2242 }
2243
2244 var callProto = {
2245 calledOn: function calledOn(thisValue) {
2246 if (sinon.match && sinon.match.isMatcher(thisValue)) {
2247 return thisValue.test(this.thisValue);
2248 }
2249 return this.thisValue === thisValue;
2250 },
2251
2252 calledWith: function calledWith() {
2253 var l = arguments.length;
2254 if (l > this.args.length) {
2255 return false;
2256 }
2257 for (var i = 0; i < l; i += 1) {
2258 if (!sinon.deepEqual(arguments[i], this.args[i])) {
2259 return false;
2260 }
2261 }
2262
2263 return true;
2264 },
2265
2266 calledWithMatch: function calledWithMatch() {
2267 var l = arguments.length;
2268 if (l > this.args.length) {
2269 return false;
2270 }
2271 for (var i = 0; i < l; i += 1) {
2272 var actual = this.args[i];
2273 var expectation = arguments[i];
2274 if (!sinon.match || !sinon.match(expectation).test(actual)) {
2275 return false;
2276 }
2277 }
2278 return true;
2279 },
2280
2281 calledWithExactly: function calledWithExactly() {
2282 return arguments.length === this.args.length &&
2283 this.calledWith.apply(this, arguments);
2284 },
2285
2286 notCalledWith: function notCalledWith() {
2287 return !this.calledWith.apply(this, arguments);
2288 },
2289
2290 notCalledWithMatch: function notCalledWithMatch() {
2291 return !this.calledWithMatch.apply(this, arguments);
2292 },
2293
2294 returned: function returned(value) {
2295 return sinon.deepEqual(value, this.returnValue);
2296 },
2297
2298 threw: function threw(error) {
2299 if (typeof error === "undefined" || !this.exception) {
2300 return !!this.exception;
2301 }
2302
2303 return this.exception === error || this.exception.name === error ;
2304 },
2305
2306 calledWithNew: function calledWithNew() {
2307 return this.proxy.prototype && this.thisValue instanceof this.pr oxy;
2308 },
2309
2310 calledBefore: function (other) {
2311 return this.callId < other.callId;
2312 },
2313
2314 calledAfter: function (other) {
2315 return this.callId > other.callId;
2316 },
2317
2318 callArg: function (pos) {
2319 this.args[pos]();
2320 },
2321
2322 callArgOn: function (pos, thisValue) {
2323 this.args[pos].apply(thisValue);
2324 },
2325
2326 callArgWith: function (pos) {
2327 this.callArgOnWith.apply(this, [pos, null].concat(slice.call(arg uments, 1)));
2328 },
2329
2330 callArgOnWith: function (pos, thisValue) {
2331 var args = slice.call(arguments, 2);
2332 this.args[pos].apply(thisValue, args);
2333 },
2334
2335 "yield": function () {
2336 this.yieldOn.apply(this, [null].concat(slice.call(arguments, 0)) );
2337 },
2338
2339 yieldOn: function (thisValue) {
2340 var args = this.args;
2341 for (var i = 0, l = args.length; i < l; ++i) {
2342 if (typeof args[i] === "function") {
2343 args[i].apply(thisValue, slice.call(arguments, 1));
2344 return;
2345 }
2346 }
2347 throwYieldError(this.proxy, " cannot yield since no callback was passed.", args);
2348 },
2349
2350 yieldTo: function (prop) {
2351 this.yieldToOn.apply(this, [prop, null].concat(slice.call(argume nts, 1)));
2352 },
2353
2354 yieldToOn: function (prop, thisValue) {
2355 var args = this.args;
2356 for (var i = 0, l = args.length; i < l; ++i) {
2357 if (args[i] && typeof args[i][prop] === "function") {
2358 args[i][prop].apply(thisValue, slice.call(arguments, 2)) ;
2359 return;
2360 }
2361 }
2362 throwYieldError(this.proxy, " cannot yield to '" + prop +
2363 "' since no callback was passed.", args);
2364 },
2365
2366 getStackFrames: function () {
2367 // Omit the error message and the two top stack frames in sinon itself:
2368 return this.stack && this.stack.split("\n").slice(3);
2369 },
2370
2371 toString: function () {
2372 var callStr = this.proxy.toString() + "(";
2373 var args = [];
2374
2375 for (var i = 0, l = this.args.length; i < l; ++i) {
2376 args.push(sinon.format(this.args[i]));
2377 }
2378
2379 callStr = callStr + args.join(", ") + ")";
2380
2381 if (typeof this.returnValue !== "undefined") {
2382 callStr += " => " + sinon.format(this.returnValue);
2383 }
2384
2385 if (this.exception) {
2386 callStr += " !" + this.exception.name;
2387
2388 if (this.exception.message) {
2389 callStr += "(" + this.exception.message + ")";
2390 }
2391 }
2392 if (this.stack) {
2393 callStr += this.getStackFrames()[0].replace(/^\s*(?:at\s+|@) ?/, " at ");
2394
2395 }
2396
2397 return callStr;
2398 }
2399 };
2400
2401 callProto.invokeCallback = callProto.yield;
2402
2403 function createSpyCall(spy, thisValue, args, returnValue, exception, id, stack) {
2404 if (typeof id !== "number") {
2405 throw new TypeError("Call id is not a number");
2406 }
2407 var proxyCall = sinon.create(callProto);
2408 proxyCall.proxy = spy;
2409 proxyCall.thisValue = thisValue;
2410 proxyCall.args = args;
2411 proxyCall.returnValue = returnValue;
2412 proxyCall.exception = exception;
2413 proxyCall.callId = id;
2414 proxyCall.stack = stack;
2415
2416 return proxyCall;
2417 }
2418 createSpyCall.toString = callProto.toString; // used by mocks
2419
2420 sinon.spyCall = createSpyCall;
2421 return createSpyCall;
2422 }
2423
2424 var isNode = typeof module !== "undefined" && module.exports && typeof requi re === "function";
2425 var isAMD = typeof define === "function" && typeof define.amd === "object" & & define.amd;
2426
2427 function loadDependencies(require, exports, module) {
2428 var sinon = require("./util/core");
2429 require("./match");
2430 require("./format");
2431 module.exports = makeApi(sinon);
2432 }
2433
2434 if (isAMD) {
2435 define(loadDependencies);
2436 return;
2437 }
2438
2439 if (isNode) {
2440 loadDependencies(require, module.exports, module);
2441 return;
2442 }
2443
2444 if (sinonGlobal) {
2445 makeApi(sinonGlobal);
2446 }
2447 }(
2448 typeof sinon === "object" && sinon // eslint-disable-line no-undef
2449 ));
2450
2451 /**
2452 * @depend times_in_words.js
2453 * @depend util/core.js
2454 * @depend extend.js
2455 * @depend call.js
2456 * @depend format.js
2457 */
2458 /**
2459 * Spy functions
2460 *
2461 * @author Christian Johansen (christian@cjohansen.no)
2462 * @license BSD
2463 *
2464 * Copyright (c) 2010-2013 Christian Johansen
2465 */
2466 (function (sinonGlobal) {
2467
2468 function makeApi(sinon) {
2469 var push = Array.prototype.push;
2470 var slice = Array.prototype.slice;
2471 var callId = 0;
2472
2473 function spy(object, property, types) {
2474 if (!property && typeof object === "function") {
2475 return spy.create(object);
2476 }
2477
2478 if (!object && !property) {
2479 return spy.create(function () { });
2480 }
2481
2482 if (types) {
2483 var methodDesc = sinon.getPropertyDescriptor(object, property);
2484 for (var i = 0; i < types.length; i++) {
2485 methodDesc[types[i]] = spy.create(methodDesc[types[i]]);
2486 }
2487 return sinon.wrapMethod(object, property, methodDesc);
2488 }
2489
2490 return sinon.wrapMethod(object, property, spy.create(object[property ]));
2491 }
2492
2493 function matchingFake(fakes, args, strict) {
2494 if (!fakes) {
2495 return undefined;
2496 }
2497
2498 for (var i = 0, l = fakes.length; i < l; i++) {
2499 if (fakes[i].matches(args, strict)) {
2500 return fakes[i];
2501 }
2502 }
2503 }
2504
2505 function incrementCallCount() {
2506 this.called = true;
2507 this.callCount += 1;
2508 this.notCalled = false;
2509 this.calledOnce = this.callCount === 1;
2510 this.calledTwice = this.callCount === 2;
2511 this.calledThrice = this.callCount === 3;
2512 }
2513
2514 function createCallProperties() {
2515 this.firstCall = this.getCall(0);
2516 this.secondCall = this.getCall(1);
2517 this.thirdCall = this.getCall(2);
2518 this.lastCall = this.getCall(this.callCount - 1);
2519 }
2520
2521 var vars = "a,b,c,d,e,f,g,h,i,j,k,l";
2522 function createProxy(func, proxyLength) {
2523 // Retain the function length:
2524 var p;
2525 if (proxyLength) {
2526 eval("p = (function proxy(" + vars.substring(0, proxyLength * 2 - 1) + // eslint-disable-line no-eval
2527 ") { return p.invoke(func, this, slice.call(arguments)); }); ");
2528 } else {
2529 p = function proxy() {
2530 return p.invoke(func, this, slice.call(arguments));
2531 };
2532 }
2533 p.isSinonProxy = true;
2534 return p;
2535 }
2536
2537 var uuid = 0;
2538
2539 // Public API
2540 var spyApi = {
2541 reset: function () {
2542 if (this.invoking) {
2543 var err = new Error("Cannot reset Sinon function while invok ing it. " +
2544 "Move the call to .reset outside of the callback.");
2545 err.name = "InvalidResetException";
2546 throw err;
2547 }
2548
2549 this.called = false;
2550 this.notCalled = true;
2551 this.calledOnce = false;
2552 this.calledTwice = false;
2553 this.calledThrice = false;
2554 this.callCount = 0;
2555 this.firstCall = null;
2556 this.secondCall = null;
2557 this.thirdCall = null;
2558 this.lastCall = null;
2559 this.args = [];
2560 this.returnValues = [];
2561 this.thisValues = [];
2562 this.exceptions = [];
2563 this.callIds = [];
2564 this.stacks = [];
2565 if (this.fakes) {
2566 for (var i = 0; i < this.fakes.length; i++) {
2567 this.fakes[i].reset();
2568 }
2569 }
2570
2571 return this;
2572 },
2573
2574 create: function create(func, spyLength) {
2575 var name;
2576
2577 if (typeof func !== "function") {
2578 func = function () { };
2579 } else {
2580 name = sinon.functionName(func);
2581 }
2582
2583 if (!spyLength) {
2584 spyLength = func.length;
2585 }
2586
2587 var proxy = createProxy(func, spyLength);
2588
2589 sinon.extend(proxy, spy);
2590 delete proxy.create;
2591 sinon.extend(proxy, func);
2592
2593 proxy.reset();
2594 proxy.prototype = func.prototype;
2595 proxy.displayName = name || "spy";
2596 proxy.toString = sinon.functionToString;
2597 proxy.instantiateFake = sinon.spy.create;
2598 proxy.id = "spy#" + uuid++;
2599
2600 return proxy;
2601 },
2602
2603 invoke: function invoke(func, thisValue, args) {
2604 var matching = matchingFake(this.fakes, args);
2605 var exception, returnValue;
2606
2607 incrementCallCount.call(this);
2608 push.call(this.thisValues, thisValue);
2609 push.call(this.args, args);
2610 push.call(this.callIds, callId++);
2611
2612 // Make call properties available from within the spied function :
2613 createCallProperties.call(this);
2614
2615 try {
2616 this.invoking = true;
2617
2618 if (matching) {
2619 returnValue = matching.invoke(func, thisValue, args);
2620 } else {
2621 returnValue = (this.func || func).apply(thisValue, args) ;
2622 }
2623
2624 var thisCall = this.getCall(this.callCount - 1);
2625 if (thisCall.calledWithNew() && typeof returnValue !== "obje ct") {
2626 returnValue = thisValue;
2627 }
2628 } catch (e) {
2629 exception = e;
2630 } finally {
2631 delete this.invoking;
2632 }
2633
2634 push.call(this.exceptions, exception);
2635 push.call(this.returnValues, returnValue);
2636 push.call(this.stacks, new Error().stack);
2637
2638 // Make return value and exception available in the calls:
2639 createCallProperties.call(this);
2640
2641 if (exception !== undefined) {
2642 throw exception;
2643 }
2644
2645 return returnValue;
2646 },
2647
2648 named: function named(name) {
2649 this.displayName = name;
2650 return this;
2651 },
2652
2653 getCall: function getCall(i) {
2654 if (i < 0 || i >= this.callCount) {
2655 return null;
2656 }
2657
2658 return sinon.spyCall(this, this.thisValues[i], this.args[i],
2659 this.returnValues[i], this.exceptions[i] ,
2660 this.callIds[i], this.stacks[i]);
2661 },
2662
2663 getCalls: function () {
2664 var calls = [];
2665 var i;
2666
2667 for (i = 0; i < this.callCount; i++) {
2668 calls.push(this.getCall(i));
2669 }
2670
2671 return calls;
2672 },
2673
2674 calledBefore: function calledBefore(spyFn) {
2675 if (!this.called) {
2676 return false;
2677 }
2678
2679 if (!spyFn.called) {
2680 return true;
2681 }
2682
2683 return this.callIds[0] < spyFn.callIds[spyFn.callIds.length - 1] ;
2684 },
2685
2686 calledAfter: function calledAfter(spyFn) {
2687 if (!this.called || !spyFn.called) {
2688 return false;
2689 }
2690
2691 return this.callIds[this.callCount - 1] > spyFn.callIds[spyFn.ca llCount - 1];
2692 },
2693
2694 withArgs: function () {
2695 var args = slice.call(arguments);
2696
2697 if (this.fakes) {
2698 var match = matchingFake(this.fakes, args, true);
2699
2700 if (match) {
2701 return match;
2702 }
2703 } else {
2704 this.fakes = [];
2705 }
2706
2707 var original = this;
2708 var fake = this.instantiateFake();
2709 fake.matchingAguments = args;
2710 fake.parent = this;
2711 push.call(this.fakes, fake);
2712
2713 fake.withArgs = function () {
2714 return original.withArgs.apply(original, arguments);
2715 };
2716
2717 for (var i = 0; i < this.args.length; i++) {
2718 if (fake.matches(this.args[i])) {
2719 incrementCallCount.call(fake);
2720 push.call(fake.thisValues, this.thisValues[i]);
2721 push.call(fake.args, this.args[i]);
2722 push.call(fake.returnValues, this.returnValues[i]);
2723 push.call(fake.exceptions, this.exceptions[i]);
2724 push.call(fake.callIds, this.callIds[i]);
2725 }
2726 }
2727 createCallProperties.call(fake);
2728
2729 return fake;
2730 },
2731
2732 matches: function (args, strict) {
2733 var margs = this.matchingAguments;
2734
2735 if (margs.length <= args.length &&
2736 sinon.deepEqual(margs, args.slice(0, margs.length))) {
2737 return !strict || margs.length === args.length;
2738 }
2739 },
2740
2741 printf: function (format) {
2742 var spyInstance = this;
2743 var args = slice.call(arguments, 1);
2744 var formatter;
2745
2746 return (format || "").replace(/%(.)/g, function (match, specifye r) {
2747 formatter = spyApi.formatters[specifyer];
2748
2749 if (typeof formatter === "function") {
2750 return formatter.call(null, spyInstance, args);
2751 } else if (!isNaN(parseInt(specifyer, 10))) {
2752 return sinon.format(args[specifyer - 1]);
2753 }
2754
2755 return "%" + specifyer;
2756 });
2757 }
2758 };
2759
2760 function delegateToCalls(method, matchAny, actual, notCalled) {
2761 spyApi[method] = function () {
2762 if (!this.called) {
2763 if (notCalled) {
2764 return notCalled.apply(this, arguments);
2765 }
2766 return false;
2767 }
2768
2769 var currentCall;
2770 var matches = 0;
2771
2772 for (var i = 0, l = this.callCount; i < l; i += 1) {
2773 currentCall = this.getCall(i);
2774
2775 if (currentCall[actual || method].apply(currentCall, argumen ts)) {
2776 matches += 1;
2777
2778 if (matchAny) {
2779 return true;
2780 }
2781 }
2782 }
2783
2784 return matches === this.callCount;
2785 };
2786 }
2787
2788 delegateToCalls("calledOn", true);
2789 delegateToCalls("alwaysCalledOn", false, "calledOn");
2790 delegateToCalls("calledWith", true);
2791 delegateToCalls("calledWithMatch", true);
2792 delegateToCalls("alwaysCalledWith", false, "calledWith");
2793 delegateToCalls("alwaysCalledWithMatch", false, "calledWithMatch");
2794 delegateToCalls("calledWithExactly", true);
2795 delegateToCalls("alwaysCalledWithExactly", false, "calledWithExactly");
2796 delegateToCalls("neverCalledWith", false, "notCalledWith", function () {
2797 return true;
2798 });
2799 delegateToCalls("neverCalledWithMatch", false, "notCalledWithMatch", fun ction () {
2800 return true;
2801 });
2802 delegateToCalls("threw", true);
2803 delegateToCalls("alwaysThrew", false, "threw");
2804 delegateToCalls("returned", true);
2805 delegateToCalls("alwaysReturned", false, "returned");
2806 delegateToCalls("calledWithNew", true);
2807 delegateToCalls("alwaysCalledWithNew", false, "calledWithNew");
2808 delegateToCalls("callArg", false, "callArgWith", function () {
2809 throw new Error(this.toString() + " cannot call arg since it was not yet invoked.");
2810 });
2811 spyApi.callArgWith = spyApi.callArg;
2812 delegateToCalls("callArgOn", false, "callArgOnWith", function () {
2813 throw new Error(this.toString() + " cannot call arg since it was not yet invoked.");
2814 });
2815 spyApi.callArgOnWith = spyApi.callArgOn;
2816 delegateToCalls("yield", false, "yield", function () {
2817 throw new Error(this.toString() + " cannot yield since it was not ye t invoked.");
2818 });
2819 // "invokeCallback" is an alias for "yield" since "yield" is invalid in strict mode.
2820 spyApi.invokeCallback = spyApi.yield;
2821 delegateToCalls("yieldOn", false, "yieldOn", function () {
2822 throw new Error(this.toString() + " cannot yield since it was not ye t invoked.");
2823 });
2824 delegateToCalls("yieldTo", false, "yieldTo", function (property) {
2825 throw new Error(this.toString() + " cannot yield to '" + property +
2826 "' since it was not yet invoked.");
2827 });
2828 delegateToCalls("yieldToOn", false, "yieldToOn", function (property) {
2829 throw new Error(this.toString() + " cannot yield to '" + property +
2830 "' since it was not yet invoked.");
2831 });
2832
2833 spyApi.formatters = {
2834 c: function (spyInstance) {
2835 return sinon.timesInWords(spyInstance.callCount);
2836 },
2837
2838 n: function (spyInstance) {
2839 return spyInstance.toString();
2840 },
2841
2842 C: function (spyInstance) {
2843 var calls = [];
2844
2845 for (var i = 0, l = spyInstance.callCount; i < l; ++i) {
2846 var stringifiedCall = " " + spyInstance.getCall(i).toStri ng();
2847 if (/\n/.test(calls[i - 1])) {
2848 stringifiedCall = "\n" + stringifiedCall;
2849 }
2850 push.call(calls, stringifiedCall);
2851 }
2852
2853 return calls.length > 0 ? "\n" + calls.join("\n") : "";
2854 },
2855
2856 t: function (spyInstance) {
2857 var objects = [];
2858
2859 for (var i = 0, l = spyInstance.callCount; i < l; ++i) {
2860 push.call(objects, sinon.format(spyInstance.thisValues[i]));
2861 }
2862
2863 return objects.join(", ");
2864 },
2865
2866 "*": function (spyInstance, args) {
2867 var formatted = [];
2868
2869 for (var i = 0, l = args.length; i < l; ++i) {
2870 push.call(formatted, sinon.format(args[i]));
2871 }
2872
2873 return formatted.join(", ");
2874 }
2875 };
2876
2877 sinon.extend(spy, spyApi);
2878
2879 spy.spyCall = sinon.spyCall;
2880 sinon.spy = spy;
2881
2882 return spy;
2883 }
2884
2885 var isNode = typeof module !== "undefined" && module.exports && typeof requi re === "function";
2886 var isAMD = typeof define === "function" && typeof define.amd === "object" & & define.amd;
2887
2888 function loadDependencies(require, exports, module) {
2889 var core = require("./util/core");
2890 require("./call");
2891 require("./extend");
2892 require("./times_in_words");
2893 require("./format");
2894 module.exports = makeApi(core);
2895 }
2896
2897 if (isAMD) {
2898 define(loadDependencies);
2899 return;
2900 }
2901
2902 if (isNode) {
2903 loadDependencies(require, module.exports, module);
2904 return;
2905 }
2906
2907 if (sinonGlobal) {
2908 makeApi(sinonGlobal);
2909 }
2910 }(
2911 typeof sinon === "object" && sinon // eslint-disable-line no-undef
2912 ));
2913
2914 /**
2915 * @depend util/core.js
2916 * @depend extend.js
2917 */
2918 /**
2919 * Stub behavior
2920 *
2921 * @author Christian Johansen (christian@cjohansen.no)
2922 * @author Tim Fischbach (mail@timfischbach.de)
2923 * @license BSD
2924 *
2925 * Copyright (c) 2010-2013 Christian Johansen
2926 */
2927 (function (sinonGlobal) {
2928
2929 var slice = Array.prototype.slice;
2930 var join = Array.prototype.join;
2931 var useLeftMostCallback = -1;
2932 var useRightMostCallback = -2;
2933
2934 var nextTick = (function () {
2935 if (typeof process === "object" && typeof process.nextTick === "function ") {
2936 return process.nextTick;
2937 }
2938
2939 if (typeof setImmediate === "function") {
2940 return setImmediate;
2941 }
2942
2943 return function (callback) {
2944 setTimeout(callback, 0);
2945 };
2946 })();
2947
2948 function throwsException(error, message) {
2949 if (typeof error === "string") {
2950 this.exception = new Error(message || "");
2951 this.exception.name = error;
2952 } else if (!error) {
2953 this.exception = new Error("Error");
2954 } else {
2955 this.exception = error;
2956 }
2957
2958 return this;
2959 }
2960
2961 function getCallback(behavior, args) {
2962 var callArgAt = behavior.callArgAt;
2963
2964 if (callArgAt >= 0) {
2965 return args[callArgAt];
2966 }
2967
2968 var argumentList;
2969
2970 if (callArgAt === useLeftMostCallback) {
2971 argumentList = args;
2972 }
2973
2974 if (callArgAt === useRightMostCallback) {
2975 argumentList = slice.call(args).reverse();
2976 }
2977
2978 var callArgProp = behavior.callArgProp;
2979
2980 for (var i = 0, l = argumentList.length; i < l; ++i) {
2981 if (!callArgProp && typeof argumentList[i] === "function") {
2982 return argumentList[i];
2983 }
2984
2985 if (callArgProp && argumentList[i] &&
2986 typeof argumentList[i][callArgProp] === "function") {
2987 return argumentList[i][callArgProp];
2988 }
2989 }
2990
2991 return null;
2992 }
2993
2994 function makeApi(sinon) {
2995 function getCallbackError(behavior, func, args) {
2996 if (behavior.callArgAt < 0) {
2997 var msg;
2998
2999 if (behavior.callArgProp) {
3000 msg = sinon.functionName(behavior.stub) +
3001 " expected to yield to '" + behavior.callArgProp +
3002 "', but no object with such a property was passed.";
3003 } else {
3004 msg = sinon.functionName(behavior.stub) +
3005 " expected to yield, but no callback was passed.";
3006 }
3007
3008 if (args.length > 0) {
3009 msg += " Received [" + join.call(args, ", ") + "]";
3010 }
3011
3012 return msg;
3013 }
3014
3015 return "argument at index " + behavior.callArgAt + " is not a functi on: " + func;
3016 }
3017
3018 function callCallback(behavior, args) {
3019 if (typeof behavior.callArgAt === "number") {
3020 var func = getCallback(behavior, args);
3021
3022 if (typeof func !== "function") {
3023 throw new TypeError(getCallbackError(behavior, func, args));
3024 }
3025
3026 if (behavior.callbackAsync) {
3027 nextTick(function () {
3028 func.apply(behavior.callbackContext, behavior.callbackAr guments);
3029 });
3030 } else {
3031 func.apply(behavior.callbackContext, behavior.callbackArgume nts);
3032 }
3033 }
3034 }
3035
3036 var proto = {
3037 create: function create(stub) {
3038 var behavior = sinon.extend({}, sinon.behavior);
3039 delete behavior.create;
3040 behavior.stub = stub;
3041
3042 return behavior;
3043 },
3044
3045 isPresent: function isPresent() {
3046 return (typeof this.callArgAt === "number" ||
3047 this.exception ||
3048 typeof this.returnArgAt === "number" ||
3049 this.returnThis ||
3050 this.returnValueDefined);
3051 },
3052
3053 invoke: function invoke(context, args) {
3054 callCallback(this, args);
3055
3056 if (this.exception) {
3057 throw this.exception;
3058 } else if (typeof this.returnArgAt === "number") {
3059 return args[this.returnArgAt];
3060 } else if (this.returnThis) {
3061 return context;
3062 }
3063
3064 return this.returnValue;
3065 },
3066
3067 onCall: function onCall(index) {
3068 return this.stub.onCall(index);
3069 },
3070
3071 onFirstCall: function onFirstCall() {
3072 return this.stub.onFirstCall();
3073 },
3074
3075 onSecondCall: function onSecondCall() {
3076 return this.stub.onSecondCall();
3077 },
3078
3079 onThirdCall: function onThirdCall() {
3080 return this.stub.onThirdCall();
3081 },
3082
3083 withArgs: function withArgs(/* arguments */) {
3084 throw new Error(
3085 "Defining a stub by invoking \"stub.onCall(...).withArgs(... )\" " +
3086 "is not supported. Use \"stub.withArgs(...).onCall(...)\" " +
3087 "to define sequential behavior for calls with certain argume nts."
3088 );
3089 },
3090
3091 callsArg: function callsArg(pos) {
3092 if (typeof pos !== "number") {
3093 throw new TypeError("argument index is not number");
3094 }
3095
3096 this.callArgAt = pos;
3097 this.callbackArguments = [];
3098 this.callbackContext = undefined;
3099 this.callArgProp = undefined;
3100 this.callbackAsync = false;
3101
3102 return this;
3103 },
3104
3105 callsArgOn: function callsArgOn(pos, context) {
3106 if (typeof pos !== "number") {
3107 throw new TypeError("argument index is not number");
3108 }
3109 if (typeof context !== "object") {
3110 throw new TypeError("argument context is not an object");
3111 }
3112
3113 this.callArgAt = pos;
3114 this.callbackArguments = [];
3115 this.callbackContext = context;
3116 this.callArgProp = undefined;
3117 this.callbackAsync = false;
3118
3119 return this;
3120 },
3121
3122 callsArgWith: function callsArgWith(pos) {
3123 if (typeof pos !== "number") {
3124 throw new TypeError("argument index is not number");
3125 }
3126
3127 this.callArgAt = pos;
3128 this.callbackArguments = slice.call(arguments, 1);
3129 this.callbackContext = undefined;
3130 this.callArgProp = undefined;
3131 this.callbackAsync = false;
3132
3133 return this;
3134 },
3135
3136 callsArgOnWith: function callsArgWith(pos, context) {
3137 if (typeof pos !== "number") {
3138 throw new TypeError("argument index is not number");
3139 }
3140 if (typeof context !== "object") {
3141 throw new TypeError("argument context is not an object");
3142 }
3143
3144 this.callArgAt = pos;
3145 this.callbackArguments = slice.call(arguments, 2);
3146 this.callbackContext = context;
3147 this.callArgProp = undefined;
3148 this.callbackAsync = false;
3149
3150 return this;
3151 },
3152
3153 yields: function () {
3154 this.callArgAt = useLeftMostCallback;
3155 this.callbackArguments = slice.call(arguments, 0);
3156 this.callbackContext = undefined;
3157 this.callArgProp = undefined;
3158 this.callbackAsync = false;
3159
3160 return this;
3161 },
3162
3163 yieldsRight: function () {
3164 this.callArgAt = useRightMostCallback;
3165 this.callbackArguments = slice.call(arguments, 0);
3166 this.callbackContext = undefined;
3167 this.callArgProp = undefined;
3168 this.callbackAsync = false;
3169
3170 return this;
3171 },
3172
3173 yieldsOn: function (context) {
3174 if (typeof context !== "object") {
3175 throw new TypeError("argument context is not an object");
3176 }
3177
3178 this.callArgAt = useLeftMostCallback;
3179 this.callbackArguments = slice.call(arguments, 1);
3180 this.callbackContext = context;
3181 this.callArgProp = undefined;
3182 this.callbackAsync = false;
3183
3184 return this;
3185 },
3186
3187 yieldsTo: function (prop) {
3188 this.callArgAt = useLeftMostCallback;
3189 this.callbackArguments = slice.call(arguments, 1);
3190 this.callbackContext = undefined;
3191 this.callArgProp = prop;
3192 this.callbackAsync = false;
3193
3194 return this;
3195 },
3196
3197 yieldsToOn: function (prop, context) {
3198 if (typeof context !== "object") {
3199 throw new TypeError("argument context is not an object");
3200 }
3201
3202 this.callArgAt = useLeftMostCallback;
3203 this.callbackArguments = slice.call(arguments, 2);
3204 this.callbackContext = context;
3205 this.callArgProp = prop;
3206 this.callbackAsync = false;
3207
3208 return this;
3209 },
3210
3211 throws: throwsException,
3212 throwsException: throwsException,
3213
3214 returns: function returns(value) {
3215 this.returnValue = value;
3216 this.returnValueDefined = true;
3217 this.exception = undefined;
3218
3219 return this;
3220 },
3221
3222 returnsArg: function returnsArg(pos) {
3223 if (typeof pos !== "number") {
3224 throw new TypeError("argument index is not number");
3225 }
3226
3227 this.returnArgAt = pos;
3228
3229 return this;
3230 },
3231
3232 returnsThis: function returnsThis() {
3233 this.returnThis = true;
3234
3235 return this;
3236 }
3237 };
3238
3239 function createAsyncVersion(syncFnName) {
3240 return function () {
3241 var result = this[syncFnName].apply(this, arguments);
3242 this.callbackAsync = true;
3243 return result;
3244 };
3245 }
3246
3247 // create asynchronous versions of callsArg* and yields* methods
3248 for (var method in proto) {
3249 // need to avoid creating anotherasync versions of the newly added a sync methods
3250 if (proto.hasOwnProperty(method) && method.match(/^(callsArg|yields) /) && !method.match(/Async/)) {
3251 proto[method + "Async"] = createAsyncVersion(method);
3252 }
3253 }
3254
3255 sinon.behavior = proto;
3256 return proto;
3257 }
3258
3259 var isNode = typeof module !== "undefined" && module.exports && typeof requi re === "function";
3260 var isAMD = typeof define === "function" && typeof define.amd === "object" & & define.amd;
3261
3262 function loadDependencies(require, exports, module) {
3263 var sinon = require("./util/core");
3264 require("./extend");
3265 module.exports = makeApi(sinon);
3266 }
3267
3268 if (isAMD) {
3269 define(loadDependencies);
3270 return;
3271 }
3272
3273 if (isNode) {
3274 loadDependencies(require, module.exports, module);
3275 return;
3276 }
3277
3278 if (sinonGlobal) {
3279 makeApi(sinonGlobal);
3280 }
3281 }(
3282 typeof sinon === "object" && sinon // eslint-disable-line no-undef
3283 ));
3284
3285 /**
3286 * @depend util/core.js
3287 */
3288 (function (sinonGlobal) {
3289
3290 function makeApi(sinon) {
3291 function walkInternal(obj, iterator, context, originalObj) {
3292 var proto, prop;
3293
3294 if (typeof Object.getOwnPropertyNames !== "function") {
3295 // We explicitly want to enumerate through all of the prototype' s properties
3296 // in this case, therefore we deliberately leave out an own prop erty check.
3297 /* eslint-disable guard-for-in */
3298 for (prop in obj) {
3299 iterator.call(context, obj[prop], prop, obj);
3300 }
3301 /* eslint-enable guard-for-in */
3302
3303 return;
3304 }
3305
3306 Object.getOwnPropertyNames(obj).forEach(function (k) {
3307 var target = typeof Object.getOwnPropertyDescriptor(obj, k).get === "function" ?
3308 originalObj : obj;
3309 iterator.call(context, target[k], k, target);
3310 });
3311
3312 proto = Object.getPrototypeOf(obj);
3313 if (proto) {
3314 walkInternal(proto, iterator, context, originalObj);
3315 }
3316 }
3317
3318 /* Public: walks the prototype chain of an object and iterates over ever y own property
3319 * name encountered. The iterator is called in the same fashion that Arr ay.prototype.forEach
3320 * works, where it is passed the value, key, and own object as the 1st, 2nd, and 3rd positional
3321 * argument, respectively. In cases where Object.getOwnPropertyNames is not available, walk will
3322 * default to using a simple for..in loop.
3323 *
3324 * obj - The object to walk the prototype chain for.
3325 * iterator - The function to be called on each pass of the walk.
3326 * context - (Optional) When given, the iterator will be called with thi s object as the receiver.
3327 */
3328 function walk(obj, iterator, context) {
3329 return walkInternal(obj, iterator, context, obj);
3330 }
3331
3332 sinon.walk = walk;
3333 return sinon.walk;
3334 }
3335
3336 function loadDependencies(require, exports, module) {
3337 var sinon = require("./util/core");
3338 module.exports = makeApi(sinon);
3339 }
3340
3341 var isNode = typeof module !== "undefined" && module.exports && typeof requi re === "function";
3342 var isAMD = typeof define === "function" && typeof define.amd === "object" & & define.amd;
3343
3344 if (isAMD) {
3345 define(loadDependencies);
3346 return;
3347 }
3348
3349 if (isNode) {
3350 loadDependencies(require, module.exports, module);
3351 return;
3352 }
3353
3354 if (sinonGlobal) {
3355 makeApi(sinonGlobal);
3356 }
3357 }(
3358 typeof sinon === "object" && sinon // eslint-disable-line no-undef
3359 ));
3360
3361 /**
3362 * @depend util/core.js
3363 * @depend extend.js
3364 * @depend spy.js
3365 * @depend behavior.js
3366 * @depend walk.js
3367 */
3368 /**
3369 * Stub functions
3370 *
3371 * @author Christian Johansen (christian@cjohansen.no)
3372 * @license BSD
3373 *
3374 * Copyright (c) 2010-2013 Christian Johansen
3375 */
3376 (function (sinonGlobal) {
3377
3378 function makeApi(sinon) {
3379 function stub(object, property, func) {
3380 if (!!func && typeof func !== "function" && typeof func !== "object" ) {
3381 throw new TypeError("Custom stub should be a function or a prope rty descriptor");
3382 }
3383
3384 var wrapper;
3385
3386 if (func) {
3387 if (typeof func === "function") {
3388 wrapper = sinon.spy && sinon.spy.create ? sinon.spy.create(f unc) : func;
3389 } else {
3390 wrapper = func;
3391 if (sinon.spy && sinon.spy.create) {
3392 var types = sinon.objectKeys(wrapper);
3393 for (var i = 0; i < types.length; i++) {
3394 wrapper[types[i]] = sinon.spy.create(wrapper[types[i ]]);
3395 }
3396 }
3397 }
3398 } else {
3399 var stubLength = 0;
3400 if (typeof object === "object" && typeof object[property] === "f unction") {
3401 stubLength = object[property].length;
3402 }
3403 wrapper = stub.create(stubLength);
3404 }
3405
3406 if (!object && typeof property === "undefined") {
3407 return sinon.stub.create();
3408 }
3409
3410 if (typeof property === "undefined" && typeof object === "object") {
3411 sinon.walk(object || {}, function (value, prop, propOwner) {
3412 // we don't want to stub things like toString(), valueOf(), etc. so we only stub if the object
3413 // is not Object.prototype
3414 if (
3415 propOwner !== Object.prototype &&
3416 prop !== "constructor" &&
3417 typeof sinon.getPropertyDescriptor(propOwner, prop).valu e === "function"
3418 ) {
3419 stub(object, prop);
3420 }
3421 });
3422
3423 return object;
3424 }
3425
3426 return sinon.wrapMethod(object, property, wrapper);
3427 }
3428
3429
3430 /*eslint-disable no-use-before-define*/
3431 function getParentBehaviour(stubInstance) {
3432 return (stubInstance.parent && getCurrentBehavior(stubInstance.paren t));
3433 }
3434
3435 function getDefaultBehavior(stubInstance) {
3436 return stubInstance.defaultBehavior ||
3437 getParentBehaviour(stubInstance) ||
3438 sinon.behavior.create(stubInstance);
3439 }
3440
3441 function getCurrentBehavior(stubInstance) {
3442 var behavior = stubInstance.behaviors[stubInstance.callCount - 1];
3443 return behavior && behavior.isPresent() ? behavior : getDefaultBehav ior(stubInstance);
3444 }
3445 /*eslint-enable no-use-before-define*/
3446
3447 var uuid = 0;
3448
3449 var proto = {
3450 create: function create(stubLength) {
3451 var functionStub = function () {
3452 return getCurrentBehavior(functionStub).invoke(this, argumen ts);
3453 };
3454
3455 functionStub.id = "stub#" + uuid++;
3456 var orig = functionStub;
3457 functionStub = sinon.spy.create(functionStub, stubLength);
3458 functionStub.func = orig;
3459
3460 sinon.extend(functionStub, stub);
3461 functionStub.instantiateFake = sinon.stub.create;
3462 functionStub.displayName = "stub";
3463 functionStub.toString = sinon.functionToString;
3464
3465 functionStub.defaultBehavior = null;
3466 functionStub.behaviors = [];
3467
3468 return functionStub;
3469 },
3470
3471 resetBehavior: function () {
3472 var i;
3473
3474 this.defaultBehavior = null;
3475 this.behaviors = [];
3476
3477 delete this.returnValue;
3478 delete this.returnArgAt;
3479 this.returnThis = false;
3480
3481 if (this.fakes) {
3482 for (i = 0; i < this.fakes.length; i++) {
3483 this.fakes[i].resetBehavior();
3484 }
3485 }
3486 },
3487
3488 onCall: function onCall(index) {
3489 if (!this.behaviors[index]) {
3490 this.behaviors[index] = sinon.behavior.create(this);
3491 }
3492
3493 return this.behaviors[index];
3494 },
3495
3496 onFirstCall: function onFirstCall() {
3497 return this.onCall(0);
3498 },
3499
3500 onSecondCall: function onSecondCall() {
3501 return this.onCall(1);
3502 },
3503
3504 onThirdCall: function onThirdCall() {
3505 return this.onCall(2);
3506 }
3507 };
3508
3509 function createBehavior(behaviorMethod) {
3510 return function () {
3511 this.defaultBehavior = this.defaultBehavior || sinon.behavior.cr eate(this);
3512 this.defaultBehavior[behaviorMethod].apply(this.defaultBehavior, arguments);
3513 return this;
3514 };
3515 }
3516
3517 for (var method in sinon.behavior) {
3518 if (sinon.behavior.hasOwnProperty(method) &&
3519 !proto.hasOwnProperty(method) &&
3520 method !== "create" &&
3521 method !== "withArgs" &&
3522 method !== "invoke") {
3523 proto[method] = createBehavior(method);
3524 }
3525 }
3526
3527 sinon.extend(stub, proto);
3528 sinon.stub = stub;
3529
3530 return stub;
3531 }
3532
3533 var isNode = typeof module !== "undefined" && module.exports && typeof requi re === "function";
3534 var isAMD = typeof define === "function" && typeof define.amd === "object" & & define.amd;
3535
3536 function loadDependencies(require, exports, module) {
3537 var core = require("./util/core");
3538 require("./behavior");
3539 require("./spy");
3540 require("./extend");
3541 module.exports = makeApi(core);
3542 }
3543
3544 if (isAMD) {
3545 define(loadDependencies);
3546 return;
3547 }
3548
3549 if (isNode) {
3550 loadDependencies(require, module.exports, module);
3551 return;
3552 }
3553
3554 if (sinonGlobal) {
3555 makeApi(sinonGlobal);
3556 }
3557 }(
3558 typeof sinon === "object" && sinon // eslint-disable-line no-undef
3559 ));
3560
3561 /**
3562 * @depend times_in_words.js
3563 * @depend util/core.js
3564 * @depend call.js
3565 * @depend extend.js
3566 * @depend match.js
3567 * @depend spy.js
3568 * @depend stub.js
3569 * @depend format.js
3570 */
3571 /**
3572 * Mock functions.
3573 *
3574 * @author Christian Johansen (christian@cjohansen.no)
3575 * @license BSD
3576 *
3577 * Copyright (c) 2010-2013 Christian Johansen
3578 */
3579 (function (sinonGlobal) {
3580
3581 function makeApi(sinon) {
3582 var push = [].push;
3583 var match = sinon.match;
3584
3585 function mock(object) {
3586 // if (typeof console !== undefined && console.warn) {
3587 // console.warn("mock will be removed from Sinon.JS v2.0");
3588 // }
3589
3590 if (!object) {
3591 return sinon.expectation.create("Anonymous mock");
3592 }
3593
3594 return mock.create(object);
3595 }
3596
3597 function each(collection, callback) {
3598 if (!collection) {
3599 return;
3600 }
3601
3602 for (var i = 0, l = collection.length; i < l; i += 1) {
3603 callback(collection[i]);
3604 }
3605 }
3606
3607 function arrayEquals(arr1, arr2, compareLength) {
3608 if (compareLength && (arr1.length !== arr2.length)) {
3609 return false;
3610 }
3611
3612 for (var i = 0, l = arr1.length; i < l; i++) {
3613 if (!sinon.deepEqual(arr1[i], arr2[i])) {
3614 return false;
3615 }
3616 }
3617 return true;
3618 }
3619
3620 sinon.extend(mock, {
3621 create: function create(object) {
3622 if (!object) {
3623 throw new TypeError("object is null");
3624 }
3625
3626 var mockObject = sinon.extend({}, mock);
3627 mockObject.object = object;
3628 delete mockObject.create;
3629
3630 return mockObject;
3631 },
3632
3633 expects: function expects(method) {
3634 if (!method) {
3635 throw new TypeError("method is falsy");
3636 }
3637
3638 if (!this.expectations) {
3639 this.expectations = {};
3640 this.proxies = [];
3641 }
3642
3643 if (!this.expectations[method]) {
3644 this.expectations[method] = [];
3645 var mockObject = this;
3646
3647 sinon.wrapMethod(this.object, method, function () {
3648 return mockObject.invokeMethod(method, this, arguments);
3649 });
3650
3651 push.call(this.proxies, method);
3652 }
3653
3654 var expectation = sinon.expectation.create(method);
3655 push.call(this.expectations[method], expectation);
3656
3657 return expectation;
3658 },
3659
3660 restore: function restore() {
3661 var object = this.object;
3662
3663 each(this.proxies, function (proxy) {
3664 if (typeof object[proxy].restore === "function") {
3665 object[proxy].restore();
3666 }
3667 });
3668 },
3669
3670 verify: function verify() {
3671 var expectations = this.expectations || {};
3672 var messages = [];
3673 var met = [];
3674
3675 each(this.proxies, function (proxy) {
3676 each(expectations[proxy], function (expectation) {
3677 if (!expectation.met()) {
3678 push.call(messages, expectation.toString());
3679 } else {
3680 push.call(met, expectation.toString());
3681 }
3682 });
3683 });
3684
3685 this.restore();
3686
3687 if (messages.length > 0) {
3688 sinon.expectation.fail(messages.concat(met).join("\n"));
3689 } else if (met.length > 0) {
3690 sinon.expectation.pass(messages.concat(met).join("\n"));
3691 }
3692
3693 return true;
3694 },
3695
3696 invokeMethod: function invokeMethod(method, thisValue, args) {
3697 var expectations = this.expectations && this.expectations[method ] ? this.expectations[method] : [];
3698 var expectationsWithMatchingArgs = [];
3699 var currentArgs = args || [];
3700 var i, available;
3701
3702 for (i = 0; i < expectations.length; i += 1) {
3703 var expectedArgs = expectations[i].expectedArguments || [];
3704 if (arrayEquals(expectedArgs, currentArgs, expectations[i].e xpectsExactArgCount)) {
3705 expectationsWithMatchingArgs.push(expectations[i]);
3706 }
3707 }
3708
3709 for (i = 0; i < expectationsWithMatchingArgs.length; i += 1) {
3710 if (!expectationsWithMatchingArgs[i].met() &&
3711 expectationsWithMatchingArgs[i].allowsCall(thisValue, ar gs)) {
3712 return expectationsWithMatchingArgs[i].apply(thisValue, args);
3713 }
3714 }
3715
3716 var messages = [];
3717 var exhausted = 0;
3718
3719 for (i = 0; i < expectationsWithMatchingArgs.length; i += 1) {
3720 if (expectationsWithMatchingArgs[i].allowsCall(thisValue, ar gs)) {
3721 available = available || expectationsWithMatchingArgs[i] ;
3722 } else {
3723 exhausted += 1;
3724 }
3725 }
3726
3727 if (available && exhausted === 0) {
3728 return available.apply(thisValue, args);
3729 }
3730
3731 for (i = 0; i < expectations.length; i += 1) {
3732 push.call(messages, " " + expectations[i].toString());
3733 }
3734
3735 messages.unshift("Unexpected call: " + sinon.spyCall.toString.ca ll({
3736 proxy: method,
3737 args: args
3738 }));
3739
3740 sinon.expectation.fail(messages.join("\n"));
3741 }
3742 });
3743
3744 var times = sinon.timesInWords;
3745 var slice = Array.prototype.slice;
3746
3747 function callCountInWords(callCount) {
3748 if (callCount === 0) {
3749 return "never called";
3750 }
3751
3752 return "called " + times(callCount);
3753 }
3754
3755 function expectedCallCountInWords(expectation) {
3756 var min = expectation.minCalls;
3757 var max = expectation.maxCalls;
3758
3759 if (typeof min === "number" && typeof max === "number") {
3760 var str = times(min);
3761
3762 if (min !== max) {
3763 str = "at least " + str + " and at most " + times(max);
3764 }
3765
3766 return str;
3767 }
3768
3769 if (typeof min === "number") {
3770 return "at least " + times(min);
3771 }
3772
3773 return "at most " + times(max);
3774 }
3775
3776 function receivedMinCalls(expectation) {
3777 var hasMinLimit = typeof expectation.minCalls === "number";
3778 return !hasMinLimit || expectation.callCount >= expectation.minCalls ;
3779 }
3780
3781 function receivedMaxCalls(expectation) {
3782 if (typeof expectation.maxCalls !== "number") {
3783 return false;
3784 }
3785
3786 return expectation.callCount === expectation.maxCalls;
3787 }
3788
3789 function verifyMatcher(possibleMatcher, arg) {
3790 var isMatcher = match && match.isMatcher(possibleMatcher);
3791
3792 return isMatcher && possibleMatcher.test(arg) || true;
3793 }
3794
3795 sinon.expectation = {
3796 minCalls: 1,
3797 maxCalls: 1,
3798
3799 create: function create(methodName) {
3800 var expectation = sinon.extend(sinon.stub.create(), sinon.expect ation);
3801 delete expectation.create;
3802 expectation.method = methodName;
3803
3804 return expectation;
3805 },
3806
3807 invoke: function invoke(func, thisValue, args) {
3808 this.verifyCallAllowed(thisValue, args);
3809
3810 return sinon.spy.invoke.apply(this, arguments);
3811 },
3812
3813 atLeast: function atLeast(num) {
3814 if (typeof num !== "number") {
3815 throw new TypeError("'" + num + "' is not number");
3816 }
3817
3818 if (!this.limitsSet) {
3819 this.maxCalls = null;
3820 this.limitsSet = true;
3821 }
3822
3823 this.minCalls = num;
3824
3825 return this;
3826 },
3827
3828 atMost: function atMost(num) {
3829 if (typeof num !== "number") {
3830 throw new TypeError("'" + num + "' is not number");
3831 }
3832
3833 if (!this.limitsSet) {
3834 this.minCalls = null;
3835 this.limitsSet = true;
3836 }
3837
3838 this.maxCalls = num;
3839
3840 return this;
3841 },
3842
3843 never: function never() {
3844 return this.exactly(0);
3845 },
3846
3847 once: function once() {
3848 return this.exactly(1);
3849 },
3850
3851 twice: function twice() {
3852 return this.exactly(2);
3853 },
3854
3855 thrice: function thrice() {
3856 return this.exactly(3);
3857 },
3858
3859 exactly: function exactly(num) {
3860 if (typeof num !== "number") {
3861 throw new TypeError("'" + num + "' is not a number");
3862 }
3863
3864 this.atLeast(num);
3865 return this.atMost(num);
3866 },
3867
3868 met: function met() {
3869 return !this.failed && receivedMinCalls(this);
3870 },
3871
3872 verifyCallAllowed: function verifyCallAllowed(thisValue, args) {
3873 if (receivedMaxCalls(this)) {
3874 this.failed = true;
3875 sinon.expectation.fail(this.method + " already called " + ti mes(this.maxCalls));
3876 }
3877
3878 if ("expectedThis" in this && this.expectedThis !== thisValue) {
3879 sinon.expectation.fail(this.method + " called with " + thisV alue + " as thisValue, expected " +
3880 this.expectedThis);
3881 }
3882
3883 if (!("expectedArguments" in this)) {
3884 return;
3885 }
3886
3887 if (!args) {
3888 sinon.expectation.fail(this.method + " received no arguments , expected " +
3889 sinon.format(this.expectedArguments));
3890 }
3891
3892 if (args.length < this.expectedArguments.length) {
3893 sinon.expectation.fail(this.method + " received too few argu ments (" + sinon.format(args) +
3894 "), expected " + sinon.format(this.expectedArguments));
3895 }
3896
3897 if (this.expectsExactArgCount &&
3898 args.length !== this.expectedArguments.length) {
3899 sinon.expectation.fail(this.method + " received too many arg uments (" + sinon.format(args) +
3900 "), expected " + sinon.format(this.expectedArguments));
3901 }
3902
3903 for (var i = 0, l = this.expectedArguments.length; i < l; i += 1 ) {
3904
3905 if (!verifyMatcher(this.expectedArguments[i], args[i])) {
3906 sinon.expectation.fail(this.method + " received wrong ar guments " + sinon.format(args) +
3907 ", didn't match " + this.expectedArguments.toString( ));
3908 }
3909
3910 if (!sinon.deepEqual(this.expectedArguments[i], args[i])) {
3911 sinon.expectation.fail(this.method + " received wrong ar guments " + sinon.format(args) +
3912 ", expected " + sinon.format(this.expectedArguments) );
3913 }
3914 }
3915 },
3916
3917 allowsCall: function allowsCall(thisValue, args) {
3918 if (this.met() && receivedMaxCalls(this)) {
3919 return false;
3920 }
3921
3922 if ("expectedThis" in this && this.expectedThis !== thisValue) {
3923 return false;
3924 }
3925
3926 if (!("expectedArguments" in this)) {
3927 return true;
3928 }
3929
3930 args = args || [];
3931
3932 if (args.length < this.expectedArguments.length) {
3933 return false;
3934 }
3935
3936 if (this.expectsExactArgCount &&
3937 args.length !== this.expectedArguments.length) {
3938 return false;
3939 }
3940
3941 for (var i = 0, l = this.expectedArguments.length; i < l; i += 1 ) {
3942 if (!verifyMatcher(this.expectedArguments[i], args[i])) {
3943 return false;
3944 }
3945
3946 if (!sinon.deepEqual(this.expectedArguments[i], args[i])) {
3947 return false;
3948 }
3949 }
3950
3951 return true;
3952 },
3953
3954 withArgs: function withArgs() {
3955 this.expectedArguments = slice.call(arguments);
3956 return this;
3957 },
3958
3959 withExactArgs: function withExactArgs() {
3960 this.withArgs.apply(this, arguments);
3961 this.expectsExactArgCount = true;
3962 return this;
3963 },
3964
3965 on: function on(thisValue) {
3966 this.expectedThis = thisValue;
3967 return this;
3968 },
3969
3970 toString: function () {
3971 var args = (this.expectedArguments || []).slice();
3972
3973 if (!this.expectsExactArgCount) {
3974 push.call(args, "[...]");
3975 }
3976
3977 var callStr = sinon.spyCall.toString.call({
3978 proxy: this.method || "anonymous mock expectation",
3979 args: args
3980 });
3981
3982 var message = callStr.replace(", [...", "[, ...") + " " +
3983 expectedCallCountInWords(this);
3984
3985 if (this.met()) {
3986 return "Expectation met: " + message;
3987 }
3988
3989 return "Expected " + message + " (" +
3990 callCountInWords(this.callCount) + ")";
3991 },
3992
3993 verify: function verify() {
3994 if (!this.met()) {
3995 sinon.expectation.fail(this.toString());
3996 } else {
3997 sinon.expectation.pass(this.toString());
3998 }
3999
4000 return true;
4001 },
4002
4003 pass: function pass(message) {
4004 sinon.assert.pass(message);
4005 },
4006
4007 fail: function fail(message) {
4008 var exception = new Error(message);
4009 exception.name = "ExpectationError";
4010
4011 throw exception;
4012 }
4013 };
4014
4015 sinon.mock = mock;
4016 return mock;
4017 }
4018
4019 var isNode = typeof module !== "undefined" && module.exports && typeof requi re === "function";
4020 var isAMD = typeof define === "function" && typeof define.amd === "object" & & define.amd;
4021
4022 function loadDependencies(require, exports, module) {
4023 var sinon = require("./util/core");
4024 require("./times_in_words");
4025 require("./call");
4026 require("./extend");
4027 require("./match");
4028 require("./spy");
4029 require("./stub");
4030 require("./format");
4031
4032 module.exports = makeApi(sinon);
4033 }
4034
4035 if (isAMD) {
4036 define(loadDependencies);
4037 return;
4038 }
4039
4040 if (isNode) {
4041 loadDependencies(require, module.exports, module);
4042 return;
4043 }
4044
4045 if (sinonGlobal) {
4046 makeApi(sinonGlobal);
4047 }
4048 }(
4049 typeof sinon === "object" && sinon // eslint-disable-line no-undef
4050 ));
4051
4052 /**
4053 * @depend util/core.js
4054 * @depend spy.js
4055 * @depend stub.js
4056 * @depend mock.js
4057 */
4058 /**
4059 * Collections of stubs, spies and mocks.
4060 *
4061 * @author Christian Johansen (christian@cjohansen.no)
4062 * @license BSD
4063 *
4064 * Copyright (c) 2010-2013 Christian Johansen
4065 */
4066 (function (sinonGlobal) {
4067
4068 var push = [].push;
4069 var hasOwnProperty = Object.prototype.hasOwnProperty;
4070
4071 function getFakes(fakeCollection) {
4072 if (!fakeCollection.fakes) {
4073 fakeCollection.fakes = [];
4074 }
4075
4076 return fakeCollection.fakes;
4077 }
4078
4079 function each(fakeCollection, method) {
4080 var fakes = getFakes(fakeCollection);
4081
4082 for (var i = 0, l = fakes.length; i < l; i += 1) {
4083 if (typeof fakes[i][method] === "function") {
4084 fakes[i][method]();
4085 }
4086 }
4087 }
4088
4089 function compact(fakeCollection) {
4090 var fakes = getFakes(fakeCollection);
4091 var i = 0;
4092 while (i < fakes.length) {
4093 fakes.splice(i, 1);
4094 }
4095 }
4096
4097 function makeApi(sinon) {
4098 var collection = {
4099 verify: function resolve() {
4100 each(this, "verify");
4101 },
4102
4103 restore: function restore() {
4104 each(this, "restore");
4105 compact(this);
4106 },
4107
4108 reset: function restore() {
4109 each(this, "reset");
4110 },
4111
4112 verifyAndRestore: function verifyAndRestore() {
4113 var exception;
4114
4115 try {
4116 this.verify();
4117 } catch (e) {
4118 exception = e;
4119 }
4120
4121 this.restore();
4122
4123 if (exception) {
4124 throw exception;
4125 }
4126 },
4127
4128 add: function add(fake) {
4129 push.call(getFakes(this), fake);
4130 return fake;
4131 },
4132
4133 spy: function spy() {
4134 return this.add(sinon.spy.apply(sinon, arguments));
4135 },
4136
4137 stub: function stub(object, property, value) {
4138 if (property) {
4139 var original = object[property];
4140
4141 if (typeof original !== "function") {
4142 if (!hasOwnProperty.call(object, property)) {
4143 throw new TypeError("Cannot stub non-existent own pr operty " + property);
4144 }
4145
4146 object[property] = value;
4147
4148 return this.add({
4149 restore: function () {
4150 object[property] = original;
4151 }
4152 });
4153 }
4154 }
4155 if (!property && !!object && typeof object === "object") {
4156 var stubbedObj = sinon.stub.apply(sinon, arguments);
4157
4158 for (var prop in stubbedObj) {
4159 if (typeof stubbedObj[prop] === "function") {
4160 this.add(stubbedObj[prop]);
4161 }
4162 }
4163
4164 return stubbedObj;
4165 }
4166
4167 return this.add(sinon.stub.apply(sinon, arguments));
4168 },
4169
4170 mock: function mock() {
4171 return this.add(sinon.mock.apply(sinon, arguments));
4172 },
4173
4174 inject: function inject(obj) {
4175 var col = this;
4176
4177 obj.spy = function () {
4178 return col.spy.apply(col, arguments);
4179 };
4180
4181 obj.stub = function () {
4182 return col.stub.apply(col, arguments);
4183 };
4184
4185 obj.mock = function () {
4186 return col.mock.apply(col, arguments);
4187 };
4188
4189 return obj;
4190 }
4191 };
4192
4193 sinon.collection = collection;
4194 return collection;
4195 }
4196
4197 var isNode = typeof module !== "undefined" && module.exports && typeof requi re === "function";
4198 var isAMD = typeof define === "function" && typeof define.amd === "object" & & define.amd;
4199
4200 function loadDependencies(require, exports, module) {
4201 var sinon = require("./util/core");
4202 require("./mock");
4203 require("./spy");
4204 require("./stub");
4205 module.exports = makeApi(sinon);
4206 }
4207
4208 if (isAMD) {
4209 define(loadDependencies);
4210 return;
4211 }
4212
4213 if (isNode) {
4214 loadDependencies(require, module.exports, module);
4215 return;
4216 }
4217
4218 if (sinonGlobal) {
4219 makeApi(sinonGlobal);
4220 }
4221 }(
4222 typeof sinon === "object" && sinon // eslint-disable-line no-undef
4223 ));
4224
4225 /**
4226 * Fake timer API
4227 * setTimeout
4228 * setInterval
4229 * clearTimeout
4230 * clearInterval
4231 * tick
4232 * reset
4233 * Date
4234 *
4235 * Inspired by jsUnitMockTimeOut from JsUnit
4236 *
4237 * @author Christian Johansen (christian@cjohansen.no)
4238 * @license BSD
4239 *
4240 * Copyright (c) 2010-2013 Christian Johansen
4241 */
4242 (function () {
4243
4244 function makeApi(s, lol) {
4245 /*global lolex */
4246 var llx = typeof lolex !== "undefined" ? lolex : lol;
4247
4248 s.useFakeTimers = function () {
4249 var now;
4250 var methods = Array.prototype.slice.call(arguments);
4251
4252 if (typeof methods[0] === "string") {
4253 now = 0;
4254 } else {
4255 now = methods.shift();
4256 }
4257
4258 var clock = llx.install(now || 0, methods);
4259 clock.restore = clock.uninstall;
4260 return clock;
4261 };
4262
4263 s.clock = {
4264 create: function (now) {
4265 return llx.createClock(now);
4266 }
4267 };
4268
4269 s.timers = {
4270 setTimeout: setTimeout,
4271 clearTimeout: clearTimeout,
4272 setImmediate: (typeof setImmediate !== "undefined" ? setImmediate : undefined),
4273 clearImmediate: (typeof clearImmediate !== "undefined" ? clearImmedi ate : undefined),
4274 setInterval: setInterval,
4275 clearInterval: clearInterval,
4276 Date: Date
4277 };
4278 }
4279
4280 var isNode = typeof module !== "undefined" && module.exports && typeof requi re === "function";
4281 var isAMD = typeof define === "function" && typeof define.amd === "object" & & define.amd;
4282
4283 function loadDependencies(require, epxorts, module, lolex) {
4284 var core = require("./core");
4285 makeApi(core, lolex);
4286 module.exports = core;
4287 }
4288
4289 if (isAMD) {
4290 define(loadDependencies);
4291 } else if (isNode) {
4292 loadDependencies(require, module.exports, module, require("lolex"));
4293 } else {
4294 makeApi(sinon); // eslint-disable-line no-undef
4295 }
4296 }());
4297
4298 /**
4299 * Minimal Event interface implementation
4300 *
4301 * Original implementation by Sven Fuchs: https://gist.github.com/995028
4302 * Modifications and tests by Christian Johansen.
4303 *
4304 * @author Sven Fuchs (svenfuchs@artweb-design.de)
4305 * @author Christian Johansen (christian@cjohansen.no)
4306 * @license BSD
4307 *
4308 * Copyright (c) 2011 Sven Fuchs, Christian Johansen
4309 */
4310 if (typeof sinon === "undefined") {
4311 this.sinon = {};
4312 }
4313
4314 (function () {
4315
4316 var push = [].push;
4317
4318 function makeApi(sinon) {
4319 sinon.Event = function Event(type, bubbles, cancelable, target) {
4320 this.initEvent(type, bubbles, cancelable, target);
4321 };
4322
4323 sinon.Event.prototype = {
4324 initEvent: function (type, bubbles, cancelable, target) {
4325 this.type = type;
4326 this.bubbles = bubbles;
4327 this.cancelable = cancelable;
4328 this.target = target;
4329 },
4330
4331 stopPropagation: function () {},
4332
4333 preventDefault: function () {
4334 this.defaultPrevented = true;
4335 }
4336 };
4337
4338 sinon.ProgressEvent = function ProgressEvent(type, progressEventRaw, tar get) {
4339 this.initEvent(type, false, false, target);
4340 this.loaded = progressEventRaw.loaded || null;
4341 this.total = progressEventRaw.total || null;
4342 this.lengthComputable = !!progressEventRaw.total;
4343 };
4344
4345 sinon.ProgressEvent.prototype = new sinon.Event();
4346
4347 sinon.ProgressEvent.prototype.constructor = sinon.ProgressEvent;
4348
4349 sinon.CustomEvent = function CustomEvent(type, customData, target) {
4350 this.initEvent(type, false, false, target);
4351 this.detail = customData.detail || null;
4352 };
4353
4354 sinon.CustomEvent.prototype = new sinon.Event();
4355
4356 sinon.CustomEvent.prototype.constructor = sinon.CustomEvent;
4357
4358 sinon.EventTarget = {
4359 addEventListener: function addEventListener(event, listener) {
4360 this.eventListeners = this.eventListeners || {};
4361 this.eventListeners[event] = this.eventListeners[event] || [];
4362 push.call(this.eventListeners[event], listener);
4363 },
4364
4365 removeEventListener: function removeEventListener(event, listener) {
4366 var listeners = this.eventListeners && this.eventListeners[event ] || [];
4367
4368 for (var i = 0, l = listeners.length; i < l; ++i) {
4369 if (listeners[i] === listener) {
4370 return listeners.splice(i, 1);
4371 }
4372 }
4373 },
4374
4375 dispatchEvent: function dispatchEvent(event) {
4376 var type = event.type;
4377 var listeners = this.eventListeners && this.eventListeners[type] || [];
4378
4379 for (var i = 0; i < listeners.length; i++) {
4380 if (typeof listeners[i] === "function") {
4381 listeners[i].call(this, event);
4382 } else {
4383 listeners[i].handleEvent(event);
4384 }
4385 }
4386
4387 return !!event.defaultPrevented;
4388 }
4389 };
4390 }
4391
4392 var isNode = typeof module !== "undefined" && module.exports && typeof requi re === "function";
4393 var isAMD = typeof define === "function" && typeof define.amd === "object" & & define.amd;
4394
4395 function loadDependencies(require) {
4396 var sinon = require("./core");
4397 makeApi(sinon);
4398 }
4399
4400 if (isAMD) {
4401 define(loadDependencies);
4402 } else if (isNode) {
4403 loadDependencies(require);
4404 } else {
4405 makeApi(sinon); // eslint-disable-line no-undef
4406 }
4407 }());
4408
4409 /**
4410 * @depend util/core.js
4411 */
4412 /**
4413 * Logs errors
4414 *
4415 * @author Christian Johansen (christian@cjohansen.no)
4416 * @license BSD
4417 *
4418 * Copyright (c) 2010-2014 Christian Johansen
4419 */
4420 (function (sinonGlobal) {
4421
4422 // cache a reference to setTimeout, so that our reference won't be stubbed o ut
4423 // when using fake timers and errors will still get logged
4424 // https://github.com/cjohansen/Sinon.JS/issues/381
4425 var realSetTimeout = setTimeout;
4426
4427 function makeApi(sinon) {
4428
4429 function log() {}
4430
4431 function logError(label, err) {
4432 var msg = label + " threw exception: ";
4433
4434 function throwLoggedError() {
4435 err.message = msg + err.message;
4436 throw err;
4437 }
4438
4439 sinon.log(msg + "[" + err.name + "] " + err.message);
4440
4441 if (err.stack) {
4442 sinon.log(err.stack);
4443 }
4444
4445 if (logError.useImmediateExceptions) {
4446 throwLoggedError();
4447 } else {
4448 logError.setTimeout(throwLoggedError, 0);
4449 }
4450 }
4451
4452 // When set to true, any errors logged will be thrown immediately;
4453 // If set to false, the errors will be thrown in separate execution fram e.
4454 logError.useImmediateExceptions = false;
4455
4456 // wrap realSetTimeout with something we can stub in tests
4457 logError.setTimeout = function (func, timeout) {
4458 realSetTimeout(func, timeout);
4459 };
4460
4461 var exports = {};
4462 exports.log = sinon.log = log;
4463 exports.logError = sinon.logError = logError;
4464
4465 return exports;
4466 }
4467
4468 function loadDependencies(require, exports, module) {
4469 var sinon = require("./util/core");
4470 module.exports = makeApi(sinon);
4471 }
4472
4473 var isNode = typeof module !== "undefined" && module.exports && typeof requi re === "function";
4474 var isAMD = typeof define === "function" && typeof define.amd === "object" & & define.amd;
4475
4476 if (isAMD) {
4477 define(loadDependencies);
4478 return;
4479 }
4480
4481 if (isNode) {
4482 loadDependencies(require, module.exports, module);
4483 return;
4484 }
4485
4486 if (sinonGlobal) {
4487 makeApi(sinonGlobal);
4488 }
4489 }(
4490 typeof sinon === "object" && sinon // eslint-disable-line no-undef
4491 ));
4492
4493 /**
4494 * @depend core.js
4495 * @depend ../extend.js
4496 * @depend event.js
4497 * @depend ../log_error.js
4498 */
4499 /**
4500 * Fake XDomainRequest object
4501 */
4502 if (typeof sinon === "undefined") {
4503 this.sinon = {};
4504 }
4505
4506 // wrapper for global
4507 (function (global) {
4508
4509 var xdr = { XDomainRequest: global.XDomainRequest };
4510 xdr.GlobalXDomainRequest = global.XDomainRequest;
4511 xdr.supportsXDR = typeof xdr.GlobalXDomainRequest !== "undefined";
4512 xdr.workingXDR = xdr.supportsXDR ? xdr.GlobalXDomainRequest : false;
4513
4514 function makeApi(sinon) {
4515 sinon.xdr = xdr;
4516
4517 function FakeXDomainRequest() {
4518 this.readyState = FakeXDomainRequest.UNSENT;
4519 this.requestBody = null;
4520 this.requestHeaders = {};
4521 this.status = 0;
4522 this.timeout = null;
4523
4524 if (typeof FakeXDomainRequest.onCreate === "function") {
4525 FakeXDomainRequest.onCreate(this);
4526 }
4527 }
4528
4529 function verifyState(x) {
4530 if (x.readyState !== FakeXDomainRequest.OPENED) {
4531 throw new Error("INVALID_STATE_ERR");
4532 }
4533
4534 if (x.sendFlag) {
4535 throw new Error("INVALID_STATE_ERR");
4536 }
4537 }
4538
4539 function verifyRequestSent(x) {
4540 if (x.readyState === FakeXDomainRequest.UNSENT) {
4541 throw new Error("Request not sent");
4542 }
4543 if (x.readyState === FakeXDomainRequest.DONE) {
4544 throw new Error("Request done");
4545 }
4546 }
4547
4548 function verifyResponseBodyType(body) {
4549 if (typeof body !== "string") {
4550 var error = new Error("Attempted to respond to fake XDomainReque st with " +
4551 body + ", which is not a string.");
4552 error.name = "InvalidBodyException";
4553 throw error;
4554 }
4555 }
4556
4557 sinon.extend(FakeXDomainRequest.prototype, sinon.EventTarget, {
4558 open: function open(method, url) {
4559 this.method = method;
4560 this.url = url;
4561
4562 this.responseText = null;
4563 this.sendFlag = false;
4564
4565 this.readyStateChange(FakeXDomainRequest.OPENED);
4566 },
4567
4568 readyStateChange: function readyStateChange(state) {
4569 this.readyState = state;
4570 var eventName = "";
4571 switch (this.readyState) {
4572 case FakeXDomainRequest.UNSENT:
4573 break;
4574 case FakeXDomainRequest.OPENED:
4575 break;
4576 case FakeXDomainRequest.LOADING:
4577 if (this.sendFlag) {
4578 //raise the progress event
4579 eventName = "onprogress";
4580 }
4581 break;
4582 case FakeXDomainRequest.DONE:
4583 if (this.isTimeout) {
4584 eventName = "ontimeout";
4585 } else if (this.errorFlag || (this.status < 200 || this.stat us > 299)) {
4586 eventName = "onerror";
4587 } else {
4588 eventName = "onload";
4589 }
4590 break;
4591 }
4592
4593 // raising event (if defined)
4594 if (eventName) {
4595 if (typeof this[eventName] === "function") {
4596 try {
4597 this[eventName]();
4598 } catch (e) {
4599 sinon.logError("Fake XHR " + eventName + " handler", e);
4600 }
4601 }
4602 }
4603 },
4604
4605 send: function send(data) {
4606 verifyState(this);
4607
4608 if (!/^(get|head)$/i.test(this.method)) {
4609 this.requestBody = data;
4610 }
4611 this.requestHeaders["Content-Type"] = "text/plain;charset=utf-8" ;
4612
4613 this.errorFlag = false;
4614 this.sendFlag = true;
4615 this.readyStateChange(FakeXDomainRequest.OPENED);
4616
4617 if (typeof this.onSend === "function") {
4618 this.onSend(this);
4619 }
4620 },
4621
4622 abort: function abort() {
4623 this.aborted = true;
4624 this.responseText = null;
4625 this.errorFlag = true;
4626
4627 if (this.readyState > sinon.FakeXDomainRequest.UNSENT && this.se ndFlag) {
4628 this.readyStateChange(sinon.FakeXDomainRequest.DONE);
4629 this.sendFlag = false;
4630 }
4631 },
4632
4633 setResponseBody: function setResponseBody(body) {
4634 verifyRequestSent(this);
4635 verifyResponseBodyType(body);
4636
4637 var chunkSize = this.chunkSize || 10;
4638 var index = 0;
4639 this.responseText = "";
4640
4641 do {
4642 this.readyStateChange(FakeXDomainRequest.LOADING);
4643 this.responseText += body.substring(index, index + chunkSize );
4644 index += chunkSize;
4645 } while (index < body.length);
4646
4647 this.readyStateChange(FakeXDomainRequest.DONE);
4648 },
4649
4650 respond: function respond(status, contentType, body) {
4651 // content-type ignored, since XDomainRequest does not carry thi s
4652 // we keep the same syntax for respond(...) as for FakeXMLHttpRe quest to ease
4653 // test integration across browsers
4654 this.status = typeof status === "number" ? status : 200;
4655 this.setResponseBody(body || "");
4656 },
4657
4658 simulatetimeout: function simulatetimeout() {
4659 this.status = 0;
4660 this.isTimeout = true;
4661 // Access to this should actually throw an error
4662 this.responseText = undefined;
4663 this.readyStateChange(FakeXDomainRequest.DONE);
4664 }
4665 });
4666
4667 sinon.extend(FakeXDomainRequest, {
4668 UNSENT: 0,
4669 OPENED: 1,
4670 LOADING: 3,
4671 DONE: 4
4672 });
4673
4674 sinon.useFakeXDomainRequest = function useFakeXDomainRequest() {
4675 sinon.FakeXDomainRequest.restore = function restore(keepOnCreate) {
4676 if (xdr.supportsXDR) {
4677 global.XDomainRequest = xdr.GlobalXDomainRequest;
4678 }
4679
4680 delete sinon.FakeXDomainRequest.restore;
4681
4682 if (keepOnCreate !== true) {
4683 delete sinon.FakeXDomainRequest.onCreate;
4684 }
4685 };
4686 if (xdr.supportsXDR) {
4687 global.XDomainRequest = sinon.FakeXDomainRequest;
4688 }
4689 return sinon.FakeXDomainRequest;
4690 };
4691
4692 sinon.FakeXDomainRequest = FakeXDomainRequest;
4693 }
4694
4695 var isNode = typeof module !== "undefined" && module.exports && typeof requi re === "function";
4696 var isAMD = typeof define === "function" && typeof define.amd === "object" & & define.amd;
4697
4698 function loadDependencies(require, exports, module) {
4699 var sinon = require("./core");
4700 require("../extend");
4701 require("./event");
4702 require("../log_error");
4703 makeApi(sinon);
4704 module.exports = sinon;
4705 }
4706
4707 if (isAMD) {
4708 define(loadDependencies);
4709 } else if (isNode) {
4710 loadDependencies(require, module.exports, module);
4711 } else {
4712 makeApi(sinon); // eslint-disable-line no-undef
4713 }
4714 })(typeof global !== "undefined" ? global : self);
4715
4716 /**
4717 * @depend core.js
4718 * @depend ../extend.js
4719 * @depend event.js
4720 * @depend ../log_error.js
4721 */
4722 /**
4723 * Fake XMLHttpRequest object
4724 *
4725 * @author Christian Johansen (christian@cjohansen.no)
4726 * @license BSD
4727 *
4728 * Copyright (c) 2010-2013 Christian Johansen
4729 */
4730 (function (sinonGlobal, global) {
4731
4732 function getWorkingXHR(globalScope) {
4733 var supportsXHR = typeof globalScope.XMLHttpRequest !== "undefined";
4734 if (supportsXHR) {
4735 return globalScope.XMLHttpRequest;
4736 }
4737
4738 var supportsActiveX = typeof globalScope.ActiveXObject !== "undefined";
4739 if (supportsActiveX) {
4740 return function () {
4741 return new globalScope.ActiveXObject("MSXML2.XMLHTTP.3.0");
4742 };
4743 }
4744
4745 return false;
4746 }
4747
4748 var supportsProgress = typeof ProgressEvent !== "undefined";
4749 var supportsCustomEvent = typeof CustomEvent !== "undefined";
4750 var supportsFormData = typeof FormData !== "undefined";
4751 var supportsArrayBuffer = typeof ArrayBuffer !== "undefined";
4752 var supportsBlob = typeof Blob === "function";
4753 var sinonXhr = { XMLHttpRequest: global.XMLHttpRequest };
4754 sinonXhr.GlobalXMLHttpRequest = global.XMLHttpRequest;
4755 sinonXhr.GlobalActiveXObject = global.ActiveXObject;
4756 sinonXhr.supportsActiveX = typeof sinonXhr.GlobalActiveXObject !== "undefine d";
4757 sinonXhr.supportsXHR = typeof sinonXhr.GlobalXMLHttpRequest !== "undefined";
4758 sinonXhr.workingXHR = getWorkingXHR(global);
4759 sinonXhr.supportsCORS = sinonXhr.supportsXHR && "withCredentials" in (new si nonXhr.GlobalXMLHttpRequest());
4760
4761 var unsafeHeaders = {
4762 "Accept-Charset": true,
4763 "Accept-Encoding": true,
4764 Connection: true,
4765 "Content-Length": true,
4766 Cookie: true,
4767 Cookie2: true,
4768 "Content-Transfer-Encoding": true,
4769 Date: true,
4770 Expect: true,
4771 Host: true,
4772 "Keep-Alive": true,
4773 Referer: true,
4774 TE: true,
4775 Trailer: true,
4776 "Transfer-Encoding": true,
4777 Upgrade: true,
4778 "User-Agent": true,
4779 Via: true
4780 };
4781
4782 // An upload object is created for each
4783 // FakeXMLHttpRequest and allows upload
4784 // events to be simulated using uploadProgress
4785 // and uploadError.
4786 function UploadProgress() {
4787 this.eventListeners = {
4788 progress: [],
4789 load: [],
4790 abort: [],
4791 error: []
4792 };
4793 }
4794
4795 UploadProgress.prototype.addEventListener = function addEventListener(event, listener) {
4796 this.eventListeners[event].push(listener);
4797 };
4798
4799 UploadProgress.prototype.removeEventListener = function removeEventListener( event, listener) {
4800 var listeners = this.eventListeners[event] || [];
4801
4802 for (var i = 0, l = listeners.length; i < l; ++i) {
4803 if (listeners[i] === listener) {
4804 return listeners.splice(i, 1);
4805 }
4806 }
4807 };
4808
4809 UploadProgress.prototype.dispatchEvent = function dispatchEvent(event) {
4810 var listeners = this.eventListeners[event.type] || [];
4811
4812 for (var i = 0, listener; (listener = listeners[i]) != null; i++) {
4813 listener(event);
4814 }
4815 };
4816
4817 // Note that for FakeXMLHttpRequest to work pre ES5
4818 // we lose some of the alignment with the spec.
4819 // To ensure as close a match as possible,
4820 // set responseType before calling open, send or respond;
4821 function FakeXMLHttpRequest() {
4822 this.readyState = FakeXMLHttpRequest.UNSENT;
4823 this.requestHeaders = {};
4824 this.requestBody = null;
4825 this.status = 0;
4826 this.statusText = "";
4827 this.upload = new UploadProgress();
4828 this.responseType = "";
4829 this.response = "";
4830 if (sinonXhr.supportsCORS) {
4831 this.withCredentials = false;
4832 }
4833
4834 var xhr = this;
4835 var events = ["loadstart", "load", "abort", "loadend"];
4836
4837 function addEventListener(eventName) {
4838 xhr.addEventListener(eventName, function (event) {
4839 var listener = xhr["on" + eventName];
4840
4841 if (listener && typeof listener === "function") {
4842 listener.call(this, event);
4843 }
4844 });
4845 }
4846
4847 for (var i = events.length - 1; i >= 0; i--) {
4848 addEventListener(events[i]);
4849 }
4850
4851 if (typeof FakeXMLHttpRequest.onCreate === "function") {
4852 FakeXMLHttpRequest.onCreate(this);
4853 }
4854 }
4855
4856 function verifyState(xhr) {
4857 if (xhr.readyState !== FakeXMLHttpRequest.OPENED) {
4858 throw new Error("INVALID_STATE_ERR");
4859 }
4860
4861 if (xhr.sendFlag) {
4862 throw new Error("INVALID_STATE_ERR");
4863 }
4864 }
4865
4866 function getHeader(headers, header) {
4867 header = header.toLowerCase();
4868
4869 for (var h in headers) {
4870 if (h.toLowerCase() === header) {
4871 return h;
4872 }
4873 }
4874
4875 return null;
4876 }
4877
4878 // filtering to enable a white-list version of Sinon FakeXhr,
4879 // where whitelisted requests are passed through to real XHR
4880 function each(collection, callback) {
4881 if (!collection) {
4882 return;
4883 }
4884
4885 for (var i = 0, l = collection.length; i < l; i += 1) {
4886 callback(collection[i]);
4887 }
4888 }
4889 function some(collection, callback) {
4890 for (var index = 0; index < collection.length; index++) {
4891 if (callback(collection[index]) === true) {
4892 return true;
4893 }
4894 }
4895 return false;
4896 }
4897 // largest arity in XHR is 5 - XHR#open
4898 var apply = function (obj, method, args) {
4899 switch (args.length) {
4900 case 0: return obj[method]();
4901 case 1: return obj[method](args[0]);
4902 case 2: return obj[method](args[0], args[1]);
4903 case 3: return obj[method](args[0], args[1], args[2]);
4904 case 4: return obj[method](args[0], args[1], args[2], args[3]);
4905 case 5: return obj[method](args[0], args[1], args[2], args[3], args[4]);
4906 }
4907 };
4908
4909 FakeXMLHttpRequest.filters = [];
4910 FakeXMLHttpRequest.addFilter = function addFilter(fn) {
4911 this.filters.push(fn);
4912 };
4913 var IE6Re = /MSIE 6/;
4914 FakeXMLHttpRequest.defake = function defake(fakeXhr, xhrArgs) {
4915 var xhr = new sinonXhr.workingXHR(); // eslint-disable-line new-cap
4916
4917 each([
4918 "open",
4919 "setRequestHeader",
4920 "send",
4921 "abort",
4922 "getResponseHeader",
4923 "getAllResponseHeaders",
4924 "addEventListener",
4925 "overrideMimeType",
4926 "removeEventListener"
4927 ], function (method) {
4928 fakeXhr[method] = function () {
4929 return apply(xhr, method, arguments);
4930 };
4931 });
4932
4933 var copyAttrs = function (args) {
4934 each(args, function (attr) {
4935 try {
4936 fakeXhr[attr] = xhr[attr];
4937 } catch (e) {
4938 if (!IE6Re.test(navigator.userAgent)) {
4939 throw e;
4940 }
4941 }
4942 });
4943 };
4944
4945 var stateChange = function stateChange() {
4946 fakeXhr.readyState = xhr.readyState;
4947 if (xhr.readyState >= FakeXMLHttpRequest.HEADERS_RECEIVED) {
4948 copyAttrs(["status", "statusText"]);
4949 }
4950 if (xhr.readyState >= FakeXMLHttpRequest.LOADING) {
4951 copyAttrs(["responseText", "response"]);
4952 }
4953 if (xhr.readyState === FakeXMLHttpRequest.DONE) {
4954 copyAttrs(["responseXML"]);
4955 }
4956 if (fakeXhr.onreadystatechange) {
4957 fakeXhr.onreadystatechange.call(fakeXhr, { target: fakeXhr });
4958 }
4959 };
4960
4961 if (xhr.addEventListener) {
4962 for (var event in fakeXhr.eventListeners) {
4963 if (fakeXhr.eventListeners.hasOwnProperty(event)) {
4964
4965 /*eslint-disable no-loop-func*/
4966 each(fakeXhr.eventListeners[event], function (handler) {
4967 xhr.addEventListener(event, handler);
4968 });
4969 /*eslint-enable no-loop-func*/
4970 }
4971 }
4972 xhr.addEventListener("readystatechange", stateChange);
4973 } else {
4974 xhr.onreadystatechange = stateChange;
4975 }
4976 apply(xhr, "open", xhrArgs);
4977 };
4978 FakeXMLHttpRequest.useFilters = false;
4979
4980 function verifyRequestOpened(xhr) {
4981 if (xhr.readyState !== FakeXMLHttpRequest.OPENED) {
4982 throw new Error("INVALID_STATE_ERR - " + xhr.readyState);
4983 }
4984 }
4985
4986 function verifyRequestSent(xhr) {
4987 if (xhr.readyState === FakeXMLHttpRequest.DONE) {
4988 throw new Error("Request done");
4989 }
4990 }
4991
4992 function verifyHeadersReceived(xhr) {
4993 if (xhr.async && xhr.readyState !== FakeXMLHttpRequest.HEADERS_RECEIVED) {
4994 throw new Error("No headers received");
4995 }
4996 }
4997
4998 function verifyResponseBodyType(body) {
4999 if (typeof body !== "string") {
5000 var error = new Error("Attempted to respond to fake XMLHttpRequest w ith " +
5001 body + ", which is not a string.");
5002 error.name = "InvalidBodyException";
5003 throw error;
5004 }
5005 }
5006
5007 function convertToArrayBuffer(body) {
5008 var buffer = new ArrayBuffer(body.length);
5009 var view = new Uint8Array(buffer);
5010 for (var i = 0; i < body.length; i++) {
5011 var charCode = body.charCodeAt(i);
5012 if (charCode >= 256) {
5013 throw new TypeError("arraybuffer or blob responseTypes require b inary string, " +
5014 "invalid character " + body[i] + " found.");
5015 }
5016 view[i] = charCode;
5017 }
5018 return buffer;
5019 }
5020
5021 function isXmlContentType(contentType) {
5022 return !contentType || /(text\/xml)|(application\/xml)|(\+xml)/.test(con tentType);
5023 }
5024
5025 function convertResponseBody(responseType, contentType, body) {
5026 if (responseType === "" || responseType === "text") {
5027 return body;
5028 } else if (supportsArrayBuffer && responseType === "arraybuffer") {
5029 return convertToArrayBuffer(body);
5030 } else if (responseType === "json") {
5031 try {
5032 return JSON.parse(body);
5033 } catch (e) {
5034 // Return parsing failure as null
5035 return null;
5036 }
5037 } else if (supportsBlob && responseType === "blob") {
5038 var blobOptions = {};
5039 if (contentType) {
5040 blobOptions.type = contentType;
5041 }
5042 return new Blob([convertToArrayBuffer(body)], blobOptions);
5043 } else if (responseType === "document") {
5044 if (isXmlContentType(contentType)) {
5045 return FakeXMLHttpRequest.parseXML(body);
5046 }
5047 return null;
5048 }
5049 throw new Error("Invalid responseType " + responseType);
5050 }
5051
5052 function clearResponse(xhr) {
5053 if (xhr.responseType === "" || xhr.responseType === "text") {
5054 xhr.response = xhr.responseText = "";
5055 } else {
5056 xhr.response = xhr.responseText = null;
5057 }
5058 xhr.responseXML = null;
5059 }
5060
5061 FakeXMLHttpRequest.parseXML = function parseXML(text) {
5062 // Treat empty string as parsing failure
5063 if (text !== "") {
5064 try {
5065 if (typeof DOMParser !== "undefined") {
5066 var parser = new DOMParser();
5067 return parser.parseFromString(text, "text/xml");
5068 }
5069 var xmlDoc = new window.ActiveXObject("Microsoft.XMLDOM");
5070 xmlDoc.async = "false";
5071 xmlDoc.loadXML(text);
5072 return xmlDoc;
5073 } catch (e) {
5074 // Unable to parse XML - no biggie
5075 }
5076 }
5077
5078 return null;
5079 };
5080
5081 FakeXMLHttpRequest.statusCodes = {
5082 100: "Continue",
5083 101: "Switching Protocols",
5084 200: "OK",
5085 201: "Created",
5086 202: "Accepted",
5087 203: "Non-Authoritative Information",
5088 204: "No Content",
5089 205: "Reset Content",
5090 206: "Partial Content",
5091 207: "Multi-Status",
5092 300: "Multiple Choice",
5093 301: "Moved Permanently",
5094 302: "Found",
5095 303: "See Other",
5096 304: "Not Modified",
5097 305: "Use Proxy",
5098 307: "Temporary Redirect",
5099 400: "Bad Request",
5100 401: "Unauthorized",
5101 402: "Payment Required",
5102 403: "Forbidden",
5103 404: "Not Found",
5104 405: "Method Not Allowed",
5105 406: "Not Acceptable",
5106 407: "Proxy Authentication Required",
5107 408: "Request Timeout",
5108 409: "Conflict",
5109 410: "Gone",
5110 411: "Length Required",
5111 412: "Precondition Failed",
5112 413: "Request Entity Too Large",
5113 414: "Request-URI Too Long",
5114 415: "Unsupported Media Type",
5115 416: "Requested Range Not Satisfiable",
5116 417: "Expectation Failed",
5117 422: "Unprocessable Entity",
5118 500: "Internal Server Error",
5119 501: "Not Implemented",
5120 502: "Bad Gateway",
5121 503: "Service Unavailable",
5122 504: "Gateway Timeout",
5123 505: "HTTP Version Not Supported"
5124 };
5125
5126 function makeApi(sinon) {
5127 sinon.xhr = sinonXhr;
5128
5129 sinon.extend(FakeXMLHttpRequest.prototype, sinon.EventTarget, {
5130 async: true,
5131
5132 open: function open(method, url, async, username, password) {
5133 this.method = method;
5134 this.url = url;
5135 this.async = typeof async === "boolean" ? async : true;
5136 this.username = username;
5137 this.password = password;
5138 clearResponse(this);
5139 this.requestHeaders = {};
5140 this.sendFlag = false;
5141
5142 if (FakeXMLHttpRequest.useFilters === true) {
5143 var xhrArgs = arguments;
5144 var defake = some(FakeXMLHttpRequest.filters, function (filt er) {
5145 return filter.apply(this, xhrArgs);
5146 });
5147 if (defake) {
5148 return FakeXMLHttpRequest.defake(this, arguments);
5149 }
5150 }
5151 this.readyStateChange(FakeXMLHttpRequest.OPENED);
5152 },
5153
5154 readyStateChange: function readyStateChange(state) {
5155 this.readyState = state;
5156
5157 var readyStateChangeEvent = new sinon.Event("readystatechange", false, false, this);
5158
5159 if (typeof this.onreadystatechange === "function") {
5160 try {
5161 this.onreadystatechange(readyStateChangeEvent);
5162 } catch (e) {
5163 sinon.logError("Fake XHR onreadystatechange handler", e) ;
5164 }
5165 }
5166
5167 switch (this.readyState) {
5168 case FakeXMLHttpRequest.DONE:
5169 if (supportsProgress) {
5170 this.upload.dispatchEvent(new sinon.ProgressEvent("p rogress", {loaded: 100, total: 100}));
5171 this.dispatchEvent(new sinon.ProgressEvent("progress ", {loaded: 100, total: 100}));
5172 }
5173 this.upload.dispatchEvent(new sinon.Event("load", false, false, this));
5174 this.dispatchEvent(new sinon.Event("load", false, false, this));
5175 this.dispatchEvent(new sinon.Event("loadend", false, fal se, this));
5176 break;
5177 }
5178
5179 this.dispatchEvent(readyStateChangeEvent);
5180 },
5181
5182 setRequestHeader: function setRequestHeader(header, value) {
5183 verifyState(this);
5184
5185 if (unsafeHeaders[header] || /^(Sec-|Proxy-)/.test(header)) {
5186 throw new Error("Refused to set unsafe header \"" + header + "\"");
5187 }
5188
5189 if (this.requestHeaders[header]) {
5190 this.requestHeaders[header] += "," + value;
5191 } else {
5192 this.requestHeaders[header] = value;
5193 }
5194 },
5195
5196 // Helps testing
5197 setResponseHeaders: function setResponseHeaders(headers) {
5198 verifyRequestOpened(this);
5199 this.responseHeaders = {};
5200
5201 for (var header in headers) {
5202 if (headers.hasOwnProperty(header)) {
5203 this.responseHeaders[header] = headers[header];
5204 }
5205 }
5206
5207 if (this.async) {
5208 this.readyStateChange(FakeXMLHttpRequest.HEADERS_RECEIVED);
5209 } else {
5210 this.readyState = FakeXMLHttpRequest.HEADERS_RECEIVED;
5211 }
5212 },
5213
5214 // Currently treats ALL data as a DOMString (i.e. no Document)
5215 send: function send(data) {
5216 verifyState(this);
5217
5218 if (!/^(get|head)$/i.test(this.method)) {
5219 var contentType = getHeader(this.requestHeaders, "Content-Ty pe");
5220 if (this.requestHeaders[contentType]) {
5221 var value = this.requestHeaders[contentType].split(";");
5222 this.requestHeaders[contentType] = value[0] + ";charset= utf-8";
5223 } else if (supportsFormData && !(data instanceof FormData)) {
5224 this.requestHeaders["Content-Type"] = "text/plain;charse t=utf-8";
5225 }
5226
5227 this.requestBody = data;
5228 }
5229
5230 this.errorFlag = false;
5231 this.sendFlag = this.async;
5232 clearResponse(this);
5233 this.readyStateChange(FakeXMLHttpRequest.OPENED);
5234
5235 if (typeof this.onSend === "function") {
5236 this.onSend(this);
5237 }
5238
5239 this.dispatchEvent(new sinon.Event("loadstart", false, false, th is));
5240 },
5241
5242 abort: function abort() {
5243 this.aborted = true;
5244 clearResponse(this);
5245 this.errorFlag = true;
5246 this.requestHeaders = {};
5247 this.responseHeaders = {};
5248
5249 if (this.readyState > FakeXMLHttpRequest.UNSENT && this.sendFlag ) {
5250 this.readyStateChange(FakeXMLHttpRequest.DONE);
5251 this.sendFlag = false;
5252 }
5253
5254 this.readyState = FakeXMLHttpRequest.UNSENT;
5255
5256 this.dispatchEvent(new sinon.Event("abort", false, false, this)) ;
5257
5258 this.upload.dispatchEvent(new sinon.Event("abort", false, false, this));
5259
5260 if (typeof this.onerror === "function") {
5261 this.onerror();
5262 }
5263 },
5264
5265 getResponseHeader: function getResponseHeader(header) {
5266 if (this.readyState < FakeXMLHttpRequest.HEADERS_RECEIVED) {
5267 return null;
5268 }
5269
5270 if (/^Set-Cookie2?$/i.test(header)) {
5271 return null;
5272 }
5273
5274 header = getHeader(this.responseHeaders, header);
5275
5276 return this.responseHeaders[header] || null;
5277 },
5278
5279 getAllResponseHeaders: function getAllResponseHeaders() {
5280 if (this.readyState < FakeXMLHttpRequest.HEADERS_RECEIVED) {
5281 return "";
5282 }
5283
5284 var headers = "";
5285
5286 for (var header in this.responseHeaders) {
5287 if (this.responseHeaders.hasOwnProperty(header) &&
5288 !/^Set-Cookie2?$/i.test(header)) {
5289 headers += header + ": " + this.responseHeaders[header] + "\r\n";
5290 }
5291 }
5292
5293 return headers;
5294 },
5295
5296 setResponseBody: function setResponseBody(body) {
5297 verifyRequestSent(this);
5298 verifyHeadersReceived(this);
5299 verifyResponseBodyType(body);
5300 var contentType = this.getResponseHeader("Content-Type");
5301
5302 var isTextResponse = this.responseType === "" || this.responseTy pe === "text";
5303 clearResponse(this);
5304 if (this.async) {
5305 var chunkSize = this.chunkSize || 10;
5306 var index = 0;
5307
5308 do {
5309 this.readyStateChange(FakeXMLHttpRequest.LOADING);
5310
5311 if (isTextResponse) {
5312 this.responseText = this.response += body.substring( index, index + chunkSize);
5313 }
5314 index += chunkSize;
5315 } while (index < body.length);
5316 }
5317
5318 this.response = convertResponseBody(this.responseType, contentTy pe, body);
5319 if (isTextResponse) {
5320 this.responseText = this.response;
5321 }
5322
5323 if (this.responseType === "document") {
5324 this.responseXML = this.response;
5325 } else if (this.responseType === "" && isXmlContentType(contentT ype)) {
5326 this.responseXML = FakeXMLHttpRequest.parseXML(this.response Text);
5327 }
5328 this.readyStateChange(FakeXMLHttpRequest.DONE);
5329 },
5330
5331 respond: function respond(status, headers, body) {
5332 this.status = typeof status === "number" ? status : 200;
5333 this.statusText = FakeXMLHttpRequest.statusCodes[this.status];
5334 this.setResponseHeaders(headers || {});
5335 this.setResponseBody(body || "");
5336 },
5337
5338 uploadProgress: function uploadProgress(progressEventRaw) {
5339 if (supportsProgress) {
5340 this.upload.dispatchEvent(new sinon.ProgressEvent("progress" , progressEventRaw));
5341 }
5342 },
5343
5344 downloadProgress: function downloadProgress(progressEventRaw) {
5345 if (supportsProgress) {
5346 this.dispatchEvent(new sinon.ProgressEvent("progress", progr essEventRaw));
5347 }
5348 },
5349
5350 uploadError: function uploadError(error) {
5351 if (supportsCustomEvent) {
5352 this.upload.dispatchEvent(new sinon.CustomEvent("error", {de tail: error}));
5353 }
5354 }
5355 });
5356
5357 sinon.extend(FakeXMLHttpRequest, {
5358 UNSENT: 0,
5359 OPENED: 1,
5360 HEADERS_RECEIVED: 2,
5361 LOADING: 3,
5362 DONE: 4
5363 });
5364
5365 sinon.useFakeXMLHttpRequest = function () {
5366 FakeXMLHttpRequest.restore = function restore(keepOnCreate) {
5367 if (sinonXhr.supportsXHR) {
5368 global.XMLHttpRequest = sinonXhr.GlobalXMLHttpRequest;
5369 }
5370
5371 if (sinonXhr.supportsActiveX) {
5372 global.ActiveXObject = sinonXhr.GlobalActiveXObject;
5373 }
5374
5375 delete FakeXMLHttpRequest.restore;
5376
5377 if (keepOnCreate !== true) {
5378 delete FakeXMLHttpRequest.onCreate;
5379 }
5380 };
5381 if (sinonXhr.supportsXHR) {
5382 global.XMLHttpRequest = FakeXMLHttpRequest;
5383 }
5384
5385 if (sinonXhr.supportsActiveX) {
5386 global.ActiveXObject = function ActiveXObject(objId) {
5387 if (objId === "Microsoft.XMLHTTP" || /^Msxml2\.XMLHTTP/i.tes t(objId)) {
5388
5389 return new FakeXMLHttpRequest();
5390 }
5391
5392 return new sinonXhr.GlobalActiveXObject(objId);
5393 };
5394 }
5395
5396 return FakeXMLHttpRequest;
5397 };
5398
5399 sinon.FakeXMLHttpRequest = FakeXMLHttpRequest;
5400 }
5401
5402 var isNode = typeof module !== "undefined" && module.exports && typeof requi re === "function";
5403 var isAMD = typeof define === "function" && typeof define.amd === "object" & & define.amd;
5404
5405 function loadDependencies(require, exports, module) {
5406 var sinon = require("./core");
5407 require("../extend");
5408 require("./event");
5409 require("../log_error");
5410 makeApi(sinon);
5411 module.exports = sinon;
5412 }
5413
5414 if (isAMD) {
5415 define(loadDependencies);
5416 return;
5417 }
5418
5419 if (isNode) {
5420 loadDependencies(require, module.exports, module);
5421 return;
5422 }
5423
5424 if (sinonGlobal) {
5425 makeApi(sinonGlobal);
5426 }
5427 }(
5428 typeof sinon === "object" && sinon, // eslint-disable-line no-undef
5429 typeof global !== "undefined" ? global : self
5430 ));
5431
5432 /**
5433 * @depend fake_xdomain_request.js
5434 * @depend fake_xml_http_request.js
5435 * @depend ../format.js
5436 * @depend ../log_error.js
5437 */
5438 /**
5439 * The Sinon "server" mimics a web server that receives requests from
5440 * sinon.FakeXMLHttpRequest and provides an API to respond to those requests,
5441 * both synchronously and asynchronously. To respond synchronuously, canned
5442 * answers have to be provided upfront.
5443 *
5444 * @author Christian Johansen (christian@cjohansen.no)
5445 * @license BSD
5446 *
5447 * Copyright (c) 2010-2013 Christian Johansen
5448 */
5449 (function () {
5450
5451 var push = [].push;
5452
5453 function responseArray(handler) {
5454 var response = handler;
5455
5456 if (Object.prototype.toString.call(handler) !== "[object Array]") {
5457 response = [200, {}, handler];
5458 }
5459
5460 if (typeof response[2] !== "string") {
5461 throw new TypeError("Fake server response body should be string, but was " +
5462 typeof response[2]);
5463 }
5464
5465 return response;
5466 }
5467
5468 var wloc = typeof window !== "undefined" ? window.location : {};
5469 var rCurrLoc = new RegExp("^" + wloc.protocol + "//" + wloc.host);
5470
5471 function matchOne(response, reqMethod, reqUrl) {
5472 var rmeth = response.method;
5473 var matchMethod = !rmeth || rmeth.toLowerCase() === reqMethod.toLowerCas e();
5474 var url = response.url;
5475 var matchUrl = !url || url === reqUrl || (typeof url.test === "function" && url.test(reqUrl));
5476
5477 return matchMethod && matchUrl;
5478 }
5479
5480 function match(response, request) {
5481 var requestUrl = request.url;
5482
5483 if (!/^https?:\/\//.test(requestUrl) || rCurrLoc.test(requestUrl)) {
5484 requestUrl = requestUrl.replace(rCurrLoc, "");
5485 }
5486
5487 if (matchOne(response, this.getHTTPMethod(request), requestUrl)) {
5488 if (typeof response.response === "function") {
5489 var ru = response.url;
5490 var args = [request].concat(ru && typeof ru.exec === "function" ? ru.exec(requestUrl).slice(1) : []);
5491 return response.response.apply(response, args);
5492 }
5493
5494 return true;
5495 }
5496
5497 return false;
5498 }
5499
5500 function makeApi(sinon) {
5501 sinon.fakeServer = {
5502 create: function (config) {
5503 var server = sinon.create(this);
5504 server.configure(config);
5505 if (!sinon.xhr.supportsCORS) {
5506 this.xhr = sinon.useFakeXDomainRequest();
5507 } else {
5508 this.xhr = sinon.useFakeXMLHttpRequest();
5509 }
5510 server.requests = [];
5511
5512 this.xhr.onCreate = function (xhrObj) {
5513 server.addRequest(xhrObj);
5514 };
5515
5516 return server;
5517 },
5518 configure: function (config) {
5519 var whitelist = {
5520 "autoRespond": true,
5521 "autoRespondAfter": true,
5522 "respondImmediately": true,
5523 "fakeHTTPMethods": true
5524 };
5525 var setting;
5526
5527 config = config || {};
5528 for (setting in config) {
5529 if (whitelist.hasOwnProperty(setting) && config.hasOwnProper ty(setting)) {
5530 this[setting] = config[setting];
5531 }
5532 }
5533 },
5534 addRequest: function addRequest(xhrObj) {
5535 var server = this;
5536 push.call(this.requests, xhrObj);
5537
5538 xhrObj.onSend = function () {
5539 server.handleRequest(this);
5540
5541 if (server.respondImmediately) {
5542 server.respond();
5543 } else if (server.autoRespond && !server.responding) {
5544 setTimeout(function () {
5545 server.responding = false;
5546 server.respond();
5547 }, server.autoRespondAfter || 10);
5548
5549 server.responding = true;
5550 }
5551 };
5552 },
5553
5554 getHTTPMethod: function getHTTPMethod(request) {
5555 if (this.fakeHTTPMethods && /post/i.test(request.method)) {
5556 var matches = (request.requestBody || "").match(/_method=([^ \b;]+)/);
5557 return matches ? matches[1] : request.method;
5558 }
5559
5560 return request.method;
5561 },
5562
5563 handleRequest: function handleRequest(xhr) {
5564 if (xhr.async) {
5565 if (!this.queue) {
5566 this.queue = [];
5567 }
5568
5569 push.call(this.queue, xhr);
5570 } else {
5571 this.processRequest(xhr);
5572 }
5573 },
5574
5575 log: function log(response, request) {
5576 var str;
5577
5578 str = "Request:\n" + sinon.format(request) + "\n\n";
5579 str += "Response:\n" + sinon.format(response) + "\n\n";
5580
5581 sinon.log(str);
5582 },
5583
5584 respondWith: function respondWith(method, url, body) {
5585 if (arguments.length === 1 && typeof method !== "function") {
5586 this.response = responseArray(method);
5587 return;
5588 }
5589
5590 if (!this.responses) {
5591 this.responses = [];
5592 }
5593
5594 if (arguments.length === 1) {
5595 body = method;
5596 url = method = null;
5597 }
5598
5599 if (arguments.length === 2) {
5600 body = url;
5601 url = method;
5602 method = null;
5603 }
5604
5605 push.call(this.responses, {
5606 method: method,
5607 url: url,
5608 response: typeof body === "function" ? body : responseArray( body)
5609 });
5610 },
5611
5612 respond: function respond() {
5613 if (arguments.length > 0) {
5614 this.respondWith.apply(this, arguments);
5615 }
5616
5617 var queue = this.queue || [];
5618 var requests = queue.splice(0, queue.length);
5619
5620 for (var i = 0; i < requests.length; i++) {
5621 this.processRequest(requests[i]);
5622 }
5623 },
5624
5625 processRequest: function processRequest(request) {
5626 try {
5627 if (request.aborted) {
5628 return;
5629 }
5630
5631 var response = this.response || [404, {}, ""];
5632
5633 if (this.responses) {
5634 for (var l = this.responses.length, i = l - 1; i >= 0; i --) {
5635 if (match.call(this, this.responses[i], request)) {
5636 response = this.responses[i].response;
5637 break;
5638 }
5639 }
5640 }
5641
5642 if (request.readyState !== 4) {
5643 this.log(response, request);
5644
5645 request.respond(response[0], response[1], response[2]);
5646 }
5647 } catch (e) {
5648 sinon.logError("Fake server request processing", e);
5649 }
5650 },
5651
5652 restore: function restore() {
5653 return this.xhr.restore && this.xhr.restore.apply(this.xhr, argu ments);
5654 }
5655 };
5656 }
5657
5658 var isNode = typeof module !== "undefined" && module.exports && typeof requi re === "function";
5659 var isAMD = typeof define === "function" && typeof define.amd === "object" & & define.amd;
5660
5661 function loadDependencies(require, exports, module) {
5662 var sinon = require("./core");
5663 require("./fake_xdomain_request");
5664 require("./fake_xml_http_request");
5665 require("../format");
5666 makeApi(sinon);
5667 module.exports = sinon;
5668 }
5669
5670 if (isAMD) {
5671 define(loadDependencies);
5672 } else if (isNode) {
5673 loadDependencies(require, module.exports, module);
5674 } else {
5675 makeApi(sinon); // eslint-disable-line no-undef
5676 }
5677 }());
5678
5679 /**
5680 * @depend fake_server.js
5681 * @depend fake_timers.js
5682 */
5683 /**
5684 * Add-on for sinon.fakeServer that automatically handles a fake timer along wit h
5685 * the FakeXMLHttpRequest. The direct inspiration for this add-on is jQuery
5686 * 1.3.x, which does not use xhr object's onreadystatehandler at all - instead,
5687 * it polls the object for completion with setInterval. Dispite the direct
5688 * motivation, there is nothing jQuery-specific in this file, so it can be used
5689 * in any environment where the ajax implementation depends on setInterval or
5690 * setTimeout.
5691 *
5692 * @author Christian Johansen (christian@cjohansen.no)
5693 * @license BSD
5694 *
5695 * Copyright (c) 2010-2013 Christian Johansen
5696 */
5697 (function () {
5698
5699 function makeApi(sinon) {
5700 function Server() {}
5701 Server.prototype = sinon.fakeServer;
5702
5703 sinon.fakeServerWithClock = new Server();
5704
5705 sinon.fakeServerWithClock.addRequest = function addRequest(xhr) {
5706 if (xhr.async) {
5707 if (typeof setTimeout.clock === "object") {
5708 this.clock = setTimeout.clock;
5709 } else {
5710 this.clock = sinon.useFakeTimers();
5711 this.resetClock = true;
5712 }
5713
5714 if (!this.longestTimeout) {
5715 var clockSetTimeout = this.clock.setTimeout;
5716 var clockSetInterval = this.clock.setInterval;
5717 var server = this;
5718
5719 this.clock.setTimeout = function (fn, timeout) {
5720 server.longestTimeout = Math.max(timeout, server.longest Timeout || 0);
5721
5722 return clockSetTimeout.apply(this, arguments);
5723 };
5724
5725 this.clock.setInterval = function (fn, timeout) {
5726 server.longestTimeout = Math.max(timeout, server.longest Timeout || 0);
5727
5728 return clockSetInterval.apply(this, arguments);
5729 };
5730 }
5731 }
5732
5733 return sinon.fakeServer.addRequest.call(this, xhr);
5734 };
5735
5736 sinon.fakeServerWithClock.respond = function respond() {
5737 var returnVal = sinon.fakeServer.respond.apply(this, arguments);
5738
5739 if (this.clock) {
5740 this.clock.tick(this.longestTimeout || 0);
5741 this.longestTimeout = 0;
5742
5743 if (this.resetClock) {
5744 this.clock.restore();
5745 this.resetClock = false;
5746 }
5747 }
5748
5749 return returnVal;
5750 };
5751
5752 sinon.fakeServerWithClock.restore = function restore() {
5753 if (this.clock) {
5754 this.clock.restore();
5755 }
5756
5757 return sinon.fakeServer.restore.apply(this, arguments);
5758 };
5759 }
5760
5761 var isNode = typeof module !== "undefined" && module.exports && typeof requi re === "function";
5762 var isAMD = typeof define === "function" && typeof define.amd === "object" & & define.amd;
5763
5764 function loadDependencies(require) {
5765 var sinon = require("./core");
5766 require("./fake_server");
5767 require("./fake_timers");
5768 makeApi(sinon);
5769 }
5770
5771 if (isAMD) {
5772 define(loadDependencies);
5773 } else if (isNode) {
5774 loadDependencies(require);
5775 } else {
5776 makeApi(sinon); // eslint-disable-line no-undef
5777 }
5778 }());
5779
5780 /**
5781 * @depend util/core.js
5782 * @depend extend.js
5783 * @depend collection.js
5784 * @depend util/fake_timers.js
5785 * @depend util/fake_server_with_clock.js
5786 */
5787 /**
5788 * Manages fake collections as well as fake utilities such as Sinon's
5789 * timers and fake XHR implementation in one convenient object.
5790 *
5791 * @author Christian Johansen (christian@cjohansen.no)
5792 * @license BSD
5793 *
5794 * Copyright (c) 2010-2013 Christian Johansen
5795 */
5796 (function (sinonGlobal) {
5797
5798 function makeApi(sinon) {
5799 var push = [].push;
5800
5801 function exposeValue(sandbox, config, key, value) {
5802 if (!value) {
5803 return;
5804 }
5805
5806 if (config.injectInto && !(key in config.injectInto)) {
5807 config.injectInto[key] = value;
5808 sandbox.injectedKeys.push(key);
5809 } else {
5810 push.call(sandbox.args, value);
5811 }
5812 }
5813
5814 function prepareSandboxFromConfig(config) {
5815 var sandbox = sinon.create(sinon.sandbox);
5816
5817 if (config.useFakeServer) {
5818 if (typeof config.useFakeServer === "object") {
5819 sandbox.serverPrototype = config.useFakeServer;
5820 }
5821
5822 sandbox.useFakeServer();
5823 }
5824
5825 if (config.useFakeTimers) {
5826 if (typeof config.useFakeTimers === "object") {
5827 sandbox.useFakeTimers.apply(sandbox, config.useFakeTimers);
5828 } else {
5829 sandbox.useFakeTimers();
5830 }
5831 }
5832
5833 return sandbox;
5834 }
5835
5836 sinon.sandbox = sinon.extend(sinon.create(sinon.collection), {
5837 useFakeTimers: function useFakeTimers() {
5838 this.clock = sinon.useFakeTimers.apply(sinon, arguments);
5839
5840 return this.add(this.clock);
5841 },
5842
5843 serverPrototype: sinon.fakeServer,
5844
5845 useFakeServer: function useFakeServer() {
5846 var proto = this.serverPrototype || sinon.fakeServer;
5847
5848 if (!proto || !proto.create) {
5849 return null;
5850 }
5851
5852 this.server = proto.create();
5853 return this.add(this.server);
5854 },
5855
5856 inject: function (obj) {
5857 sinon.collection.inject.call(this, obj);
5858
5859 if (this.clock) {
5860 obj.clock = this.clock;
5861 }
5862
5863 if (this.server) {
5864 obj.server = this.server;
5865 obj.requests = this.server.requests;
5866 }
5867
5868 obj.match = sinon.match;
5869
5870 return obj;
5871 },
5872
5873 restore: function () {
5874 sinon.collection.restore.apply(this, arguments);
5875 this.restoreContext();
5876 },
5877
5878 restoreContext: function () {
5879 if (this.injectedKeys) {
5880 for (var i = 0, j = this.injectedKeys.length; i < j; i++) {
5881 delete this.injectInto[this.injectedKeys[i]];
5882 }
5883 this.injectedKeys = [];
5884 }
5885 },
5886
5887 create: function (config) {
5888 if (!config) {
5889 return sinon.create(sinon.sandbox);
5890 }
5891
5892 var sandbox = prepareSandboxFromConfig(config);
5893 sandbox.args = sandbox.args || [];
5894 sandbox.injectedKeys = [];
5895 sandbox.injectInto = config.injectInto;
5896 var prop,
5897 value;
5898 var exposed = sandbox.inject({});
5899
5900 if (config.properties) {
5901 for (var i = 0, l = config.properties.length; i < l; i++) {
5902 prop = config.properties[i];
5903 value = exposed[prop] || prop === "sandbox" && sandbox;
5904 exposeValue(sandbox, config, prop, value);
5905 }
5906 } else {
5907 exposeValue(sandbox, config, "sandbox", value);
5908 }
5909
5910 return sandbox;
5911 },
5912
5913 match: sinon.match
5914 });
5915
5916 sinon.sandbox.useFakeXMLHttpRequest = sinon.sandbox.useFakeServer;
5917
5918 return sinon.sandbox;
5919 }
5920
5921 var isNode = typeof module !== "undefined" && module.exports && typeof requi re === "function";
5922 var isAMD = typeof define === "function" && typeof define.amd === "object" & & define.amd;
5923
5924 function loadDependencies(require, exports, module) {
5925 var sinon = require("./util/core");
5926 require("./extend");
5927 require("./util/fake_server_with_clock");
5928 require("./util/fake_timers");
5929 require("./collection");
5930 module.exports = makeApi(sinon);
5931 }
5932
5933 if (isAMD) {
5934 define(loadDependencies);
5935 return;
5936 }
5937
5938 if (isNode) {
5939 loadDependencies(require, module.exports, module);
5940 return;
5941 }
5942
5943 if (sinonGlobal) {
5944 makeApi(sinonGlobal);
5945 }
5946 }(
5947 typeof sinon === "object" && sinon // eslint-disable-line no-undef
5948 ));
5949
5950 /**
5951 * @depend util/core.js
5952 * @depend sandbox.js
5953 */
5954 /**
5955 * Test function, sandboxes fakes
5956 *
5957 * @author Christian Johansen (christian@cjohansen.no)
5958 * @license BSD
5959 *
5960 * Copyright (c) 2010-2013 Christian Johansen
5961 */
5962 (function (sinonGlobal) {
5963
5964 function makeApi(sinon) {
5965 var slice = Array.prototype.slice;
5966
5967 function test(callback) {
5968 var type = typeof callback;
5969
5970 if (type !== "function") {
5971 throw new TypeError("sinon.test needs to wrap a test function, g ot " + type);
5972 }
5973
5974 function sinonSandboxedTest() {
5975 var config = sinon.getConfig(sinon.config);
5976 config.injectInto = config.injectIntoThis && this || config.inje ctInto;
5977 var sandbox = sinon.sandbox.create(config);
5978 var args = slice.call(arguments);
5979 var oldDone = args.length && args[args.length - 1];
5980 var exception, result;
5981
5982 if (typeof oldDone === "function") {
5983 args[args.length - 1] = function sinonDone(res) {
5984 if (res) {
5985 sandbox.restore();
5986 } else {
5987 sandbox.verifyAndRestore();
5988 }
5989 oldDone(res);
5990 };
5991 }
5992
5993 try {
5994 result = callback.apply(this, args.concat(sandbox.args));
5995 } catch (e) {
5996 exception = e;
5997 }
5998
5999 if (typeof oldDone !== "function") {
6000 if (typeof exception !== "undefined") {
6001 sandbox.restore();
6002 throw exception;
6003 } else {
6004 sandbox.verifyAndRestore();
6005 }
6006 }
6007
6008 return result;
6009 }
6010
6011 if (callback.length) {
6012 return function sinonAsyncSandboxedTest(done) { // eslint-disabl e-line no-unused-vars
6013 return sinonSandboxedTest.apply(this, arguments);
6014 };
6015 }
6016
6017 return sinonSandboxedTest;
6018 }
6019
6020 test.config = {
6021 injectIntoThis: true,
6022 injectInto: null,
6023 properties: ["spy", "stub", "mock", "clock", "server", "requests"],
6024 useFakeTimers: true,
6025 useFakeServer: true
6026 };
6027
6028 sinon.test = test;
6029 return test;
6030 }
6031
6032 var isNode = typeof module !== "undefined" && module.exports && typeof requi re === "function";
6033 var isAMD = typeof define === "function" && typeof define.amd === "object" & & define.amd;
6034
6035 function loadDependencies(require, exports, module) {
6036 var core = require("./util/core");
6037 require("./sandbox");
6038 module.exports = makeApi(core);
6039 }
6040
6041 if (isAMD) {
6042 define(loadDependencies);
6043 } else if (isNode) {
6044 loadDependencies(require, module.exports, module);
6045 } else if (sinonGlobal) {
6046 makeApi(sinonGlobal);
6047 }
6048 }(typeof sinon === "object" && sinon || null)); // eslint-disable-line no-undef
6049
6050 /**
6051 * @depend util/core.js
6052 * @depend test.js
6053 */
6054 /**
6055 * Test case, sandboxes all test functions
6056 *
6057 * @author Christian Johansen (christian@cjohansen.no)
6058 * @license BSD
6059 *
6060 * Copyright (c) 2010-2013 Christian Johansen
6061 */
6062 (function (sinonGlobal) {
6063
6064 function createTest(property, setUp, tearDown) {
6065 return function () {
6066 if (setUp) {
6067 setUp.apply(this, arguments);
6068 }
6069
6070 var exception, result;
6071
6072 try {
6073 result = property.apply(this, arguments);
6074 } catch (e) {
6075 exception = e;
6076 }
6077
6078 if (tearDown) {
6079 tearDown.apply(this, arguments);
6080 }
6081
6082 if (exception) {
6083 throw exception;
6084 }
6085
6086 return result;
6087 };
6088 }
6089
6090 function makeApi(sinon) {
6091 function testCase(tests, prefix) {
6092 if (!tests || typeof tests !== "object") {
6093 throw new TypeError("sinon.testCase needs an object with test fu nctions");
6094 }
6095
6096 prefix = prefix || "test";
6097 var rPrefix = new RegExp("^" + prefix);
6098 var methods = {};
6099 var setUp = tests.setUp;
6100 var tearDown = tests.tearDown;
6101 var testName,
6102 property,
6103 method;
6104
6105 for (testName in tests) {
6106 if (tests.hasOwnProperty(testName) && !/^(setUp|tearDown)$/.test (testName)) {
6107 property = tests[testName];
6108
6109 if (typeof property === "function" && rPrefix.test(testName) ) {
6110 method = property;
6111
6112 if (setUp || tearDown) {
6113 method = createTest(property, setUp, tearDown);
6114 }
6115
6116 methods[testName] = sinon.test(method);
6117 } else {
6118 methods[testName] = tests[testName];
6119 }
6120 }
6121 }
6122
6123 return methods;
6124 }
6125
6126 sinon.testCase = testCase;
6127 return testCase;
6128 }
6129
6130 var isNode = typeof module !== "undefined" && module.exports && typeof requi re === "function";
6131 var isAMD = typeof define === "function" && typeof define.amd === "object" & & define.amd;
6132
6133 function loadDependencies(require, exports, module) {
6134 var core = require("./util/core");
6135 require("./test");
6136 module.exports = makeApi(core);
6137 }
6138
6139 if (isAMD) {
6140 define(loadDependencies);
6141 return;
6142 }
6143
6144 if (isNode) {
6145 loadDependencies(require, module.exports, module);
6146 return;
6147 }
6148
6149 if (sinonGlobal) {
6150 makeApi(sinonGlobal);
6151 }
6152 }(
6153 typeof sinon === "object" && sinon // eslint-disable-line no-undef
6154 ));
6155
6156 /**
6157 * @depend times_in_words.js
6158 * @depend util/core.js
6159 * @depend match.js
6160 * @depend format.js
6161 */
6162 /**
6163 * Assertions matching the test spy retrieval interface.
6164 *
6165 * @author Christian Johansen (christian@cjohansen.no)
6166 * @license BSD
6167 *
6168 * Copyright (c) 2010-2013 Christian Johansen
6169 */
6170 (function (sinonGlobal, global) {
6171
6172 var slice = Array.prototype.slice;
6173
6174 function makeApi(sinon) {
6175 var assert;
6176
6177 function verifyIsStub() {
6178 var method;
6179
6180 for (var i = 0, l = arguments.length; i < l; ++i) {
6181 method = arguments[i];
6182
6183 if (!method) {
6184 assert.fail("fake is not a spy");
6185 }
6186
6187 if (method.proxy && method.proxy.isSinonProxy) {
6188 verifyIsStub(method.proxy);
6189 } else {
6190 if (typeof method !== "function") {
6191 assert.fail(method + " is not a function");
6192 }
6193
6194 if (typeof method.getCall !== "function") {
6195 assert.fail(method + " is not stubbed");
6196 }
6197 }
6198
6199 }
6200 }
6201
6202 function failAssertion(object, msg) {
6203 object = object || global;
6204 var failMethod = object.fail || assert.fail;
6205 failMethod.call(object, msg);
6206 }
6207
6208 function mirrorPropAsAssertion(name, method, message) {
6209 if (arguments.length === 2) {
6210 message = method;
6211 method = name;
6212 }
6213
6214 assert[name] = function (fake) {
6215 verifyIsStub(fake);
6216
6217 var args = slice.call(arguments, 1);
6218 var failed = false;
6219
6220 if (typeof method === "function") {
6221 failed = !method(fake);
6222 } else {
6223 failed = typeof fake[method] === "function" ?
6224 !fake[method].apply(fake, args) : !fake[method];
6225 }
6226
6227 if (failed) {
6228 failAssertion(this, (fake.printf || fake.proxy.printf).apply (fake, [message].concat(args)));
6229 } else {
6230 assert.pass(name);
6231 }
6232 };
6233 }
6234
6235 function exposedName(prefix, prop) {
6236 return !prefix || /^fail/.test(prop) ? prop :
6237 prefix + prop.slice(0, 1).toUpperCase() + prop.slice(1);
6238 }
6239
6240 assert = {
6241 failException: "AssertError",
6242
6243 fail: function fail(message) {
6244 var error = new Error(message);
6245 error.name = this.failException || assert.failException;
6246
6247 throw error;
6248 },
6249
6250 pass: function pass() {},
6251
6252 callOrder: function assertCallOrder() {
6253 verifyIsStub.apply(null, arguments);
6254 var expected = "";
6255 var actual = "";
6256
6257 if (!sinon.calledInOrder(arguments)) {
6258 try {
6259 expected = [].join.call(arguments, ", ");
6260 var calls = slice.call(arguments);
6261 var i = calls.length;
6262 while (i) {
6263 if (!calls[--i].called) {
6264 calls.splice(i, 1);
6265 }
6266 }
6267 actual = sinon.orderByFirstCall(calls).join(", ");
6268 } catch (e) {
6269 // If this fails, we'll just fall back to the blank stri ng
6270 }
6271
6272 failAssertion(this, "expected " + expected + " to be " +
6273 "called in order but were called as " + actual);
6274 } else {
6275 assert.pass("callOrder");
6276 }
6277 },
6278
6279 callCount: function assertCallCount(method, count) {
6280 verifyIsStub(method);
6281
6282 if (method.callCount !== count) {
6283 var msg = "expected %n to be called " + sinon.timesInWords(c ount) +
6284 " but was called %c%C";
6285 failAssertion(this, method.printf(msg));
6286 } else {
6287 assert.pass("callCount");
6288 }
6289 },
6290
6291 expose: function expose(target, options) {
6292 if (!target) {
6293 throw new TypeError("target is null or undefined");
6294 }
6295
6296 var o = options || {};
6297 var prefix = typeof o.prefix === "undefined" && "assert" || o.pr efix;
6298 var includeFail = typeof o.includeFail === "undefined" || !!o.in cludeFail;
6299
6300 for (var method in this) {
6301 if (method !== "expose" && (includeFail || !/^(fail)/.test(m ethod))) {
6302 target[exposedName(prefix, method)] = this[method];
6303 }
6304 }
6305
6306 return target;
6307 },
6308
6309 match: function match(actual, expectation) {
6310 var matcher = sinon.match(expectation);
6311 if (matcher.test(actual)) {
6312 assert.pass("match");
6313 } else {
6314 var formatted = [
6315 "expected value to match",
6316 " expected = " + sinon.format(expectation),
6317 " actual = " + sinon.format(actual)
6318 ];
6319
6320 failAssertion(this, formatted.join("\n"));
6321 }
6322 }
6323 };
6324
6325 mirrorPropAsAssertion("called", "expected %n to have been called at leas t once but was never called");
6326 mirrorPropAsAssertion("notCalled", function (spy) {
6327 return !spy.called;
6328 }, "expected %n to not have been called but was called %c%C");
6329 mirrorPropAsAssertion("calledOnce", "expected %n to be called once but w as called %c%C");
6330 mirrorPropAsAssertion("calledTwice", "expected %n to be called twice but was called %c%C");
6331 mirrorPropAsAssertion("calledThrice", "expected %n to be called thrice b ut was called %c%C");
6332 mirrorPropAsAssertion("calledOn", "expected %n to be called with %1 as t his but was called with %t");
6333 mirrorPropAsAssertion(
6334 "alwaysCalledOn",
6335 "expected %n to always be called with %1 as this but was called with %t"
6336 );
6337 mirrorPropAsAssertion("calledWithNew", "expected %n to be called with ne w");
6338 mirrorPropAsAssertion("alwaysCalledWithNew", "expected %n to always be c alled with new");
6339 mirrorPropAsAssertion("calledWith", "expected %n to be called with argum ents %*%C");
6340 mirrorPropAsAssertion("calledWithMatch", "expected %n to be called with match %*%C");
6341 mirrorPropAsAssertion("alwaysCalledWith", "expected %n to always be call ed with arguments %*%C");
6342 mirrorPropAsAssertion("alwaysCalledWithMatch", "expected %n to always be called with match %*%C");
6343 mirrorPropAsAssertion("calledWithExactly", "expected %n to be called wit h exact arguments %*%C");
6344 mirrorPropAsAssertion("alwaysCalledWithExactly", "expected %n to always be called with exact arguments %*%C");
6345 mirrorPropAsAssertion("neverCalledWith", "expected %n to never be called with arguments %*%C");
6346 mirrorPropAsAssertion("neverCalledWithMatch", "expected %n to never be c alled with match %*%C");
6347 mirrorPropAsAssertion("threw", "%n did not throw exception%C");
6348 mirrorPropAsAssertion("alwaysThrew", "%n did not always throw exception% C");
6349
6350 sinon.assert = assert;
6351 return assert;
6352 }
6353
6354 var isNode = typeof module !== "undefined" && module.exports && typeof requi re === "function";
6355 var isAMD = typeof define === "function" && typeof define.amd === "object" & & define.amd;
6356
6357 function loadDependencies(require, exports, module) {
6358 var sinon = require("./util/core");
6359 require("./match");
6360 require("./format");
6361 module.exports = makeApi(sinon);
6362 }
6363
6364 if (isAMD) {
6365 define(loadDependencies);
6366 return;
6367 }
6368
6369 if (isNode) {
6370 loadDependencies(require, module.exports, module);
6371 return;
6372 }
6373
6374 if (sinonGlobal) {
6375 makeApi(sinonGlobal);
6376 }
6377 }(
6378 typeof sinon === "object" && sinon, // eslint-disable-line no-undef
6379 typeof global !== "undefined" ? global : self
6380 ));
6381
6382 return sinon;
6383 }));
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698