sinon-rails 1.7.3 → 1.9.0

Sign up to get free protection for your applications and to get access to all the features.
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 || {}));