2  * Sinon.JS 1.7.3, 2013/06/20
 
   4  * @author Christian Johansen (christian@cjohansen.no)
 
   5  * @author Contributors: https://github.com/cjohansen/Sinon.JS/blob/master/AUTHORS
 
   9  * Copyright (c) 2010-2013, Christian Johansen, christian@cjohansen.no
 
  10  * All rights reserved.
 
  12  * Redistribution and use in source and binary forms, with or without modification,
 
  13  * are permitted provided that the following conditions are met:
 
  15  *     * Redistributions of source code must retain the above copyright notice,
 
  16  *       this list of conditions and the following disclaimer.
 
  17  *     * Redistributions in binary form must reproduce the above copyright notice,
 
  18  *       this list of conditions and the following disclaimer in the documentation
 
  19  *       and/or other materials provided with the distribution.
 
  20  *     * Neither the name of Christian Johansen nor the names of his contributors
 
  21  *       may be used to endorse or promote products derived from this software
 
  22  *       without specific prior written permission.
 
  24  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 
  25  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 
  26  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 
  27  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
 
  28  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 
  29  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 
  30  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 
  31  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 
  32  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 
  33  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
  36 this.sinon = (function () {
 
  37 var buster = (function (setTimeout, B) {
 
  38     var isNode = typeof require == "function" && typeof module == "object";
 
  39     var div = typeof document != "undefined" && document.createElement("div");
 
  40     var F = function () {};
 
  43         bind: function bind(obj, methOrProp) {
 
  44             var method = typeof methOrProp == "string" ? obj[methOrProp] : methOrProp;
 
  45             var args = Array.prototype.slice.call(arguments, 2);
 
  47                 var allArgs = args.concat(Array.prototype.slice.call(arguments));
 
  48                 return method.apply(obj, allArgs);
 
  52         partial: function partial(fn) {
 
  53             var args = [].slice.call(arguments, 1);
 
  55                 return fn.apply(this, args.concat([].slice.call(arguments)));
 
  59         create: function create(object) {
 
  64         extend: function extend(target) {
 
  65             if (!target) { return; }
 
  66             for (var i = 1, l = arguments.length, prop; i < l; ++i) {
 
  67                 for (prop in arguments[i]) {
 
  68                     target[prop] = arguments[i][prop];
 
  74         nextTick: function nextTick(callback) {
 
  75             if (typeof process != "undefined" && process.nextTick) {
 
  76                 return process.nextTick(callback);
 
  78             setTimeout(callback, 0);
 
  81         functionName: function functionName(func) {
 
  83             if (func.displayName) return func.displayName;
 
  84             if (func.name) return func.name;
 
  85             var matches = func.toString().match(/function\s+([^\(]+)/m);
 
  86             return matches && matches[1] || "";
 
  89         isNode: function isNode(obj) {
 
  90             if (!div) return false;
 
 100         isElement: function isElement(obj) {
 
 101             return obj && obj.nodeType === 1 && buster.isNode(obj);
 
 104         isArray: function isArray(arr) {
 
 105             return Object.prototype.toString.call(arr) == "[object Array]";
 
 108         flatten: function flatten(arr) {
 
 109             var result = [], arr = arr || [];
 
 110             for (var i = 0, l = arr.length; i < l; ++i) {
 
 111                 result = result.concat(buster.isArray(arr[i]) ? flatten(arr[i]) : arr[i]);
 
 116         each: function each(arr, callback) {
 
 117             for (var i = 0, l = arr.length; i < l; ++i) {
 
 122         map: function map(arr, callback) {
 
 124             for (var i = 0, l = arr.length; i < l; ++i) {
 
 125                 results.push(callback(arr[i]));
 
 130         parallel: function parallel(fns, callback) {
 
 131             function cb(err, res) {
 
 132                 if (typeof callback == "function") {
 
 137             if (fns.length == 0) { return cb(null, []); }
 
 138             var remaining = fns.length, results = [];
 
 139             function makeDone(num) {
 
 140                 return function done(err, result) {
 
 141                     if (err) { return cb(err); }
 
 142                     results[num] = result;
 
 143                     if (--remaining == 0) { cb(null, results); }
 
 146             for (var i = 0, l = fns.length; i < l; ++i) {
 
 151         series: function series(fns, callback) {
 
 152             function cb(err, res) {
 
 153                 if (typeof callback == "function") {
 
 157             var remaining = fns.slice();
 
 159             function callNext() {
 
 160                 if (remaining.length == 0) return cb(null, results);
 
 161                 var promise = remaining.shift()(next);
 
 162                 if (promise && typeof promise.then == "function") {
 
 163                     promise.then(buster.partial(next, null), next);
 
 166             function next(err, result) {
 
 167                 if (err) return cb(err);
 
 168                 results.push(result);
 
 174         countdown: function countdown(num, done) {
 
 176                 if (--num == 0) done();
 
 181     if (typeof process === "object" &&
 
 182         typeof require === "function" && typeof module === "object") {
 
 183         var crypto = require("crypto");
 
 184         var path = require("path");
 
 186         buster.tmpFile = function (fileName) {
 
 187             var hashed = crypto.createHash("sha1");
 
 188             hashed.update(fileName);
 
 189             var tmpfileName = hashed.digest("hex");
 
 191             if (process.platform == "win32") {
 
 192                 return path.join(process.env["TEMP"], tmpfileName);
 
 194                 return path.join("/tmp", tmpfileName);
 
 199     if (Array.prototype.some) {
 
 200         buster.some = function (arr, fn, thisp) {
 
 201             return arr.some(fn, thisp);
 
 204         // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/some
 
 205         buster.some = function (arr, fun, thisp) {
 
 206                         if (arr == null) { throw new TypeError(); }
 
 208             var len = arr.length >>> 0;
 
 209             if (typeof fun !== "function") { throw new TypeError(); }
 
 211             for (var i = 0; i < len; i++) {
 
 212                 if (arr.hasOwnProperty(i) && fun.call(thisp, arr[i], i, arr)) {
 
 221     if (Array.prototype.filter) {
 
 222         buster.filter = function (arr, fn, thisp) {
 
 223             return arr.filter(fn, thisp);
 
 226         // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/filter
 
 227         buster.filter = function (fn, thisp) {
 
 228                         if (this == null) { throw new TypeError(); }
 
 230             var t = Object(this);
 
 231             var len = t.length >>> 0;
 
 232             if (typeof fn != "function") { throw new TypeError(); }
 
 235             for (var i = 0; i < len; i++) {
 
 237                     var val = t[i]; // in case fun mutates this
 
 238                     if (fn.call(thisp, val, i, t)) { res.push(val); }
 
 247         module.exports = buster;
 
 248         buster.eventEmitter = require("./buster-event-emitter");
 
 249         Object.defineProperty(buster, "defineVersionGetter", {
 
 251                 return require("./define-version-getter");
 
 256     return buster.extend(B || {}, buster);
 
 257 }(setTimeout, buster));
 
 258 if (typeof buster === "undefined") {
 
 262 if (typeof module === "object" && typeof require === "function") {
 
 263     buster = require("buster-core");
 
 266 buster.format = buster.format || {};
 
 267 buster.format.excludeConstructors = ["Object", /^.$/];
 
 268 buster.format.quoteStrings = true;
 
 270 buster.format.ascii = (function () {
 
 272     var hasOwn = Object.prototype.hasOwnProperty;
 
 274     var specialObjects = [];
 
 275     if (typeof global != "undefined") {
 
 276         specialObjects.push({ obj: global, value: "[object global]" });
 
 278     if (typeof document != "undefined") {
 
 279         specialObjects.push({ obj: document, value: "[object HTMLDocument]" });
 
 281     if (typeof window != "undefined") {
 
 282         specialObjects.push({ obj: window, value: "[object Window]" });
 
 285     function keys(object) {
 
 286         var k = Object.keys && Object.keys(object) || [];
 
 289             for (var prop in object) {
 
 290                 if (hasOwn.call(object, prop)) {
 
 299     function isCircular(object, objects) {
 
 300         if (typeof object != "object") {
 
 304         for (var i = 0, l = objects.length; i < l; ++i) {
 
 305             if (objects[i] === object) {
 
 313     function ascii(object, processed, indent) {
 
 314         if (typeof object == "string") {
 
 315             var quote = typeof this.quoteStrings != "boolean" || this.quoteStrings;
 
 316             return processed || quote ? '"' + object + '"' : object;
 
 319         if (typeof object == "function" && !(object instanceof RegExp)) {
 
 320             return ascii.func(object);
 
 323         processed = processed || [];
 
 325         if (isCircular(object, processed)) {
 
 329         if (Object.prototype.toString.call(object) == "[object Array]") {
 
 330             return ascii.array.call(this, object, processed);
 
 337         if (buster.isElement(object)) {
 
 338             return ascii.element(object);
 
 341         if (typeof object.toString == "function" &&
 
 342             object.toString !== Object.prototype.toString) {
 
 343             return object.toString();
 
 346         for (var i = 0, l = specialObjects.length; i < l; i++) {
 
 347             if (object === specialObjects[i].obj) {
 
 348                 return specialObjects[i].value;
 
 352         return ascii.object.call(this, object, processed, indent);
 
 355     ascii.func = function (func) {
 
 356         return "function " + buster.functionName(func) + "() {}";
 
 359     ascii.array = function (array, processed) {
 
 360         processed = processed || [];
 
 361         processed.push(array);
 
 364         for (var i = 0, l = array.length; i < l; ++i) {
 
 365             pieces.push(ascii.call(this, array[i], processed));
 
 368         return "[" + pieces.join(", ") + "]";
 
 371     ascii.object = function (object, processed, indent) {
 
 372         processed = processed || [];
 
 373         processed.push(object);
 
 374         indent = indent || 0;
 
 375         var pieces = [], properties = keys(object), prop, str, obj;
 
 379         for (var i = 0, l = indent; i < l; ++i) {
 
 383         for (i = 0, l = properties.length; i < l; ++i) {
 
 384             prop = properties[i];
 
 387             if (isCircular(obj, processed)) {
 
 390                 str = ascii.call(this, obj, processed, indent + 2);
 
 393             str = (/\s/.test(prop) ? '"' + prop + '"' : prop) + ": " + str;
 
 394             length += str.length;
 
 398         var cons = ascii.constructorName.call(this, object);
 
 399         var prefix = cons ? "[" + cons + "] " : ""
 
 401         return (length + indent) > 80 ?
 
 402             prefix + "{\n  " + is + pieces.join(",\n  " + is) + "\n" + is + "}" :
 
 403             prefix + "{ " + pieces.join(", ") + " }";
 
 406     ascii.element = function (element) {
 
 407         var tagName = element.tagName.toLowerCase();
 
 408         var attrs = element.attributes, attribute, pairs = [], attrName;
 
 410         for (var i = 0, l = attrs.length; i < l; ++i) {
 
 411             attribute = attrs.item(i);
 
 412             attrName = attribute.nodeName.toLowerCase().replace("html:", "");
 
 414             if (attrName == "contenteditable" && attribute.nodeValue == "inherit") {
 
 418             if (!!attribute.nodeValue) {
 
 419                 pairs.push(attrName + "=\"" + attribute.nodeValue + "\"");
 
 423         var formatted = "<" + tagName + (pairs.length > 0 ? " " : "");
 
 424         var content = element.innerHTML;
 
 426         if (content.length > 20) {
 
 427             content = content.substr(0, 20) + "[...]";
 
 430         var res = formatted + pairs.join(" ") + ">" + content + "</" + tagName + ">";
 
 432         return res.replace(/ contentEditable="inherit"/, "");
 
 435     ascii.constructorName = function (object) {
 
 436         var name = buster.functionName(object && object.constructor);
 
 437         var excludes = this.excludeConstructors || buster.format.excludeConstructors || [];
 
 439         for (var i = 0, l = excludes.length; i < l; ++i) {
 
 440             if (typeof excludes[i] == "string" && excludes[i] == name) {
 
 442             } else if (excludes[i].test && excludes[i].test(name)) {
 
 453 if (typeof module != "undefined") {
 
 454     module.exports = buster.format;
 
 456 /*jslint eqeqeq: false, onevar: false, forin: true, nomen: false, regexp: false, plusplus: false*/
 
 457 /*global module, require, __dirname, document*/
 
 459  * Sinon core utilities. For internal use only.
 
 461  * @author Christian Johansen (christian@cjohansen.no)
 
 464  * Copyright (c) 2010-2013 Christian Johansen
 
 467 var sinon = (function (buster) {
 
 468     var div = typeof document != "undefined" && document.createElement("div");
 
 469     var hasOwn = Object.prototype.hasOwnProperty;
 
 471     function isDOMNode(obj) {
 
 475             obj.appendChild(div);
 
 476             success = div.parentNode == obj;
 
 481                 obj.removeChild(div);
 
 483                 // Remove failed, not much we can do about that
 
 490     function isElement(obj) {
 
 491         return div && obj && obj.nodeType === 1 && isDOMNode(obj);
 
 494     function isFunction(obj) {
 
 495         return typeof obj === "function" || !!(obj && obj.constructor && obj.call && obj.apply);
 
 498     function mirrorProperties(target, source) {
 
 499         for (var prop in source) {
 
 500             if (!hasOwn.call(target, prop)) {
 
 501                 target[prop] = source[prop];
 
 506     function isRestorable (obj) {
 
 507         return typeof obj === "function" && typeof obj.restore === "function" && obj.restore.sinon;
 
 511         wrapMethod: function wrapMethod(object, property, method) {
 
 513                 throw new TypeError("Should wrap property of object");
 
 516             if (typeof method != "function") {
 
 517                 throw new TypeError("Method wrapper should be function");
 
 520             var wrappedMethod = object[property];
 
 522             if (!isFunction(wrappedMethod)) {
 
 523                 throw new TypeError("Attempted to wrap " + (typeof wrappedMethod) + " property " +
 
 524                                     property + " as function");
 
 527             if (wrappedMethod.restore && wrappedMethod.restore.sinon) {
 
 528                 throw new TypeError("Attempted to wrap " + property + " which is already wrapped");
 
 531             if (wrappedMethod.calledBefore) {
 
 532                 var verb = !!wrappedMethod.returns ? "stubbed" : "spied on";
 
 533                 throw new TypeError("Attempted to wrap " + property + " which is already " + verb);
 
 536             // IE 8 does not support hasOwnProperty on the window object.
 
 537             var owned = hasOwn.call(object, property);
 
 538             object[property] = method;
 
 539             method.displayName = property;
 
 541             method.restore = function () {
 
 542                 // For prototype properties try to reset by delete first.
 
 543                 // If this fails (ex: localStorage on mobile safari) then force a reset
 
 544                 // via direct assignment.
 
 546                     delete object[property];
 
 548                 if (object[property] === method) {
 
 549                     object[property] = wrappedMethod;
 
 553             method.restore.sinon = true;
 
 554             mirrorProperties(method, wrappedMethod);
 
 559         extend: function extend(target) {
 
 560             for (var i = 1, l = arguments.length; i < l; i += 1) {
 
 561                 for (var prop in arguments[i]) {
 
 562                     if (arguments[i].hasOwnProperty(prop)) {
 
 563                         target[prop] = arguments[i][prop];
 
 566                     // DONT ENUM bug, only care about toString
 
 567                     if (arguments[i].hasOwnProperty("toString") &&
 
 568                         arguments[i].toString != target.toString) {
 
 569                         target.toString = arguments[i].toString;
 
 577         create: function create(proto) {
 
 578             var F = function () {};
 
 583         deepEqual: function deepEqual(a, b) {
 
 584             if (sinon.match && sinon.match.isMatcher(a)) {
 
 587             if (typeof a != "object" || typeof b != "object") {
 
 591             if (isElement(a) || isElement(b)) {
 
 599             if ((a === null && b !== null) || (a !== null && b === null)) {
 
 603             var aString = Object.prototype.toString.call(a);
 
 604             if (aString != Object.prototype.toString.call(b)) {
 
 608             if (aString == "[object Array]") {
 
 609                 if (a.length !== b.length) {
 
 613                 for (var i = 0, l = a.length; i < l; i += 1) {
 
 614                     if (!deepEqual(a[i], b[i])) {
 
 622             if (aString == "[object Date]") {
 
 623                 return a.valueOf() === b.valueOf();
 
 626             var prop, aLength = 0, bLength = 0;
 
 631                 if (!deepEqual(a[prop], b[prop])) {
 
 640             return aLength == bLength;
 
 643         functionName: function functionName(func) {
 
 644             var name = func.displayName || func.name;
 
 646             // Use function decomposition as a last resort to get function
 
 647             // name. Does not rely on function decomposition to work - if it
 
 648             // doesn't debugging will be slightly less informative
 
 649             // (i.e. toString will say 'spy' rather than 'myFunc').
 
 651                 var matches = func.toString().match(/function ([^\s\(]+)/);
 
 652                 name = matches && matches[1];
 
 658         functionToString: function toString() {
 
 659             if (this.getCall && this.callCount) {
 
 660                 var thisValue, prop, i = this.callCount;
 
 663                     thisValue = this.getCall(i).thisValue;
 
 665                     for (prop in thisValue) {
 
 666                         if (thisValue[prop] === this) {
 
 673             return this.displayName || "sinon fake";
 
 676         getConfig: function (custom) {
 
 678             custom = custom || {};
 
 679             var defaults = sinon.defaultConfig;
 
 681             for (var prop in defaults) {
 
 682                 if (defaults.hasOwnProperty(prop)) {
 
 683                     config[prop] = custom.hasOwnProperty(prop) ? custom[prop] : defaults[prop];
 
 690         format: function (val) {
 
 695             injectIntoThis: true,
 
 697             properties: ["spy", "stub", "mock", "clock", "server", "requests"],
 
 702         timesInWords: function timesInWords(count) {
 
 703             return count == 1 && "once" ||
 
 704                 count == 2 && "twice" ||
 
 705                 count == 3 && "thrice" ||
 
 706                 (count || 0) + " times";
 
 709         calledInOrder: function (spies) {
 
 710             for (var i = 1, l = spies.length; i < l; i++) {
 
 711                 if (!spies[i - 1].calledBefore(spies[i]) || !spies[i].called) {
 
 719         orderByFirstCall: function (spies) {
 
 720             return spies.sort(function (a, b) {
 
 721                 // uuid, won't ever be equal
 
 722                 var aCall = a.getCall(0);
 
 723                 var bCall = b.getCall(0);
 
 724                 var aId = aCall && aCall.callId || -1;
 
 725                 var bId = bCall && bCall.callId || -1;
 
 727                 return aId < bId ? -1 : 1;
 
 733         logError: function (label, err) {
 
 734             var msg = label + " threw exception: "
 
 735             sinon.log(msg + "[" + err.name + "] " + err.message);
 
 736             if (err.stack) { sinon.log(err.stack); }
 
 738             setTimeout(function () {
 
 739                 err.message = msg + err.message;
 
 744         typeOf: function (value) {
 
 745             if (value === null) {
 
 748             else if (value === undefined) {
 
 751             var string = Object.prototype.toString.call(value);
 
 752             return string.substring(8, string.length - 1).toLowerCase();
 
 755         createStubInstance: function (constructor) {
 
 756             if (typeof constructor !== "function") {
 
 757                 throw new TypeError("The constructor should be a function.");
 
 759             return sinon.stub(sinon.create(constructor.prototype));
 
 762         restore: function (object) {
 
 763             if (object !== null && typeof object === "object") {
 
 764                 for (var prop in object) {
 
 765                     if (isRestorable(object[prop])) {
 
 766                         object[prop].restore();
 
 770             else if (isRestorable(object)) {
 
 776     var isNode = typeof module == "object" && typeof require == "function";
 
 780             buster = { format: require("buster-format") };
 
 782         module.exports = sinon;
 
 783         module.exports.spy = require("./sinon/spy");
 
 784         module.exports.stub = require("./sinon/stub");
 
 785         module.exports.mock = require("./sinon/mock");
 
 786         module.exports.collection = require("./sinon/collection");
 
 787         module.exports.assert = require("./sinon/assert");
 
 788         module.exports.sandbox = require("./sinon/sandbox");
 
 789         module.exports.test = require("./sinon/test");
 
 790         module.exports.testCase = require("./sinon/test_case");
 
 791         module.exports.assert = require("./sinon/assert");
 
 792         module.exports.match = require("./sinon/match");
 
 796         var formatter = sinon.create(buster.format);
 
 797         formatter.quoteStrings = false;
 
 798         sinon.format = function () {
 
 799             return formatter.ascii.apply(formatter, arguments);
 
 803             var util = require("util");
 
 804             sinon.format = function (value) {
 
 805                 return typeof value == "object" && value.toString === Object.prototype.toString ? util.inspect(value) : value;
 
 808             /* Node, but no util module - would be very old, but better safe than
 
 814 }(typeof buster == "object" && buster));
 
 816 /* @depend ../sinon.js */
 
 817 /*jslint eqeqeq: false, onevar: false, plusplus: false*/
 
 818 /*global module, require, sinon*/
 
 822  * @author Maximilian Antoni (mail@maxantoni.de)
 
 825  * Copyright (c) 2012 Maximilian Antoni
 
 829     var commonJSModule = typeof module == "object" && typeof require == "function";
 
 831     if (!sinon && commonJSModule) {
 
 832         sinon = require("../sinon");
 
 839     function assertType(value, type, name) {
 
 840         var actual = sinon.typeOf(value);
 
 841         if (actual !== type) {
 
 842             throw new TypeError("Expected type of " + name + " to be " +
 
 843                 type + ", but was " + actual);
 
 848         toString: function () {
 
 853     function isMatcher(object) {
 
 854         return matcher.isPrototypeOf(object);
 
 857     function matchObject(expectation, actual) {
 
 858         if (actual === null || actual === undefined) {
 
 861         for (var key in expectation) {
 
 862             if (expectation.hasOwnProperty(key)) {
 
 863                 var exp = expectation[key];
 
 864                 var act = actual[key];
 
 865                 if (match.isMatcher(exp)) {
 
 866                     if (!exp.test(act)) {
 
 869                 } else if (sinon.typeOf(exp) === "object") {
 
 870                     if (!matchObject(exp, act)) {
 
 873                 } else if (!sinon.deepEqual(exp, act)) {
 
 881     matcher.or = function (m2) {
 
 882         if (!isMatcher(m2)) {
 
 883             throw new TypeError("Matcher expected");
 
 886         var or = sinon.create(matcher);
 
 887         or.test = function (actual) {
 
 888             return m1.test(actual) || m2.test(actual);
 
 890         or.message = m1.message + ".or(" + m2.message + ")";
 
 894     matcher.and = function (m2) {
 
 895         if (!isMatcher(m2)) {
 
 896             throw new TypeError("Matcher expected");
 
 899         var and = sinon.create(matcher);
 
 900         and.test = function (actual) {
 
 901             return m1.test(actual) && m2.test(actual);
 
 903         and.message = m1.message + ".and(" + m2.message + ")";
 
 907     var match = function (expectation, message) {
 
 908         var m = sinon.create(matcher);
 
 909         var type = sinon.typeOf(expectation);
 
 912             if (typeof expectation.test === "function") {
 
 913                 m.test = function (actual) {
 
 914                     return expectation.test(actual) === true;
 
 916                 m.message = "match(" + sinon.functionName(expectation.test) + ")";
 
 920             for (var key in expectation) {
 
 921                 if (expectation.hasOwnProperty(key)) {
 
 922                     str.push(key + ": " + expectation[key]);
 
 925             m.test = function (actual) {
 
 926                 return matchObject(expectation, actual);
 
 928             m.message = "match(" + str.join(", ") + ")";
 
 931             m.test = function (actual) {
 
 932                 return expectation == actual;
 
 936             m.test = function (actual) {
 
 937                 if (typeof actual !== "string") {
 
 940                 return actual.indexOf(expectation) !== -1;
 
 942             m.message = "match(\"" + expectation + "\")";
 
 945             m.test = function (actual) {
 
 946                 if (typeof actual !== "string") {
 
 949                 return expectation.test(actual);
 
 953             m.test = expectation;
 
 957                 m.message = "match(" + sinon.functionName(expectation) + ")";
 
 961             m.test = function (actual) {
 
 962               return sinon.deepEqual(expectation, actual);
 
 966             m.message = "match(" + expectation + ")";
 
 971     match.isMatcher = isMatcher;
 
 973     match.any = match(function () {
 
 977     match.defined = match(function (actual) {
 
 978         return actual !== null && actual !== undefined;
 
 981     match.truthy = match(function (actual) {
 
 985     match.falsy = match(function (actual) {
 
 989     match.same = function (expectation) {
 
 990         return match(function (actual) {
 
 991             return expectation === actual;
 
 992         }, "same(" + expectation + ")");
 
 995     match.typeOf = function (type) {
 
 996         assertType(type, "string", "type");
 
 997         return match(function (actual) {
 
 998             return sinon.typeOf(actual) === type;
 
 999         }, "typeOf(\"" + type + "\")");
 
1002     match.instanceOf = function (type) {
 
1003         assertType(type, "function", "type");
 
1004         return match(function (actual) {
 
1005             return actual instanceof type;
 
1006         }, "instanceOf(" + sinon.functionName(type) + ")");
 
1009     function createPropertyMatcher(propertyTest, messagePrefix) {
 
1010         return function (property, value) {
 
1011             assertType(property, "string", "property");
 
1012             var onlyProperty = arguments.length === 1;
 
1013             var message = messagePrefix + "(\"" + property + "\"";
 
1014             if (!onlyProperty) {
 
1015                 message += ", " + value;
 
1018             return match(function (actual) {
 
1019                 if (actual === undefined || actual === null ||
 
1020                         !propertyTest(actual, property)) {
 
1023                 return onlyProperty || sinon.deepEqual(value, actual[property]);
 
1028     match.has = createPropertyMatcher(function (actual, property) {
 
1029         if (typeof actual === "object") {
 
1030             return property in actual;
 
1032         return actual[property] !== undefined;
 
1035     match.hasOwn = createPropertyMatcher(function (actual, property) {
 
1036         return actual.hasOwnProperty(property);
 
1039     match.bool = match.typeOf("boolean");
 
1040     match.number = match.typeOf("number");
 
1041     match.string = match.typeOf("string");
 
1042     match.object = match.typeOf("object");
 
1043     match.func = match.typeOf("function");
 
1044     match.array = match.typeOf("array");
 
1045     match.regexp = match.typeOf("regexp");
 
1046     match.date = match.typeOf("date");
 
1048     if (commonJSModule) {
 
1049         module.exports = match;
 
1051         sinon.match = match;
 
1053 }(typeof sinon == "object" && sinon || null));
 
1056   * @depend ../sinon.js
 
1059 /*jslint eqeqeq: false, onevar: false, plusplus: false*/
 
1060 /*global module, require, sinon*/
 
1064   * @author Christian Johansen (christian@cjohansen.no)
 
1065   * @author Maximilian Antoni (mail@maxantoni.de)
 
1068   * Copyright (c) 2010-2013 Christian Johansen
 
1069   * Copyright (c) 2013 Maximilian Antoni
 
1072 var commonJSModule = typeof module == "object" && typeof require == "function";
 
1074 if (!this.sinon && commonJSModule) {
 
1075     var sinon = require("../sinon");
 
1079     function throwYieldError(proxy, text, args) {
 
1080         var msg = sinon.functionName(proxy) + text;
 
1082             msg += " Received [" + slice.call(args).join(", ") + "]";
 
1084         throw new Error(msg);
 
1087     var slice = Array.prototype.slice;
 
1090         calledOn: function calledOn(thisValue) {
 
1091             if (sinon.match && sinon.match.isMatcher(thisValue)) {
 
1092                 return thisValue.test(this.thisValue);
 
1094             return this.thisValue === thisValue;
 
1097         calledWith: function calledWith() {
 
1098             for (var i = 0, l = arguments.length; i < l; i += 1) {
 
1099                 if (!sinon.deepEqual(arguments[i], this.args[i])) {
 
1107         calledWithMatch: function calledWithMatch() {
 
1108             for (var i = 0, l = arguments.length; i < l; i += 1) {
 
1109                 var actual = this.args[i];
 
1110                 var expectation = arguments[i];
 
1111                 if (!sinon.match || !sinon.match(expectation).test(actual)) {
 
1118         calledWithExactly: function calledWithExactly() {
 
1119             return arguments.length == this.args.length &&
 
1120                 this.calledWith.apply(this, arguments);
 
1123         notCalledWith: function notCalledWith() {
 
1124             return !this.calledWith.apply(this, arguments);
 
1127         notCalledWithMatch: function notCalledWithMatch() {
 
1128             return !this.calledWithMatch.apply(this, arguments);
 
1131         returned: function returned(value) {
 
1132             return sinon.deepEqual(value, this.returnValue);
 
1135         threw: function threw(error) {
 
1136             if (typeof error === "undefined" || !this.exception) {
 
1137                 return !!this.exception;
 
1140             return this.exception === error || this.exception.name === error;
 
1143         calledWithNew: function calledWithNew(thisValue) {
 
1144             return this.thisValue instanceof this.proxy;
 
1147         calledBefore: function (other) {
 
1148             return this.callId < other.callId;
 
1151         calledAfter: function (other) {
 
1152             return this.callId > other.callId;
 
1155         callArg: function (pos) {
 
1159         callArgOn: function (pos, thisValue) {
 
1160             this.args[pos].apply(thisValue);
 
1163         callArgWith: function (pos) {
 
1164             this.callArgOnWith.apply(this, [pos, null].concat(slice.call(arguments, 1)));
 
1167         callArgOnWith: function (pos, thisValue) {
 
1168             var args = slice.call(arguments, 2);
 
1169             this.args[pos].apply(thisValue, args);
 
1172         "yield": function () {
 
1173             this.yieldOn.apply(this, [null].concat(slice.call(arguments, 0)));
 
1176         yieldOn: function (thisValue) {
 
1177             var args = this.args;
 
1178             for (var i = 0, l = args.length; i < l; ++i) {
 
1179                 if (typeof args[i] === "function") {
 
1180                     args[i].apply(thisValue, slice.call(arguments, 1));
 
1184             throwYieldError(this.proxy, " cannot yield since no callback was passed.", args);
 
1187         yieldTo: function (prop) {
 
1188             this.yieldToOn.apply(this, [prop, null].concat(slice.call(arguments, 1)));
 
1191         yieldToOn: function (prop, thisValue) {
 
1192             var args = this.args;
 
1193             for (var i = 0, l = args.length; i < l; ++i) {
 
1194                 if (args[i] && typeof args[i][prop] === "function") {
 
1195                     args[i][prop].apply(thisValue, slice.call(arguments, 2));
 
1199             throwYieldError(this.proxy, " cannot yield to '" + prop +
 
1200                 "' since no callback was passed.", args);
 
1203         toString: function () {
 
1204             var callStr = this.proxy.toString() + "(";
 
1207             for (var i = 0, l = this.args.length; i < l; ++i) {
 
1208                 args.push(sinon.format(this.args[i]));
 
1211             callStr = callStr + args.join(", ") + ")";
 
1213             if (typeof this.returnValue != "undefined") {
 
1214                 callStr += " => " + sinon.format(this.returnValue);
 
1217             if (this.exception) {
 
1218                 callStr += " !" + this.exception.name;
 
1220                 if (this.exception.message) {
 
1221                     callStr += "(" + this.exception.message + ")";
 
1229     callProto.invokeCallback = callProto.yield;
 
1231     function createSpyCall(spy, thisValue, args, returnValue, exception, id) {
 
1232         if (typeof id !== "number") {
 
1233             throw new TypeError("Call id is not a number");
 
1235         var proxyCall = sinon.create(callProto);
 
1236         proxyCall.proxy = spy;
 
1237         proxyCall.thisValue = thisValue;
 
1238         proxyCall.args = args;
 
1239         proxyCall.returnValue = returnValue;
 
1240         proxyCall.exception = exception;
 
1241         proxyCall.callId = id;
 
1245     createSpyCall.toString = callProto.toString; // used by mocks
 
1247     sinon.spyCall = createSpyCall;
 
1248 }(typeof sinon == "object" && sinon || null));
 
1251   * @depend ../sinon.js
 
1253 /*jslint eqeqeq: false, onevar: false, plusplus: false*/
 
1254 /*global module, require, sinon*/
 
1258   * @author Christian Johansen (christian@cjohansen.no)
 
1261   * Copyright (c) 2010-2013 Christian Johansen
 
1265     var commonJSModule = typeof module == "object" && typeof require == "function";
 
1266     var push = Array.prototype.push;
 
1267     var slice = Array.prototype.slice;
 
1270     function spy(object, property) {
 
1271         if (!property && typeof object == "function") {
 
1272             return spy.create(object);
 
1275         if (!object && !property) {
 
1276             return spy.create(function () { });
 
1279         var method = object[property];
 
1280         return sinon.wrapMethod(object, property, spy.create(method));
 
1283     function matchingFake(fakes, args, strict) {
 
1288         var alen = args.length;
 
1290         for (var i = 0, l = fakes.length; i < l; i++) {
 
1291             if (fakes[i].matches(args, strict)) {
 
1297     function incrementCallCount() {
 
1299         this.callCount += 1;
 
1300         this.notCalled = false;
 
1301         this.calledOnce = this.callCount == 1;
 
1302         this.calledTwice = this.callCount == 2;
 
1303         this.calledThrice = this.callCount == 3;
 
1306     function createCallProperties() {
 
1307         this.firstCall = this.getCall(0);
 
1308         this.secondCall = this.getCall(1);
 
1309         this.thirdCall = this.getCall(2);
 
1310         this.lastCall = this.getCall(this.callCount - 1);
 
1313     var vars = "a,b,c,d,e,f,g,h,i,j,k,l";
 
1314     function createProxy(func) {
 
1315         // Retain the function length:
 
1318             eval("p = (function proxy(" + vars.substring(0, func.length * 2 - 1) +
 
1319                 ") { return p.invoke(func, this, slice.call(arguments)); });");
 
1322             p = function proxy() {
 
1323                 return p.invoke(func, this, slice.call(arguments));
 
1333         reset: function () {
 
1334             this.called = false;
 
1335             this.notCalled = true;
 
1336             this.calledOnce = false;
 
1337             this.calledTwice = false;
 
1338             this.calledThrice = false;
 
1340             this.firstCall = null;
 
1341             this.secondCall = null;
 
1342             this.thirdCall = null;
 
1343             this.lastCall = null;
 
1345             this.returnValues = [];
 
1346             this.thisValues = [];
 
1347             this.exceptions = [];
 
1350                 for (var i = 0; i < this.fakes.length; i++) {
 
1351                     this.fakes[i].reset();
 
1356         create: function create(func) {
 
1359             if (typeof func != "function") {
 
1360                 func = function () { };
 
1362                 name = sinon.functionName(func);
 
1365             var proxy = createProxy(func);
 
1367             sinon.extend(proxy, spy);
 
1368             delete proxy.create;
 
1369             sinon.extend(proxy, func);
 
1372             proxy.prototype = func.prototype;
 
1373             proxy.displayName = name || "spy";
 
1374             proxy.toString = sinon.functionToString;
 
1375             proxy._create = sinon.spy.create;
 
1376             proxy.id = "spy#" + uuid++;
 
1381         invoke: function invoke(func, thisValue, args) {
 
1382             var matching = matchingFake(this.fakes, args);
 
1383             var exception, returnValue;
 
1385             incrementCallCount.call(this);
 
1386             push.call(this.thisValues, thisValue);
 
1387             push.call(this.args, args);
 
1388             push.call(this.callIds, callId++);
 
1392                     returnValue = matching.invoke(func, thisValue, args);
 
1394                     returnValue = (this.func || func).apply(thisValue, args);
 
1397                 push.call(this.returnValues, undefined);
 
1401                 push.call(this.exceptions, exception);
 
1404             push.call(this.returnValues, returnValue);
 
1406             createCallProperties.call(this);
 
1411         getCall: function getCall(i) {
 
1412             if (i < 0 || i >= this.callCount) {
 
1416             return sinon.spyCall(this, this.thisValues[i], this.args[i],
 
1417                                     this.returnValues[i], this.exceptions[i],
 
1421         calledBefore: function calledBefore(spyFn) {
 
1426             if (!spyFn.called) {
 
1430             return this.callIds[0] < spyFn.callIds[spyFn.callIds.length - 1];
 
1433         calledAfter: function calledAfter(spyFn) {
 
1434             if (!this.called || !spyFn.called) {
 
1438             return this.callIds[this.callCount - 1] > spyFn.callIds[spyFn.callCount - 1];
 
1441         withArgs: function () {
 
1442             var args = slice.call(arguments);
 
1445                 var match = matchingFake(this.fakes, args, true);
 
1454             var original = this;
 
1455             var fake = this._create();
 
1456             fake.matchingAguments = args;
 
1457             push.call(this.fakes, fake);
 
1459             fake.withArgs = function () {
 
1460                 return original.withArgs.apply(original, arguments);
 
1463             for (var i = 0; i < this.args.length; i++) {
 
1464                 if (fake.matches(this.args[i])) {
 
1465                     incrementCallCount.call(fake);
 
1466                     push.call(fake.thisValues, this.thisValues[i]);
 
1467                     push.call(fake.args, this.args[i]);
 
1468                     push.call(fake.returnValues, this.returnValues[i]);
 
1469                     push.call(fake.exceptions, this.exceptions[i]);
 
1470                     push.call(fake.callIds, this.callIds[i]);
 
1473             createCallProperties.call(fake);
 
1478         matches: function (args, strict) {
 
1479             var margs = this.matchingAguments;
 
1481             if (margs.length <= args.length &&
 
1482                 sinon.deepEqual(margs, args.slice(0, margs.length))) {
 
1483                 return !strict || margs.length == args.length;
 
1487         printf: function (format) {
 
1489             var args = slice.call(arguments, 1);
 
1492             return (format || "").replace(/%(.)/g, function (match, specifyer) {
 
1493                 formatter = spyApi.formatters[specifyer];
 
1495                 if (typeof formatter == "function") {
 
1496                     return formatter.call(null, spy, args);
 
1497                 } else if (!isNaN(parseInt(specifyer), 10)) {
 
1498                     return sinon.format(args[specifyer - 1]);
 
1501                 return "%" + specifyer;
 
1506     function delegateToCalls(method, matchAny, actual, notCalled) {
 
1507         spyApi[method] = function () {
 
1510                     return notCalled.apply(this, arguments);
 
1518             for (var i = 0, l = this.callCount; i < l; i += 1) {
 
1519                 currentCall = this.getCall(i);
 
1521                 if (currentCall[actual || method].apply(currentCall, arguments)) {
 
1530             return matches === this.callCount;
 
1534     delegateToCalls("calledOn", true);
 
1535     delegateToCalls("alwaysCalledOn", false, "calledOn");
 
1536     delegateToCalls("calledWith", true);
 
1537     delegateToCalls("calledWithMatch", true);
 
1538     delegateToCalls("alwaysCalledWith", false, "calledWith");
 
1539     delegateToCalls("alwaysCalledWithMatch", false, "calledWithMatch");
 
1540     delegateToCalls("calledWithExactly", true);
 
1541     delegateToCalls("alwaysCalledWithExactly", false, "calledWithExactly");
 
1542     delegateToCalls("neverCalledWith", false, "notCalledWith",
 
1543         function () { return true; });
 
1544     delegateToCalls("neverCalledWithMatch", false, "notCalledWithMatch",
 
1545         function () { return true; });
 
1546     delegateToCalls("threw", true);
 
1547     delegateToCalls("alwaysThrew", false, "threw");
 
1548     delegateToCalls("returned", true);
 
1549     delegateToCalls("alwaysReturned", false, "returned");
 
1550     delegateToCalls("calledWithNew", true);
 
1551     delegateToCalls("alwaysCalledWithNew", false, "calledWithNew");
 
1552     delegateToCalls("callArg", false, "callArgWith", function () {
 
1553         throw new Error(this.toString() + " cannot call arg since it was not yet invoked.");
 
1555     spyApi.callArgWith = spyApi.callArg;
 
1556     delegateToCalls("callArgOn", false, "callArgOnWith", function () {
 
1557         throw new Error(this.toString() + " cannot call arg since it was not yet invoked.");
 
1559     spyApi.callArgOnWith = spyApi.callArgOn;
 
1560     delegateToCalls("yield", false, "yield", function () {
 
1561         throw new Error(this.toString() + " cannot yield since it was not yet invoked.");
 
1563     // "invokeCallback" is an alias for "yield" since "yield" is invalid in strict mode.
 
1564     spyApi.invokeCallback = spyApi.yield;
 
1565     delegateToCalls("yieldOn", false, "yieldOn", function () {
 
1566         throw new Error(this.toString() + " cannot yield since it was not yet invoked.");
 
1568     delegateToCalls("yieldTo", false, "yieldTo", function (property) {
 
1569         throw new Error(this.toString() + " cannot yield to '" + property +
 
1570             "' since it was not yet invoked.");
 
1572     delegateToCalls("yieldToOn", false, "yieldToOn", function (property) {
 
1573         throw new Error(this.toString() + " cannot yield to '" + property +
 
1574             "' since it was not yet invoked.");
 
1577     spyApi.formatters = {
 
1578         "c": function (spy) {
 
1579             return sinon.timesInWords(spy.callCount);
 
1582         "n": function (spy) {
 
1583             return spy.toString();
 
1586         "C": function (spy) {
 
1589             for (var i = 0, l = spy.callCount; i < l; ++i) {
 
1590                 var stringifiedCall = "    " + spy.getCall(i).toString();
 
1591                 if (/\n/.test(calls[i - 1])) {
 
1592                     stringifiedCall = "\n" + stringifiedCall;
 
1594                 push.call(calls, stringifiedCall);
 
1597             return calls.length > 0 ? "\n" + calls.join("\n") : "";
 
1600         "t": function (spy) {
 
1603             for (var i = 0, l = spy.callCount; i < l; ++i) {
 
1604                 push.call(objects, sinon.format(spy.thisValues[i]));
 
1607             return objects.join(", ");
 
1610         "*": function (spy, args) {
 
1613             for (var i = 0, l = args.length; i < l; ++i) {
 
1614                 push.call(formatted, sinon.format(args[i]));
 
1617             return formatted.join(", ");
 
1621     sinon.extend(spy, spyApi);
 
1623     spy.spyCall = sinon.spyCall;
 
1625     if (commonJSModule) {
 
1626         module.exports = spy;
 
1630 }(typeof sinon == "object" && sinon || null));
 
1633  * @depend ../sinon.js
 
1636 /*jslint eqeqeq: false, onevar: false*/
 
1637 /*global module, require, sinon*/
 
1641  * @author Christian Johansen (christian@cjohansen.no)
 
1644  * Copyright (c) 2010-2013 Christian Johansen
 
1648     var commonJSModule = typeof module == "object" && typeof require == "function";
 
1650     if (!sinon && commonJSModule) {
 
1651         sinon = require("../sinon");
 
1658     function stub(object, property, func) {
 
1659         if (!!func && typeof func != "function") {
 
1660             throw new TypeError("Custom stub should be function");
 
1666             wrapper = sinon.spy && sinon.spy.create ? sinon.spy.create(func) : func;
 
1668             wrapper = stub.create();
 
1671         if (!object && !property) {
 
1672             return sinon.stub.create();
 
1675         if (!property && !!object && typeof object == "object") {
 
1676             for (var prop in object) {
 
1677                 if (typeof object[prop] === "function") {
 
1685         return sinon.wrapMethod(object, property, wrapper);
 
1688     function getChangingValue(stub, property) {
 
1689         var index = stub.callCount - 1;
 
1690         var values = stub[property];
 
1691         var prop = index in values ? values[index] : values[values.length - 1];
 
1692         stub[property + "Last"] = prop;
 
1697     function getCallback(stub, args) {
 
1698         var callArgAt = getChangingValue(stub, "callArgAts");
 
1700         if (callArgAt < 0) {
 
1701             var callArgProp = getChangingValue(stub, "callArgProps");
 
1703             for (var i = 0, l = args.length; i < l; ++i) {
 
1704                 if (!callArgProp && typeof args[i] == "function") {
 
1708                 if (callArgProp && args[i] &&
 
1709                     typeof args[i][callArgProp] == "function") {
 
1710                     return args[i][callArgProp];
 
1717         return args[callArgAt];
 
1720     var join = Array.prototype.join;
 
1722     function getCallbackError(stub, func, args) {
 
1723         if (stub.callArgAtsLast < 0) {
 
1726             if (stub.callArgPropsLast) {
 
1727                 msg = sinon.functionName(stub) +
 
1728                     " expected to yield to '" + stub.callArgPropsLast +
 
1729                     "', but no object with such a property was passed."
 
1731                 msg = sinon.functionName(stub) +
 
1732                             " expected to yield, but no callback was passed."
 
1735             if (args.length > 0) {
 
1736                 msg += " Received [" + join.call(args, ", ") + "]";
 
1742         return "argument at index " + stub.callArgAtsLast + " is not a function: " + func;
 
1745     var nextTick = (function () {
 
1746         if (typeof process === "object" && typeof process.nextTick === "function") {
 
1747             return process.nextTick;
 
1748         } else if (typeof setImmediate === "function") {
 
1749             return setImmediate;
 
1751             return function (callback) {
 
1752                 setTimeout(callback, 0);
 
1757     function callCallback(stub, args) {
 
1758         if (stub.callArgAts.length > 0) {
 
1759             var func = getCallback(stub, args);
 
1761             if (typeof func != "function") {
 
1762                 throw new TypeError(getCallbackError(stub, func, args));
 
1765             var callbackArguments = getChangingValue(stub, "callbackArguments");
 
1766             var callbackContext = getChangingValue(stub, "callbackContexts");
 
1768             if (stub.callbackAsync) {
 
1769                 nextTick(function() {
 
1770                     func.apply(callbackContext, callbackArguments);
 
1773                 func.apply(callbackContext, callbackArguments);
 
1780     sinon.extend(stub, (function () {
 
1781         var slice = Array.prototype.slice, proto;
 
1783         function throwsException(error, message) {
 
1784             if (typeof error == "string") {
 
1785                 this.exception = new Error(message || "");
 
1786                 this.exception.name = error;
 
1787             } else if (!error) {
 
1788                 this.exception = new Error("Error");
 
1790                 this.exception = error;
 
1797             create: function create() {
 
1798                 var functionStub = function () {
 
1800                     callCallback(functionStub, arguments);
 
1802                     if (functionStub.exception) {
 
1803                         throw functionStub.exception;
 
1804                     } else if (typeof functionStub.returnArgAt == 'number') {
 
1805                         return arguments[functionStub.returnArgAt];
 
1806                     } else if (functionStub.returnThis) {
 
1809                     return functionStub.returnValue;
 
1812                 functionStub.id = "stub#" + uuid++;
 
1813                 var orig = functionStub;
 
1814                 functionStub = sinon.spy.create(functionStub);
 
1815                 functionStub.func = orig;
 
1817                 functionStub.callArgAts = [];
 
1818                 functionStub.callbackArguments = [];
 
1819                 functionStub.callbackContexts = [];
 
1820                 functionStub.callArgProps = [];
 
1822                 sinon.extend(functionStub, stub);
 
1823                 functionStub._create = sinon.stub.create;
 
1824                 functionStub.displayName = "stub";
 
1825                 functionStub.toString = sinon.functionToString;
 
1827                 return functionStub;
 
1830             resetBehavior: function () {
 
1833                 this.callArgAts = [];
 
1834                 this.callbackArguments = [];
 
1835                 this.callbackContexts = [];
 
1836                 this.callArgProps = [];
 
1838                 delete this.returnValue;
 
1839                 delete this.returnArgAt;
 
1840                 this.returnThis = false;
 
1843                     for (i = 0; i < this.fakes.length; i++) {
 
1844                         this.fakes[i].resetBehavior();
 
1849             returns: function returns(value) {
 
1850                 this.returnValue = value;
 
1855             returnsArg: function returnsArg(pos) {
 
1856                 if (typeof pos != "number") {
 
1857                     throw new TypeError("argument index is not number");
 
1860                 this.returnArgAt = pos;
 
1865             returnsThis: function returnsThis() {
 
1866                 this.returnThis = true;
 
1871             "throws": throwsException,
 
1872             throwsException: throwsException,
 
1874             callsArg: function callsArg(pos) {
 
1875                 if (typeof pos != "number") {
 
1876                     throw new TypeError("argument index is not number");
 
1879                 this.callArgAts.push(pos);
 
1880                 this.callbackArguments.push([]);
 
1881                 this.callbackContexts.push(undefined);
 
1882                 this.callArgProps.push(undefined);
 
1887             callsArgOn: function callsArgOn(pos, context) {
 
1888                 if (typeof pos != "number") {
 
1889                     throw new TypeError("argument index is not number");
 
1891                 if (typeof context != "object") {
 
1892                     throw new TypeError("argument context is not an object");
 
1895                 this.callArgAts.push(pos);
 
1896                 this.callbackArguments.push([]);
 
1897                 this.callbackContexts.push(context);
 
1898                 this.callArgProps.push(undefined);
 
1903             callsArgWith: function callsArgWith(pos) {
 
1904                 if (typeof pos != "number") {
 
1905                     throw new TypeError("argument index is not number");
 
1908                 this.callArgAts.push(pos);
 
1909                 this.callbackArguments.push(slice.call(arguments, 1));
 
1910                 this.callbackContexts.push(undefined);
 
1911                 this.callArgProps.push(undefined);
 
1916             callsArgOnWith: function callsArgWith(pos, context) {
 
1917                 if (typeof pos != "number") {
 
1918                     throw new TypeError("argument index is not number");
 
1920                 if (typeof context != "object") {
 
1921                     throw new TypeError("argument context is not an object");
 
1924                 this.callArgAts.push(pos);
 
1925                 this.callbackArguments.push(slice.call(arguments, 2));
 
1926                 this.callbackContexts.push(context);
 
1927                 this.callArgProps.push(undefined);
 
1932             yields: function () {
 
1933                 this.callArgAts.push(-1);
 
1934                 this.callbackArguments.push(slice.call(arguments, 0));
 
1935                 this.callbackContexts.push(undefined);
 
1936                 this.callArgProps.push(undefined);
 
1941             yieldsOn: function (context) {
 
1942                 if (typeof context != "object") {
 
1943                     throw new TypeError("argument context is not an object");
 
1946                 this.callArgAts.push(-1);
 
1947                 this.callbackArguments.push(slice.call(arguments, 1));
 
1948                 this.callbackContexts.push(context);
 
1949                 this.callArgProps.push(undefined);
 
1954             yieldsTo: function (prop) {
 
1955                 this.callArgAts.push(-1);
 
1956                 this.callbackArguments.push(slice.call(arguments, 1));
 
1957                 this.callbackContexts.push(undefined);
 
1958                 this.callArgProps.push(prop);
 
1963             yieldsToOn: function (prop, context) {
 
1964                 if (typeof context != "object") {
 
1965                     throw new TypeError("argument context is not an object");
 
1968                 this.callArgAts.push(-1);
 
1969                 this.callbackArguments.push(slice.call(arguments, 2));
 
1970                 this.callbackContexts.push(context);
 
1971                 this.callArgProps.push(prop);
 
1977         // create asynchronous versions of callsArg* and yields* methods
 
1978         for (var method in proto) {
 
1979             // need to avoid creating anotherasync versions of the newly added async methods
 
1980             if (proto.hasOwnProperty(method) &&
 
1981                 method.match(/^(callsArg|yields|thenYields$)/) &&
 
1982                 !method.match(/Async/)) {
 
1983                 proto[method + 'Async'] = (function (syncFnName) {
 
1984                     return function () {
 
1985                         this.callbackAsync = true;
 
1986                         return this[syncFnName].apply(this, arguments);
 
1996     if (commonJSModule) {
 
1997         module.exports = stub;
 
2001 }(typeof sinon == "object" && sinon || null));
 
2004  * @depend ../sinon.js
 
2007 /*jslint eqeqeq: false, onevar: false, nomen: false*/
 
2008 /*global module, require, sinon*/
 
2012  * @author Christian Johansen (christian@cjohansen.no)
 
2015  * Copyright (c) 2010-2013 Christian Johansen
 
2019     var commonJSModule = typeof module == "object" && typeof require == "function";
 
2022     if (!sinon && commonJSModule) {
 
2023         sinon = require("../sinon");
 
2030     function mock(object) {
 
2032             return sinon.expectation.create("Anonymous mock");
 
2035         return mock.create(object);
 
2040     sinon.extend(mock, (function () {
 
2041         function each(collection, callback) {
 
2046             for (var i = 0, l = collection.length; i < l; i += 1) {
 
2047                 callback(collection[i]);
 
2052             create: function create(object) {
 
2054                     throw new TypeError("object is null");
 
2057                 var mockObject = sinon.extend({}, mock);
 
2058                 mockObject.object = object;
 
2059                 delete mockObject.create;
 
2064             expects: function expects(method) {
 
2066                     throw new TypeError("method is falsy");
 
2069                 if (!this.expectations) {
 
2070                     this.expectations = {};
 
2074                 if (!this.expectations[method]) {
 
2075                     this.expectations[method] = [];
 
2076                     var mockObject = this;
 
2078                     sinon.wrapMethod(this.object, method, function () {
 
2079                         return mockObject.invokeMethod(method, this, arguments);
 
2082                     push.call(this.proxies, method);
 
2085                 var expectation = sinon.expectation.create(method);
 
2086                 push.call(this.expectations[method], expectation);
 
2091             restore: function restore() {
 
2092                 var object = this.object;
 
2094                 each(this.proxies, function (proxy) {
 
2095                     if (typeof object[proxy].restore == "function") {
 
2096                         object[proxy].restore();
 
2101             verify: function verify() {
 
2102                 var expectations = this.expectations || {};
 
2103                 var messages = [], met = [];
 
2105                 each(this.proxies, function (proxy) {
 
2106                     each(expectations[proxy], function (expectation) {
 
2107                         if (!expectation.met()) {
 
2108                             push.call(messages, expectation.toString());
 
2110                             push.call(met, expectation.toString());
 
2117                 if (messages.length > 0) {
 
2118                     sinon.expectation.fail(messages.concat(met).join("\n"));
 
2120                     sinon.expectation.pass(messages.concat(met).join("\n"));
 
2126             invokeMethod: function invokeMethod(method, thisValue, args) {
 
2127                 var expectations = this.expectations && this.expectations[method];
 
2128                 var length = expectations && expectations.length || 0, i;
 
2130                 for (i = 0; i < length; i += 1) {
 
2131                     if (!expectations[i].met() &&
 
2132                         expectations[i].allowsCall(thisValue, args)) {
 
2133                         return expectations[i].apply(thisValue, args);
 
2137                 var messages = [], available, exhausted = 0;
 
2139                 for (i = 0; i < length; i += 1) {
 
2140                     if (expectations[i].allowsCall(thisValue, args)) {
 
2141                         available = available || expectations[i];
 
2145                     push.call(messages, "    " + expectations[i].toString());
 
2148                 if (exhausted === 0) {
 
2149                     return available.apply(thisValue, args);
 
2152                 messages.unshift("Unexpected call: " + sinon.spyCall.toString.call({
 
2157                 sinon.expectation.fail(messages.join("\n"));
 
2162     var times = sinon.timesInWords;
 
2164     sinon.expectation = (function () {
 
2165         var slice = Array.prototype.slice;
 
2166         var _invoke = sinon.spy.invoke;
 
2168         function callCountInWords(callCount) {
 
2169             if (callCount == 0) {
 
2170                 return "never called";
 
2172                 return "called " + times(callCount);
 
2176         function expectedCallCountInWords(expectation) {
 
2177             var min = expectation.minCalls;
 
2178             var max = expectation.maxCalls;
 
2180             if (typeof min == "number" && typeof max == "number") {
 
2181                 var str = times(min);
 
2184                     str = "at least " + str + " and at most " + times(max);
 
2190             if (typeof min == "number") {
 
2191                 return "at least " + times(min);
 
2194             return "at most " + times(max);
 
2197         function receivedMinCalls(expectation) {
 
2198             var hasMinLimit = typeof expectation.minCalls == "number";
 
2199             return !hasMinLimit || expectation.callCount >= expectation.minCalls;
 
2202         function receivedMaxCalls(expectation) {
 
2203             if (typeof expectation.maxCalls != "number") {
 
2207             return expectation.callCount == expectation.maxCalls;
 
2214             create: function create(methodName) {
 
2215                 var expectation = sinon.extend(sinon.stub.create(), sinon.expectation);
 
2216                 delete expectation.create;
 
2217                 expectation.method = methodName;
 
2222             invoke: function invoke(func, thisValue, args) {
 
2223                 this.verifyCallAllowed(thisValue, args);
 
2225                 return _invoke.apply(this, arguments);
 
2228             atLeast: function atLeast(num) {
 
2229                 if (typeof num != "number") {
 
2230                     throw new TypeError("'" + num + "' is not number");
 
2233                 if (!this.limitsSet) {
 
2234                     this.maxCalls = null;
 
2235                     this.limitsSet = true;
 
2238                 this.minCalls = num;
 
2243             atMost: function atMost(num) {
 
2244                 if (typeof num != "number") {
 
2245                     throw new TypeError("'" + num + "' is not number");
 
2248                 if (!this.limitsSet) {
 
2249                     this.minCalls = null;
 
2250                     this.limitsSet = true;
 
2253                 this.maxCalls = num;
 
2258             never: function never() {
 
2259                 return this.exactly(0);
 
2262             once: function once() {
 
2263                 return this.exactly(1);
 
2266             twice: function twice() {
 
2267                 return this.exactly(2);
 
2270             thrice: function thrice() {
 
2271                 return this.exactly(3);
 
2274             exactly: function exactly(num) {
 
2275                 if (typeof num != "number") {
 
2276                     throw new TypeError("'" + num + "' is not a number");
 
2280                 return this.atMost(num);
 
2283             met: function met() {
 
2284                 return !this.failed && receivedMinCalls(this);
 
2287             verifyCallAllowed: function verifyCallAllowed(thisValue, args) {
 
2288                 if (receivedMaxCalls(this)) {
 
2290                     sinon.expectation.fail(this.method + " already called " + times(this.maxCalls));
 
2293                 if ("expectedThis" in this && this.expectedThis !== thisValue) {
 
2294                     sinon.expectation.fail(this.method + " called with " + thisValue + " as thisValue, expected " +
 
2298                 if (!("expectedArguments" in this)) {
 
2303                     sinon.expectation.fail(this.method + " received no arguments, expected " +
 
2304                         sinon.format(this.expectedArguments));
 
2307                 if (args.length < this.expectedArguments.length) {
 
2308                     sinon.expectation.fail(this.method + " received too few arguments (" + sinon.format(args) +
 
2309                         "), expected " + sinon.format(this.expectedArguments));
 
2312                 if (this.expectsExactArgCount &&
 
2313                     args.length != this.expectedArguments.length) {
 
2314                     sinon.expectation.fail(this.method + " received too many arguments (" + sinon.format(args) +
 
2315                         "), expected " + sinon.format(this.expectedArguments));
 
2318                 for (var i = 0, l = this.expectedArguments.length; i < l; i += 1) {
 
2319                     if (!sinon.deepEqual(this.expectedArguments[i], args[i])) {
 
2320                         sinon.expectation.fail(this.method + " received wrong arguments " + sinon.format(args) +
 
2321                             ", expected " + sinon.format(this.expectedArguments));
 
2326             allowsCall: function allowsCall(thisValue, args) {
 
2327                 if (this.met() && receivedMaxCalls(this)) {
 
2331                 if ("expectedThis" in this && this.expectedThis !== thisValue) {
 
2335                 if (!("expectedArguments" in this)) {
 
2341                 if (args.length < this.expectedArguments.length) {
 
2345                 if (this.expectsExactArgCount &&
 
2346                     args.length != this.expectedArguments.length) {
 
2350                 for (var i = 0, l = this.expectedArguments.length; i < l; i += 1) {
 
2351                     if (!sinon.deepEqual(this.expectedArguments[i], args[i])) {
 
2359             withArgs: function withArgs() {
 
2360                 this.expectedArguments = slice.call(arguments);
 
2364             withExactArgs: function withExactArgs() {
 
2365                 this.withArgs.apply(this, arguments);
 
2366                 this.expectsExactArgCount = true;
 
2370             on: function on(thisValue) {
 
2371                 this.expectedThis = thisValue;
 
2375             toString: function () {
 
2376                 var args = (this.expectedArguments || []).slice();
 
2378                 if (!this.expectsExactArgCount) {
 
2379                     push.call(args, "[...]");
 
2382                 var callStr = sinon.spyCall.toString.call({
 
2383                     proxy: this.method || "anonymous mock expectation",
 
2387                 var message = callStr.replace(", [...", "[, ...") + " " +
 
2388                     expectedCallCountInWords(this);
 
2391                     return "Expectation met: " + message;
 
2394                 return "Expected " + message + " (" +
 
2395                     callCountInWords(this.callCount) + ")";
 
2398             verify: function verify() {
 
2400                     sinon.expectation.fail(this.toString());
 
2402                     sinon.expectation.pass(this.toString());
 
2408             pass: function(message) {
 
2409               sinon.assert.pass(message);
 
2411             fail: function (message) {
 
2412                 var exception = new Error(message);
 
2413                 exception.name = "ExpectationError";
 
2420     if (commonJSModule) {
 
2421         module.exports = mock;
 
2425 }(typeof sinon == "object" && sinon || null));
 
2428  * @depend ../sinon.js
 
2432 /*jslint eqeqeq: false, onevar: false, forin: true*/
 
2433 /*global module, require, sinon*/
 
2435  * Collections of stubs, spies and mocks.
 
2437  * @author Christian Johansen (christian@cjohansen.no)
 
2440  * Copyright (c) 2010-2013 Christian Johansen
 
2444     var commonJSModule = typeof module == "object" && typeof require == "function";
 
2446     var hasOwnProperty = Object.prototype.hasOwnProperty;
 
2448     if (!sinon && commonJSModule) {
 
2449         sinon = require("../sinon");
 
2456     function getFakes(fakeCollection) {
 
2457         if (!fakeCollection.fakes) {
 
2458             fakeCollection.fakes = [];
 
2461         return fakeCollection.fakes;
 
2464     function each(fakeCollection, method) {
 
2465         var fakes = getFakes(fakeCollection);
 
2467         for (var i = 0, l = fakes.length; i < l; i += 1) {
 
2468             if (typeof fakes[i][method] == "function") {
 
2474     function compact(fakeCollection) {
 
2475         var fakes = getFakes(fakeCollection);
 
2477         while (i < fakes.length) {
 
2483         verify: function resolve() {
 
2484             each(this, "verify");
 
2487         restore: function restore() {
 
2488             each(this, "restore");
 
2492         verifyAndRestore: function verifyAndRestore() {
 
2508         add: function add(fake) {
 
2509             push.call(getFakes(this), fake);
 
2513         spy: function spy() {
 
2514             return this.add(sinon.spy.apply(sinon, arguments));
 
2517         stub: function stub(object, property, value) {
 
2519                 var original = object[property];
 
2521                 if (typeof original != "function") {
 
2522                     if (!hasOwnProperty.call(object, property)) {
 
2523                         throw new TypeError("Cannot stub non-existent own property " + property);
 
2526                     object[property] = value;
 
2529                         restore: function () {
 
2530                             object[property] = original;
 
2535             if (!property && !!object && typeof object == "object") {
 
2536                 var stubbedObj = sinon.stub.apply(sinon, arguments);
 
2538                 for (var prop in stubbedObj) {
 
2539                     if (typeof stubbedObj[prop] === "function") {
 
2540                         this.add(stubbedObj[prop]);
 
2547             return this.add(sinon.stub.apply(sinon, arguments));
 
2550         mock: function mock() {
 
2551             return this.add(sinon.mock.apply(sinon, arguments));
 
2554         inject: function inject(obj) {
 
2557             obj.spy = function () {
 
2558                 return col.spy.apply(col, arguments);
 
2561             obj.stub = function () {
 
2562                 return col.stub.apply(col, arguments);
 
2565             obj.mock = function () {
 
2566                 return col.mock.apply(col, arguments);
 
2573     if (commonJSModule) {
 
2574         module.exports = collection;
 
2576         sinon.collection = collection;
 
2578 }(typeof sinon == "object" && sinon || null));
 
2580 /*jslint eqeqeq: false, plusplus: false, evil: true, onevar: false, browser: true, forin: false*/
 
2581 /*global module, require, window*/
 
2592  * Inspired by jsUnitMockTimeOut from JsUnit
 
2594  * @author Christian Johansen (christian@cjohansen.no)
 
2597  * Copyright (c) 2010-2013 Christian Johansen
 
2600 if (typeof sinon == "undefined") {
 
2604 (function (global) {
 
2607     function addTimer(args, recurring) {
 
2608         if (args.length === 0) {
 
2609             throw new Error("Function requires at least 1 parameter");
 
2613         var delay = args[1] || 0;
 
2615         if (!this.timeouts) {
 
2619         this.timeouts[toId] = {
 
2622             callAt: this.now + delay,
 
2623             invokeArgs: Array.prototype.slice.call(args, 2)
 
2626         if (recurring === true) {
 
2627             this.timeouts[toId].interval = delay;
 
2633     function parseTime(str) {
 
2638         var strings = str.split(":");
 
2639         var l = strings.length, i = l;
 
2642         if (l > 3 || !/^(\d\d:){0,2}\d\d?$/.test(str)) {
 
2643             throw new Error("tick only understands numbers and 'h:m:s'");
 
2647             parsed = parseInt(strings[i], 10);
 
2650                 throw new Error("Invalid time " + str);
 
2653             ms += parsed * Math.pow(60, (l - i - 1));
 
2659     function createObject(object) {
 
2662         if (Object.create) {
 
2663             newObject = Object.create(object);
 
2665             var F = function () {};
 
2666             F.prototype = object;
 
2667             newObject = new F();
 
2670         newObject.Date.clock = newObject;
 
2677         create: function create(now) {
 
2678             var clock = createObject(this);
 
2680             if (typeof now == "number") {
 
2684             if (!!now && typeof now == "object") {
 
2685                 throw new TypeError("now should be milliseconds since UNIX epoch");
 
2691         setTimeout: function setTimeout(callback, timeout) {
 
2692             return addTimer.call(this, arguments, false);
 
2695         clearTimeout: function clearTimeout(timerId) {
 
2696             if (!this.timeouts) {
 
2700             if (timerId in this.timeouts) {
 
2701                 delete this.timeouts[timerId];
 
2705         setInterval: function setInterval(callback, timeout) {
 
2706             return addTimer.call(this, arguments, true);
 
2709         clearInterval: function clearInterval(timerId) {
 
2710             this.clearTimeout(timerId);
 
2713         tick: function tick(ms) {
 
2714             ms = typeof ms == "number" ? ms : parseTime(ms);
 
2715             var tickFrom = this.now, tickTo = this.now + ms, previous = this.now;
 
2716             var timer = this.firstTimerInRange(tickFrom, tickTo);
 
2719             while (timer && tickFrom <= tickTo) {
 
2720                 if (this.timeouts[timer.id]) {
 
2721                     tickFrom = this.now = timer.callAt;
 
2723                       this.callTimer(timer);
 
2725                       firstException = firstException || e;
 
2729                 timer = this.firstTimerInRange(previous, tickTo);
 
2730                 previous = tickFrom;
 
2735             if (firstException) {
 
2736               throw firstException;
 
2742         firstTimerInRange: function (from, to) {
 
2743             var timer, smallest, originalTimer;
 
2745             for (var id in this.timeouts) {
 
2746                 if (this.timeouts.hasOwnProperty(id)) {
 
2747                     if (this.timeouts[id].callAt < from || this.timeouts[id].callAt > to) {
 
2751                     if (!smallest || this.timeouts[id].callAt < smallest) {
 
2752                         originalTimer = this.timeouts[id];
 
2753                         smallest = this.timeouts[id].callAt;
 
2756                             func: this.timeouts[id].func,
 
2757                             callAt: this.timeouts[id].callAt,
 
2758                             interval: this.timeouts[id].interval,
 
2759                             id: this.timeouts[id].id,
 
2760                             invokeArgs: this.timeouts[id].invokeArgs
 
2766             return timer || null;
 
2769         callTimer: function (timer) {
 
2770             if (typeof timer.interval == "number") {
 
2771                 this.timeouts[timer.id].callAt += timer.interval;
 
2773                 delete this.timeouts[timer.id];
 
2777                 if (typeof timer.func == "function") {
 
2778                     timer.func.apply(null, timer.invokeArgs);
 
2786             if (!this.timeouts[timer.id]) {
 
2798         reset: function reset() {
 
2802         Date: (function () {
 
2803             var NativeDate = Date;
 
2805             function ClockDate(year, month, date, hour, minute, second, ms) {
 
2806                 // Defensive and verbose to avoid potential harm in passing
 
2807                 // explicit undefined when user does not pass argument
 
2808                 switch (arguments.length) {
 
2810                     return new NativeDate(ClockDate.clock.now);
 
2812                     return new NativeDate(year);
 
2814                     return new NativeDate(year, month);
 
2816                     return new NativeDate(year, month, date);
 
2818                     return new NativeDate(year, month, date, hour);
 
2820                     return new NativeDate(year, month, date, hour, minute);
 
2822                     return new NativeDate(year, month, date, hour, minute, second);
 
2824                     return new NativeDate(year, month, date, hour, minute, second, ms);
 
2828             return mirrorDateProperties(ClockDate, NativeDate);
 
2832     function mirrorDateProperties(target, source) {
 
2834             target.now = function now() {
 
2835                 return target.clock.now;
 
2841         if (source.toSource) {
 
2842             target.toSource = function toSource() {
 
2843                 return source.toSource();
 
2846             delete target.toSource;
 
2849         target.toString = function toString() {
 
2850             return source.toString();
 
2853         target.prototype = source.prototype;
 
2854         target.parse = source.parse;
 
2855         target.UTC = source.UTC;
 
2856         target.prototype.toUTCString = source.prototype.toUTCString;
 
2860     var methods = ["Date", "setTimeout", "setInterval",
 
2861                    "clearTimeout", "clearInterval"];
 
2863     function restore() {
 
2866         for (var i = 0, l = this.methods.length; i < l; i++) {
 
2867             method = this.methods[i];
 
2868             if (global[method].hadOwnProperty) {
 
2869                 global[method] = this["_" + method];
 
2871                 delete global[method];
 
2875         // Prevent multiple executions which will completely remove these props
 
2879     function stubGlobal(method, clock) {
 
2880         clock[method].hadOwnProperty = Object.prototype.hasOwnProperty.call(global, method);
 
2881         clock["_" + method] = global[method];
 
2883         if (method == "Date") {
 
2884             var date = mirrorDateProperties(clock[method], global[method]);
 
2885             global[method] = date;
 
2887             global[method] = function () {
 
2888                 return clock[method].apply(clock, arguments);
 
2891             for (var prop in clock[method]) {
 
2892                 if (clock[method].hasOwnProperty(prop)) {
 
2893                     global[method][prop] = clock[method][prop];
 
2898         global[method].clock = clock;
 
2901     sinon.useFakeTimers = function useFakeTimers(now) {
 
2902         var clock = sinon.clock.create(now);
 
2903         clock.restore = restore;
 
2904         clock.methods = Array.prototype.slice.call(arguments,
 
2905                                                    typeof now == "number" ? 1 : 0);
 
2907         if (clock.methods.length === 0) {
 
2908             clock.methods = methods;
 
2911         for (var i = 0, l = clock.methods.length; i < l; i++) {
 
2912             stubGlobal(clock.methods[i], clock);
 
2917 }(typeof global != "undefined" && typeof global !== "function" ? global : this));
 
2920     setTimeout: setTimeout,
 
2921     clearTimeout: clearTimeout,
 
2922     setInterval: setInterval,
 
2923     clearInterval: clearInterval,
 
2927 if (typeof module == "object" && typeof require == "function") {
 
2928     module.exports = sinon;
 
2931 /*jslint eqeqeq: false, onevar: false*/
 
2932 /*global sinon, module, require, ActiveXObject, XMLHttpRequest, DOMParser*/
 
2934  * Minimal Event interface implementation
 
2936  * Original implementation by Sven Fuchs: https://gist.github.com/995028
 
2937  * Modifications and tests by Christian Johansen.
 
2939  * @author Sven Fuchs (svenfuchs@artweb-design.de)
 
2940  * @author Christian Johansen (christian@cjohansen.no)
 
2943  * Copyright (c) 2011 Sven Fuchs, Christian Johansen
 
2946 if (typeof sinon == "undefined") {
 
2953     sinon.Event = function Event(type, bubbles, cancelable, target) {
 
2954         this.initEvent(type, bubbles, cancelable, target);
 
2957     sinon.Event.prototype = {
 
2958         initEvent: function(type, bubbles, cancelable, target) {
 
2960             this.bubbles = bubbles;
 
2961             this.cancelable = cancelable;
 
2962             this.target = target;
 
2965         stopPropagation: function () {},
 
2967         preventDefault: function () {
 
2968             this.defaultPrevented = true;
 
2972     sinon.EventTarget = {
 
2973         addEventListener: function addEventListener(event, listener, useCapture) {
 
2974             this.eventListeners = this.eventListeners || {};
 
2975             this.eventListeners[event] = this.eventListeners[event] || [];
 
2976             push.call(this.eventListeners[event], listener);
 
2979         removeEventListener: function removeEventListener(event, listener, useCapture) {
 
2980             var listeners = this.eventListeners && this.eventListeners[event] || [];
 
2982             for (var i = 0, l = listeners.length; i < l; ++i) {
 
2983                 if (listeners[i] == listener) {
 
2984                     return listeners.splice(i, 1);
 
2989         dispatchEvent: function dispatchEvent(event) {
 
2990             var type = event.type;
 
2991             var listeners = this.eventListeners && this.eventListeners[type] || [];
 
2993             for (var i = 0; i < listeners.length; i++) {
 
2994                 if (typeof listeners[i] == "function") {
 
2995                     listeners[i].call(this, event);
 
2997                     listeners[i].handleEvent(event);
 
3001             return !!event.defaultPrevented;
 
3007  * @depend ../../sinon.js
 
3010 /*jslint eqeqeq: false, onevar: false*/
 
3011 /*global sinon, module, require, ActiveXObject, XMLHttpRequest, DOMParser*/
 
3013  * Fake XMLHttpRequest object
 
3015  * @author Christian Johansen (christian@cjohansen.no)
 
3018  * Copyright (c) 2010-2013 Christian Johansen
 
3021 if (typeof sinon == "undefined") {
 
3024 sinon.xhr = { XMLHttpRequest: this.XMLHttpRequest };
 
3026 // wrapper for global
 
3028     var xhr = sinon.xhr;
 
3029     xhr.GlobalXMLHttpRequest = global.XMLHttpRequest;
 
3030     xhr.GlobalActiveXObject = global.ActiveXObject;
 
3031     xhr.supportsActiveX = typeof xhr.GlobalActiveXObject != "undefined";
 
3032     xhr.supportsXHR = typeof xhr.GlobalXMLHttpRequest != "undefined";
 
3033     xhr.workingXHR = xhr.supportsXHR ? xhr.GlobalXMLHttpRequest : xhr.supportsActiveX
 
3034                                      ? function() { return new xhr.GlobalActiveXObject("MSXML2.XMLHTTP.3.0") } : false;
 
3037     var unsafeHeaders = {
 
3038         "Accept-Charset": true,
 
3039         "Accept-Encoding": true,
 
3041         "Content-Length": true,
 
3044         "Content-Transfer-Encoding": true,
 
3052         "Transfer-Encoding": true,
 
3059     function FakeXMLHttpRequest() {
 
3060         this.readyState = FakeXMLHttpRequest.UNSENT;
 
3061         this.requestHeaders = {};
 
3062         this.requestBody = null;
 
3064         this.statusText = "";
 
3067         var events = ["loadstart", "load", "abort", "loadend"];
 
3069         function addEventListener(eventName) {
 
3070             xhr.addEventListener(eventName, function (event) {
 
3071                 var listener = xhr["on" + eventName];
 
3073                 if (listener && typeof listener == "function") {
 
3079         for (var i = events.length - 1; i >= 0; i--) {
 
3080             addEventListener(events[i]);
 
3083         if (typeof FakeXMLHttpRequest.onCreate == "function") {
 
3084             FakeXMLHttpRequest.onCreate(this);
 
3088     function verifyState(xhr) {
 
3089         if (xhr.readyState !== FakeXMLHttpRequest.OPENED) {
 
3090             throw new Error("INVALID_STATE_ERR");
 
3094             throw new Error("INVALID_STATE_ERR");
 
3098     // filtering to enable a white-list version of Sinon FakeXhr,
 
3099     // where whitelisted requests are passed through to real XHR
 
3100     function each(collection, callback) {
 
3101         if (!collection) return;
 
3102         for (var i = 0, l = collection.length; i < l; i += 1) {
 
3103             callback(collection[i]);
 
3106     function some(collection, callback) {
 
3107         for (var index = 0; index < collection.length; index++) {
 
3108             if(callback(collection[index]) === true) return true;
 
3112     // largest arity in XHR is 5 - XHR#open
 
3113     var apply = function(obj,method,args) {
 
3114         switch(args.length) {
 
3115         case 0: return obj[method]();
 
3116         case 1: return obj[method](args[0]);
 
3117         case 2: return obj[method](args[0],args[1]);
 
3118         case 3: return obj[method](args[0],args[1],args[2]);
 
3119         case 4: return obj[method](args[0],args[1],args[2],args[3]);
 
3120         case 5: return obj[method](args[0],args[1],args[2],args[3],args[4]);
 
3124     FakeXMLHttpRequest.filters = [];
 
3125     FakeXMLHttpRequest.addFilter = function(fn) {
 
3126         this.filters.push(fn)
 
3128     var IE6Re = /MSIE 6/;
 
3129     FakeXMLHttpRequest.defake = function(fakeXhr,xhrArgs) {
 
3130         var xhr = new sinon.xhr.workingXHR();
 
3131         each(["open","setRequestHeader","send","abort","getResponseHeader",
 
3132               "getAllResponseHeaders","addEventListener","overrideMimeType","removeEventListener"],
 
3134                  fakeXhr[method] = function() {
 
3135                    return apply(xhr,method,arguments);
 
3139         var copyAttrs = function(args) {
 
3140             each(args, function(attr) {
 
3142                 fakeXhr[attr] = xhr[attr]
 
3144                 if(!IE6Re.test(navigator.userAgent)) throw e;
 
3149         var stateChange = function() {
 
3150             fakeXhr.readyState = xhr.readyState;
 
3151             if(xhr.readyState >= FakeXMLHttpRequest.HEADERS_RECEIVED) {
 
3152                 copyAttrs(["status","statusText"]);
 
3154             if(xhr.readyState >= FakeXMLHttpRequest.LOADING) {
 
3155                 copyAttrs(["responseText"]);
 
3157             if(xhr.readyState === FakeXMLHttpRequest.DONE) {
 
3158                 copyAttrs(["responseXML"]);
 
3160             if(fakeXhr.onreadystatechange) fakeXhr.onreadystatechange.call(fakeXhr);
 
3162         if(xhr.addEventListener) {
 
3163           for(var event in fakeXhr.eventListeners) {
 
3164               if(fakeXhr.eventListeners.hasOwnProperty(event)) {
 
3165                   each(fakeXhr.eventListeners[event],function(handler) {
 
3166                       xhr.addEventListener(event, handler);
 
3170           xhr.addEventListener("readystatechange",stateChange);
 
3172           xhr.onreadystatechange = stateChange;
 
3174         apply(xhr,"open",xhrArgs);
 
3176     FakeXMLHttpRequest.useFilters = false;
 
3178     function verifyRequestSent(xhr) {
 
3179         if (xhr.readyState == FakeXMLHttpRequest.DONE) {
 
3180             throw new Error("Request done");
 
3184     function verifyHeadersReceived(xhr) {
 
3185         if (xhr.async && xhr.readyState != FakeXMLHttpRequest.HEADERS_RECEIVED) {
 
3186             throw new Error("No headers received");
 
3190     function verifyResponseBodyType(body) {
 
3191         if (typeof body != "string") {
 
3192             var error = new Error("Attempted to respond to fake XMLHttpRequest with " +
 
3193                                  body + ", which is not a string.");
 
3194             error.name = "InvalidBodyException";
 
3199     sinon.extend(FakeXMLHttpRequest.prototype, sinon.EventTarget, {
 
3202         open: function open(method, url, async, username, password) {
 
3203             this.method = method;
 
3205             this.async = typeof async == "boolean" ? async : true;
 
3206             this.username = username;
 
3207             this.password = password;
 
3208             this.responseText = null;
 
3209             this.responseXML = null;
 
3210             this.requestHeaders = {};
 
3211             this.sendFlag = false;
 
3212             if(sinon.FakeXMLHttpRequest.useFilters === true) {
 
3213                 var xhrArgs = arguments;
 
3214                 var defake = some(FakeXMLHttpRequest.filters,function(filter) {
 
3215                     return filter.apply(this,xhrArgs)
 
3218                   return sinon.FakeXMLHttpRequest.defake(this,arguments);
 
3221             this.readyStateChange(FakeXMLHttpRequest.OPENED);
 
3224         readyStateChange: function readyStateChange(state) {
 
3225             this.readyState = state;
 
3227             if (typeof this.onreadystatechange == "function") {
 
3229                     this.onreadystatechange();
 
3231                     sinon.logError("Fake XHR onreadystatechange handler", e);
 
3235             this.dispatchEvent(new sinon.Event("readystatechange"));
 
3237             switch (this.readyState) {
 
3238                 case FakeXMLHttpRequest.DONE:
 
3239                     this.dispatchEvent(new sinon.Event("load", false, false, this));
 
3240                     this.dispatchEvent(new sinon.Event("loadend", false, false, this));
 
3245         setRequestHeader: function setRequestHeader(header, value) {
 
3248             if (unsafeHeaders[header] || /^(Sec-|Proxy-)/.test(header)) {
 
3249                 throw new Error("Refused to set unsafe header \"" + header + "\"");
 
3252             if (this.requestHeaders[header]) {
 
3253                 this.requestHeaders[header] += "," + value;
 
3255                 this.requestHeaders[header] = value;
 
3260         setResponseHeaders: function setResponseHeaders(headers) {
 
3261             this.responseHeaders = {};
 
3263             for (var header in headers) {
 
3264                 if (headers.hasOwnProperty(header)) {
 
3265                     this.responseHeaders[header] = headers[header];
 
3270                 this.readyStateChange(FakeXMLHttpRequest.HEADERS_RECEIVED);
 
3272                 this.readyState = FakeXMLHttpRequest.HEADERS_RECEIVED;
 
3276         // Currently treats ALL data as a DOMString (i.e. no Document)
 
3277         send: function send(data) {
 
3280             if (!/^(get|head)$/i.test(this.method)) {
 
3281                 if (this.requestHeaders["Content-Type"]) {
 
3282                     var value = this.requestHeaders["Content-Type"].split(";");
 
3283                     this.requestHeaders["Content-Type"] = value[0] + ";charset=utf-8";
 
3285                     this.requestHeaders["Content-Type"] = "text/plain;charset=utf-8";
 
3288                 this.requestBody = data;
 
3291             this.errorFlag = false;
 
3292             this.sendFlag = this.async;
 
3293             this.readyStateChange(FakeXMLHttpRequest.OPENED);
 
3295             if (typeof this.onSend == "function") {
 
3299             this.dispatchEvent(new sinon.Event("loadstart", false, false, this));
 
3302         abort: function abort() {
 
3303             this.aborted = true;
 
3304             this.responseText = null;
 
3305             this.errorFlag = true;
 
3306             this.requestHeaders = {};
 
3308             if (this.readyState > sinon.FakeXMLHttpRequest.UNSENT && this.sendFlag) {
 
3309                 this.readyStateChange(sinon.FakeXMLHttpRequest.DONE);
 
3310                 this.sendFlag = false;
 
3313             this.readyState = sinon.FakeXMLHttpRequest.UNSENT;
 
3315             this.dispatchEvent(new sinon.Event("abort", false, false, this));
 
3316             if (typeof this.onerror === "function") {
 
3321         getResponseHeader: function getResponseHeader(header) {
 
3322             if (this.readyState < FakeXMLHttpRequest.HEADERS_RECEIVED) {
 
3326             if (/^Set-Cookie2?$/i.test(header)) {
 
3330             header = header.toLowerCase();
 
3332             for (var h in this.responseHeaders) {
 
3333                 if (h.toLowerCase() == header) {
 
3334                     return this.responseHeaders[h];
 
3341         getAllResponseHeaders: function getAllResponseHeaders() {
 
3342             if (this.readyState < FakeXMLHttpRequest.HEADERS_RECEIVED) {
 
3348             for (var header in this.responseHeaders) {
 
3349                 if (this.responseHeaders.hasOwnProperty(header) &&
 
3350                     !/^Set-Cookie2?$/i.test(header)) {
 
3351                     headers += header + ": " + this.responseHeaders[header] + "\r\n";
 
3358         setResponseBody: function setResponseBody(body) {
 
3359             verifyRequestSent(this);
 
3360             verifyHeadersReceived(this);
 
3361             verifyResponseBodyType(body);
 
3363             var chunkSize = this.chunkSize || 10;
 
3365             this.responseText = "";
 
3369                     this.readyStateChange(FakeXMLHttpRequest.LOADING);
 
3372                 this.responseText += body.substring(index, index + chunkSize);
 
3374             } while (index < body.length);
 
3376             var type = this.getResponseHeader("Content-Type");
 
3378             if (this.responseText &&
 
3379                 (!type || /(text\/xml)|(application\/xml)|(\+xml)/.test(type))) {
 
3381                     this.responseXML = FakeXMLHttpRequest.parseXML(this.responseText);
 
3383                     // Unable to parse XML - no biggie
 
3388                 this.readyStateChange(FakeXMLHttpRequest.DONE);
 
3390                 this.readyState = FakeXMLHttpRequest.DONE;
 
3394         respond: function respond(status, headers, body) {
 
3395             this.setResponseHeaders(headers || {});
 
3396             this.status = typeof status == "number" ? status : 200;
 
3397             this.statusText = FakeXMLHttpRequest.statusCodes[this.status];
 
3398             this.setResponseBody(body || "");
 
3399             if (typeof this.onload === "function"){
 
3406     sinon.extend(FakeXMLHttpRequest, {
 
3409         HEADERS_RECEIVED: 2,
 
3414     // Borrowed from JSpec
 
3415     FakeXMLHttpRequest.parseXML = function parseXML(text) {
 
3418         if (typeof DOMParser != "undefined") {
 
3419             var parser = new DOMParser();
 
3420             xmlDoc = parser.parseFromString(text, "text/xml");
 
3422             xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
 
3423             xmlDoc.async = "false";
 
3424             xmlDoc.loadXML(text);
 
3430     FakeXMLHttpRequest.statusCodes = {
 
3432         101: "Switching Protocols",
 
3436         203: "Non-Authoritative Information",
 
3438         205: "Reset Content",
 
3439         206: "Partial Content",
 
3440         300: "Multiple Choice",
 
3441         301: "Moved Permanently",
 
3444         304: "Not Modified",
 
3446         307: "Temporary Redirect",
 
3448         401: "Unauthorized",
 
3449         402: "Payment Required",
 
3452         405: "Method Not Allowed",
 
3453         406: "Not Acceptable",
 
3454         407: "Proxy Authentication Required",
 
3455         408: "Request Timeout",
 
3458         411: "Length Required",
 
3459         412: "Precondition Failed",
 
3460         413: "Request Entity Too Large",
 
3461         414: "Request-URI Too Long",
 
3462         415: "Unsupported Media Type",
 
3463         416: "Requested Range Not Satisfiable",
 
3464         417: "Expectation Failed",
 
3465         422: "Unprocessable Entity",
 
3466         500: "Internal Server Error",
 
3467         501: "Not Implemented",
 
3469         503: "Service Unavailable",
 
3470         504: "Gateway Timeout",
 
3471         505: "HTTP Version Not Supported"
 
3474     sinon.useFakeXMLHttpRequest = function () {
 
3475         sinon.FakeXMLHttpRequest.restore = function restore(keepOnCreate) {
 
3476             if (xhr.supportsXHR) {
 
3477                 global.XMLHttpRequest = xhr.GlobalXMLHttpRequest;
 
3480             if (xhr.supportsActiveX) {
 
3481                 global.ActiveXObject = xhr.GlobalActiveXObject;
 
3484             delete sinon.FakeXMLHttpRequest.restore;
 
3486             if (keepOnCreate !== true) {
 
3487                 delete sinon.FakeXMLHttpRequest.onCreate;
 
3490         if (xhr.supportsXHR) {
 
3491             global.XMLHttpRequest = sinon.FakeXMLHttpRequest;
 
3494         if (xhr.supportsActiveX) {
 
3495             global.ActiveXObject = function ActiveXObject(objId) {
 
3496                 if (objId == "Microsoft.XMLHTTP" || /^Msxml2\.XMLHTTP/i.test(objId)) {
 
3498                     return new sinon.FakeXMLHttpRequest();
 
3501                 return new xhr.GlobalActiveXObject(objId);
 
3505         return sinon.FakeXMLHttpRequest;
 
3508     sinon.FakeXMLHttpRequest = FakeXMLHttpRequest;
 
3511 if (typeof module == "object" && typeof require == "function") {
 
3512     module.exports = sinon;
 
3516  * @depend fake_xml_http_request.js
 
3518 /*jslint eqeqeq: false, onevar: false, regexp: false, plusplus: false*/
 
3519 /*global module, require, window*/
 
3521  * The Sinon "server" mimics a web server that receives requests from
 
3522  * sinon.FakeXMLHttpRequest and provides an API to respond to those requests,
 
3523  * both synchronously and asynchronously. To respond synchronuously, canned
 
3524  * answers have to be provided upfront.
 
3526  * @author Christian Johansen (christian@cjohansen.no)
 
3529  * Copyright (c) 2010-2013 Christian Johansen
 
3532 if (typeof sinon == "undefined") {
 
3536 sinon.fakeServer = (function () {
 
3540     function create(proto) {
 
3541         F.prototype = proto;
 
3545     function responseArray(handler) {
 
3546         var response = handler;
 
3548         if (Object.prototype.toString.call(handler) != "[object Array]") {
 
3549             response = [200, {}, handler];
 
3552         if (typeof response[2] != "string") {
 
3553             throw new TypeError("Fake server response body should be string, but was " +
 
3554                                 typeof response[2]);
 
3560     var wloc = typeof window !== "undefined" ? window.location : {};
 
3561     var rCurrLoc = new RegExp("^" + wloc.protocol + "//" + wloc.host);
 
3563     function matchOne(response, reqMethod, reqUrl) {
 
3564         var rmeth = response.method;
 
3565         var matchMethod = !rmeth || rmeth.toLowerCase() == reqMethod.toLowerCase();
 
3566         var url = response.url;
 
3567         var matchUrl = !url || url == reqUrl || (typeof url.test == "function" && url.test(reqUrl));
 
3569         return matchMethod && matchUrl;
 
3572     function match(response, request) {
 
3573         var requestMethod = this.getHTTPMethod(request);
 
3574         var requestUrl = request.url;
 
3576         if (!/^https?:\/\//.test(requestUrl) || rCurrLoc.test(requestUrl)) {
 
3577             requestUrl = requestUrl.replace(rCurrLoc, "");
 
3580         if (matchOne(response, this.getHTTPMethod(request), requestUrl)) {
 
3581             if (typeof response.response == "function") {
 
3582                 var ru = response.url;
 
3583                 var args = [request].concat(!ru ? [] : requestUrl.match(ru).slice(1));
 
3584                 return response.response.apply(response, args);
 
3593     function log(response, request) {
 
3596         str =  "Request:\n"  + sinon.format(request)  + "\n\n";
 
3597         str += "Response:\n" + sinon.format(response) + "\n\n";
 
3603         create: function () {
 
3604             var server = create(this);
 
3605             this.xhr = sinon.useFakeXMLHttpRequest();
 
3606             server.requests = [];
 
3608             this.xhr.onCreate = function (xhrObj) {
 
3609                 server.addRequest(xhrObj);
 
3615         addRequest: function addRequest(xhrObj) {
 
3617             push.call(this.requests, xhrObj);
 
3619             xhrObj.onSend = function () {
 
3620                 server.handleRequest(this);
 
3623             if (this.autoRespond && !this.responding) {
 
3624                 setTimeout(function () {
 
3625                     server.responding = false;
 
3627                 }, this.autoRespondAfter || 10);
 
3629                 this.responding = true;
 
3633         getHTTPMethod: function getHTTPMethod(request) {
 
3634             if (this.fakeHTTPMethods && /post/i.test(request.method)) {
 
3635                 var matches = (request.requestBody || "").match(/_method=([^\b;]+)/);
 
3636                 return !!matches ? matches[1] : request.method;
 
3639             return request.method;
 
3642         handleRequest: function handleRequest(xhr) {
 
3648                 push.call(this.queue, xhr);
 
3650                 this.processRequest(xhr);
 
3654         respondWith: function respondWith(method, url, body) {
 
3655             if (arguments.length == 1 && typeof method != "function") {
 
3656                 this.response = responseArray(method);
 
3660             if (!this.responses) { this.responses = []; }
 
3662             if (arguments.length == 1) {
 
3664                 url = method = null;
 
3667             if (arguments.length == 2) {
 
3673             push.call(this.responses, {
 
3676                 response: typeof body == "function" ? body : responseArray(body)
 
3680         respond: function respond() {
 
3681             if (arguments.length > 0) this.respondWith.apply(this, arguments);
 
3682             var queue = this.queue || [];
 
3685             while(request = queue.shift()) {
 
3686                 this.processRequest(request);
 
3690         processRequest: function processRequest(request) {
 
3692                 if (request.aborted) {
 
3696                 var response = this.response || [404, {}, ""];
 
3698                 if (this.responses) {
 
3699                     for (var i = 0, l = this.responses.length; i < l; i++) {
 
3700                         if (match.call(this, this.responses[i], request)) {
 
3701                             response = this.responses[i].response;
 
3707                 if (request.readyState != 4) {
 
3708                     log(response, request);
 
3710                     request.respond(response[0], response[1], response[2]);
 
3713                 sinon.logError("Fake server request processing", e);
 
3717         restore: function restore() {
 
3718             return this.xhr.restore && this.xhr.restore.apply(this.xhr, arguments);
 
3723 if (typeof module == "object" && typeof require == "function") {
 
3724     module.exports = sinon;
 
3728  * @depend fake_server.js
 
3729  * @depend fake_timers.js
 
3731 /*jslint browser: true, eqeqeq: false, onevar: false*/
 
3734  * Add-on for sinon.fakeServer that automatically handles a fake timer along with
 
3735  * the FakeXMLHttpRequest. The direct inspiration for this add-on is jQuery
 
3736  * 1.3.x, which does not use xhr object's onreadystatehandler at all - instead,
 
3737  * it polls the object for completion with setInterval. Dispite the direct
 
3738  * motivation, there is nothing jQuery-specific in this file, so it can be used
 
3739  * in any environment where the ajax implementation depends on setInterval or
 
3742  * @author Christian Johansen (christian@cjohansen.no)
 
3745  * Copyright (c) 2010-2013 Christian Johansen
 
3749     function Server() {}
 
3750     Server.prototype = sinon.fakeServer;
 
3752     sinon.fakeServerWithClock = new Server();
 
3754     sinon.fakeServerWithClock.addRequest = function addRequest(xhr) {
 
3756             if (typeof setTimeout.clock == "object") {
 
3757                 this.clock = setTimeout.clock;
 
3759                 this.clock = sinon.useFakeTimers();
 
3760                 this.resetClock = true;
 
3763             if (!this.longestTimeout) {
 
3764                 var clockSetTimeout = this.clock.setTimeout;
 
3765                 var clockSetInterval = this.clock.setInterval;
 
3768                 this.clock.setTimeout = function (fn, timeout) {
 
3769                     server.longestTimeout = Math.max(timeout, server.longestTimeout || 0);
 
3771                     return clockSetTimeout.apply(this, arguments);
 
3774                 this.clock.setInterval = function (fn, timeout) {
 
3775                     server.longestTimeout = Math.max(timeout, server.longestTimeout || 0);
 
3777                     return clockSetInterval.apply(this, arguments);
 
3782         return sinon.fakeServer.addRequest.call(this, xhr);
 
3785     sinon.fakeServerWithClock.respond = function respond() {
 
3786         var returnVal = sinon.fakeServer.respond.apply(this, arguments);
 
3789             this.clock.tick(this.longestTimeout || 0);
 
3790             this.longestTimeout = 0;
 
3792             if (this.resetClock) {
 
3793                 this.clock.restore();
 
3794                 this.resetClock = false;
 
3801     sinon.fakeServerWithClock.restore = function restore() {
 
3803             this.clock.restore();
 
3806         return sinon.fakeServer.restore.apply(this, arguments);
 
3811  * @depend ../sinon.js
 
3812  * @depend collection.js
 
3813  * @depend util/fake_timers.js
 
3814  * @depend util/fake_server_with_clock.js
 
3816 /*jslint eqeqeq: false, onevar: false, plusplus: false*/
 
3817 /*global require, module*/
 
3819  * Manages fake collections as well as fake utilities such as Sinon's
 
3820  * timers and fake XHR implementation in one convenient object.
 
3822  * @author Christian Johansen (christian@cjohansen.no)
 
3825  * Copyright (c) 2010-2013 Christian Johansen
 
3828 if (typeof module == "object" && typeof require == "function") {
 
3829     var sinon = require("../sinon");
 
3830     sinon.extend(sinon, require("./util/fake_timers"));
 
3836     function exposeValue(sandbox, config, key, value) {
 
3841         if (config.injectInto) {
 
3842             config.injectInto[key] = value;
 
3844             push.call(sandbox.args, value);
 
3848     function prepareSandboxFromConfig(config) {
 
3849         var sandbox = sinon.create(sinon.sandbox);
 
3851         if (config.useFakeServer) {
 
3852             if (typeof config.useFakeServer == "object") {
 
3853                 sandbox.serverPrototype = config.useFakeServer;
 
3856             sandbox.useFakeServer();
 
3859         if (config.useFakeTimers) {
 
3860             if (typeof config.useFakeTimers == "object") {
 
3861                 sandbox.useFakeTimers.apply(sandbox, config.useFakeTimers);
 
3863                 sandbox.useFakeTimers();
 
3870     sinon.sandbox = sinon.extend(sinon.create(sinon.collection), {
 
3871         useFakeTimers: function useFakeTimers() {
 
3872             this.clock = sinon.useFakeTimers.apply(sinon, arguments);
 
3874             return this.add(this.clock);
 
3877         serverPrototype: sinon.fakeServer,
 
3879         useFakeServer: function useFakeServer() {
 
3880             var proto = this.serverPrototype || sinon.fakeServer;
 
3882             if (!proto || !proto.create) {
 
3886             this.server = proto.create();
 
3887             return this.add(this.server);
 
3890         inject: function (obj) {
 
3891             sinon.collection.inject.call(this, obj);
 
3894                 obj.clock = this.clock;
 
3898                 obj.server = this.server;
 
3899                 obj.requests = this.server.requests;
 
3905         create: function (config) {
 
3907                 return sinon.create(sinon.sandbox);
 
3910             var sandbox = prepareSandboxFromConfig(config);
 
3911             sandbox.args = sandbox.args || [];
 
3912             var prop, value, exposed = sandbox.inject({});
 
3914             if (config.properties) {
 
3915                 for (var i = 0, l = config.properties.length; i < l; i++) {
 
3916                     prop = config.properties[i];
 
3917                     value = exposed[prop] || prop == "sandbox" && sandbox;
 
3918                     exposeValue(sandbox, config, prop, value);
 
3921                 exposeValue(sandbox, config, "sandbox", value);
 
3928     sinon.sandbox.useFakeXMLHttpRequest = sinon.sandbox.useFakeServer;
 
3930     if (typeof module == "object" && typeof require == "function") {
 
3931         module.exports = sinon.sandbox;
 
3936  * @depend ../sinon.js
 
3939  * @depend sandbox.js
 
3941 /*jslint eqeqeq: false, onevar: false, forin: true, plusplus: false*/
 
3942 /*global module, require, sinon*/
 
3944  * Test function, sandboxes fakes
 
3946  * @author Christian Johansen (christian@cjohansen.no)
 
3949  * Copyright (c) 2010-2013 Christian Johansen
 
3953     var commonJSModule = typeof module == "object" && typeof require == "function";
 
3955     if (!sinon && commonJSModule) {
 
3956         sinon = require("../sinon");
 
3963     function test(callback) {
 
3964         var type = typeof callback;
 
3966         if (type != "function") {
 
3967             throw new TypeError("sinon.test needs to wrap a test function, got " + type);
 
3970         return function () {
 
3971             var config = sinon.getConfig(sinon.config);
 
3972             config.injectInto = config.injectIntoThis && this || config.injectInto;
 
3973             var sandbox = sinon.sandbox.create(config);
 
3974             var exception, result;
 
3975             var args = Array.prototype.slice.call(arguments).concat(sandbox.args);
 
3978                 result = callback.apply(this, args);
 
3983             if (typeof exception !== "undefined") {
 
3988                 sandbox.verifyAndRestore();
 
3996         injectIntoThis: true,
 
3998         properties: ["spy", "stub", "mock", "clock", "server", "requests"],
 
3999         useFakeTimers: true,
 
4003     if (commonJSModule) {
 
4004         module.exports = test;
 
4008 }(typeof sinon == "object" && sinon || null));
 
4011  * @depend ../sinon.js
 
4014 /*jslint eqeqeq: false, onevar: false, eqeqeq: false*/
 
4015 /*global module, require, sinon*/
 
4017  * Test case, sandboxes all test functions
 
4019  * @author Christian Johansen (christian@cjohansen.no)
 
4022  * Copyright (c) 2010-2013 Christian Johansen
 
4026     var commonJSModule = typeof module == "object" && typeof require == "function";
 
4028     if (!sinon && commonJSModule) {
 
4029         sinon = require("../sinon");
 
4032     if (!sinon || !Object.prototype.hasOwnProperty) {
 
4036     function createTest(property, setUp, tearDown) {
 
4037         return function () {
 
4039                 setUp.apply(this, arguments);
 
4042             var exception, result;
 
4045                 result = property.apply(this, arguments);
 
4051                 tearDown.apply(this, arguments);
 
4062     function testCase(tests, prefix) {
 
4064         if (!tests || typeof tests != "object") {
 
4065             throw new TypeError("sinon.testCase needs an object with test functions");
 
4069         prefix = prefix || "test";
 
4070         var rPrefix = new RegExp("^" + prefix);
 
4071         var methods = {}, testName, property, method;
 
4072         var setUp = tests.setUp;
 
4073         var tearDown = tests.tearDown;
 
4075         for (testName in tests) {
 
4076             if (tests.hasOwnProperty(testName)) {
 
4077                 property = tests[testName];
 
4079                 if (/^(setUp|tearDown)$/.test(testName)) {
 
4083                 if (typeof property == "function" && rPrefix.test(testName)) {
 
4086                     if (setUp || tearDown) {
 
4087                         method = createTest(property, setUp, tearDown);
 
4090                     methods[testName] = sinon.test(method);
 
4092                     methods[testName] = tests[testName];
 
4100     if (commonJSModule) {
 
4101         module.exports = testCase;
 
4103         sinon.testCase = testCase;
 
4105 }(typeof sinon == "object" && sinon || null));
 
4108  * @depend ../sinon.js
 
4111 /*jslint eqeqeq: false, onevar: false, nomen: false, plusplus: false*/
 
4112 /*global module, require, sinon*/
 
4114  * Assertions matching the test spy retrieval interface.
 
4116  * @author Christian Johansen (christian@cjohansen.no)
 
4119  * Copyright (c) 2010-2013 Christian Johansen
 
4122 (function (sinon, global) {
 
4123     var commonJSModule = typeof module == "object" && typeof require == "function";
 
4124     var slice = Array.prototype.slice;
 
4127     if (!sinon && commonJSModule) {
 
4128         sinon = require("../sinon");
 
4135     function verifyIsStub() {
 
4138         for (var i = 0, l = arguments.length; i < l; ++i) {
 
4139             method = arguments[i];
 
4142                 assert.fail("fake is not a spy");
 
4145             if (typeof method != "function") {
 
4146                 assert.fail(method + " is not a function");
 
4149             if (typeof method.getCall != "function") {
 
4150                 assert.fail(method + " is not stubbed");
 
4155     function failAssertion(object, msg) {
 
4156         object = object || global;
 
4157         var failMethod = object.fail || assert.fail;
 
4158         failMethod.call(object, msg);
 
4161     function mirrorPropAsAssertion(name, method, message) {
 
4162         if (arguments.length == 2) {
 
4167         assert[name] = function (fake) {
 
4170             var args = slice.call(arguments, 1);
 
4173             if (typeof method == "function") {
 
4174                 failed = !method(fake);
 
4176                 failed = typeof fake[method] == "function" ?
 
4177                     !fake[method].apply(fake, args) : !fake[method];
 
4181                 failAssertion(this, fake.printf.apply(fake, [message].concat(args)));
 
4188     function exposedName(prefix, prop) {
 
4189         return !prefix || /^fail/.test(prop) ? prop :
 
4190             prefix + prop.slice(0, 1).toUpperCase() + prop.slice(1);
 
4194         failException: "AssertError",
 
4196         fail: function fail(message) {
 
4197             var error = new Error(message);
 
4198             error.name = this.failException || assert.failException;
 
4203         pass: function pass(assertion) {},
 
4205         callOrder: function assertCallOrder() {
 
4206             verifyIsStub.apply(null, arguments);
 
4207             var expected = "", actual = "";
 
4209             if (!sinon.calledInOrder(arguments)) {
 
4211                     expected = [].join.call(arguments, ", ");
 
4212                     var calls = slice.call(arguments);
 
4213                     var i = calls.length;
 
4215                         if (!calls[--i].called) {
 
4219                     actual = sinon.orderByFirstCall(calls).join(", ");
 
4221                     // If this fails, we'll just fall back to the blank string
 
4224                 failAssertion(this, "expected " + expected + " to be " +
 
4225                               "called in order but were called as " + actual);
 
4227                 assert.pass("callOrder");
 
4231         callCount: function assertCallCount(method, count) {
 
4232             verifyIsStub(method);
 
4234             if (method.callCount != count) {
 
4235                 var msg = "expected %n to be called " + sinon.timesInWords(count) +
 
4236                     " but was called %c%C";
 
4237                 failAssertion(this, method.printf(msg));
 
4239                 assert.pass("callCount");
 
4243         expose: function expose(target, options) {
 
4245                 throw new TypeError("target is null or undefined");
 
4248             var o = options || {};
 
4249             var prefix = typeof o.prefix == "undefined" && "assert" || o.prefix;
 
4250             var includeFail = typeof o.includeFail == "undefined" || !!o.includeFail;
 
4252             for (var method in this) {
 
4253                 if (method != "export" && (includeFail || !/^(fail)/.test(method))) {
 
4254                     target[exposedName(prefix, method)] = this[method];
 
4262     mirrorPropAsAssertion("called", "expected %n to have been called at least once but was never called");
 
4263     mirrorPropAsAssertion("notCalled", function (spy) { return !spy.called; },
 
4264                           "expected %n to not have been called but was called %c%C");
 
4265     mirrorPropAsAssertion("calledOnce", "expected %n to be called once but was called %c%C");
 
4266     mirrorPropAsAssertion("calledTwice", "expected %n to be called twice but was called %c%C");
 
4267     mirrorPropAsAssertion("calledThrice", "expected %n to be called thrice but was called %c%C");
 
4268     mirrorPropAsAssertion("calledOn", "expected %n to be called with %1 as this but was called with %t");
 
4269     mirrorPropAsAssertion("alwaysCalledOn", "expected %n to always be called with %1 as this but was called with %t");
 
4270     mirrorPropAsAssertion("calledWithNew", "expected %n to be called with new");
 
4271     mirrorPropAsAssertion("alwaysCalledWithNew", "expected %n to always be called with new");
 
4272     mirrorPropAsAssertion("calledWith", "expected %n to be called with arguments %*%C");
 
4273     mirrorPropAsAssertion("calledWithMatch", "expected %n to be called with match %*%C");
 
4274     mirrorPropAsAssertion("alwaysCalledWith", "expected %n to always be called with arguments %*%C");
 
4275     mirrorPropAsAssertion("alwaysCalledWithMatch", "expected %n to always be called with match %*%C");
 
4276     mirrorPropAsAssertion("calledWithExactly", "expected %n to be called with exact arguments %*%C");
 
4277     mirrorPropAsAssertion("alwaysCalledWithExactly", "expected %n to always be called with exact arguments %*%C");
 
4278     mirrorPropAsAssertion("neverCalledWith", "expected %n to never be called with arguments %*%C");
 
4279     mirrorPropAsAssertion("neverCalledWithMatch", "expected %n to never be called with match %*%C");
 
4280     mirrorPropAsAssertion("threw", "%n did not throw exception%C");
 
4281     mirrorPropAsAssertion("alwaysThrew", "%n did not always throw exception%C");
 
4283     if (commonJSModule) {
 
4284         module.exports = assert;
 
4286         sinon.assert = assert;
 
4288 }(typeof sinon == "object" && sinon || null, typeof window != "undefined" ? window : (typeof self != "undefined") ? self : global));
 
4290 return sinon;}.call(typeof window != 'undefined' && window || {}));