sinon-rails 1.7.3 → 1.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d9812c464137a0e33419966fe1ff20a7a38cc6e1
4
- data.tar.gz: 1a674485c7539e55ce93b7f56ced5f26d4f09887
3
+ metadata.gz: b1cb98e6422863e4390638e3ef04849675fb94af
4
+ data.tar.gz: dfadbf5735f311e238775110b080940c14ccf3bc
5
5
  SHA512:
6
- metadata.gz: 70ac91e60d69d314b60962b2ee47257adb292ba8a3ca2d1f70cc13b113e423ba0db3779248c37cbd2ee02975b92aa40ad7ed275e77cddc00b8e4ad94958d2657
7
- data.tar.gz: 3f026525158af9853e8130dabcc0ce10b3ac8d65cbc03eb8824e263b71e0fde5a1dfc63a18569fe608a48d43daf3f2f53ec3147879650d4c09de6596bd378ac0
6
+ metadata.gz: a339a8ffe6f7adeccecd115c4eaac89689d2297e81f1ef493ca0864b0957e0d3205ac11c4e8d1802abbc9dc1d16e245099485e9681972a894123c01d678405ce
7
+ data.tar.gz: 9329e86f48c0cac9270a433d9f67e70fa06ef6dc8e19ec731b1f6f68449940e4f80a2bcc90bff2d5eadc5ce8bae01f63b7bdf22e404cb51798f1039e30b2b9e3
data/README.md CHANGED
@@ -6,8 +6,10 @@ sinon.js via asset pipeline
6
6
 
7
7
  Add this line to your application's Gemfile:
8
8
 
9
- gem 'sinon-rails'
10
-
9
+ group :test, :development do
10
+ gem 'sinon-rails'
11
+ end
12
+
11
13
  And then execute:
12
14
 
13
15
  $ bundle
@@ -1,5 +1,5 @@
1
1
  module Sinon
2
2
  module Rails
3
- VERSION = "1.7.3"
3
+ VERSION = "1.9.0"
4
4
  end
5
5
  end
@@ -1,12 +1,12 @@
1
1
  /**
2
- * Sinon.JS 1.7.3, 2013/06/20
2
+ * Sinon.JS 1.9.0, 2014/03/05
3
3
  *
4
4
  * @author Christian Johansen (christian@cjohansen.no)
5
5
  * @author Contributors: https://github.com/cjohansen/Sinon.JS/blob/master/AUTHORS
6
6
  *
7
7
  * (The BSD License)
8
8
  *
9
- * Copyright (c) 2010-2013, Christian Johansen, christian@cjohansen.no
9
+ * Copyright (c) 2010-2014, Christian Johansen, christian@cjohansen.no
10
10
  * All rights reserved.
11
11
  *
12
12
  * Redistribution and use in source and binary forms, with or without modification,
@@ -34,337 +34,497 @@
34
34
  */
35
35
 
36
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 () {};
41
-
42
- var buster = {
43
- bind: function bind(obj, methOrProp) {
44
- var method = typeof methOrProp == "string" ? obj[methOrProp] : methOrProp;
45
- var args = Array.prototype.slice.call(arguments, 2);
46
- return function () {
47
- var allArgs = args.concat(Array.prototype.slice.call(arguments));
48
- return method.apply(obj, allArgs);
49
- };
50
- },
37
+ var samsam, formatio;
38
+ function define(mod, deps, fn) { if (mod == "samsam") { samsam = deps(); } else { formatio = fn(samsam); } }
39
+ define.amd = true;
40
+ ((typeof define === "function" && define.amd && function (m) { define("samsam", m); }) ||
41
+ (typeof module === "object" &&
42
+ function (m) { module.exports = m(); }) || // Node
43
+ function (m) { this.samsam = m(); } // Browser globals
44
+ )(function () {
45
+ var o = Object.prototype;
46
+ var div = typeof document !== "undefined" && document.createElement("div");
47
+
48
+ function isNaN(value) {
49
+ // Unlike global isNaN, this avoids type coercion
50
+ // typeof check avoids IE host object issues, hat tip to
51
+ // lodash
52
+ var val = value; // JsLint thinks value !== value is "weird"
53
+ return typeof value === "number" && value !== val;
54
+ }
51
55
 
52
- partial: function partial(fn) {
53
- var args = [].slice.call(arguments, 1);
54
- return function () {
55
- return fn.apply(this, args.concat([].slice.call(arguments)));
56
- };
57
- },
56
+ function getClass(value) {
57
+ // Returns the internal [[Class]] by calling Object.prototype.toString
58
+ // with the provided value as this. Return value is a string, naming the
59
+ // internal class, e.g. "Array"
60
+ return o.toString.call(value).split(/[ \]]/)[1];
61
+ }
58
62
 
59
- create: function create(object) {
60
- F.prototype = object;
61
- return new F();
62
- },
63
+ /**
64
+ * @name samsam.isArguments
65
+ * @param Object object
66
+ *
67
+ * Returns ``true`` if ``object`` is an ``arguments`` object,
68
+ * ``false`` otherwise.
69
+ */
70
+ function isArguments(object) {
71
+ if (typeof object !== "object" || typeof object.length !== "number" ||
72
+ getClass(object) === "Array") {
73
+ return false;
74
+ }
75
+ if (typeof object.callee == "function") { return true; }
76
+ try {
77
+ object[object.length] = 6;
78
+ delete object[object.length];
79
+ } catch (e) {
80
+ return true;
81
+ }
82
+ return false;
83
+ }
63
84
 
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];
69
- }
70
- }
71
- return target;
72
- },
85
+ /**
86
+ * @name samsam.isElement
87
+ * @param Object object
88
+ *
89
+ * Returns ``true`` if ``object`` is a DOM element node. Unlike
90
+ * Underscore.js/lodash, this function will return ``false`` if ``object``
91
+ * is an *element-like* object, i.e. a regular object with a ``nodeType``
92
+ * property that holds the value ``1``.
93
+ */
94
+ function isElement(object) {
95
+ if (!object || object.nodeType !== 1 || !div) { return false; }
96
+ try {
97
+ object.appendChild(div);
98
+ object.removeChild(div);
99
+ } catch (e) {
100
+ return false;
101
+ }
102
+ return true;
103
+ }
73
104
 
74
- nextTick: function nextTick(callback) {
75
- if (typeof process != "undefined" && process.nextTick) {
76
- return process.nextTick(callback);
77
- }
78
- setTimeout(callback, 0);
79
- },
105
+ /**
106
+ * @name samsam.keys
107
+ * @param Object object
108
+ *
109
+ * Return an array of own property names.
110
+ */
111
+ function keys(object) {
112
+ var ks = [], prop;
113
+ for (prop in object) {
114
+ if (o.hasOwnProperty.call(object, prop)) { ks.push(prop); }
115
+ }
116
+ return ks;
117
+ }
80
118
 
81
- functionName: function functionName(func) {
82
- if (!func) return "";
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] || "";
87
- },
119
+ /**
120
+ * @name samsam.isDate
121
+ * @param Object value
122
+ *
123
+ * Returns true if the object is a ``Date``, or *date-like*. Duck typing
124
+ * of date objects work by checking that the object has a ``getTime``
125
+ * function whose return value equals the return value from the object's
126
+ * ``valueOf``.
127
+ */
128
+ function isDate(value) {
129
+ return typeof value.getTime == "function" &&
130
+ value.getTime() == value.valueOf();
131
+ }
88
132
 
89
- isNode: function isNode(obj) {
90
- if (!div) return false;
91
- try {
92
- obj.appendChild(div);
93
- obj.removeChild(div);
94
- } catch (e) {
95
- return false;
96
- }
97
- return true;
98
- },
133
+ /**
134
+ * @name samsam.isNegZero
135
+ * @param Object value
136
+ *
137
+ * Returns ``true`` if ``value`` is ``-0``.
138
+ */
139
+ function isNegZero(value) {
140
+ return value === 0 && 1 / value === -Infinity;
141
+ }
99
142
 
100
- isElement: function isElement(obj) {
101
- return obj && obj.nodeType === 1 && buster.isNode(obj);
102
- },
143
+ /**
144
+ * @name samsam.equal
145
+ * @param Object obj1
146
+ * @param Object obj2
147
+ *
148
+ * Returns ``true`` if two objects are strictly equal. Compared to
149
+ * ``===`` there are two exceptions:
150
+ *
151
+ * - NaN is considered equal to NaN
152
+ * - -0 and +0 are not considered equal
153
+ */
154
+ function identical(obj1, obj2) {
155
+ if (obj1 === obj2 || (isNaN(obj1) && isNaN(obj2))) {
156
+ return obj1 !== 0 || isNegZero(obj1) === isNegZero(obj2);
157
+ }
158
+ }
103
159
 
104
- isArray: function isArray(arr) {
105
- return Object.prototype.toString.call(arr) == "[object Array]";
106
- },
107
160
 
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]);
112
- }
113
- return result;
114
- },
161
+ /**
162
+ * @name samsam.deepEqual
163
+ * @param Object obj1
164
+ * @param Object obj2
165
+ *
166
+ * Deep equal comparison. Two values are "deep equal" if:
167
+ *
168
+ * - They are equal, according to samsam.identical
169
+ * - They are both date objects representing the same time
170
+ * - They are both arrays containing elements that are all deepEqual
171
+ * - They are objects with the same set of properties, and each property
172
+ * in ``obj1`` is deepEqual to the corresponding property in ``obj2``
173
+ *
174
+ * Supports cyclic objects.
175
+ */
176
+ function deepEqualCyclic(obj1, obj2) {
177
+
178
+ // used for cyclic comparison
179
+ // contain already visited objects
180
+ var objects1 = [],
181
+ objects2 = [],
182
+ // contain pathes (position in the object structure)
183
+ // of the already visited objects
184
+ // indexes same as in objects arrays
185
+ paths1 = [],
186
+ paths2 = [],
187
+ // contains combinations of already compared objects
188
+ // in the manner: { "$1['ref']$2['ref']": true }
189
+ compared = {};
190
+
191
+ /**
192
+ * used to check, if the value of a property is an object
193
+ * (cyclic logic is only needed for objects)
194
+ * only needed for cyclic logic
195
+ */
196
+ function isObject(value) {
197
+
198
+ if (typeof value === 'object' && value !== null &&
199
+ !(value instanceof Boolean) &&
200
+ !(value instanceof Date) &&
201
+ !(value instanceof Number) &&
202
+ !(value instanceof RegExp) &&
203
+ !(value instanceof String)) {
115
204
 
116
- each: function each(arr, callback) {
117
- for (var i = 0, l = arr.length; i < l; ++i) {
118
- callback(arr[i]);
205
+ return true;
119
206
  }
120
- },
121
207
 
122
- map: function map(arr, callback) {
123
- var results = [];
124
- for (var i = 0, l = arr.length; i < l; ++i) {
125
- results.push(callback(arr[i]));
126
- }
127
- return results;
128
- },
208
+ return false;
209
+ }
129
210
 
130
- parallel: function parallel(fns, callback) {
131
- function cb(err, res) {
132
- if (typeof callback == "function") {
133
- callback(err, res);
134
- callback = null;
211
+ /**
212
+ * returns the index of the given object in the
213
+ * given objects array, -1 if not contained
214
+ * only needed for cyclic logic
215
+ */
216
+ function getIndex(objects, obj) {
217
+
218
+ var i;
219
+ for (i = 0; i < objects.length; i++) {
220
+ if (objects[i] === obj) {
221
+ return i;
135
222
  }
136
223
  }
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); }
144
- };
145
- }
146
- for (var i = 0, l = fns.length; i < l; ++i) {
147
- fns[i](makeDone(i));
148
- }
149
- },
150
224
 
151
- series: function series(fns, callback) {
152
- function cb(err, res) {
153
- if (typeof callback == "function") {
154
- callback(err, res);
155
- }
225
+ return -1;
226
+ }
227
+
228
+ // does the recursion for the deep equal check
229
+ return (function deepEqual(obj1, obj2, path1, path2) {
230
+ var type1 = typeof obj1;
231
+ var type2 = typeof obj2;
232
+
233
+ // == null also matches undefined
234
+ if (obj1 === obj2 ||
235
+ isNaN(obj1) || isNaN(obj2) ||
236
+ obj1 == null || obj2 == null ||
237
+ type1 !== "object" || type2 !== "object") {
238
+
239
+ return identical(obj1, obj2);
156
240
  }
157
- var remaining = fns.slice();
158
- var results = [];
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);
241
+
242
+ // Elements are only equal if identical(expected, actual)
243
+ if (isElement(obj1) || isElement(obj2)) { return false; }
244
+
245
+ var isDate1 = isDate(obj1), isDate2 = isDate(obj2);
246
+ if (isDate1 || isDate2) {
247
+ if (!isDate1 || !isDate2 || obj1.getTime() !== obj2.getTime()) {
248
+ return false;
164
249
  }
165
250
  }
166
- function next(err, result) {
167
- if (err) return cb(err);
168
- results.push(result);
169
- callNext();
170
- }
171
- callNext();
172
- },
173
251
 
174
- countdown: function countdown(num, done) {
175
- return function () {
176
- if (--num == 0) done();
177
- };
178
- }
179
- };
180
-
181
- if (typeof process === "object" &&
182
- typeof require === "function" && typeof module === "object") {
183
- var crypto = require("crypto");
184
- var path = require("path");
252
+ if (obj1 instanceof RegExp && obj2 instanceof RegExp) {
253
+ if (obj1.toString() !== obj2.toString()) { return false; }
254
+ }
185
255
 
186
- buster.tmpFile = function (fileName) {
187
- var hashed = crypto.createHash("sha1");
188
- hashed.update(fileName);
189
- var tmpfileName = hashed.digest("hex");
256
+ var class1 = getClass(obj1);
257
+ var class2 = getClass(obj2);
258
+ var keys1 = keys(obj1);
259
+ var keys2 = keys(obj2);
190
260
 
191
- if (process.platform == "win32") {
192
- return path.join(process.env["TEMP"], tmpfileName);
261
+ if (isArguments(obj1) || isArguments(obj2)) {
262
+ if (obj1.length !== obj2.length) { return false; }
193
263
  } else {
194
- return path.join("/tmp", tmpfileName);
264
+ if (type1 !== type2 || class1 !== class2 ||
265
+ keys1.length !== keys2.length) {
266
+ return false;
267
+ }
195
268
  }
196
- };
197
- }
198
269
 
199
- if (Array.prototype.some) {
200
- buster.some = function (arr, fn, thisp) {
201
- return arr.some(fn, thisp);
202
- };
203
- } else {
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(); }
207
- arr = Object(arr);
208
- var len = arr.length >>> 0;
209
- if (typeof fun !== "function") { throw new TypeError(); }
210
-
211
- for (var i = 0; i < len; i++) {
212
- if (arr.hasOwnProperty(i) && fun.call(thisp, arr[i], i, arr)) {
270
+ var key, i, l,
271
+ // following vars are used for the cyclic logic
272
+ value1, value2,
273
+ isObject1, isObject2,
274
+ index1, index2,
275
+ newPath1, newPath2;
276
+
277
+ for (i = 0, l = keys1.length; i < l; i++) {
278
+ key = keys1[i];
279
+ if (!o.hasOwnProperty.call(obj2, key)) {
280
+ return false;
281
+ }
282
+
283
+ // Start of the cyclic logic
284
+
285
+ value1 = obj1[key];
286
+ value2 = obj2[key];
287
+
288
+ isObject1 = isObject(value1);
289
+ isObject2 = isObject(value2);
290
+
291
+ // determine, if the objects were already visited
292
+ // (it's faster to check for isObject first, than to
293
+ // get -1 from getIndex for non objects)
294
+ index1 = isObject1 ? getIndex(objects1, value1) : -1;
295
+ index2 = isObject2 ? getIndex(objects2, value2) : -1;
296
+
297
+ // determine the new pathes of the objects
298
+ // - for non cyclic objects the current path will be extended
299
+ // by current property name
300
+ // - for cyclic objects the stored path is taken
301
+ newPath1 = index1 !== -1
302
+ ? paths1[index1]
303
+ : path1 + '[' + JSON.stringify(key) + ']';
304
+ newPath2 = index2 !== -1
305
+ ? paths2[index2]
306
+ : path2 + '[' + JSON.stringify(key) + ']';
307
+
308
+ // stop recursion if current objects are already compared
309
+ if (compared[newPath1 + newPath2]) {
213
310
  return true;
214
311
  }
215
- }
216
312
 
217
- return false;
218
- };
219
- }
313
+ // remember the current objects and their pathes
314
+ if (index1 === -1 && isObject1) {
315
+ objects1.push(value1);
316
+ paths1.push(newPath1);
317
+ }
318
+ if (index2 === -1 && isObject2) {
319
+ objects2.push(value2);
320
+ paths2.push(newPath2);
321
+ }
220
322
 
221
- if (Array.prototype.filter) {
222
- buster.filter = function (arr, fn, thisp) {
223
- return arr.filter(fn, thisp);
224
- };
225
- } else {
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(); }
229
-
230
- var t = Object(this);
231
- var len = t.length >>> 0;
232
- if (typeof fn != "function") { throw new TypeError(); }
233
-
234
- var res = [];
235
- for (var i = 0; i < len; i++) {
236
- if (i in t) {
237
- var val = t[i]; // in case fun mutates this
238
- if (fn.call(thisp, val, i, t)) { res.push(val); }
323
+ // remember that the current objects are already compared
324
+ if (isObject1 && isObject2) {
325
+ compared[newPath1 + newPath2] = true;
326
+ }
327
+
328
+ // End of cyclic logic
329
+
330
+ // neither value1 nor value2 is a cycle
331
+ // continue with next level
332
+ if (!deepEqual(value1, value2, newPath1, newPath2)) {
333
+ return false;
239
334
  }
240
335
  }
241
336
 
242
- return res;
243
- };
337
+ return true;
338
+
339
+ }(obj1, obj2, '$1', '$2'));
244
340
  }
245
341
 
246
- if (isNode) {
247
- module.exports = buster;
248
- buster.eventEmitter = require("./buster-event-emitter");
249
- Object.defineProperty(buster, "defineVersionGetter", {
250
- get: function () {
251
- return require("./define-version-getter");
342
+ var match;
343
+
344
+ function arrayContains(array, subset) {
345
+ if (subset.length === 0) { return true; }
346
+ var i, l, j, k;
347
+ for (i = 0, l = array.length; i < l; ++i) {
348
+ if (match(array[i], subset[0])) {
349
+ for (j = 0, k = subset.length; j < k; ++j) {
350
+ if (!match(array[i + j], subset[j])) { return false; }
351
+ }
352
+ return true;
252
353
  }
253
- });
354
+ }
355
+ return false;
254
356
  }
255
357
 
256
- return buster.extend(B || {}, buster);
257
- }(setTimeout, buster));
258
- if (typeof buster === "undefined") {
259
- var buster = {};
260
- }
358
+ /**
359
+ * @name samsam.match
360
+ * @param Object object
361
+ * @param Object matcher
362
+ *
363
+ * Compare arbitrary value ``object`` with matcher.
364
+ */
365
+ match = function match(object, matcher) {
366
+ if (matcher && typeof matcher.test === "function") {
367
+ return matcher.test(object);
368
+ }
261
369
 
262
- if (typeof module === "object" && typeof require === "function") {
263
- buster = require("buster-core");
264
- }
370
+ if (typeof matcher === "function") {
371
+ return matcher(object) === true;
372
+ }
373
+
374
+ if (typeof matcher === "string") {
375
+ matcher = matcher.toLowerCase();
376
+ var notNull = typeof object === "string" || !!object;
377
+ return notNull &&
378
+ (String(object)).toLowerCase().indexOf(matcher) >= 0;
379
+ }
380
+
381
+ if (typeof matcher === "number") {
382
+ return matcher === object;
383
+ }
265
384
 
266
- buster.format = buster.format || {};
267
- buster.format.excludeConstructors = ["Object", /^.$/];
268
- buster.format.quoteStrings = true;
385
+ if (typeof matcher === "boolean") {
386
+ return matcher === object;
387
+ }
388
+
389
+ if (getClass(object) === "Array" && getClass(matcher) === "Array") {
390
+ return arrayContains(object, matcher);
391
+ }
269
392
 
270
- buster.format.ascii = (function () {
393
+ if (matcher && typeof matcher === "object") {
394
+ var prop;
395
+ for (prop in matcher) {
396
+ if (!match(object[prop], matcher[prop])) {
397
+ return false;
398
+ }
399
+ }
400
+ return true;
401
+ }
402
+
403
+ throw new Error("Matcher was not a string, a number, a " +
404
+ "function, a boolean or an object");
405
+ };
406
+
407
+ return {
408
+ isArguments: isArguments,
409
+ isElement: isElement,
410
+ isDate: isDate,
411
+ isNegZero: isNegZero,
412
+ identical: identical,
413
+ deepEqual: deepEqualCyclic,
414
+ match: match,
415
+ keys: keys
416
+ };
417
+ });
418
+ ((typeof define === "function" && define.amd && function (m) {
419
+ define("formatio", ["samsam"], m);
420
+ }) || (typeof module === "object" && function (m) {
421
+ module.exports = m(require("samsam"));
422
+ }) || function (m) { this.formatio = m(this.samsam); }
423
+ )(function (samsam) {
271
424
 
425
+ var formatio = {
426
+ excludeConstructors: ["Object", /^.$/],
427
+ quoteStrings: true
428
+ };
429
+
272
430
  var hasOwn = Object.prototype.hasOwnProperty;
273
431
 
274
432
  var specialObjects = [];
275
- if (typeof global != "undefined") {
276
- specialObjects.push({ obj: global, value: "[object global]" });
433
+ if (typeof global !== "undefined") {
434
+ specialObjects.push({ object: global, value: "[object global]" });
277
435
  }
278
- if (typeof document != "undefined") {
279
- specialObjects.push({ obj: document, value: "[object HTMLDocument]" });
436
+ if (typeof document !== "undefined") {
437
+ specialObjects.push({
438
+ object: document,
439
+ value: "[object HTMLDocument]"
440
+ });
280
441
  }
281
- if (typeof window != "undefined") {
282
- specialObjects.push({ obj: window, value: "[object Window]" });
442
+ if (typeof window !== "undefined") {
443
+ specialObjects.push({ object: window, value: "[object Window]" });
283
444
  }
284
445
 
285
- function keys(object) {
286
- var k = Object.keys && Object.keys(object) || [];
446
+ function functionName(func) {
447
+ if (!func) { return ""; }
448
+ if (func.displayName) { return func.displayName; }
449
+ if (func.name) { return func.name; }
450
+ var matches = func.toString().match(/function\s+([^\(]+)/m);
451
+ return (matches && matches[1]) || "";
452
+ }
287
453
 
288
- if (k.length == 0) {
289
- for (var prop in object) {
290
- if (hasOwn.call(object, prop)) {
291
- k.push(prop);
292
- }
454
+ function constructorName(f, object) {
455
+ var name = functionName(object && object.constructor);
456
+ var excludes = f.excludeConstructors ||
457
+ formatio.excludeConstructors || [];
458
+
459
+ var i, l;
460
+ for (i = 0, l = excludes.length; i < l; ++i) {
461
+ if (typeof excludes[i] === "string" && excludes[i] === name) {
462
+ return "";
463
+ } else if (excludes[i].test && excludes[i].test(name)) {
464
+ return "";
293
465
  }
294
466
  }
295
467
 
296
- return k.sort();
468
+ return name;
297
469
  }
298
470
 
299
471
  function isCircular(object, objects) {
300
- if (typeof object != "object") {
301
- return false;
472
+ if (typeof object !== "object") { return false; }
473
+ var i, l;
474
+ for (i = 0, l = objects.length; i < l; ++i) {
475
+ if (objects[i] === object) { return true; }
302
476
  }
303
-
304
- for (var i = 0, l = objects.length; i < l; ++i) {
305
- if (objects[i] === object) {
306
- return true;
307
- }
308
- }
309
-
310
477
  return false;
311
478
  }
312
479
 
313
- function ascii(object, processed, indent) {
314
- if (typeof object == "string") {
315
- var quote = typeof this.quoteStrings != "boolean" || this.quoteStrings;
480
+ function ascii(f, object, processed, indent) {
481
+ if (typeof object === "string") {
482
+ var qs = f.quoteStrings;
483
+ var quote = typeof qs !== "boolean" || qs;
316
484
  return processed || quote ? '"' + object + '"' : object;
317
485
  }
318
486
 
319
- if (typeof object == "function" && !(object instanceof RegExp)) {
487
+ if (typeof object === "function" && !(object instanceof RegExp)) {
320
488
  return ascii.func(object);
321
489
  }
322
490
 
323
491
  processed = processed || [];
324
492
 
325
- if (isCircular(object, processed)) {
326
- return "[Circular]";
327
- }
328
-
329
- if (Object.prototype.toString.call(object) == "[object Array]") {
330
- return ascii.array.call(this, object, processed);
331
- }
493
+ if (isCircular(object, processed)) { return "[Circular]"; }
332
494
 
333
- if (!object) {
334
- return "" + object;
495
+ if (Object.prototype.toString.call(object) === "[object Array]") {
496
+ return ascii.array.call(f, object, processed);
335
497
  }
336
498
 
337
- if (buster.isElement(object)) {
338
- return ascii.element(object);
339
- }
499
+ if (!object) { return String((1/object) === -Infinity ? "-0" : object); }
500
+ if (samsam.isElement(object)) { return ascii.element(object); }
340
501
 
341
- if (typeof object.toString == "function" &&
342
- object.toString !== Object.prototype.toString) {
502
+ if (typeof object.toString === "function" &&
503
+ object.toString !== Object.prototype.toString) {
343
504
  return object.toString();
344
505
  }
345
506
 
346
- for (var i = 0, l = specialObjects.length; i < l; i++) {
347
- if (object === specialObjects[i].obj) {
507
+ var i, l;
508
+ for (i = 0, l = specialObjects.length; i < l; i++) {
509
+ if (object === specialObjects[i].object) {
348
510
  return specialObjects[i].value;
349
511
  }
350
512
  }
351
513
 
352
- return ascii.object.call(this, object, processed, indent);
514
+ return ascii.object.call(f, object, processed, indent);
353
515
  }
354
516
 
355
517
  ascii.func = function (func) {
356
- return "function " + buster.functionName(func) + "() {}";
518
+ return "function " + functionName(func) + "() {}";
357
519
  };
358
520
 
359
521
  ascii.array = function (array, processed) {
360
522
  processed = processed || [];
361
523
  processed.push(array);
362
- var pieces = [];
363
-
364
- for (var i = 0, l = array.length; i < l; ++i) {
365
- pieces.push(ascii.call(this, array[i], processed));
524
+ var i, l, pieces = [];
525
+ for (i = 0, l = array.length; i < l; ++i) {
526
+ pieces.push(ascii(this, array[i], processed));
366
527
  }
367
-
368
528
  return "[" + pieces.join(", ") + "]";
369
529
  };
370
530
 
@@ -372,13 +532,9 @@ buster.format.ascii = (function () {
372
532
  processed = processed || [];
373
533
  processed.push(object);
374
534
  indent = indent || 0;
375
- var pieces = [], properties = keys(object), prop, str, obj;
376
- var is = "";
535
+ var pieces = [], properties = samsam.keys(object).sort();
377
536
  var length = 3;
378
-
379
- for (var i = 0, l = indent; i < l; ++i) {
380
- is += " ";
381
- }
537
+ var prop, str, obj, i, l;
382
538
 
383
539
  for (i = 0, l = properties.length; i < l; ++i) {
384
540
  prop = properties[i];
@@ -387,7 +543,7 @@ buster.format.ascii = (function () {
387
543
  if (isCircular(obj, processed)) {
388
544
  str = "[Circular]";
389
545
  } else {
390
- str = ascii.call(this, obj, processed, indent + 2);
546
+ str = ascii(this, obj, processed, indent + 2);
391
547
  }
392
548
 
393
549
  str = (/\s/.test(prop) ? '"' + prop + '"' : prop) + ": " + str;
@@ -395,28 +551,28 @@ buster.format.ascii = (function () {
395
551
  pieces.push(str);
396
552
  }
397
553
 
398
- var cons = ascii.constructorName.call(this, object);
399
- var prefix = cons ? "[" + cons + "] " : ""
554
+ var cons = constructorName(this, object);
555
+ var prefix = cons ? "[" + cons + "] " : "";
556
+ var is = "";
557
+ for (i = 0, l = indent; i < l; ++i) { is += " "; }
400
558
 
401
- return (length + indent) > 80 ?
402
- prefix + "{\n " + is + pieces.join(",\n " + is) + "\n" + is + "}" :
403
- prefix + "{ " + pieces.join(", ") + " }";
559
+ if (length + indent > 80) {
560
+ return prefix + "{\n " + is + pieces.join(",\n " + is) + "\n" +
561
+ is + "}";
562
+ }
563
+ return prefix + "{ " + pieces.join(", ") + " }";
404
564
  };
405
565
 
406
566
  ascii.element = function (element) {
407
567
  var tagName = element.tagName.toLowerCase();
408
- var attrs = element.attributes, attribute, pairs = [], attrName;
409
-
410
- for (var i = 0, l = attrs.length; i < l; ++i) {
411
- attribute = attrs.item(i);
412
- attrName = attribute.nodeName.toLowerCase().replace("html:", "");
568
+ var attrs = element.attributes, attr, pairs = [], attrName, i, l, val;
413
569
 
414
- if (attrName == "contenteditable" && attribute.nodeValue == "inherit") {
415
- continue;
416
- }
417
-
418
- if (!!attribute.nodeValue) {
419
- pairs.push(attrName + "=\"" + attribute.nodeValue + "\"");
570
+ for (i = 0, l = attrs.length; i < l; ++i) {
571
+ attr = attrs.item(i);
572
+ attrName = attr.nodeName.toLowerCase().replace("html:", "");
573
+ val = attr.nodeValue;
574
+ if (attrName !== "contenteditable" || val !== "inherit") {
575
+ if (!!val) { pairs.push(attrName + "=\"" + val + "\""); }
420
576
  }
421
577
  }
422
578
 
@@ -427,32 +583,36 @@ buster.format.ascii = (function () {
427
583
  content = content.substr(0, 20) + "[...]";
428
584
  }
429
585
 
430
- var res = formatted + pairs.join(" ") + ">" + content + "</" + tagName + ">";
586
+ var res = formatted + pairs.join(" ") + ">" + content +
587
+ "</" + tagName + ">";
431
588
 
432
589
  return res.replace(/ contentEditable="inherit"/, "");
433
590
  };
434
591
 
435
- ascii.constructorName = function (object) {
436
- var name = buster.functionName(object && object.constructor);
437
- var excludes = this.excludeConstructors || buster.format.excludeConstructors || [];
438
-
439
- for (var i = 0, l = excludes.length; i < l; ++i) {
440
- if (typeof excludes[i] == "string" && excludes[i] == name) {
441
- return "";
442
- } else if (excludes[i].test && excludes[i].test(name)) {
443
- return "";
444
- }
592
+ function Formatio(options) {
593
+ for (var opt in options) {
594
+ this[opt] = options[opt];
445
595
  }
596
+ }
446
597
 
447
- return name;
448
- };
598
+ Formatio.prototype = {
599
+ functionName: functionName,
449
600
 
450
- return ascii;
451
- }());
601
+ configure: function (options) {
602
+ return new Formatio(options);
603
+ },
452
604
 
453
- if (typeof module != "undefined") {
454
- module.exports = buster.format;
455
- }
605
+ constructorName: function (object) {
606
+ return constructorName(this, object);
607
+ },
608
+
609
+ ascii: function (object, processed, indent) {
610
+ return ascii(this, object, processed, indent);
611
+ }
612
+ };
613
+
614
+ return Formatio.prototype;
615
+ });
456
616
  /*jslint eqeqeq: false, onevar: false, forin: true, nomen: false, regexp: false, plusplus: false*/
457
617
  /*global module, require, __dirname, document*/
458
618
  /**
@@ -464,7 +624,7 @@ if (typeof module != "undefined") {
464
624
  * Copyright (c) 2010-2013 Christian Johansen
465
625
  */
466
626
 
467
- var sinon = (function (buster) {
627
+ var sinon = (function (formatio) {
468
628
  var div = typeof document != "undefined" && document.createElement("div");
469
629
  var hasOwn = Object.prototype.hasOwnProperty;
470
630
 
@@ -517,26 +677,38 @@ var sinon = (function (buster) {
517
677
  throw new TypeError("Method wrapper should be function");
518
678
  }
519
679
 
520
- var wrappedMethod = object[property];
680
+ var wrappedMethod = object[property],
681
+ error;
521
682
 
522
683
  if (!isFunction(wrappedMethod)) {
523
- throw new TypeError("Attempted to wrap " + (typeof wrappedMethod) + " property " +
684
+ error = new TypeError("Attempted to wrap " + (typeof wrappedMethod) + " property " +
524
685
  property + " as function");
525
686
  }
526
687
 
527
688
  if (wrappedMethod.restore && wrappedMethod.restore.sinon) {
528
- throw new TypeError("Attempted to wrap " + property + " which is already wrapped");
689
+ error = new TypeError("Attempted to wrap " + property + " which is already wrapped");
529
690
  }
530
691
 
531
692
  if (wrappedMethod.calledBefore) {
532
693
  var verb = !!wrappedMethod.returns ? "stubbed" : "spied on";
533
- throw new TypeError("Attempted to wrap " + property + " which is already " + verb);
694
+ error = new TypeError("Attempted to wrap " + property + " which is already " + verb);
534
695
  }
535
696
 
536
- // IE 8 does not support hasOwnProperty on the window object.
537
- var owned = hasOwn.call(object, property);
697
+ if (error) {
698
+ if (wrappedMethod._stack) {
699
+ error.stack += '\n--------------\n' + wrappedMethod._stack;
700
+ }
701
+ throw error;
702
+ }
703
+
704
+ // IE 8 does not support hasOwnProperty on the window object and Firefox has a problem
705
+ // when using hasOwn.call on objects from other frames.
706
+ var owned = object.hasOwnProperty ? object.hasOwnProperty(property) : hasOwn.call(object, property);
538
707
  object[property] = method;
539
708
  method.displayName = property;
709
+ // Set up a stack trace which can be used later to find what line of
710
+ // code the original method was created on.
711
+ method._stack = (new Error('Stack Trace for original')).stack;
540
712
 
541
713
  method.restore = function () {
542
714
  // For prototype properties try to reset by delete first.
@@ -600,31 +772,26 @@ var sinon = (function (buster) {
600
772
  return false;
601
773
  }
602
774
 
775
+ if (a instanceof RegExp && b instanceof RegExp) {
776
+ return (a.source === b.source) && (a.global === b.global) &&
777
+ (a.ignoreCase === b.ignoreCase) && (a.multiline === b.multiline);
778
+ }
779
+
603
780
  var aString = Object.prototype.toString.call(a);
604
781
  if (aString != Object.prototype.toString.call(b)) {
605
782
  return false;
606
783
  }
607
784
 
608
- if (aString == "[object Array]") {
609
- if (a.length !== b.length) {
610
- return false;
611
- }
612
-
613
- for (var i = 0, l = a.length; i < l; i += 1) {
614
- if (!deepEqual(a[i], b[i])) {
615
- return false;
616
- }
617
- }
618
-
619
- return true;
620
- }
621
-
622
785
  if (aString == "[object Date]") {
623
786
  return a.valueOf() === b.valueOf();
624
787
  }
625
788
 
626
789
  var prop, aLength = 0, bLength = 0;
627
790
 
791
+ if (aString == "[object Array]" && a.length !== b.length) {
792
+ return false;
793
+ }
794
+
628
795
  for (prop in a) {
629
796
  aLength += 1;
630
797
 
@@ -731,7 +898,7 @@ var sinon = (function (buster) {
731
898
  log: function () {},
732
899
 
733
900
  logError: function (label, err) {
734
- var msg = label + " threw exception: "
901
+ var msg = label + " threw exception: ";
735
902
  sinon.log(msg + "[" + err.name + "] " + err.message);
736
903
  if (err.stack) { sinon.log(err.stack); }
737
904
 
@@ -773,14 +940,21 @@ var sinon = (function (buster) {
773
940
  }
774
941
  };
775
942
 
776
- var isNode = typeof module == "object" && typeof require == "function";
943
+ var isNode = typeof module !== "undefined" && module.exports;
944
+ var isAMD = typeof define === 'function' && typeof define.amd === 'object' && define.amd;
777
945
 
778
- if (isNode) {
946
+ if (isAMD) {
947
+ define(function(){
948
+ return sinon;
949
+ });
950
+ } else if (isNode) {
779
951
  try {
780
- buster = { format: require("buster-format") };
952
+ formatio = require("formatio");
781
953
  } catch (e) {}
782
954
  module.exports = sinon;
783
955
  module.exports.spy = require("./sinon/spy");
956
+ module.exports.spyCall = require("./sinon/call");
957
+ module.exports.behavior = require("./sinon/behavior");
784
958
  module.exports.stub = require("./sinon/stub");
785
959
  module.exports.mock = require("./sinon/mock");
786
960
  module.exports.collection = require("./sinon/collection");
@@ -792,9 +966,8 @@ var sinon = (function (buster) {
792
966
  module.exports.match = require("./sinon/match");
793
967
  }
794
968
 
795
- if (buster) {
796
- var formatter = sinon.create(buster.format);
797
- formatter.quoteStrings = false;
969
+ if (formatio) {
970
+ var formatter = formatio.configure({ quoteStrings: false });
798
971
  sinon.format = function () {
799
972
  return formatter.ascii.apply(formatter, arguments);
800
973
  };
@@ -811,7 +984,7 @@ var sinon = (function (buster) {
811
984
  }
812
985
 
813
986
  return sinon;
814
- }(typeof buster == "object" && buster));
987
+ }(typeof formatio == "object" && formatio));
815
988
 
816
989
  /* @depend ../sinon.js */
817
990
  /*jslint eqeqeq: false, onevar: false, plusplus: false*/
@@ -826,7 +999,7 @@ var sinon = (function (buster) {
826
999
  */
827
1000
 
828
1001
  (function (sinon) {
829
- var commonJSModule = typeof module == "object" && typeof require == "function";
1002
+ var commonJSModule = typeof module !== 'undefined' && module.exports;
830
1003
 
831
1004
  if (!sinon && commonJSModule) {
832
1005
  sinon = require("../sinon");
@@ -879,8 +1052,10 @@ var sinon = (function (buster) {
879
1052
  }
880
1053
 
881
1054
  matcher.or = function (m2) {
882
- if (!isMatcher(m2)) {
1055
+ if (!arguments.length) {
883
1056
  throw new TypeError("Matcher expected");
1057
+ } else if (!isMatcher(m2)) {
1058
+ m2 = match(m2);
884
1059
  }
885
1060
  var m1 = this;
886
1061
  var or = sinon.create(matcher);
@@ -892,8 +1067,10 @@ var sinon = (function (buster) {
892
1067
  };
893
1068
 
894
1069
  matcher.and = function (m2) {
895
- if (!isMatcher(m2)) {
1070
+ if (!arguments.length) {
896
1071
  throw new TypeError("Matcher expected");
1072
+ } else if (!isMatcher(m2)) {
1073
+ m2 = match(m2);
897
1074
  }
898
1075
  var m1 = this;
899
1076
  var and = sinon.create(matcher);
@@ -1069,13 +1246,16 @@ var sinon = (function (buster) {
1069
1246
  * Copyright (c) 2013 Maximilian Antoni
1070
1247
  */
1071
1248
 
1072
- var commonJSModule = typeof module == "object" && typeof require == "function";
1249
+ (function (sinon) {
1250
+ var commonJSModule = typeof module !== 'undefined' && module.exports;
1251
+ if (!sinon && commonJSModule) {
1252
+ sinon = require("../sinon");
1253
+ }
1073
1254
 
1074
- if (!this.sinon && commonJSModule) {
1075
- var sinon = require("../sinon");
1076
- }
1255
+ if (!sinon) {
1256
+ return;
1257
+ }
1077
1258
 
1078
- (function (sinon) {
1079
1259
  function throwYieldError(proxy, text, args) {
1080
1260
  var msg = sinon.functionName(proxy) + text;
1081
1261
  if (args.length) {
@@ -1140,8 +1320,8 @@ if (!this.sinon && commonJSModule) {
1140
1320
  return this.exception === error || this.exception.name === error;
1141
1321
  },
1142
1322
 
1143
- calledWithNew: function calledWithNew(thisValue) {
1144
- return this.thisValue instanceof this.proxy;
1323
+ calledWithNew: function calledWithNew() {
1324
+ return this.proxy.prototype && this.thisValue instanceof this.proxy;
1145
1325
  },
1146
1326
 
1147
1327
  calledBefore: function (other) {
@@ -1241,14 +1421,20 @@ if (!this.sinon && commonJSModule) {
1241
1421
  proxyCall.callId = id;
1242
1422
 
1243
1423
  return proxyCall;
1244
- };
1424
+ }
1245
1425
  createSpyCall.toString = callProto.toString; // used by mocks
1246
1426
 
1247
- sinon.spyCall = createSpyCall;
1427
+ if (commonJSModule) {
1428
+ module.exports = createSpyCall;
1429
+ } else {
1430
+ sinon.spyCall = createSpyCall;
1431
+ }
1248
1432
  }(typeof sinon == "object" && sinon || null));
1249
1433
 
1434
+
1250
1435
  /**
1251
1436
  * @depend ../sinon.js
1437
+ * @depend call.js
1252
1438
  */
1253
1439
  /*jslint eqeqeq: false, onevar: false, plusplus: false*/
1254
1440
  /*global module, require, sinon*/
@@ -1262,11 +1448,19 @@ if (!this.sinon && commonJSModule) {
1262
1448
  */
1263
1449
 
1264
1450
  (function (sinon) {
1265
- var commonJSModule = typeof module == "object" && typeof require == "function";
1451
+ var commonJSModule = typeof module !== 'undefined' && module.exports;
1266
1452
  var push = Array.prototype.push;
1267
1453
  var slice = Array.prototype.slice;
1268
1454
  var callId = 0;
1269
1455
 
1456
+ if (!sinon && commonJSModule) {
1457
+ sinon = require("../sinon");
1458
+ }
1459
+
1460
+ if (!sinon) {
1461
+ return;
1462
+ }
1463
+
1270
1464
  function spy(object, property) {
1271
1465
  if (!property && typeof object == "function") {
1272
1466
  return spy.create(object);
@@ -1285,8 +1479,6 @@ if (!this.sinon && commonJSModule) {
1285
1479
  return;
1286
1480
  }
1287
1481
 
1288
- var alen = args.length;
1289
-
1290
1482
  for (var i = 0, l = fakes.length; i < l; i++) {
1291
1483
  if (fakes[i].matches(args, strict)) {
1292
1484
  return fakes[i];
@@ -1393,18 +1585,24 @@ if (!this.sinon && commonJSModule) {
1393
1585
  } else {
1394
1586
  returnValue = (this.func || func).apply(thisValue, args);
1395
1587
  }
1588
+
1589
+ var thisCall = this.getCall(this.callCount - 1);
1590
+ if (thisCall.calledWithNew() && typeof returnValue !== 'object') {
1591
+ returnValue = thisValue;
1592
+ }
1396
1593
  } catch (e) {
1397
- push.call(this.returnValues, undefined);
1398
1594
  exception = e;
1399
- throw e;
1400
- } finally {
1401
- push.call(this.exceptions, exception);
1402
1595
  }
1403
1596
 
1597
+ push.call(this.exceptions, exception);
1404
1598
  push.call(this.returnValues, returnValue);
1405
1599
 
1406
1600
  createCallProperties.call(this);
1407
1601
 
1602
+ if (exception !== undefined) {
1603
+ throw exception;
1604
+ }
1605
+
1408
1606
  return returnValue;
1409
1607
  },
1410
1608
 
@@ -1418,6 +1616,17 @@ if (!this.sinon && commonJSModule) {
1418
1616
  this.callIds[i]);
1419
1617
  },
1420
1618
 
1619
+ getCalls: function () {
1620
+ var calls = [];
1621
+ var i;
1622
+
1623
+ for (i = 0; i < this.callCount; i++) {
1624
+ calls.push(this.getCall(i));
1625
+ }
1626
+
1627
+ return calls;
1628
+ },
1629
+
1421
1630
  calledBefore: function calledBefore(spyFn) {
1422
1631
  if (!this.called) {
1423
1632
  return false;
@@ -1454,6 +1663,7 @@ if (!this.sinon && commonJSModule) {
1454
1663
  var original = this;
1455
1664
  var fake = this._create();
1456
1665
  fake.matchingAguments = args;
1666
+ fake.parent = this;
1457
1667
  push.call(this.fakes, fake);
1458
1668
 
1459
1669
  fake.withArgs = function () {
@@ -1494,7 +1704,7 @@ if (!this.sinon && commonJSModule) {
1494
1704
 
1495
1705
  if (typeof formatter == "function") {
1496
1706
  return formatter.call(null, spy, args);
1497
- } else if (!isNaN(parseInt(specifyer), 10)) {
1707
+ } else if (!isNaN(parseInt(specifyer, 10))) {
1498
1708
  return sinon.format(args[specifyer - 1]);
1499
1709
  }
1500
1710
 
@@ -1597,41 +1807,373 @@ if (!this.sinon && commonJSModule) {
1597
1807
  return calls.length > 0 ? "\n" + calls.join("\n") : "";
1598
1808
  },
1599
1809
 
1600
- "t": function (spy) {
1601
- var objects = [];
1810
+ "t": function (spy) {
1811
+ var objects = [];
1812
+
1813
+ for (var i = 0, l = spy.callCount; i < l; ++i) {
1814
+ push.call(objects, sinon.format(spy.thisValues[i]));
1815
+ }
1816
+
1817
+ return objects.join(", ");
1818
+ },
1819
+
1820
+ "*": function (spy, args) {
1821
+ var formatted = [];
1822
+
1823
+ for (var i = 0, l = args.length; i < l; ++i) {
1824
+ push.call(formatted, sinon.format(args[i]));
1825
+ }
1826
+
1827
+ return formatted.join(", ");
1828
+ }
1829
+ };
1830
+
1831
+ sinon.extend(spy, spyApi);
1832
+
1833
+ spy.spyCall = sinon.spyCall;
1834
+
1835
+ if (commonJSModule) {
1836
+ module.exports = spy;
1837
+ } else {
1838
+ sinon.spy = spy;
1839
+ }
1840
+ }(typeof sinon == "object" && sinon || null));
1841
+
1842
+ /**
1843
+ * @depend ../sinon.js
1844
+ */
1845
+ /*jslint eqeqeq: false, onevar: false*/
1846
+ /*global module, require, sinon, process, setImmediate, setTimeout*/
1847
+ /**
1848
+ * Stub behavior
1849
+ *
1850
+ * @author Christian Johansen (christian@cjohansen.no)
1851
+ * @author Tim Fischbach (mail@timfischbach.de)
1852
+ * @license BSD
1853
+ *
1854
+ * Copyright (c) 2010-2013 Christian Johansen
1855
+ */
1856
+
1857
+ (function (sinon) {
1858
+ var commonJSModule = typeof module !== 'undefined' && module.exports;
1859
+
1860
+ if (!sinon && commonJSModule) {
1861
+ sinon = require("../sinon");
1862
+ }
1863
+
1864
+ if (!sinon) {
1865
+ return;
1866
+ }
1867
+
1868
+ var slice = Array.prototype.slice;
1869
+ var join = Array.prototype.join;
1870
+ var proto;
1871
+
1872
+ var nextTick = (function () {
1873
+ if (typeof process === "object" && typeof process.nextTick === "function") {
1874
+ return process.nextTick;
1875
+ } else if (typeof setImmediate === "function") {
1876
+ return setImmediate;
1877
+ } else {
1878
+ return function (callback) {
1879
+ setTimeout(callback, 0);
1880
+ };
1881
+ }
1882
+ })();
1883
+
1884
+ function throwsException(error, message) {
1885
+ if (typeof error == "string") {
1886
+ this.exception = new Error(message || "");
1887
+ this.exception.name = error;
1888
+ } else if (!error) {
1889
+ this.exception = new Error("Error");
1890
+ } else {
1891
+ this.exception = error;
1892
+ }
1893
+
1894
+ return this;
1895
+ }
1896
+
1897
+ function getCallback(behavior, args) {
1898
+ var callArgAt = behavior.callArgAt;
1899
+
1900
+ if (callArgAt < 0) {
1901
+ var callArgProp = behavior.callArgProp;
1902
+
1903
+ for (var i = 0, l = args.length; i < l; ++i) {
1904
+ if (!callArgProp && typeof args[i] == "function") {
1905
+ return args[i];
1906
+ }
1907
+
1908
+ if (callArgProp && args[i] &&
1909
+ typeof args[i][callArgProp] == "function") {
1910
+ return args[i][callArgProp];
1911
+ }
1912
+ }
1913
+
1914
+ return null;
1915
+ }
1916
+
1917
+ return args[callArgAt];
1918
+ }
1919
+
1920
+ function getCallbackError(behavior, func, args) {
1921
+ if (behavior.callArgAt < 0) {
1922
+ var msg;
1923
+
1924
+ if (behavior.callArgProp) {
1925
+ msg = sinon.functionName(behavior.stub) +
1926
+ " expected to yield to '" + behavior.callArgProp +
1927
+ "', but no object with such a property was passed.";
1928
+ } else {
1929
+ msg = sinon.functionName(behavior.stub) +
1930
+ " expected to yield, but no callback was passed.";
1931
+ }
1932
+
1933
+ if (args.length > 0) {
1934
+ msg += " Received [" + join.call(args, ", ") + "]";
1935
+ }
1936
+
1937
+ return msg;
1938
+ }
1939
+
1940
+ return "argument at index " + behavior.callArgAt + " is not a function: " + func;
1941
+ }
1942
+
1943
+ function callCallback(behavior, args) {
1944
+ if (typeof behavior.callArgAt == "number") {
1945
+ var func = getCallback(behavior, args);
1946
+
1947
+ if (typeof func != "function") {
1948
+ throw new TypeError(getCallbackError(behavior, func, args));
1949
+ }
1950
+
1951
+ if (behavior.callbackAsync) {
1952
+ nextTick(function() {
1953
+ func.apply(behavior.callbackContext, behavior.callbackArguments);
1954
+ });
1955
+ } else {
1956
+ func.apply(behavior.callbackContext, behavior.callbackArguments);
1957
+ }
1958
+ }
1959
+ }
1960
+
1961
+ proto = {
1962
+ create: function(stub) {
1963
+ var behavior = sinon.extend({}, sinon.behavior);
1964
+ delete behavior.create;
1965
+ behavior.stub = stub;
1966
+
1967
+ return behavior;
1968
+ },
1969
+
1970
+ isPresent: function() {
1971
+ return (typeof this.callArgAt == 'number' ||
1972
+ this.exception ||
1973
+ typeof this.returnArgAt == 'number' ||
1974
+ this.returnThis ||
1975
+ this.returnValueDefined);
1976
+ },
1977
+
1978
+ invoke: function(context, args) {
1979
+ callCallback(this, args);
1980
+
1981
+ if (this.exception) {
1982
+ throw this.exception;
1983
+ } else if (typeof this.returnArgAt == 'number') {
1984
+ return args[this.returnArgAt];
1985
+ } else if (this.returnThis) {
1986
+ return context;
1987
+ }
1988
+
1989
+ return this.returnValue;
1990
+ },
1991
+
1992
+ onCall: function(index) {
1993
+ return this.stub.onCall(index);
1994
+ },
1995
+
1996
+ onFirstCall: function() {
1997
+ return this.stub.onFirstCall();
1998
+ },
1999
+
2000
+ onSecondCall: function() {
2001
+ return this.stub.onSecondCall();
2002
+ },
2003
+
2004
+ onThirdCall: function() {
2005
+ return this.stub.onThirdCall();
2006
+ },
2007
+
2008
+ withArgs: function(/* arguments */) {
2009
+ throw new Error('Defining a stub by invoking "stub.onCall(...).withArgs(...)" is not supported. ' +
2010
+ 'Use "stub.withArgs(...).onCall(...)" to define sequential behavior for calls with certain arguments.');
2011
+ },
2012
+
2013
+ callsArg: function callsArg(pos) {
2014
+ if (typeof pos != "number") {
2015
+ throw new TypeError("argument index is not number");
2016
+ }
2017
+
2018
+ this.callArgAt = pos;
2019
+ this.callbackArguments = [];
2020
+ this.callbackContext = undefined;
2021
+ this.callArgProp = undefined;
2022
+ this.callbackAsync = false;
2023
+
2024
+ return this;
2025
+ },
2026
+
2027
+ callsArgOn: function callsArgOn(pos, context) {
2028
+ if (typeof pos != "number") {
2029
+ throw new TypeError("argument index is not number");
2030
+ }
2031
+ if (typeof context != "object") {
2032
+ throw new TypeError("argument context is not an object");
2033
+ }
2034
+
2035
+ this.callArgAt = pos;
2036
+ this.callbackArguments = [];
2037
+ this.callbackContext = context;
2038
+ this.callArgProp = undefined;
2039
+ this.callbackAsync = false;
2040
+
2041
+ return this;
2042
+ },
2043
+
2044
+ callsArgWith: function callsArgWith(pos) {
2045
+ if (typeof pos != "number") {
2046
+ throw new TypeError("argument index is not number");
2047
+ }
2048
+
2049
+ this.callArgAt = pos;
2050
+ this.callbackArguments = slice.call(arguments, 1);
2051
+ this.callbackContext = undefined;
2052
+ this.callArgProp = undefined;
2053
+ this.callbackAsync = false;
2054
+
2055
+ return this;
2056
+ },
2057
+
2058
+ callsArgOnWith: function callsArgWith(pos, context) {
2059
+ if (typeof pos != "number") {
2060
+ throw new TypeError("argument index is not number");
2061
+ }
2062
+ if (typeof context != "object") {
2063
+ throw new TypeError("argument context is not an object");
2064
+ }
2065
+
2066
+ this.callArgAt = pos;
2067
+ this.callbackArguments = slice.call(arguments, 2);
2068
+ this.callbackContext = context;
2069
+ this.callArgProp = undefined;
2070
+ this.callbackAsync = false;
2071
+
2072
+ return this;
2073
+ },
2074
+
2075
+ yields: function () {
2076
+ this.callArgAt = -1;
2077
+ this.callbackArguments = slice.call(arguments, 0);
2078
+ this.callbackContext = undefined;
2079
+ this.callArgProp = undefined;
2080
+ this.callbackAsync = false;
2081
+
2082
+ return this;
2083
+ },
2084
+
2085
+ yieldsOn: function (context) {
2086
+ if (typeof context != "object") {
2087
+ throw new TypeError("argument context is not an object");
2088
+ }
2089
+
2090
+ this.callArgAt = -1;
2091
+ this.callbackArguments = slice.call(arguments, 1);
2092
+ this.callbackContext = context;
2093
+ this.callArgProp = undefined;
2094
+ this.callbackAsync = false;
2095
+
2096
+ return this;
2097
+ },
2098
+
2099
+ yieldsTo: function (prop) {
2100
+ this.callArgAt = -1;
2101
+ this.callbackArguments = slice.call(arguments, 1);
2102
+ this.callbackContext = undefined;
2103
+ this.callArgProp = prop;
2104
+ this.callbackAsync = false;
1602
2105
 
1603
- for (var i = 0, l = spy.callCount; i < l; ++i) {
1604
- push.call(objects, sinon.format(spy.thisValues[i]));
2106
+ return this;
2107
+ },
2108
+
2109
+ yieldsToOn: function (prop, context) {
2110
+ if (typeof context != "object") {
2111
+ throw new TypeError("argument context is not an object");
1605
2112
  }
1606
2113
 
1607
- return objects.join(", ");
2114
+ this.callArgAt = -1;
2115
+ this.callbackArguments = slice.call(arguments, 2);
2116
+ this.callbackContext = context;
2117
+ this.callArgProp = prop;
2118
+ this.callbackAsync = false;
2119
+
2120
+ return this;
1608
2121
  },
1609
2122
 
1610
- "*": function (spy, args) {
1611
- var formatted = [];
1612
2123
 
1613
- for (var i = 0, l = args.length; i < l; ++i) {
1614
- push.call(formatted, sinon.format(args[i]));
2124
+ "throws": throwsException,
2125
+ throwsException: throwsException,
2126
+
2127
+ returns: function returns(value) {
2128
+ this.returnValue = value;
2129
+ this.returnValueDefined = true;
2130
+
2131
+ return this;
2132
+ },
2133
+
2134
+ returnsArg: function returnsArg(pos) {
2135
+ if (typeof pos != "number") {
2136
+ throw new TypeError("argument index is not number");
1615
2137
  }
1616
2138
 
1617
- return formatted.join(", ");
2139
+ this.returnArgAt = pos;
2140
+
2141
+ return this;
2142
+ },
2143
+
2144
+ returnsThis: function returnsThis() {
2145
+ this.returnThis = true;
2146
+
2147
+ return this;
1618
2148
  }
1619
2149
  };
1620
2150
 
1621
- sinon.extend(spy, spyApi);
1622
-
1623
- spy.spyCall = sinon.spyCall;
2151
+ // create asynchronous versions of callsArg* and yields* methods
2152
+ for (var method in proto) {
2153
+ // need to avoid creating anotherasync versions of the newly added async methods
2154
+ if (proto.hasOwnProperty(method) &&
2155
+ method.match(/^(callsArg|yields)/) &&
2156
+ !method.match(/Async/)) {
2157
+ proto[method + 'Async'] = (function (syncFnName) {
2158
+ return function () {
2159
+ var result = this[syncFnName].apply(this, arguments);
2160
+ this.callbackAsync = true;
2161
+ return result;
2162
+ };
2163
+ })(method);
2164
+ }
2165
+ }
1624
2166
 
1625
2167
  if (commonJSModule) {
1626
- module.exports = spy;
2168
+ module.exports = proto;
1627
2169
  } else {
1628
- sinon.spy = spy;
2170
+ sinon.behavior = proto;
1629
2171
  }
1630
2172
  }(typeof sinon == "object" && sinon || null));
1631
-
1632
2173
  /**
1633
2174
  * @depend ../sinon.js
1634
2175
  * @depend spy.js
2176
+ * @depend behavior.js
1635
2177
  */
1636
2178
  /*jslint eqeqeq: false, onevar: false*/
1637
2179
  /*global module, require, sinon*/
@@ -1645,7 +2187,7 @@ if (!this.sinon && commonJSModule) {
1645
2187
  */
1646
2188
 
1647
2189
  (function (sinon) {
1648
- var commonJSModule = typeof module == "object" && typeof require == "function";
2190
+ var commonJSModule = typeof module !== 'undefined' && module.exports;
1649
2191
 
1650
2192
  if (!sinon && commonJSModule) {
1651
2193
  sinon = require("../sinon");
@@ -1668,11 +2210,11 @@ if (!this.sinon && commonJSModule) {
1668
2210
  wrapper = stub.create();
1669
2211
  }
1670
2212
 
1671
- if (!object && !property) {
2213
+ if (!object && typeof property === "undefined") {
1672
2214
  return sinon.stub.create();
1673
2215
  }
1674
2216
 
1675
- if (!property && !!object && typeof object == "object") {
2217
+ if (typeof property === "undefined" && typeof object == "object") {
1676
2218
  for (var prop in object) {
1677
2219
  if (typeof object[prop] === "function") {
1678
2220
  stub(object, prop);
@@ -1685,128 +2227,26 @@ if (!this.sinon && commonJSModule) {
1685
2227
  return sinon.wrapMethod(object, property, wrapper);
1686
2228
  }
1687
2229
 
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;
1693
-
1694
- return prop;
1695
- }
1696
-
1697
- function getCallback(stub, args) {
1698
- var callArgAt = getChangingValue(stub, "callArgAts");
1699
-
1700
- if (callArgAt < 0) {
1701
- var callArgProp = getChangingValue(stub, "callArgProps");
1702
-
1703
- for (var i = 0, l = args.length; i < l; ++i) {
1704
- if (!callArgProp && typeof args[i] == "function") {
1705
- return args[i];
1706
- }
1707
-
1708
- if (callArgProp && args[i] &&
1709
- typeof args[i][callArgProp] == "function") {
1710
- return args[i][callArgProp];
1711
- }
1712
- }
1713
-
1714
- return null;
1715
- }
1716
-
1717
- return args[callArgAt];
2230
+ function getDefaultBehavior(stub) {
2231
+ return stub.defaultBehavior || getParentBehaviour(stub) || sinon.behavior.create(stub);
1718
2232
  }
1719
2233
 
1720
- var join = Array.prototype.join;
1721
-
1722
- function getCallbackError(stub, func, args) {
1723
- if (stub.callArgAtsLast < 0) {
1724
- var msg;
1725
-
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."
1730
- } else {
1731
- msg = sinon.functionName(stub) +
1732
- " expected to yield, but no callback was passed."
1733
- }
1734
-
1735
- if (args.length > 0) {
1736
- msg += " Received [" + join.call(args, ", ") + "]";
1737
- }
1738
-
1739
- return msg;
1740
- }
1741
-
1742
- return "argument at index " + stub.callArgAtsLast + " is not a function: " + func;
2234
+ function getParentBehaviour(stub) {
2235
+ return (stub.parent && getCurrentBehavior(stub.parent));
1743
2236
  }
1744
2237
 
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;
1750
- } else {
1751
- return function (callback) {
1752
- setTimeout(callback, 0);
1753
- };
1754
- }
1755
- })();
1756
-
1757
- function callCallback(stub, args) {
1758
- if (stub.callArgAts.length > 0) {
1759
- var func = getCallback(stub, args);
1760
-
1761
- if (typeof func != "function") {
1762
- throw new TypeError(getCallbackError(stub, func, args));
1763
- }
1764
-
1765
- var callbackArguments = getChangingValue(stub, "callbackArguments");
1766
- var callbackContext = getChangingValue(stub, "callbackContexts");
1767
-
1768
- if (stub.callbackAsync) {
1769
- nextTick(function() {
1770
- func.apply(callbackContext, callbackArguments);
1771
- });
1772
- } else {
1773
- func.apply(callbackContext, callbackArguments);
1774
- }
1775
- }
2238
+ function getCurrentBehavior(stub) {
2239
+ var behavior = stub.behaviors[stub.callCount - 1];
2240
+ return behavior && behavior.isPresent() ? behavior : getDefaultBehavior(stub);
1776
2241
  }
1777
2242
 
1778
2243
  var uuid = 0;
1779
2244
 
1780
2245
  sinon.extend(stub, (function () {
1781
- var slice = Array.prototype.slice, proto;
1782
-
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");
1789
- } else {
1790
- this.exception = error;
1791
- }
1792
-
1793
- return this;
1794
- }
1795
-
1796
- proto = {
2246
+ var proto = {
1797
2247
  create: function create() {
1798
2248
  var functionStub = function () {
1799
-
1800
- callCallback(functionStub, arguments);
1801
-
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) {
1807
- return this;
1808
- }
1809
- return functionStub.returnValue;
2249
+ return getCurrentBehavior(functionStub).invoke(this, arguments);
1810
2250
  };
1811
2251
 
1812
2252
  functionStub.id = "stub#" + uuid++;
@@ -1814,26 +2254,22 @@ if (!this.sinon && commonJSModule) {
1814
2254
  functionStub = sinon.spy.create(functionStub);
1815
2255
  functionStub.func = orig;
1816
2256
 
1817
- functionStub.callArgAts = [];
1818
- functionStub.callbackArguments = [];
1819
- functionStub.callbackContexts = [];
1820
- functionStub.callArgProps = [];
1821
-
1822
2257
  sinon.extend(functionStub, stub);
1823
2258
  functionStub._create = sinon.stub.create;
1824
2259
  functionStub.displayName = "stub";
1825
2260
  functionStub.toString = sinon.functionToString;
1826
2261
 
2262
+ functionStub.defaultBehavior = null;
2263
+ functionStub.behaviors = [];
2264
+
1827
2265
  return functionStub;
1828
2266
  },
1829
2267
 
1830
2268
  resetBehavior: function () {
1831
2269
  var i;
1832
2270
 
1833
- this.callArgAts = [];
1834
- this.callbackArguments = [];
1835
- this.callbackContexts = [];
1836
- this.callArgProps = [];
2271
+ this.defaultBehavior = null;
2272
+ this.behaviors = [];
1837
2273
 
1838
2274
  delete this.returnValue;
1839
2275
  delete this.returnArgAt;
@@ -1846,151 +2282,44 @@ if (!this.sinon && commonJSModule) {
1846
2282
  }
1847
2283
  },
1848
2284
 
1849
- returns: function returns(value) {
1850
- this.returnValue = value;
1851
-
1852
- return this;
1853
- },
1854
-
1855
- returnsArg: function returnsArg(pos) {
1856
- if (typeof pos != "number") {
1857
- throw new TypeError("argument index is not number");
1858
- }
1859
-
1860
- this.returnArgAt = pos;
1861
-
1862
- return this;
1863
- },
1864
-
1865
- returnsThis: function returnsThis() {
1866
- this.returnThis = true;
1867
-
1868
- return this;
1869
- },
1870
-
1871
- "throws": throwsException,
1872
- throwsException: throwsException,
1873
-
1874
- callsArg: function callsArg(pos) {
1875
- if (typeof pos != "number") {
1876
- throw new TypeError("argument index is not number");
1877
- }
1878
-
1879
- this.callArgAts.push(pos);
1880
- this.callbackArguments.push([]);
1881
- this.callbackContexts.push(undefined);
1882
- this.callArgProps.push(undefined);
1883
-
1884
- return this;
1885
- },
1886
-
1887
- callsArgOn: function callsArgOn(pos, context) {
1888
- if (typeof pos != "number") {
1889
- throw new TypeError("argument index is not number");
1890
- }
1891
- if (typeof context != "object") {
1892
- throw new TypeError("argument context is not an object");
1893
- }
1894
-
1895
- this.callArgAts.push(pos);
1896
- this.callbackArguments.push([]);
1897
- this.callbackContexts.push(context);
1898
- this.callArgProps.push(undefined);
1899
-
1900
- return this;
1901
- },
1902
-
1903
- callsArgWith: function callsArgWith(pos) {
1904
- if (typeof pos != "number") {
1905
- throw new TypeError("argument index is not number");
1906
- }
1907
-
1908
- this.callArgAts.push(pos);
1909
- this.callbackArguments.push(slice.call(arguments, 1));
1910
- this.callbackContexts.push(undefined);
1911
- this.callArgProps.push(undefined);
1912
-
1913
- return this;
1914
- },
1915
-
1916
- callsArgOnWith: function callsArgWith(pos, context) {
1917
- if (typeof pos != "number") {
1918
- throw new TypeError("argument index is not number");
1919
- }
1920
- if (typeof context != "object") {
1921
- throw new TypeError("argument context is not an object");
2285
+ onCall: function(index) {
2286
+ if (!this.behaviors[index]) {
2287
+ this.behaviors[index] = sinon.behavior.create(this);
1922
2288
  }
1923
2289
 
1924
- this.callArgAts.push(pos);
1925
- this.callbackArguments.push(slice.call(arguments, 2));
1926
- this.callbackContexts.push(context);
1927
- this.callArgProps.push(undefined);
1928
-
1929
- return this;
1930
- },
1931
-
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);
1937
-
1938
- return this;
2290
+ return this.behaviors[index];
1939
2291
  },
1940
2292
 
1941
- yieldsOn: function (context) {
1942
- if (typeof context != "object") {
1943
- throw new TypeError("argument context is not an object");
1944
- }
1945
-
1946
- this.callArgAts.push(-1);
1947
- this.callbackArguments.push(slice.call(arguments, 1));
1948
- this.callbackContexts.push(context);
1949
- this.callArgProps.push(undefined);
1950
-
1951
- return this;
2293
+ onFirstCall: function() {
2294
+ return this.onCall(0);
1952
2295
  },
1953
2296
 
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);
1959
-
1960
- return this;
2297
+ onSecondCall: function() {
2298
+ return this.onCall(1);
1961
2299
  },
1962
2300
 
1963
- yieldsToOn: function (prop, context) {
1964
- if (typeof context != "object") {
1965
- throw new TypeError("argument context is not an object");
1966
- }
1967
-
1968
- this.callArgAts.push(-1);
1969
- this.callbackArguments.push(slice.call(arguments, 2));
1970
- this.callbackContexts.push(context);
1971
- this.callArgProps.push(prop);
1972
-
1973
- return this;
2301
+ onThirdCall: function() {
2302
+ return this.onCall(2);
1974
2303
  }
1975
2304
  };
1976
2305
 
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);
2306
+ for (var method in sinon.behavior) {
2307
+ if (sinon.behavior.hasOwnProperty(method) &&
2308
+ !proto.hasOwnProperty(method) &&
2309
+ method != 'create' &&
2310
+ method != 'withArgs' &&
2311
+ method != 'invoke') {
2312
+ proto[method] = (function(behaviorMethod) {
2313
+ return function() {
2314
+ this.defaultBehavior = this.defaultBehavior || sinon.behavior.create(this);
2315
+ this.defaultBehavior[behaviorMethod].apply(this.defaultBehavior, arguments);
2316
+ return this;
1987
2317
  };
1988
- })(method);
2318
+ }(method));
1989
2319
  }
1990
2320
  }
1991
2321
 
1992
2322
  return proto;
1993
-
1994
2323
  }()));
1995
2324
 
1996
2325
  if (commonJSModule) {
@@ -2016,8 +2345,9 @@ if (!this.sinon && commonJSModule) {
2016
2345
  */
2017
2346
 
2018
2347
  (function (sinon) {
2019
- var commonJSModule = typeof module == "object" && typeof require == "function";
2348
+ var commonJSModule = typeof module !== 'undefined' && module.exports;
2020
2349
  var push = [].push;
2350
+ var match;
2021
2351
 
2022
2352
  if (!sinon && commonJSModule) {
2023
2353
  sinon = require("../sinon");
@@ -2027,6 +2357,12 @@ if (!this.sinon && commonJSModule) {
2027
2357
  return;
2028
2358
  }
2029
2359
 
2360
+ match = sinon.match;
2361
+
2362
+ if (!match && commonJSModule) {
2363
+ match = require("./match");
2364
+ }
2365
+
2030
2366
  function mock(object) {
2031
2367
  if (!object) {
2032
2368
  return sinon.expectation.create("Anonymous mock");
@@ -2207,6 +2543,14 @@ if (!this.sinon && commonJSModule) {
2207
2543
  return expectation.callCount == expectation.maxCalls;
2208
2544
  }
2209
2545
 
2546
+ function verifyMatcher(possibleMatcher, arg){
2547
+ if (match && match.isMatcher(possibleMatcher)) {
2548
+ return possibleMatcher.test(arg);
2549
+ } else {
2550
+ return true;
2551
+ }
2552
+ }
2553
+
2210
2554
  return {
2211
2555
  minCalls: 1,
2212
2556
  maxCalls: 1,
@@ -2316,6 +2660,12 @@ if (!this.sinon && commonJSModule) {
2316
2660
  }
2317
2661
 
2318
2662
  for (var i = 0, l = this.expectedArguments.length; i < l; i += 1) {
2663
+
2664
+ if (!verifyMatcher(this.expectedArguments[i],args[i])) {
2665
+ sinon.expectation.fail(this.method + " received wrong arguments " + sinon.format(args) +
2666
+ ", didn't match " + this.expectedArguments.toString());
2667
+ }
2668
+
2319
2669
  if (!sinon.deepEqual(this.expectedArguments[i], args[i])) {
2320
2670
  sinon.expectation.fail(this.method + " received wrong arguments " + sinon.format(args) +
2321
2671
  ", expected " + sinon.format(this.expectedArguments));
@@ -2348,6 +2698,10 @@ if (!this.sinon && commonJSModule) {
2348
2698
  }
2349
2699
 
2350
2700
  for (var i = 0, l = this.expectedArguments.length; i < l; i += 1) {
2701
+ if (!verifyMatcher(this.expectedArguments[i],args[i])) {
2702
+ return false;
2703
+ }
2704
+
2351
2705
  if (!sinon.deepEqual(this.expectedArguments[i], args[i])) {
2352
2706
  return false;
2353
2707
  }
@@ -2441,7 +2795,7 @@ if (!this.sinon && commonJSModule) {
2441
2795
  */
2442
2796
 
2443
2797
  (function (sinon) {
2444
- var commonJSModule = typeof module == "object" && typeof require == "function";
2798
+ var commonJSModule = typeof module !== 'undefined' && module.exports;
2445
2799
  var push = [].push;
2446
2800
  var hasOwnProperty = Object.prototype.hasOwnProperty;
2447
2801
 
@@ -2609,6 +2963,10 @@ if (typeof sinon == "undefined") {
2609
2963
  throw new Error("Function requires at least 1 parameter");
2610
2964
  }
2611
2965
 
2966
+ if (typeof args[0] === "undefined") {
2967
+ throw new Error("Callback must be provided to timer calls");
2968
+ }
2969
+
2612
2970
  var toId = id++;
2613
2971
  var delay = args[1] || 0;
2614
2972
 
@@ -2710,6 +3068,16 @@ if (typeof sinon == "undefined") {
2710
3068
  this.clearTimeout(timerId);
2711
3069
  },
2712
3070
 
3071
+ setImmediate: function setImmediate(callback) {
3072
+ var passThruArgs = Array.prototype.slice.call(arguments, 1);
3073
+
3074
+ return addTimer.call(this, [callback, 0].concat(passThruArgs), false);
3075
+ },
3076
+
3077
+ clearImmediate: function clearImmediate(timerId) {
3078
+ this.clearTimeout(timerId);
3079
+ },
3080
+
2713
3081
  tick: function tick(ms) {
2714
3082
  ms = typeof ms == "number" ? ms : parseTime(ms);
2715
3083
  var tickFrom = this.now, tickTo = this.now + ms, previous = this.now;
@@ -2740,7 +3108,7 @@ if (typeof sinon == "undefined") {
2740
3108
  },
2741
3109
 
2742
3110
  firstTimerInRange: function (from, to) {
2743
- var timer, smallest, originalTimer;
3111
+ var timer, smallest = null, originalTimer;
2744
3112
 
2745
3113
  for (var id in this.timeouts) {
2746
3114
  if (this.timeouts.hasOwnProperty(id)) {
@@ -2748,7 +3116,7 @@ if (typeof sinon == "undefined") {
2748
3116
  continue;
2749
3117
  }
2750
3118
 
2751
- if (!smallest || this.timeouts[id].callAt < smallest) {
3119
+ if (smallest === null || this.timeouts[id].callAt < smallest) {
2752
3120
  originalTimer = this.timeouts[id];
2753
3121
  smallest = this.timeouts[id].callAt;
2754
3122
 
@@ -2854,21 +3222,39 @@ if (typeof sinon == "undefined") {
2854
3222
  target.parse = source.parse;
2855
3223
  target.UTC = source.UTC;
2856
3224
  target.prototype.toUTCString = source.prototype.toUTCString;
3225
+
3226
+ for (var prop in source) {
3227
+ if (source.hasOwnProperty(prop)) {
3228
+ target[prop] = source[prop];
3229
+ }
3230
+ }
3231
+
2857
3232
  return target;
2858
3233
  }
2859
3234
 
2860
3235
  var methods = ["Date", "setTimeout", "setInterval",
2861
3236
  "clearTimeout", "clearInterval"];
2862
3237
 
3238
+ if (typeof global.setImmediate !== "undefined") {
3239
+ methods.push("setImmediate");
3240
+ }
3241
+
3242
+ if (typeof global.clearImmediate !== "undefined") {
3243
+ methods.push("clearImmediate");
3244
+ }
3245
+
2863
3246
  function restore() {
2864
3247
  var method;
2865
3248
 
2866
3249
  for (var i = 0, l = this.methods.length; i < l; i++) {
2867
3250
  method = this.methods[i];
3251
+
2868
3252
  if (global[method].hadOwnProperty) {
2869
3253
  global[method] = this["_" + method];
2870
3254
  } else {
2871
- delete global[method];
3255
+ try {
3256
+ delete global[method];
3257
+ } catch (e) {}
2872
3258
  }
2873
3259
  }
2874
3260
 
@@ -2919,12 +3305,14 @@ if (typeof sinon == "undefined") {
2919
3305
  sinon.timers = {
2920
3306
  setTimeout: setTimeout,
2921
3307
  clearTimeout: clearTimeout,
3308
+ setImmediate: (typeof setImmediate !== "undefined" ? setImmediate : undefined),
3309
+ clearImmediate: (typeof clearImmediate !== "undefined" ? clearImmediate: undefined),
2922
3310
  setInterval: setInterval,
2923
3311
  clearInterval: clearInterval,
2924
3312
  Date: Date
2925
3313
  };
2926
3314
 
2927
- if (typeof module == "object" && typeof require == "function") {
3315
+ if (typeof module !== 'undefined' && module.exports) {
2928
3316
  module.exports = sinon;
2929
3317
  }
2930
3318
 
@@ -2969,14 +3357,33 @@ if (typeof sinon == "undefined") {
2969
3357
  }
2970
3358
  };
2971
3359
 
3360
+ sinon.ProgressEvent = function ProgressEvent(type, progressEventRaw, target) {
3361
+ this.initEvent(type, false, false, target);
3362
+ this.loaded = progressEventRaw.loaded || null;
3363
+ this.total = progressEventRaw.total || null;
3364
+ };
3365
+
3366
+ sinon.ProgressEvent.prototype = new sinon.Event();
3367
+
3368
+ sinon.ProgressEvent.prototype.constructor = sinon.ProgressEvent;
3369
+
3370
+ sinon.CustomEvent = function CustomEvent(type, customData, target) {
3371
+ this.initEvent(type, false, false, target);
3372
+ this.detail = customData.detail || null;
3373
+ };
3374
+
3375
+ sinon.CustomEvent.prototype = new sinon.Event();
3376
+
3377
+ sinon.CustomEvent.prototype.constructor = sinon.CustomEvent;
3378
+
2972
3379
  sinon.EventTarget = {
2973
- addEventListener: function addEventListener(event, listener, useCapture) {
3380
+ addEventListener: function addEventListener(event, listener) {
2974
3381
  this.eventListeners = this.eventListeners || {};
2975
3382
  this.eventListeners[event] = this.eventListeners[event] || [];
2976
3383
  push.call(this.eventListeners[event], listener);
2977
3384
  },
2978
3385
 
2979
- removeEventListener: function removeEventListener(event, listener, useCapture) {
3386
+ removeEventListener: function removeEventListener(event, listener) {
2980
3387
  var listeners = this.eventListeners && this.eventListeners[event] || [];
2981
3388
 
2982
3389
  for (var i = 0, l = listeners.length; i < l; ++i) {
@@ -3018,13 +3425,15 @@ if (typeof sinon == "undefined") {
3018
3425
  * Copyright (c) 2010-2013 Christian Johansen
3019
3426
  */
3020
3427
 
3021
- if (typeof sinon == "undefined") {
3022
- this.sinon = {};
3023
- }
3024
- sinon.xhr = { XMLHttpRequest: this.XMLHttpRequest };
3025
-
3026
3428
  // wrapper for global
3027
3429
  (function(global) {
3430
+ if (typeof sinon === "undefined") {
3431
+ global.sinon = {};
3432
+ }
3433
+
3434
+ var supportsProgress = typeof ProgressEvent !== "undefined";
3435
+ var supportsCustomEvent = typeof CustomEvent !== "undefined";
3436
+ sinon.xhr = { XMLHttpRequest: global.XMLHttpRequest };
3028
3437
  var xhr = sinon.xhr;
3029
3438
  xhr.GlobalXMLHttpRequest = global.XMLHttpRequest;
3030
3439
  xhr.GlobalActiveXObject = global.ActiveXObject;
@@ -3032,6 +3441,7 @@ sinon.xhr = { XMLHttpRequest: this.XMLHttpRequest };
3032
3441
  xhr.supportsXHR = typeof xhr.GlobalXMLHttpRequest != "undefined";
3033
3442
  xhr.workingXHR = xhr.supportsXHR ? xhr.GlobalXMLHttpRequest : xhr.supportsActiveX
3034
3443
  ? function() { return new xhr.GlobalActiveXObject("MSXML2.XMLHTTP.3.0") } : false;
3444
+ xhr.supportsCORS = 'withCredentials' in (new sinon.xhr.GlobalXMLHttpRequest());
3035
3445
 
3036
3446
  /*jsl:ignore*/
3037
3447
  var unsafeHeaders = {
@@ -3062,6 +3472,11 @@ sinon.xhr = { XMLHttpRequest: this.XMLHttpRequest };
3062
3472
  this.requestBody = null;
3063
3473
  this.status = 0;
3064
3474
  this.statusText = "";
3475
+ this.upload = new UploadProgress();
3476
+ if (sinon.xhr.supportsCORS) {
3477
+ this.withCredentials = false;
3478
+ }
3479
+
3065
3480
 
3066
3481
  var xhr = this;
3067
3482
  var events = ["loadstart", "load", "abort", "loadend"];
@@ -3071,7 +3486,7 @@ sinon.xhr = { XMLHttpRequest: this.XMLHttpRequest };
3071
3486
  var listener = xhr["on" + eventName];
3072
3487
 
3073
3488
  if (listener && typeof listener == "function") {
3074
- listener(event);
3489
+ listener.call(this, event);
3075
3490
  }
3076
3491
  });
3077
3492
  }
@@ -3085,6 +3500,41 @@ sinon.xhr = { XMLHttpRequest: this.XMLHttpRequest };
3085
3500
  }
3086
3501
  }
3087
3502
 
3503
+ // An upload object is created for each
3504
+ // FakeXMLHttpRequest and allows upload
3505
+ // events to be simulated using uploadProgress
3506
+ // and uploadError.
3507
+ function UploadProgress() {
3508
+ this.eventListeners = {
3509
+ "progress": [],
3510
+ "load": [],
3511
+ "abort": [],
3512
+ "error": []
3513
+ }
3514
+ }
3515
+
3516
+ UploadProgress.prototype.addEventListener = function(event, listener) {
3517
+ this.eventListeners[event].push(listener);
3518
+ };
3519
+
3520
+ UploadProgress.prototype.removeEventListener = function(event, listener) {
3521
+ var listeners = this.eventListeners[event] || [];
3522
+
3523
+ for (var i = 0, l = listeners.length; i < l; ++i) {
3524
+ if (listeners[i] == listener) {
3525
+ return listeners.splice(i, 1);
3526
+ }
3527
+ }
3528
+ };
3529
+
3530
+ UploadProgress.prototype.dispatchEvent = function(event) {
3531
+ var listeners = this.eventListeners[event.type] || [];
3532
+
3533
+ for (var i = 0, listener; (listener = listeners[i]) != null; i++) {
3534
+ listener(event);
3535
+ }
3536
+ };
3537
+
3088
3538
  function verifyState(xhr) {
3089
3539
  if (xhr.readyState !== FakeXMLHttpRequest.OPENED) {
3090
3540
  throw new Error("INVALID_STATE_ERR");
@@ -3106,7 +3556,7 @@ sinon.xhr = { XMLHttpRequest: this.XMLHttpRequest };
3106
3556
  function some(collection, callback) {
3107
3557
  for (var index = 0; index < collection.length; index++) {
3108
3558
  if(callback(collection[index]) === true) return true;
3109
- };
3559
+ }
3110
3560
  return false;
3111
3561
  }
3112
3562
  // largest arity in XHR is 5 - XHR#open
@@ -3118,7 +3568,7 @@ sinon.xhr = { XMLHttpRequest: this.XMLHttpRequest };
3118
3568
  case 3: return obj[method](args[0],args[1],args[2]);
3119
3569
  case 4: return obj[method](args[0],args[1],args[2],args[3]);
3120
3570
  case 5: return obj[method](args[0],args[1],args[2],args[3],args[4]);
3121
- };
3571
+ }
3122
3572
  };
3123
3573
 
3124
3574
  FakeXMLHttpRequest.filters = [];
@@ -3157,7 +3607,7 @@ sinon.xhr = { XMLHttpRequest: this.XMLHttpRequest };
3157
3607
  if(xhr.readyState === FakeXMLHttpRequest.DONE) {
3158
3608
  copyAttrs(["responseXML"]);
3159
3609
  }
3160
- if(fakeXhr.onreadystatechange) fakeXhr.onreadystatechange.call(fakeXhr);
3610
+ if(fakeXhr.onreadystatechange) fakeXhr.onreadystatechange.call(fakeXhr, { target: fakeXhr });
3161
3611
  };
3162
3612
  if(xhr.addEventListener) {
3163
3613
  for(var event in fakeXhr.eventListeners) {
@@ -3175,6 +3625,12 @@ sinon.xhr = { XMLHttpRequest: this.XMLHttpRequest };
3175
3625
  };
3176
3626
  FakeXMLHttpRequest.useFilters = false;
3177
3627
 
3628
+ function verifyRequestOpened(xhr) {
3629
+ if (xhr.readyState != FakeXMLHttpRequest.OPENED) {
3630
+ throw new Error("INVALID_STATE_ERR - " + xhr.readyState);
3631
+ }
3632
+ }
3633
+
3178
3634
  function verifyRequestSent(xhr) {
3179
3635
  if (xhr.readyState == FakeXMLHttpRequest.DONE) {
3180
3636
  throw new Error("Request done");
@@ -3238,6 +3694,10 @@ sinon.xhr = { XMLHttpRequest: this.XMLHttpRequest };
3238
3694
  case FakeXMLHttpRequest.DONE:
3239
3695
  this.dispatchEvent(new sinon.Event("load", false, false, this));
3240
3696
  this.dispatchEvent(new sinon.Event("loadend", false, false, this));
3697
+ this.upload.dispatchEvent(new sinon.Event("load", false, false, this));
3698
+ if (supportsProgress) {
3699
+ this.upload.dispatchEvent(new sinon.ProgressEvent('progress', {loaded: 100, total: 100}));
3700
+ }
3241
3701
  break;
3242
3702
  }
3243
3703
  },
@@ -3258,6 +3718,7 @@ sinon.xhr = { XMLHttpRequest: this.XMLHttpRequest };
3258
3718
 
3259
3719
  // Helps testing
3260
3720
  setResponseHeaders: function setResponseHeaders(headers) {
3721
+ verifyRequestOpened(this);
3261
3722
  this.responseHeaders = {};
3262
3723
 
3263
3724
  for (var header in headers) {
@@ -3313,6 +3774,9 @@ sinon.xhr = { XMLHttpRequest: this.XMLHttpRequest };
3313
3774
  this.readyState = sinon.FakeXMLHttpRequest.UNSENT;
3314
3775
 
3315
3776
  this.dispatchEvent(new sinon.Event("abort", false, false, this));
3777
+
3778
+ this.upload.dispatchEvent(new sinon.Event("abort", false, false, this));
3779
+
3316
3780
  if (typeof this.onerror === "function") {
3317
3781
  this.onerror();
3318
3782
  }
@@ -3392,14 +3856,22 @@ sinon.xhr = { XMLHttpRequest: this.XMLHttpRequest };
3392
3856
  },
3393
3857
 
3394
3858
  respond: function respond(status, headers, body) {
3395
- this.setResponseHeaders(headers || {});
3396
3859
  this.status = typeof status == "number" ? status : 200;
3397
3860
  this.statusText = FakeXMLHttpRequest.statusCodes[this.status];
3861
+ this.setResponseHeaders(headers || {});
3398
3862
  this.setResponseBody(body || "");
3399
- if (typeof this.onload === "function"){
3400
- this.onload();
3863
+ },
3864
+
3865
+ uploadProgress: function uploadProgress(progressEventRaw) {
3866
+ if (supportsProgress) {
3867
+ this.upload.dispatchEvent(new sinon.ProgressEvent("progress", progressEventRaw));
3401
3868
  }
3869
+ },
3402
3870
 
3871
+ uploadError: function uploadError(error) {
3872
+ if (supportsCustomEvent) {
3873
+ this.upload.dispatchEvent(new sinon.CustomEvent("error", {"detail": error}));
3874
+ }
3403
3875
  }
3404
3876
  });
3405
3877
 
@@ -3506,9 +3978,10 @@ sinon.xhr = { XMLHttpRequest: this.XMLHttpRequest };
3506
3978
  };
3507
3979
 
3508
3980
  sinon.FakeXMLHttpRequest = FakeXMLHttpRequest;
3509
- })(this);
3510
3981
 
3511
- if (typeof module == "object" && typeof require == "function") {
3982
+ })(typeof global === "object" ? global : this);
3983
+
3984
+ if (typeof module !== 'undefined' && module.exports) {
3512
3985
  module.exports = sinon;
3513
3986
  }
3514
3987
 
@@ -3570,7 +4043,6 @@ sinon.fakeServer = (function () {
3570
4043
  }
3571
4044
 
3572
4045
  function match(response, request) {
3573
- var requestMethod = this.getHTTPMethod(request);
3574
4046
  var requestUrl = request.url;
3575
4047
 
3576
4048
  if (!/^https?:\/\//.test(requestUrl) || rCurrLoc.test(requestUrl)) {
@@ -3580,7 +4052,7 @@ sinon.fakeServer = (function () {
3580
4052
  if (matchOne(response, this.getHTTPMethod(request), requestUrl)) {
3581
4053
  if (typeof response.response == "function") {
3582
4054
  var ru = response.url;
3583
- var args = [request].concat(!ru ? [] : requestUrl.match(ru).slice(1));
4055
+ var args = [request].concat(ru && typeof ru.exec == "function" ? ru.exec(requestUrl).slice(1) : []);
3584
4056
  return response.response.apply(response, args);
3585
4057
  }
3586
4058
 
@@ -3618,16 +4090,16 @@ sinon.fakeServer = (function () {
3618
4090
 
3619
4091
  xhrObj.onSend = function () {
3620
4092
  server.handleRequest(this);
3621
- };
3622
4093
 
3623
- if (this.autoRespond && !this.responding) {
3624
- setTimeout(function () {
3625
- server.responding = false;
3626
- server.respond();
3627
- }, this.autoRespondAfter || 10);
4094
+ if (server.autoRespond && !server.responding) {
4095
+ setTimeout(function () {
4096
+ server.responding = false;
4097
+ server.respond();
4098
+ }, server.autoRespondAfter || 10);
3628
4099
 
3629
- this.responding = true;
3630
- }
4100
+ server.responding = true;
4101
+ }
4102
+ };
3631
4103
  },
3632
4104
 
3633
4105
  getHTTPMethod: function getHTTPMethod(request) {
@@ -3680,9 +4152,10 @@ sinon.fakeServer = (function () {
3680
4152
  respond: function respond() {
3681
4153
  if (arguments.length > 0) this.respondWith.apply(this, arguments);
3682
4154
  var queue = this.queue || [];
4155
+ var requests = queue.splice(0);
3683
4156
  var request;
3684
4157
 
3685
- while(request = queue.shift()) {
4158
+ while(request = requests.shift()) {
3686
4159
  this.processRequest(request);
3687
4160
  }
3688
4161
  },
@@ -3696,7 +4169,7 @@ sinon.fakeServer = (function () {
3696
4169
  var response = this.response || [404, {}, ""];
3697
4170
 
3698
4171
  if (this.responses) {
3699
- for (var i = 0, l = this.responses.length; i < l; i++) {
4172
+ for (var l = this.responses.length, i = l - 1; i >= 0; i--) {
3700
4173
  if (match.call(this, this.responses[i], request)) {
3701
4174
  response = this.responses[i].response;
3702
4175
  break;
@@ -3720,7 +4193,7 @@ sinon.fakeServer = (function () {
3720
4193
  };
3721
4194
  }());
3722
4195
 
3723
- if (typeof module == "object" && typeof require == "function") {
4196
+ if (typeof module !== 'undefined' && module.exports) {
3724
4197
  module.exports = sinon;
3725
4198
  }
3726
4199
 
@@ -3825,7 +4298,7 @@ if (typeof module == "object" && typeof require == "function") {
3825
4298
  * Copyright (c) 2010-2013 Christian Johansen
3826
4299
  */
3827
4300
 
3828
- if (typeof module == "object" && typeof require == "function") {
4301
+ if (typeof module !== 'undefined' && module.exports) {
3829
4302
  var sinon = require("../sinon");
3830
4303
  sinon.extend(sinon, require("./util/fake_timers"));
3831
4304
  }
@@ -3838,8 +4311,9 @@ if (typeof module == "object" && typeof require == "function") {
3838
4311
  return;
3839
4312
  }
3840
4313
 
3841
- if (config.injectInto) {
4314
+ if (config.injectInto && !(key in config.injectInto)) {
3842
4315
  config.injectInto[key] = value;
4316
+ sandbox.injectedKeys.push(key);
3843
4317
  } else {
3844
4318
  push.call(sandbox.args, value);
3845
4319
  }
@@ -3902,6 +4376,20 @@ if (typeof module == "object" && typeof require == "function") {
3902
4376
  return obj;
3903
4377
  },
3904
4378
 
4379
+ restore: function () {
4380
+ sinon.collection.restore.apply(this, arguments);
4381
+ this.restoreContext();
4382
+ },
4383
+
4384
+ restoreContext: function () {
4385
+ if (this.injectedKeys) {
4386
+ for (var i = 0, j = this.injectedKeys.length; i < j; i++) {
4387
+ delete this.injectInto[this.injectedKeys[i]];
4388
+ }
4389
+ this.injectedKeys = [];
4390
+ }
4391
+ },
4392
+
3905
4393
  create: function (config) {
3906
4394
  if (!config) {
3907
4395
  return sinon.create(sinon.sandbox);
@@ -3909,6 +4397,8 @@ if (typeof module == "object" && typeof require == "function") {
3909
4397
 
3910
4398
  var sandbox = prepareSandboxFromConfig(config);
3911
4399
  sandbox.args = sandbox.args || [];
4400
+ sandbox.injectedKeys = [];
4401
+ sandbox.injectInto = config.injectInto;
3912
4402
  var prop, value, exposed = sandbox.inject({});
3913
4403
 
3914
4404
  if (config.properties) {
@@ -3927,7 +4417,7 @@ if (typeof module == "object" && typeof require == "function") {
3927
4417
 
3928
4418
  sinon.sandbox.useFakeXMLHttpRequest = sinon.sandbox.useFakeServer;
3929
4419
 
3930
- if (typeof module == "object" && typeof require == "function") {
4420
+ if (typeof module !== 'undefined' && module.exports) {
3931
4421
  module.exports = sinon.sandbox;
3932
4422
  }
3933
4423
  }());
@@ -3950,7 +4440,7 @@ if (typeof module == "object" && typeof require == "function") {
3950
4440
  */
3951
4441
 
3952
4442
  (function (sinon) {
3953
- var commonJSModule = typeof module == "object" && typeof require == "function";
4443
+ var commonJSModule = typeof module !== 'undefined' && module.exports;
3954
4444
 
3955
4445
  if (!sinon && commonJSModule) {
3956
4446
  sinon = require("../sinon");
@@ -4023,7 +4513,7 @@ if (typeof module == "object" && typeof require == "function") {
4023
4513
  */
4024
4514
 
4025
4515
  (function (sinon) {
4026
- var commonJSModule = typeof module == "object" && typeof require == "function";
4516
+ var commonJSModule = typeof module !== 'undefined' && module.exports;
4027
4517
 
4028
4518
  if (!sinon && commonJSModule) {
4029
4519
  sinon = require("../sinon");
@@ -4120,7 +4610,7 @@ if (typeof module == "object" && typeof require == "function") {
4120
4610
  */
4121
4611
 
4122
4612
  (function (sinon, global) {
4123
- var commonJSModule = typeof module == "object" && typeof require == "function";
4613
+ var commonJSModule = typeof module !== "undefined" && module.exports;
4124
4614
  var slice = Array.prototype.slice;
4125
4615
  var assert;
4126
4616
 
@@ -4188,7 +4678,7 @@ if (typeof module == "object" && typeof require == "function") {
4188
4678
  function exposedName(prefix, prop) {
4189
4679
  return !prefix || /^fail/.test(prop) ? prop :
4190
4680
  prefix + prop.slice(0, 1).toUpperCase() + prop.slice(1);
4191
- };
4681
+ }
4192
4682
 
4193
4683
  assert = {
4194
4684
  failException: "AssertError",
@@ -4256,6 +4746,20 @@ if (typeof module == "object" && typeof require == "function") {
4256
4746
  }
4257
4747
 
4258
4748
  return target;
4749
+ },
4750
+
4751
+ match: function match(actual, expectation) {
4752
+ var matcher = sinon.match(expectation);
4753
+ if (matcher.test(actual)) {
4754
+ assert.pass("match");
4755
+ } else {
4756
+ var formatted = [
4757
+ "expected value to match",
4758
+ " expected = " + sinon.format(expectation),
4759
+ " actual = " + sinon.format(actual)
4760
+ ]
4761
+ failAssertion(this, formatted.join("\n"));
4762
+ }
4259
4763
  }
4260
4764
  };
4261
4765
 
@@ -4287,4 +4791,4 @@ if (typeof module == "object" && typeof require == "function") {
4287
4791
  }
4288
4792
  }(typeof sinon == "object" && sinon || null, typeof window != "undefined" ? window : (typeof self != "undefined") ? self : global));
4289
4793
 
4290
- return sinon;}.call(typeof window != 'undefined' && window || {}));
4794
+ return sinon;}.call(typeof window != 'undefined' && window || {}));