sinon-rails 1.4.2.1 → 1.7.1.1

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 11a0bac72b389c4bdc03ae66d0eaa3623091a4d6
4
+ data.tar.gz: 9294b7e031987f093d57a3bfac7510a016401369
5
+ SHA512:
6
+ metadata.gz: 62e074e8febff58dcfd878352717214df9110c7548ef5f4ecbe8eb61a0f04b90a348983a4d5c31f73ae00f1be99560e7333561bea1f33855f098c3231acaabfa
7
+ data.tar.gz: dbe097e0498ae20cc5e2e4b2c626dc0702bf7435f1775aebc9cf0e77bce8ec5529b82c6e5802536743898beeeb69a7ea817bb34f6b05cc8983505a21a568ae30
@@ -1,5 +1,5 @@
1
1
  module Sinon
2
2
  module Rails
3
- VERSION = "1.4.2.1"
3
+ VERSION = "1.7.1.1"
4
4
  end
5
5
  end
@@ -1,12 +1,12 @@
1
1
  /**
2
- * Sinon.JS 1.4.2, 2012/07/11
2
+ * Sinon.JS 1.7.1, 2013/05/07
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-2012, Christian Johansen, christian@cjohansen.no
9
+ * Copyright (c) 2010-2013, 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,
@@ -33,8 +33,7 @@
33
33
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34
34
  */
35
35
 
36
- "use strict";
37
- var sinon = (function () {
36
+ this.sinon = (function () {
38
37
  var buster = (function (setTimeout, B) {
39
38
  var isNode = typeof require == "function" && typeof module == "object";
40
39
  var div = typeof document != "undefined" && document.createElement("div");
@@ -462,7 +461,7 @@ if (typeof module != "undefined") {
462
461
  * @author Christian Johansen (christian@cjohansen.no)
463
462
  * @license BSD
464
463
  *
465
- * Copyright (c) 2010-2011 Christian Johansen
464
+ * Copyright (c) 2010-2013 Christian Johansen
466
465
  */
467
466
 
468
467
  var sinon = (function (buster) {
@@ -493,7 +492,7 @@ var sinon = (function (buster) {
493
492
  }
494
493
 
495
494
  function isFunction(obj) {
496
- return !!(obj && obj.constructor && obj.call && obj.apply);
495
+ return typeof obj === "function" || !!(obj && obj.constructor && obj.call && obj.apply);
497
496
  }
498
497
 
499
498
  function mirrorProperties(target, source) {
@@ -504,6 +503,10 @@ var sinon = (function (buster) {
504
503
  }
505
504
  }
506
505
 
506
+ function isRestorable (obj) {
507
+ return typeof obj === "function" && typeof obj.restore === "function" && obj.restore.sinon;
508
+ }
509
+
507
510
  var sinon = {
508
511
  wrapMethod: function wrapMethod(object, property, method) {
509
512
  if (!object) {
@@ -593,6 +596,10 @@ var sinon = (function (buster) {
593
596
  return true;
594
597
  }
595
598
 
599
+ if ((a === null && b !== null) || (a !== null && b === null)) {
600
+ return false;
601
+ }
602
+
596
603
  var aString = Object.prototype.toString.call(a);
597
604
  if (aString != Object.prototype.toString.call(b)) {
598
605
  return false;
@@ -626,11 +633,7 @@ var sinon = (function (buster) {
626
633
  bLength += 1;
627
634
  }
628
635
 
629
- if (aLength != bLength) {
630
- return false;
631
- }
632
-
633
- return true;
636
+ return aLength == bLength;
634
637
  },
635
638
 
636
639
  functionName: function functionName(func) {
@@ -701,7 +704,7 @@ var sinon = (function (buster) {
701
704
 
702
705
  calledInOrder: function (spies) {
703
706
  for (var i = 1, l = spies.length; i < l; i++) {
704
- if (!spies[i - 1].calledBefore(spies[i])) {
707
+ if (!spies[i - 1].calledBefore(spies[i]) || !spies[i].called) {
705
708
  return false;
706
709
  }
707
710
  }
@@ -736,10 +739,33 @@ var sinon = (function (buster) {
736
739
 
737
740
  typeOf: function (value) {
738
741
  if (value === null) {
739
- return "null";
742
+ return "null";
743
+ }
744
+ else if (value === undefined) {
745
+ return "undefined";
740
746
  }
741
747
  var string = Object.prototype.toString.call(value);
742
748
  return string.substring(8, string.length - 1).toLowerCase();
749
+ },
750
+
751
+ createStubInstance: function (constructor) {
752
+ if (typeof constructor !== "function") {
753
+ throw new TypeError("The constructor should be a function.");
754
+ }
755
+ return sinon.stub(sinon.create(constructor.prototype));
756
+ },
757
+
758
+ restore: function (object) {
759
+ if (object !== null && typeof object === "object") {
760
+ for (var prop in object) {
761
+ if (isRestorable(object[prop])) {
762
+ object[prop].restore();
763
+ }
764
+ }
765
+ }
766
+ else if (isRestorable(object)) {
767
+ object.restore();
768
+ }
743
769
  }
744
770
  };
745
771
 
@@ -751,6 +777,7 @@ var sinon = (function (buster) {
751
777
  } catch (e) {}
752
778
  module.exports = sinon;
753
779
  module.exports.spy = require("./sinon/spy");
780
+ module.exports.spyCall = require("./sinon/call");
754
781
  module.exports.stub = require("./sinon/stub");
755
782
  module.exports.mock = require("./sinon/mock");
756
783
  module.exports.collection = require("./sinon/collection");
@@ -1023,27 +1050,24 @@ var sinon = (function (buster) {
1023
1050
  }(typeof sinon == "object" && sinon || null));
1024
1051
 
1025
1052
  /**
1026
- * @depend ../sinon.js
1027
- * @depend match.js
1028
- */
1053
+ * @depend ../sinon.js
1054
+ * @depend match.js
1055
+ */
1029
1056
  /*jslint eqeqeq: false, onevar: false, plusplus: false*/
1030
1057
  /*global module, require, sinon*/
1031
1058
  /**
1032
- * Spy functions
1033
- *
1034
- * @author Christian Johansen (christian@cjohansen.no)
1035
- * @license BSD
1036
- *
1037
- * Copyright (c) 2010-2011 Christian Johansen
1038
- */
1059
+ * Spy calls
1060
+ *
1061
+ * @author Christian Johansen (christian@cjohansen.no)
1062
+ * @author Maximilian Antoni (mail@maxantoni.de)
1063
+ * @license BSD
1064
+ *
1065
+ * Copyright (c) 2010-2013 Christian Johansen
1066
+ * Copyright (c) 2013 Maximilian Antoni
1067
+ */
1039
1068
 
1040
1069
  (function (sinon) {
1041
1070
  var commonJSModule = typeof module == "object" && typeof require == "function";
1042
- var spyCall;
1043
- var callId = 0;
1044
- var push = [].push;
1045
- var slice = Array.prototype.slice;
1046
-
1047
1071
  if (!sinon && commonJSModule) {
1048
1072
  sinon = require("../sinon");
1049
1073
  }
@@ -1052,486 +1076,565 @@ var sinon = (function (buster) {
1052
1076
  return;
1053
1077
  }
1054
1078
 
1055
- function spy(object, property) {
1056
- if (!property && typeof object == "function") {
1057
- return spy.create(object);
1079
+ function throwYieldError(proxy, text, args) {
1080
+ var msg = sinon.functionName(proxy) + text;
1081
+ if (args.length) {
1082
+ msg += " Received [" + slice.call(args).join(", ") + "]";
1058
1083
  }
1059
-
1060
- if (!object && !property) {
1061
- return spy.create(function () {});
1062
- }
1063
-
1064
- var method = object[property];
1065
- return sinon.wrapMethod(object, property, spy.create(method));
1084
+ throw new Error(msg);
1066
1085
  }
1067
1086
 
1068
- sinon.extend(spy, (function () {
1087
+ var slice = Array.prototype.slice;
1069
1088
 
1070
- function delegateToCalls(api, method, matchAny, actual, notCalled) {
1071
- api[method] = function () {
1072
- if (!this.called) {
1073
- if (notCalled) {
1074
- return notCalled.apply(this, arguments);
1075
- }
1089
+ var callProto = {
1090
+ calledOn: function calledOn(thisValue) {
1091
+ if (sinon.match && sinon.match.isMatcher(thisValue)) {
1092
+ return thisValue.test(this.thisValue);
1093
+ }
1094
+ return this.thisValue === thisValue;
1095
+ },
1096
+
1097
+ calledWith: function calledWith() {
1098
+ for (var i = 0, l = arguments.length; i < l; i += 1) {
1099
+ if (!sinon.deepEqual(arguments[i], this.args[i])) {
1076
1100
  return false;
1077
1101
  }
1102
+ }
1078
1103
 
1079
- var currentCall;
1080
- var matches = 0;
1104
+ return true;
1105
+ },
1081
1106
 
1082
- for (var i = 0, l = this.callCount; i < l; i += 1) {
1083
- currentCall = this.getCall(i);
1107
+ calledWithMatch: function calledWithMatch() {
1108
+ for (var i = 0, l = arguments.length; i < l; i += 1) {
1109
+ var actual = this.args[i];
1110
+ var expectation = arguments[i];
1111
+ if (!sinon.match || !sinon.match(expectation).test(actual)) {
1112
+ return false;
1113
+ }
1114
+ }
1115
+ return true;
1116
+ },
1084
1117
 
1085
- if (currentCall[actual || method].apply(currentCall, arguments)) {
1086
- matches += 1;
1118
+ calledWithExactly: function calledWithExactly() {
1119
+ return arguments.length == this.args.length &&
1120
+ this.calledWith.apply(this, arguments);
1121
+ },
1087
1122
 
1088
- if (matchAny) {
1089
- return true;
1090
- }
1091
- }
1092
- }
1123
+ notCalledWith: function notCalledWith() {
1124
+ return !this.calledWith.apply(this, arguments);
1125
+ },
1093
1126
 
1094
- return matches === this.callCount;
1095
- };
1096
- }
1127
+ notCalledWithMatch: function notCalledWithMatch() {
1128
+ return !this.calledWithMatch.apply(this, arguments);
1129
+ },
1097
1130
 
1098
- function matchingFake(fakes, args, strict) {
1099
- if (!fakes) {
1100
- return;
1131
+ returned: function returned(value) {
1132
+ return sinon.deepEqual(value, this.returnValue);
1133
+ },
1134
+
1135
+ threw: function threw(error) {
1136
+ if (typeof error === "undefined" || !this.exception) {
1137
+ return !!this.exception;
1101
1138
  }
1102
1139
 
1103
- var alen = args.length;
1140
+ return this.exception === error || this.exception.name === error;
1141
+ },
1104
1142
 
1105
- for (var i = 0, l = fakes.length; i < l; i++) {
1106
- if (fakes[i].matches(args, strict)) {
1107
- return fakes[i];
1108
- }
1109
- }
1110
- }
1143
+ calledWithNew: function calledWithNew(thisValue) {
1144
+ return this.thisValue instanceof this.proxy;
1145
+ },
1111
1146
 
1112
- function incrementCallCount() {
1113
- this.called = true;
1114
- this.callCount += 1;
1115
- this.notCalled = false;
1116
- this.calledOnce = this.callCount == 1;
1117
- this.calledTwice = this.callCount == 2;
1118
- this.calledThrice = this.callCount == 3;
1119
- }
1147
+ calledBefore: function (other) {
1148
+ return this.callId < other.callId;
1149
+ },
1120
1150
 
1121
- function createCallProperties() {
1122
- this.firstCall = this.getCall(0);
1123
- this.secondCall = this.getCall(1);
1124
- this.thirdCall = this.getCall(2);
1125
- this.lastCall = this.getCall(this.callCount - 1);
1126
- }
1151
+ calledAfter: function (other) {
1152
+ return this.callId > other.callId;
1153
+ },
1154
+
1155
+ callArg: function (pos) {
1156
+ this.args[pos]();
1157
+ },
1127
1158
 
1128
- var uuid = 0;
1159
+ callArgOn: function (pos, thisValue) {
1160
+ this.args[pos].apply(thisValue);
1161
+ },
1129
1162
 
1130
- // Public API
1131
- var spyApi = {
1132
- reset: function () {
1133
- this.called = false;
1134
- this.notCalled = true;
1135
- this.calledOnce = false;
1136
- this.calledTwice = false;
1137
- this.calledThrice = false;
1138
- this.callCount = 0;
1139
- this.firstCall = null;
1140
- this.secondCall = null;
1141
- this.thirdCall = null;
1142
- this.lastCall = null;
1143
- this.args = [];
1144
- this.returnValues = [];
1145
- this.thisValues = [];
1146
- this.exceptions = [];
1147
- this.callIds = [];
1148
- if (this.fakes) {
1149
- for (var i = 0; i < this.fakes.length; i++) {
1150
- this.fakes[i].reset();
1151
- }
1152
- }
1153
- },
1163
+ callArgWith: function (pos) {
1164
+ this.callArgOnWith.apply(this, [pos, null].concat(slice.call(arguments, 1)));
1165
+ },
1154
1166
 
1155
- create: function create(func) {
1156
- var name;
1167
+ callArgOnWith: function (pos, thisValue) {
1168
+ var args = slice.call(arguments, 2);
1169
+ this.args[pos].apply(thisValue, args);
1170
+ },
1157
1171
 
1158
- if (typeof func != "function") {
1159
- func = function () {};
1160
- } else {
1161
- name = sinon.functionName(func);
1172
+ "yield": function () {
1173
+ this.yieldOn.apply(this, [null].concat(slice.call(arguments, 0)));
1174
+ },
1175
+
1176
+ yieldOn: function (thisValue) {
1177
+ var args = this.args;
1178
+ for (var i = 0, l = args.length; i < l; ++i) {
1179
+ if (typeof args[i] === "function") {
1180
+ args[i].apply(thisValue, slice.call(arguments, 1));
1181
+ return;
1162
1182
  }
1183
+ }
1184
+ throwYieldError(this.proxy, " cannot yield since no callback was passed.", args);
1185
+ },
1163
1186
 
1164
- function proxy() {
1165
- return proxy.invoke(func, this, slice.call(arguments));
1187
+ yieldTo: function (prop) {
1188
+ this.yieldToOn.apply(this, [prop, null].concat(slice.call(arguments, 1)));
1189
+ },
1190
+
1191
+ yieldToOn: function (prop, thisValue) {
1192
+ var args = this.args;
1193
+ for (var i = 0, l = args.length; i < l; ++i) {
1194
+ if (args[i] && typeof args[i][prop] === "function") {
1195
+ args[i][prop].apply(thisValue, slice.call(arguments, 2));
1196
+ return;
1166
1197
  }
1198
+ }
1199
+ throwYieldError(this.proxy, " cannot yield to '" + prop +
1200
+ "' since no callback was passed.", args);
1201
+ },
1167
1202
 
1168
- sinon.extend(proxy, spy);
1169
- delete proxy.create;
1170
- sinon.extend(proxy, func);
1203
+ toString: function () {
1204
+ var callStr = this.proxy.toString() + "(";
1205
+ var args = [];
1171
1206
 
1172
- proxy.reset();
1173
- proxy.prototype = func.prototype;
1174
- proxy.displayName = name || "spy";
1175
- proxy.toString = sinon.functionToString;
1176
- proxy._create = sinon.spy.create;
1177
- proxy.id = "spy#" + uuid++;
1207
+ for (var i = 0, l = this.args.length; i < l; ++i) {
1208
+ args.push(sinon.format(this.args[i]));
1209
+ }
1178
1210
 
1179
- return proxy;
1180
- },
1211
+ callStr = callStr + args.join(", ") + ")";
1181
1212
 
1182
- invoke: function invoke(func, thisValue, args) {
1183
- var matching = matchingFake(this.fakes, args);
1184
- var exception, returnValue;
1213
+ if (typeof this.returnValue != "undefined") {
1214
+ callStr += " => " + sinon.format(this.returnValue);
1215
+ }
1185
1216
 
1186
- incrementCallCount.call(this);
1187
- push.call(this.thisValues, thisValue);
1188
- push.call(this.args, args);
1189
- push.call(this.callIds, callId++);
1217
+ if (this.exception) {
1218
+ callStr += " !" + this.exception.name;
1190
1219
 
1191
- try {
1192
- if (matching) {
1193
- returnValue = matching.invoke(func, thisValue, args);
1194
- } else {
1195
- returnValue = (this.func || func).apply(thisValue, args);
1196
- }
1197
- } catch (e) {
1198
- push.call(this.returnValues, undefined);
1199
- exception = e;
1200
- throw e;
1201
- } finally {
1202
- push.call(this.exceptions, exception);
1220
+ if (this.exception.message) {
1221
+ callStr += "(" + this.exception.message + ")";
1203
1222
  }
1223
+ }
1204
1224
 
1205
- push.call(this.returnValues, returnValue);
1225
+ return callStr;
1226
+ }
1227
+ };
1206
1228
 
1207
- createCallProperties.call(this);
1229
+ callProto.invokeCallback = callProto.yield;
1208
1230
 
1209
- return returnValue;
1210
- },
1231
+ function createSpyCall(spy, thisValue, args, returnValue, exception, id) {
1232
+ if (typeof id !== "number") {
1233
+ throw new TypeError("Call id is not a number");
1234
+ }
1235
+ var proxyCall = sinon.create(callProto);
1236
+ proxyCall.proxy = spy;
1237
+ proxyCall.thisValue = thisValue;
1238
+ proxyCall.args = args;
1239
+ proxyCall.returnValue = returnValue;
1240
+ proxyCall.exception = exception;
1241
+ proxyCall.callId = id;
1242
+
1243
+ return proxyCall;
1244
+ };
1245
+ createSpyCall.toString = callProto.toString; // used by mocks
1211
1246
 
1212
- getCall: function getCall(i) {
1213
- if (i < 0 || i >= this.callCount) {
1214
- return null;
1215
- }
1247
+ if (commonJSModule) {
1248
+ module.exports = createSpyCall;
1249
+ } else {
1250
+ sinon.spyCall = createSpyCall;
1251
+ }
1252
+ }(typeof sinon == "object" && sinon || null));
1216
1253
 
1217
- return spyCall.create(this, this.thisValues[i], this.args[i],
1218
- this.returnValues[i], this.exceptions[i],
1219
- this.callIds[i]);
1220
- },
1221
1254
 
1222
- calledBefore: function calledBefore(spyFn) {
1223
- if (!this.called) {
1224
- return false;
1225
- }
1255
+ /**
1256
+ * @depend ../sinon.js
1257
+ * @depend call.js
1258
+ */
1259
+ /*jslint eqeqeq: false, onevar: false, plusplus: false*/
1260
+ /*global module, require, sinon*/
1261
+ /**
1262
+ * Spy functions
1263
+ *
1264
+ * @author Christian Johansen (christian@cjohansen.no)
1265
+ * @license BSD
1266
+ *
1267
+ * Copyright (c) 2010-2013 Christian Johansen
1268
+ */
1226
1269
 
1227
- if (!spyFn.called) {
1228
- return true;
1229
- }
1270
+ (function (sinon) {
1271
+ var commonJSModule = typeof module == "object" && typeof require == "function";
1272
+ var push = Array.prototype.push;
1273
+ var slice = Array.prototype.slice;
1274
+ var callId = 0;
1230
1275
 
1231
- return this.callIds[0] < spyFn.callIds[spyFn.callIds.length - 1];
1232
- },
1276
+ if (!sinon && commonJSModule) {
1277
+ sinon = require("../sinon");
1278
+ }
1233
1279
 
1234
- calledAfter: function calledAfter(spyFn) {
1235
- if (!this.called || !spyFn.called) {
1236
- return false;
1237
- }
1280
+ if (!sinon) {
1281
+ return;
1282
+ }
1238
1283
 
1239
- return this.callIds[this.callCount - 1] > spyFn.callIds[spyFn.callCount - 1];
1240
- },
1284
+ function spy(object, property) {
1285
+ if (!property && typeof object == "function") {
1286
+ return spy.create(object);
1287
+ }
1241
1288
 
1242
- withArgs: function () {
1243
- var args = slice.call(arguments);
1289
+ if (!object && !property) {
1290
+ return spy.create(function () { });
1291
+ }
1244
1292
 
1245
- if (this.fakes) {
1246
- var match = matchingFake(this.fakes, args, true);
1293
+ var method = object[property];
1294
+ return sinon.wrapMethod(object, property, spy.create(method));
1295
+ }
1247
1296
 
1248
- if (match) {
1249
- return match;
1250
- }
1251
- } else {
1252
- this.fakes = [];
1253
- }
1297
+ function matchingFake(fakes, args, strict) {
1298
+ if (!fakes) {
1299
+ return;
1300
+ }
1254
1301
 
1255
- var original = this;
1256
- var fake = this._create();
1257
- fake.matchingAguments = args;
1258
- push.call(this.fakes, fake);
1302
+ var alen = args.length;
1259
1303
 
1260
- fake.withArgs = function () {
1261
- return original.withArgs.apply(original, arguments);
1262
- };
1304
+ for (var i = 0, l = fakes.length; i < l; i++) {
1305
+ if (fakes[i].matches(args, strict)) {
1306
+ return fakes[i];
1307
+ }
1308
+ }
1309
+ }
1263
1310
 
1264
- for (var i = 0; i < this.args.length; i++) {
1265
- if (fake.matches(this.args[i])) {
1266
- incrementCallCount.call(fake);
1267
- push.call(fake.thisValues, this.thisValues[i]);
1268
- push.call(fake.args, this.args[i]);
1269
- push.call(fake.returnValues, this.returnValues[i]);
1270
- push.call(fake.exceptions, this.exceptions[i]);
1271
- push.call(fake.callIds, this.callIds[i]);
1272
- }
1273
- }
1274
- createCallProperties.call(fake);
1311
+ function incrementCallCount() {
1312
+ this.called = true;
1313
+ this.callCount += 1;
1314
+ this.notCalled = false;
1315
+ this.calledOnce = this.callCount == 1;
1316
+ this.calledTwice = this.callCount == 2;
1317
+ this.calledThrice = this.callCount == 3;
1318
+ }
1275
1319
 
1276
- return fake;
1277
- },
1320
+ function createCallProperties() {
1321
+ this.firstCall = this.getCall(0);
1322
+ this.secondCall = this.getCall(1);
1323
+ this.thirdCall = this.getCall(2);
1324
+ this.lastCall = this.getCall(this.callCount - 1);
1325
+ }
1278
1326
 
1279
- matches: function (args, strict) {
1280
- var margs = this.matchingAguments;
1327
+ var vars = "a,b,c,d,e,f,g,h,i,j,k,l";
1328
+ function createProxy(func) {
1329
+ // Retain the function length:
1330
+ var p;
1331
+ if (func.length) {
1332
+ eval("p = (function proxy(" + vars.substring(0, func.length * 2 - 1) +
1333
+ ") { return p.invoke(func, this, slice.call(arguments)); });");
1334
+ }
1335
+ else {
1336
+ p = function proxy() {
1337
+ return p.invoke(func, this, slice.call(arguments));
1338
+ };
1339
+ }
1340
+ return p;
1341
+ }
1281
1342
 
1282
- if (margs.length <= args.length &&
1283
- sinon.deepEqual(margs, args.slice(0, margs.length))) {
1284
- return !strict || margs.length == args.length;
1343
+ var uuid = 0;
1344
+
1345
+ // Public API
1346
+ var spyApi = {
1347
+ reset: function () {
1348
+ this.called = false;
1349
+ this.notCalled = true;
1350
+ this.calledOnce = false;
1351
+ this.calledTwice = false;
1352
+ this.calledThrice = false;
1353
+ this.callCount = 0;
1354
+ this.firstCall = null;
1355
+ this.secondCall = null;
1356
+ this.thirdCall = null;
1357
+ this.lastCall = null;
1358
+ this.args = [];
1359
+ this.returnValues = [];
1360
+ this.thisValues = [];
1361
+ this.exceptions = [];
1362
+ this.callIds = [];
1363
+ if (this.fakes) {
1364
+ for (var i = 0; i < this.fakes.length; i++) {
1365
+ this.fakes[i].reset();
1285
1366
  }
1286
- },
1367
+ }
1368
+ },
1287
1369
 
1288
- printf: function (format) {
1289
- var spy = this;
1290
- var args = slice.call(arguments, 1);
1291
- var formatter;
1370
+ create: function create(func) {
1371
+ var name;
1292
1372
 
1293
- return (format || "").replace(/%(.)/g, function (match, specifyer) {
1294
- formatter = spyApi.formatters[specifyer];
1373
+ if (typeof func != "function") {
1374
+ func = function () { };
1375
+ } else {
1376
+ name = sinon.functionName(func);
1377
+ }
1295
1378
 
1296
- if (typeof formatter == "function") {
1297
- return formatter.call(null, spy, args);
1298
- } else if (!isNaN(parseInt(specifyer), 10)) {
1299
- return sinon.format(args[specifyer - 1]);
1300
- }
1379
+ var proxy = createProxy(func);
1301
1380
 
1302
- return "%" + specifyer;
1303
- });
1304
- }
1305
- };
1381
+ sinon.extend(proxy, spy);
1382
+ delete proxy.create;
1383
+ sinon.extend(proxy, func);
1306
1384
 
1307
- delegateToCalls(spyApi, "calledOn", true);
1308
- delegateToCalls(spyApi, "alwaysCalledOn", false, "calledOn");
1309
- delegateToCalls(spyApi, "calledWith", true);
1310
- delegateToCalls(spyApi, "calledWithMatch", true);
1311
- delegateToCalls(spyApi, "alwaysCalledWith", false, "calledWith");
1312
- delegateToCalls(spyApi, "alwaysCalledWithMatch", false, "calledWithMatch");
1313
- delegateToCalls(spyApi, "calledWithExactly", true);
1314
- delegateToCalls(spyApi, "alwaysCalledWithExactly", false, "calledWithExactly");
1315
- delegateToCalls(spyApi, "neverCalledWith", false, "notCalledWith",
1316
- function () { return true; });
1317
- delegateToCalls(spyApi, "neverCalledWithMatch", false, "notCalledWithMatch",
1318
- function () { return true; });
1319
- delegateToCalls(spyApi, "threw", true);
1320
- delegateToCalls(spyApi, "alwaysThrew", false, "threw");
1321
- delegateToCalls(spyApi, "returned", true);
1322
- delegateToCalls(spyApi, "alwaysReturned", false, "returned");
1323
- delegateToCalls(spyApi, "calledWithNew", true);
1324
- delegateToCalls(spyApi, "alwaysCalledWithNew", false, "calledWithNew");
1325
- delegateToCalls(spyApi, "callArg", false, "callArgWith", function () {
1326
- throw new Error(this.toString() + " cannot call arg since it was not yet invoked.");
1327
- });
1328
- spyApi.callArgWith = spyApi.callArg;
1329
- delegateToCalls(spyApi, "yield", false, "yield", function () {
1330
- throw new Error(this.toString() + " cannot yield since it was not yet invoked.");
1331
- });
1332
- // "invokeCallback" is an alias for "yield" since "yield" is invalid in strict mode.
1333
- spyApi.invokeCallback = spyApi.yield;
1334
- delegateToCalls(spyApi, "yieldTo", false, "yieldTo", function (property) {
1335
- throw new Error(this.toString() + " cannot yield to '" + property +
1336
- "' since it was not yet invoked.");
1337
- });
1385
+ proxy.reset();
1386
+ proxy.prototype = func.prototype;
1387
+ proxy.displayName = name || "spy";
1388
+ proxy.toString = sinon.functionToString;
1389
+ proxy._create = sinon.spy.create;
1390
+ proxy.id = "spy#" + uuid++;
1338
1391
 
1339
- spyApi.formatters = {
1340
- "c": function (spy) {
1341
- return sinon.timesInWords(spy.callCount);
1342
- },
1392
+ return proxy;
1393
+ },
1343
1394
 
1344
- "n": function (spy) {
1345
- return spy.toString();
1346
- },
1395
+ invoke: function invoke(func, thisValue, args) {
1396
+ var matching = matchingFake(this.fakes, args);
1397
+ var exception, returnValue;
1347
1398
 
1348
- "C": function (spy) {
1349
- var calls = [];
1399
+ incrementCallCount.call(this);
1400
+ push.call(this.thisValues, thisValue);
1401
+ push.call(this.args, args);
1402
+ push.call(this.callIds, callId++);
1350
1403
 
1351
- for (var i = 0, l = spy.callCount; i < l; ++i) {
1352
- push.call(calls, " " + spy.getCall(i).toString());
1404
+ try {
1405
+ if (matching) {
1406
+ returnValue = matching.invoke(func, thisValue, args);
1407
+ } else {
1408
+ returnValue = (this.func || func).apply(thisValue, args);
1353
1409
  }
1410
+ } catch (e) {
1411
+ push.call(this.returnValues, undefined);
1412
+ exception = e;
1413
+ throw e;
1414
+ } finally {
1415
+ push.call(this.exceptions, exception);
1416
+ }
1354
1417
 
1355
- return calls.length > 0 ? "\n" + calls.join("\n") : "";
1356
- },
1357
-
1358
- "t": function (spy) {
1359
- var objects = [];
1418
+ push.call(this.returnValues, returnValue);
1360
1419
 
1361
- for (var i = 0, l = spy.callCount; i < l; ++i) {
1362
- push.call(objects, sinon.format(spy.thisValues[i]));
1363
- }
1420
+ createCallProperties.call(this);
1364
1421
 
1365
- return objects.join(", ");
1366
- },
1422
+ return returnValue;
1423
+ },
1367
1424
 
1368
- "*": function (spy, args) {
1369
- var formatted = [];
1425
+ getCall: function getCall(i) {
1426
+ if (i < 0 || i >= this.callCount) {
1427
+ return null;
1428
+ }
1370
1429
 
1371
- for (var i = 0, l = args.length; i < l; ++i) {
1372
- push.call(formatted, sinon.format(args[i]));
1373
- }
1430
+ return sinon.spyCall(this, this.thisValues[i], this.args[i],
1431
+ this.returnValues[i], this.exceptions[i],
1432
+ this.callIds[i]);
1433
+ },
1374
1434
 
1375
- return formatted.join(", ");
1435
+ calledBefore: function calledBefore(spyFn) {
1436
+ if (!this.called) {
1437
+ return false;
1376
1438
  }
1377
- };
1378
1439
 
1379
- return spyApi;
1380
- }()));
1440
+ if (!spyFn.called) {
1441
+ return true;
1442
+ }
1381
1443
 
1382
- spyCall = (function () {
1444
+ return this.callIds[0] < spyFn.callIds[spyFn.callIds.length - 1];
1445
+ },
1383
1446
 
1384
- function throwYieldError(proxy, text, args) {
1385
- var msg = sinon.functionName(proxy) + text;
1386
- if (args.length) {
1387
- msg += " Received [" + slice.call(args).join(", ") + "]";
1447
+ calledAfter: function calledAfter(spyFn) {
1448
+ if (!this.called || !spyFn.called) {
1449
+ return false;
1388
1450
  }
1389
- throw new Error(msg);
1390
- }
1391
1451
 
1392
- return {
1393
- create: function create(spy, thisValue, args, returnValue, exception, id) {
1394
- var proxyCall = sinon.create(spyCall);
1395
- delete proxyCall.create;
1396
- proxyCall.proxy = spy;
1397
- proxyCall.thisValue = thisValue;
1398
- proxyCall.args = args;
1399
- proxyCall.returnValue = returnValue;
1400
- proxyCall.exception = exception;
1401
- proxyCall.callId = typeof id == "number" && id || callId++;
1402
-
1403
- return proxyCall;
1404
- },
1452
+ return this.callIds[this.callCount - 1] > spyFn.callIds[spyFn.callCount - 1];
1453
+ },
1405
1454
 
1406
- calledOn: function calledOn(thisValue) {
1407
- return this.thisValue === thisValue;
1408
- },
1455
+ withArgs: function () {
1456
+ var args = slice.call(arguments);
1409
1457
 
1410
- calledWith: function calledWith() {
1411
- for (var i = 0, l = arguments.length; i < l; i += 1) {
1412
- if (!sinon.deepEqual(arguments[i], this.args[i])) {
1413
- return false;
1414
- }
1458
+ if (this.fakes) {
1459
+ var match = matchingFake(this.fakes, args, true);
1460
+
1461
+ if (match) {
1462
+ return match;
1415
1463
  }
1464
+ } else {
1465
+ this.fakes = [];
1466
+ }
1416
1467
 
1417
- return true;
1418
- },
1468
+ var original = this;
1469
+ var fake = this._create();
1470
+ fake.matchingAguments = args;
1471
+ push.call(this.fakes, fake);
1419
1472
 
1420
- calledWithMatch: function calledWithMatch() {
1421
- for (var i = 0, l = arguments.length; i < l; i += 1) {
1422
- var actual = this.args[i];
1423
- var expectation = arguments[i];
1424
- if (!sinon.match || !sinon.match(expectation).test(actual)) {
1425
- return false;
1426
- }
1427
- }
1428
- return true;
1429
- },
1473
+ fake.withArgs = function () {
1474
+ return original.withArgs.apply(original, arguments);
1475
+ };
1430
1476
 
1431
- calledWithExactly: function calledWithExactly() {
1432
- return arguments.length == this.args.length &&
1433
- this.calledWith.apply(this, arguments);
1434
- },
1477
+ for (var i = 0; i < this.args.length; i++) {
1478
+ if (fake.matches(this.args[i])) {
1479
+ incrementCallCount.call(fake);
1480
+ push.call(fake.thisValues, this.thisValues[i]);
1481
+ push.call(fake.args, this.args[i]);
1482
+ push.call(fake.returnValues, this.returnValues[i]);
1483
+ push.call(fake.exceptions, this.exceptions[i]);
1484
+ push.call(fake.callIds, this.callIds[i]);
1485
+ }
1486
+ }
1487
+ createCallProperties.call(fake);
1435
1488
 
1436
- notCalledWith: function notCalledWith() {
1437
- return !this.calledWith.apply(this, arguments);
1438
- },
1489
+ return fake;
1490
+ },
1439
1491
 
1440
- notCalledWithMatch: function notCalledWithMatch() {
1441
- return !this.calledWithMatch.apply(this, arguments);
1442
- },
1492
+ matches: function (args, strict) {
1493
+ var margs = this.matchingAguments;
1443
1494
 
1444
- returned: function returned(value) {
1445
- return sinon.deepEqual(value, this.returnValue);
1446
- },
1495
+ if (margs.length <= args.length &&
1496
+ sinon.deepEqual(margs, args.slice(0, margs.length))) {
1497
+ return !strict || margs.length == args.length;
1498
+ }
1499
+ },
1447
1500
 
1448
- threw: function threw(error) {
1449
- if (typeof error == "undefined" || !this.exception) {
1450
- return !!this.exception;
1451
- }
1501
+ printf: function (format) {
1502
+ var spy = this;
1503
+ var args = slice.call(arguments, 1);
1504
+ var formatter;
1452
1505
 
1453
- if (typeof error == "string") {
1454
- return this.exception.name == error;
1455
- }
1506
+ return (format || "").replace(/%(.)/g, function (match, specifyer) {
1507
+ formatter = spyApi.formatters[specifyer];
1456
1508
 
1457
- return this.exception === error;
1458
- },
1509
+ if (typeof formatter == "function") {
1510
+ return formatter.call(null, spy, args);
1511
+ } else if (!isNaN(parseInt(specifyer), 10)) {
1512
+ return sinon.format(args[specifyer - 1]);
1513
+ }
1459
1514
 
1460
- calledWithNew: function calledWithNew(thisValue) {
1461
- return this.thisValue instanceof this.proxy;
1462
- },
1515
+ return "%" + specifyer;
1516
+ });
1517
+ }
1518
+ };
1463
1519
 
1464
- calledBefore: function (other) {
1465
- return this.callId < other.callId;
1466
- },
1520
+ function delegateToCalls(method, matchAny, actual, notCalled) {
1521
+ spyApi[method] = function () {
1522
+ if (!this.called) {
1523
+ if (notCalled) {
1524
+ return notCalled.apply(this, arguments);
1525
+ }
1526
+ return false;
1527
+ }
1467
1528
 
1468
- calledAfter: function (other) {
1469
- return this.callId > other.callId;
1470
- },
1529
+ var currentCall;
1530
+ var matches = 0;
1471
1531
 
1472
- callArg: function (pos) {
1473
- this.args[pos]();
1474
- },
1532
+ for (var i = 0, l = this.callCount; i < l; i += 1) {
1533
+ currentCall = this.getCall(i);
1475
1534
 
1476
- callArgWith: function (pos) {
1477
- var args = slice.call(arguments, 1);
1478
- this.args[pos].apply(null, args);
1479
- },
1535
+ if (currentCall[actual || method].apply(currentCall, arguments)) {
1536
+ matches += 1;
1480
1537
 
1481
- "yield": function () {
1482
- var args = this.args;
1483
- for (var i = 0, l = args.length; i < l; ++i) {
1484
- if (typeof args[i] === "function") {
1485
- args[i].apply(null, slice.call(arguments));
1486
- return;
1538
+ if (matchAny) {
1539
+ return true;
1487
1540
  }
1488
1541
  }
1489
- throwYieldError(this.proxy, " cannot yield since no callback was passed.", args);
1490
- },
1542
+ }
1491
1543
 
1492
- yieldTo: function (prop) {
1493
- var args = this.args;
1494
- for (var i = 0, l = args.length; i < l; ++i) {
1495
- if (args[i] && typeof args[i][prop] === "function") {
1496
- args[i][prop].apply(null, slice.call(arguments, 1));
1497
- return;
1498
- }
1499
- }
1500
- throwYieldError(this.proxy, " cannot yield to '" + prop +
1501
- "' since no callback was passed.", args);
1502
- },
1544
+ return matches === this.callCount;
1545
+ };
1546
+ }
1503
1547
 
1504
- toString: function () {
1505
- var callStr = this.proxy.toString() + "(";
1506
- var args = [];
1548
+ delegateToCalls("calledOn", true);
1549
+ delegateToCalls("alwaysCalledOn", false, "calledOn");
1550
+ delegateToCalls("calledWith", true);
1551
+ delegateToCalls("calledWithMatch", true);
1552
+ delegateToCalls("alwaysCalledWith", false, "calledWith");
1553
+ delegateToCalls("alwaysCalledWithMatch", false, "calledWithMatch");
1554
+ delegateToCalls("calledWithExactly", true);
1555
+ delegateToCalls("alwaysCalledWithExactly", false, "calledWithExactly");
1556
+ delegateToCalls("neverCalledWith", false, "notCalledWith",
1557
+ function () { return true; });
1558
+ delegateToCalls("neverCalledWithMatch", false, "notCalledWithMatch",
1559
+ function () { return true; });
1560
+ delegateToCalls("threw", true);
1561
+ delegateToCalls("alwaysThrew", false, "threw");
1562
+ delegateToCalls("returned", true);
1563
+ delegateToCalls("alwaysReturned", false, "returned");
1564
+ delegateToCalls("calledWithNew", true);
1565
+ delegateToCalls("alwaysCalledWithNew", false, "calledWithNew");
1566
+ delegateToCalls("callArg", false, "callArgWith", function () {
1567
+ throw new Error(this.toString() + " cannot call arg since it was not yet invoked.");
1568
+ });
1569
+ spyApi.callArgWith = spyApi.callArg;
1570
+ delegateToCalls("callArgOn", false, "callArgOnWith", function () {
1571
+ throw new Error(this.toString() + " cannot call arg since it was not yet invoked.");
1572
+ });
1573
+ spyApi.callArgOnWith = spyApi.callArgOn;
1574
+ delegateToCalls("yield", false, "yield", function () {
1575
+ throw new Error(this.toString() + " cannot yield since it was not yet invoked.");
1576
+ });
1577
+ // "invokeCallback" is an alias for "yield" since "yield" is invalid in strict mode.
1578
+ spyApi.invokeCallback = spyApi.yield;
1579
+ delegateToCalls("yieldOn", false, "yieldOn", function () {
1580
+ throw new Error(this.toString() + " cannot yield since it was not yet invoked.");
1581
+ });
1582
+ delegateToCalls("yieldTo", false, "yieldTo", function (property) {
1583
+ throw new Error(this.toString() + " cannot yield to '" + property +
1584
+ "' since it was not yet invoked.");
1585
+ });
1586
+ delegateToCalls("yieldToOn", false, "yieldToOn", function (property) {
1587
+ throw new Error(this.toString() + " cannot yield to '" + property +
1588
+ "' since it was not yet invoked.");
1589
+ });
1507
1590
 
1508
- for (var i = 0, l = this.args.length; i < l; ++i) {
1509
- push.call(args, sinon.format(this.args[i]));
1510
- }
1591
+ spyApi.formatters = {
1592
+ "c": function (spy) {
1593
+ return sinon.timesInWords(spy.callCount);
1594
+ },
1595
+
1596
+ "n": function (spy) {
1597
+ return spy.toString();
1598
+ },
1511
1599
 
1512
- callStr = callStr + args.join(", ") + ")";
1600
+ "C": function (spy) {
1601
+ var calls = [];
1513
1602
 
1514
- if (typeof this.returnValue != "undefined") {
1515
- callStr += " => " + sinon.format(this.returnValue);
1603
+ for (var i = 0, l = spy.callCount; i < l; ++i) {
1604
+ var stringifiedCall = " " + spy.getCall(i).toString();
1605
+ if (/\n/.test(calls[i - 1])) {
1606
+ stringifiedCall = "\n" + stringifiedCall;
1516
1607
  }
1608
+ push.call(calls, stringifiedCall);
1609
+ }
1517
1610
 
1518
- if (this.exception) {
1519
- callStr += " !" + this.exception.name;
1611
+ return calls.length > 0 ? "\n" + calls.join("\n") : "";
1612
+ },
1520
1613
 
1521
- if (this.exception.message) {
1522
- callStr += "(" + this.exception.message + ")";
1523
- }
1524
- }
1614
+ "t": function (spy) {
1615
+ var objects = [];
1525
1616
 
1526
- return callStr;
1617
+ for (var i = 0, l = spy.callCount; i < l; ++i) {
1618
+ push.call(objects, sinon.format(spy.thisValues[i]));
1527
1619
  }
1528
- };
1529
- }());
1530
1620
 
1531
- spy.spyCall = spyCall;
1621
+ return objects.join(", ");
1622
+ },
1623
+
1624
+ "*": function (spy, args) {
1625
+ var formatted = [];
1626
+
1627
+ for (var i = 0, l = args.length; i < l; ++i) {
1628
+ push.call(formatted, sinon.format(args[i]));
1629
+ }
1630
+
1631
+ return formatted.join(", ");
1632
+ }
1633
+ };
1634
+
1635
+ sinon.extend(spy, spyApi);
1532
1636
 
1533
- // This steps outside the module sandbox and will be removed
1534
- sinon.spyCall = spyCall;
1637
+ spy.spyCall = sinon.spyCall;
1535
1638
 
1536
1639
  if (commonJSModule) {
1537
1640
  module.exports = spy;
@@ -1552,7 +1655,7 @@ var sinon = (function (buster) {
1552
1655
  * @author Christian Johansen (christian@cjohansen.no)
1553
1656
  * @license BSD
1554
1657
  *
1555
- * Copyright (c) 2010-2011 Christian Johansen
1658
+ * Copyright (c) 2010-2013 Christian Johansen
1556
1659
  */
1557
1660
 
1558
1661
  (function (sinon) {
@@ -1596,34 +1699,47 @@ var sinon = (function (buster) {
1596
1699
  return sinon.wrapMethod(object, property, wrapper);
1597
1700
  }
1598
1701
 
1702
+ function getChangingValue(stub, property) {
1703
+ var index = stub.callCount - 1;
1704
+ var values = stub[property];
1705
+ var prop = index in values ? values[index] : values[values.length - 1];
1706
+ stub[property + "Last"] = prop;
1707
+
1708
+ return prop;
1709
+ }
1710
+
1599
1711
  function getCallback(stub, args) {
1600
- if (stub.callArgAt < 0) {
1712
+ var callArgAt = getChangingValue(stub, "callArgAts");
1713
+
1714
+ if (callArgAt < 0) {
1715
+ var callArgProp = getChangingValue(stub, "callArgProps");
1716
+
1601
1717
  for (var i = 0, l = args.length; i < l; ++i) {
1602
- if (!stub.callArgProp && typeof args[i] == "function") {
1718
+ if (!callArgProp && typeof args[i] == "function") {
1603
1719
  return args[i];
1604
1720
  }
1605
1721
 
1606
- if (stub.callArgProp && args[i] &&
1607
- typeof args[i][stub.callArgProp] == "function") {
1608
- return args[i][stub.callArgProp];
1722
+ if (callArgProp && args[i] &&
1723
+ typeof args[i][callArgProp] == "function") {
1724
+ return args[i][callArgProp];
1609
1725
  }
1610
1726
  }
1611
1727
 
1612
1728
  return null;
1613
1729
  }
1614
1730
 
1615
- return args[stub.callArgAt];
1731
+ return args[callArgAt];
1616
1732
  }
1617
1733
 
1618
1734
  var join = Array.prototype.join;
1619
1735
 
1620
1736
  function getCallbackError(stub, func, args) {
1621
- if (stub.callArgAt < 0) {
1737
+ if (stub.callArgAtsLast < 0) {
1622
1738
  var msg;
1623
1739
 
1624
- if (stub.callArgProp) {
1740
+ if (stub.callArgPropsLast) {
1625
1741
  msg = sinon.functionName(stub) +
1626
- " expected to yield to '" + stub.callArgProp +
1742
+ " expected to yield to '" + stub.callArgPropsLast +
1627
1743
  "', but no object with such a property was passed."
1628
1744
  } else {
1629
1745
  msg = sinon.functionName(stub) +
@@ -1637,14 +1753,12 @@ var sinon = (function (buster) {
1637
1753
  return msg;
1638
1754
  }
1639
1755
 
1640
- return "argument at index " + stub.callArgAt + " is not a function: " + func;
1756
+ return "argument at index " + stub.callArgAtsLast + " is not a function: " + func;
1641
1757
  }
1642
1758
 
1643
1759
  var nextTick = (function () {
1644
1760
  if (typeof process === "object" && typeof process.nextTick === "function") {
1645
1761
  return process.nextTick;
1646
- } else if (typeof msSetImmediate === "function") {
1647
- return msSetImmediate.bind(window);
1648
1762
  } else if (typeof setImmediate === "function") {
1649
1763
  return setImmediate;
1650
1764
  } else {
@@ -1655,19 +1769,22 @@ var sinon = (function (buster) {
1655
1769
  })();
1656
1770
 
1657
1771
  function callCallback(stub, args) {
1658
- if (typeof stub.callArgAt == "number") {
1772
+ if (stub.callArgAts.length > 0) {
1659
1773
  var func = getCallback(stub, args);
1660
1774
 
1661
1775
  if (typeof func != "function") {
1662
1776
  throw new TypeError(getCallbackError(stub, func, args));
1663
1777
  }
1664
1778
 
1779
+ var callbackArguments = getChangingValue(stub, "callbackArguments");
1780
+ var callbackContext = getChangingValue(stub, "callbackContexts");
1781
+
1665
1782
  if (stub.callbackAsync) {
1666
1783
  nextTick(function() {
1667
- func.apply(stub.callbackContext, stub.callbackArguments);
1784
+ func.apply(callbackContext, callbackArguments);
1668
1785
  });
1669
1786
  } else {
1670
- func.apply(stub.callbackContext, stub.callbackArguments);
1787
+ func.apply(callbackContext, callbackArguments);
1671
1788
  }
1672
1789
  }
1673
1790
  }
@@ -1711,6 +1828,11 @@ var sinon = (function (buster) {
1711
1828
  functionStub = sinon.spy.create(functionStub);
1712
1829
  functionStub.func = orig;
1713
1830
 
1831
+ functionStub.callArgAts = [];
1832
+ functionStub.callbackArguments = [];
1833
+ functionStub.callbackContexts = [];
1834
+ functionStub.callArgProps = [];
1835
+
1714
1836
  sinon.extend(functionStub, stub);
1715
1837
  functionStub._create = sinon.stub.create;
1716
1838
  functionStub.displayName = "stub";
@@ -1719,6 +1841,25 @@ var sinon = (function (buster) {
1719
1841
  return functionStub;
1720
1842
  },
1721
1843
 
1844
+ resetBehavior: function () {
1845
+ var i;
1846
+
1847
+ this.callArgAts = [];
1848
+ this.callbackArguments = [];
1849
+ this.callbackContexts = [];
1850
+ this.callArgProps = [];
1851
+
1852
+ delete this.returnValue;
1853
+ delete this.returnArgAt;
1854
+ this.returnThis = false;
1855
+
1856
+ if (this.fakes) {
1857
+ for (i = 0; i < this.fakes.length; i++) {
1858
+ this.fakes[i].resetBehavior();
1859
+ }
1860
+ }
1861
+ },
1862
+
1722
1863
  returns: function returns(value) {
1723
1864
  this.returnValue = value;
1724
1865
 
@@ -1749,8 +1890,10 @@ var sinon = (function (buster) {
1749
1890
  throw new TypeError("argument index is not number");
1750
1891
  }
1751
1892
 
1752
- this.callArgAt = pos;
1753
- this.callbackArguments = [];
1893
+ this.callArgAts.push(pos);
1894
+ this.callbackArguments.push([]);
1895
+ this.callbackContexts.push(undefined);
1896
+ this.callArgProps.push(undefined);
1754
1897
 
1755
1898
  return this;
1756
1899
  },
@@ -1763,9 +1906,10 @@ var sinon = (function (buster) {
1763
1906
  throw new TypeError("argument context is not an object");
1764
1907
  }
1765
1908
 
1766
- this.callArgAt = pos;
1767
- this.callbackArguments = [];
1768
- this.callbackContext = context;
1909
+ this.callArgAts.push(pos);
1910
+ this.callbackArguments.push([]);
1911
+ this.callbackContexts.push(context);
1912
+ this.callArgProps.push(undefined);
1769
1913
 
1770
1914
  return this;
1771
1915
  },
@@ -1775,8 +1919,10 @@ var sinon = (function (buster) {
1775
1919
  throw new TypeError("argument index is not number");
1776
1920
  }
1777
1921
 
1778
- this.callArgAt = pos;
1779
- this.callbackArguments = slice.call(arguments, 1);
1922
+ this.callArgAts.push(pos);
1923
+ this.callbackArguments.push(slice.call(arguments, 1));
1924
+ this.callbackContexts.push(undefined);
1925
+ this.callArgProps.push(undefined);
1780
1926
 
1781
1927
  return this;
1782
1928
  },
@@ -1789,16 +1935,19 @@ var sinon = (function (buster) {
1789
1935
  throw new TypeError("argument context is not an object");
1790
1936
  }
1791
1937
 
1792
- this.callArgAt = pos;
1793
- this.callbackArguments = slice.call(arguments, 2);
1794
- this.callbackContext = context;
1938
+ this.callArgAts.push(pos);
1939
+ this.callbackArguments.push(slice.call(arguments, 2));
1940
+ this.callbackContexts.push(context);
1941
+ this.callArgProps.push(undefined);
1795
1942
 
1796
1943
  return this;
1797
1944
  },
1798
1945
 
1799
1946
  yields: function () {
1800
- this.callArgAt = -1;
1801
- this.callbackArguments = slice.call(arguments, 0);
1947
+ this.callArgAts.push(-1);
1948
+ this.callbackArguments.push(slice.call(arguments, 0));
1949
+ this.callbackContexts.push(undefined);
1950
+ this.callArgProps.push(undefined);
1802
1951
 
1803
1952
  return this;
1804
1953
  },
@@ -1808,17 +1957,19 @@ var sinon = (function (buster) {
1808
1957
  throw new TypeError("argument context is not an object");
1809
1958
  }
1810
1959
 
1811
- this.callArgAt = -1;
1812
- this.callbackArguments = slice.call(arguments, 1);
1813
- this.callbackContext = context;
1960
+ this.callArgAts.push(-1);
1961
+ this.callbackArguments.push(slice.call(arguments, 1));
1962
+ this.callbackContexts.push(context);
1963
+ this.callArgProps.push(undefined);
1814
1964
 
1815
1965
  return this;
1816
1966
  },
1817
1967
 
1818
1968
  yieldsTo: function (prop) {
1819
- this.callArgAt = -1;
1820
- this.callArgProp = prop;
1821
- this.callbackArguments = slice.call(arguments, 1);
1969
+ this.callArgAts.push(-1);
1970
+ this.callbackArguments.push(slice.call(arguments, 1));
1971
+ this.callbackContexts.push(undefined);
1972
+ this.callArgProps.push(prop);
1822
1973
 
1823
1974
  return this;
1824
1975
  },
@@ -1828,18 +1979,21 @@ var sinon = (function (buster) {
1828
1979
  throw new TypeError("argument context is not an object");
1829
1980
  }
1830
1981
 
1831
- this.callArgAt = -1;
1832
- this.callArgProp = prop;
1833
- this.callbackArguments = slice.call(arguments, 2);
1834
- this.callbackContext = context;
1982
+ this.callArgAts.push(-1);
1983
+ this.callbackArguments.push(slice.call(arguments, 2));
1984
+ this.callbackContexts.push(context);
1985
+ this.callArgProps.push(prop);
1835
1986
 
1836
1987
  return this;
1837
1988
  }
1838
1989
  };
1839
-
1990
+
1840
1991
  // create asynchronous versions of callsArg* and yields* methods
1841
1992
  for (var method in proto) {
1842
- if (proto.hasOwnProperty(method) && method.match(/^(callsArg|yields)/)) {
1993
+ // need to avoid creating anotherasync versions of the newly added async methods
1994
+ if (proto.hasOwnProperty(method) &&
1995
+ method.match(/^(callsArg|yields|thenYields$)/) &&
1996
+ !method.match(/Async/)) {
1843
1997
  proto[method + 'Async'] = (function (syncFnName) {
1844
1998
  return function () {
1845
1999
  this.callbackAsync = true;
@@ -1848,9 +2002,9 @@ var sinon = (function (buster) {
1848
2002
  })(method);
1849
2003
  }
1850
2004
  }
1851
-
2005
+
1852
2006
  return proto;
1853
-
2007
+
1854
2008
  }()));
1855
2009
 
1856
2010
  if (commonJSModule) {
@@ -1872,7 +2026,7 @@ var sinon = (function (buster) {
1872
2026
  * @author Christian Johansen (christian@cjohansen.no)
1873
2027
  * @license BSD
1874
2028
  *
1875
- * Copyright (c) 2010-2011 Christian Johansen
2029
+ * Copyright (c) 2010-2013 Christian Johansen
1876
2030
  */
1877
2031
 
1878
2032
  (function (sinon) {
@@ -2161,24 +2315,24 @@ var sinon = (function (buster) {
2161
2315
 
2162
2316
  if (!args) {
2163
2317
  sinon.expectation.fail(this.method + " received no arguments, expected " +
2164
- this.expectedArguments.join());
2318
+ sinon.format(this.expectedArguments));
2165
2319
  }
2166
2320
 
2167
2321
  if (args.length < this.expectedArguments.length) {
2168
- sinon.expectation.fail(this.method + " received too few arguments (" + args.join() +
2169
- "), expected " + this.expectedArguments.join());
2322
+ sinon.expectation.fail(this.method + " received too few arguments (" + sinon.format(args) +
2323
+ "), expected " + sinon.format(this.expectedArguments));
2170
2324
  }
2171
2325
 
2172
2326
  if (this.expectsExactArgCount &&
2173
2327
  args.length != this.expectedArguments.length) {
2174
- sinon.expectation.fail(this.method + " received too many arguments (" + args.join() +
2175
- "), expected " + this.expectedArguments.join());
2328
+ sinon.expectation.fail(this.method + " received too many arguments (" + sinon.format(args) +
2329
+ "), expected " + sinon.format(this.expectedArguments));
2176
2330
  }
2177
2331
 
2178
2332
  for (var i = 0, l = this.expectedArguments.length; i < l; i += 1) {
2179
2333
  if (!sinon.deepEqual(this.expectedArguments[i], args[i])) {
2180
- sinon.expectation.fail(this.method + " received wrong arguments (" + args.join() +
2181
- "), expected " + this.expectedArguments.join());
2334
+ sinon.expectation.fail(this.method + " received wrong arguments " + sinon.format(args) +
2335
+ ", expected " + sinon.format(this.expectedArguments));
2182
2336
  }
2183
2337
  }
2184
2338
  },
@@ -2240,7 +2394,8 @@ var sinon = (function (buster) {
2240
2394
  }
2241
2395
 
2242
2396
  var callStr = sinon.spyCall.toString.call({
2243
- proxy: this.method, args: args
2397
+ proxy: this.method || "anonymous mock expectation",
2398
+ args: args
2244
2399
  });
2245
2400
 
2246
2401
  var message = callStr.replace(", [...", "[, ...") + " " +
@@ -2296,12 +2451,13 @@ var sinon = (function (buster) {
2296
2451
  * @author Christian Johansen (christian@cjohansen.no)
2297
2452
  * @license BSD
2298
2453
  *
2299
- * Copyright (c) 2010-2011 Christian Johansen
2454
+ * Copyright (c) 2010-2013 Christian Johansen
2300
2455
  */
2301
2456
 
2302
2457
  (function (sinon) {
2303
2458
  var commonJSModule = typeof module == "object" && typeof require == "function";
2304
2459
  var push = [].push;
2460
+ var hasOwnProperty = Object.prototype.hasOwnProperty;
2305
2461
 
2306
2462
  if (!sinon && commonJSModule) {
2307
2463
  sinon = require("../sinon");
@@ -2377,7 +2533,7 @@ var sinon = (function (buster) {
2377
2533
  var original = object[property];
2378
2534
 
2379
2535
  if (typeof original != "function") {
2380
- if (!object.hasOwnProperty(property)) {
2536
+ if (!hasOwnProperty.call(object, property)) {
2381
2537
  throw new TypeError("Cannot stub non-existent own property " + property);
2382
2538
  }
2383
2539
 
@@ -2452,7 +2608,7 @@ var sinon = (function (buster) {
2452
2608
  * @author Christian Johansen (christian@cjohansen.no)
2453
2609
  * @license BSD
2454
2610
  *
2455
- * Copyright (c) 2010-2011 Christian Johansen
2611
+ * Copyright (c) 2010-2013 Christian Johansen
2456
2612
  */
2457
2613
 
2458
2614
  if (typeof sinon == "undefined") {
@@ -2593,6 +2749,8 @@ if (typeof sinon == "undefined") {
2593
2749
  if (firstException) {
2594
2750
  throw firstException;
2595
2751
  }
2752
+
2753
+ return this.now;
2596
2754
  },
2597
2755
 
2598
2756
  firstTimerInRange: function (from, to) {
@@ -2806,15 +2964,16 @@ if (typeof sinon == "undefined") {
2806
2964
  (function () {
2807
2965
  var push = [].push;
2808
2966
 
2809
- sinon.Event = function Event(type, bubbles, cancelable) {
2810
- this.initEvent(type, bubbles, cancelable);
2967
+ sinon.Event = function Event(type, bubbles, cancelable, target) {
2968
+ this.initEvent(type, bubbles, cancelable, target);
2811
2969
  };
2812
2970
 
2813
2971
  sinon.Event.prototype = {
2814
- initEvent: function(type, bubbles, cancelable) {
2972
+ initEvent: function(type, bubbles, cancelable, target) {
2815
2973
  this.type = type;
2816
2974
  this.bubbles = bubbles;
2817
2975
  this.cancelable = cancelable;
2976
+ this.target = target;
2818
2977
  },
2819
2978
 
2820
2979
  stopPropagation: function () {},
@@ -2859,6 +3018,7 @@ if (typeof sinon == "undefined") {
2859
3018
  }());
2860
3019
 
2861
3020
  /**
3021
+ * @depend ../../sinon.js
2862
3022
  * @depend event.js
2863
3023
  */
2864
3024
  /*jslint eqeqeq: false, onevar: false*/
@@ -2869,7 +3029,7 @@ if (typeof sinon == "undefined") {
2869
3029
  * @author Christian Johansen (christian@cjohansen.no)
2870
3030
  * @license BSD
2871
3031
  *
2872
- * Copyright (c) 2010-2011 Christian Johansen
3032
+ * Copyright (c) 2010-2013 Christian Johansen
2873
3033
  */
2874
3034
 
2875
3035
  if (typeof sinon == "undefined") {
@@ -2917,6 +3077,18 @@ sinon.xhr = { XMLHttpRequest: this.XMLHttpRequest };
2917
3077
  this.status = 0;
2918
3078
  this.statusText = "";
2919
3079
 
3080
+ var xhr = this;
3081
+
3082
+ ["loadstart", "load", "abort", "loadend"].forEach(function (eventName) {
3083
+ xhr.addEventListener(eventName, function (event) {
3084
+ var listener = xhr["on" + eventName];
3085
+
3086
+ if (listener && typeof listener == "function") {
3087
+ listener(event);
3088
+ }
3089
+ });
3090
+ });
3091
+
2920
3092
  if (typeof FakeXMLHttpRequest.onCreate == "function") {
2921
3093
  FakeXMLHttpRequest.onCreate(this);
2922
3094
  }
@@ -3070,6 +3242,13 @@ sinon.xhr = { XMLHttpRequest: this.XMLHttpRequest };
3070
3242
  }
3071
3243
 
3072
3244
  this.dispatchEvent(new sinon.Event("readystatechange"));
3245
+
3246
+ switch (this.readyState) {
3247
+ case FakeXMLHttpRequest.DONE:
3248
+ this.dispatchEvent(new sinon.Event("load", false, false, this));
3249
+ this.dispatchEvent(new sinon.Event("loadend", false, false, this));
3250
+ break;
3251
+ }
3073
3252
  },
3074
3253
 
3075
3254
  setRequestHeader: function setRequestHeader(header, value) {
@@ -3098,6 +3277,8 @@ sinon.xhr = { XMLHttpRequest: this.XMLHttpRequest };
3098
3277
 
3099
3278
  if (this.async) {
3100
3279
  this.readyStateChange(FakeXMLHttpRequest.HEADERS_RECEIVED);
3280
+ } else {
3281
+ this.readyState = FakeXMLHttpRequest.HEADERS_RECEIVED;
3101
3282
  }
3102
3283
  },
3103
3284
 
@@ -3123,6 +3304,8 @@ sinon.xhr = { XMLHttpRequest: this.XMLHttpRequest };
3123
3304
  if (typeof this.onSend == "function") {
3124
3305
  this.onSend(this);
3125
3306
  }
3307
+
3308
+ this.dispatchEvent(new sinon.Event("loadstart", false, false, this));
3126
3309
  },
3127
3310
 
3128
3311
  abort: function abort() {
@@ -3137,6 +3320,11 @@ sinon.xhr = { XMLHttpRequest: this.XMLHttpRequest };
3137
3320
  }
3138
3321
 
3139
3322
  this.readyState = sinon.FakeXMLHttpRequest.UNSENT;
3323
+
3324
+ this.dispatchEvent(new sinon.Event("abort", false, false, this));
3325
+ if (typeof this.onerror === "function") {
3326
+ this.onerror();
3327
+ }
3140
3328
  },
3141
3329
 
3142
3330
  getResponseHeader: function getResponseHeader(header) {
@@ -3217,6 +3405,10 @@ sinon.xhr = { XMLHttpRequest: this.XMLHttpRequest };
3217
3405
  this.status = typeof status == "number" ? status : 200;
3218
3406
  this.statusText = FakeXMLHttpRequest.statusCodes[this.status];
3219
3407
  this.setResponseBody(body || "");
3408
+ if (typeof this.onload === "function"){
3409
+ this.onload();
3410
+ }
3411
+
3220
3412
  }
3221
3413
  });
3222
3414
 
@@ -3343,7 +3535,7 @@ if (typeof module == "object" && typeof require == "function") {
3343
3535
  * @author Christian Johansen (christian@cjohansen.no)
3344
3536
  * @license BSD
3345
3537
  *
3346
- * Copyright (c) 2010-2011 Christian Johansen
3538
+ * Copyright (c) 2010-2013 Christian Johansen
3347
3539
  */
3348
3540
 
3349
3541
  if (typeof sinon == "undefined") {
@@ -3407,6 +3599,15 @@ sinon.fakeServer = (function () {
3407
3599
  return false;
3408
3600
  }
3409
3601
 
3602
+ function log(response, request) {
3603
+ var str;
3604
+
3605
+ str = "Request:\n" + sinon.format(request) + "\n\n";
3606
+ str += "Response:\n" + sinon.format(response) + "\n\n";
3607
+
3608
+ sinon.log(str);
3609
+ }
3610
+
3410
3611
  return {
3411
3612
  create: function () {
3412
3613
  var server = create(this);
@@ -3513,6 +3714,8 @@ sinon.fakeServer = (function () {
3513
3714
  }
3514
3715
 
3515
3716
  if (request.readyState != 4) {
3717
+ log(response, request);
3718
+
3516
3719
  request.respond(response[0], response[1], response[2]);
3517
3720
  }
3518
3721
  } catch (e) {
@@ -3548,7 +3751,7 @@ if (typeof module == "object" && typeof require == "function") {
3548
3751
  * @author Christian Johansen (christian@cjohansen.no)
3549
3752
  * @license BSD
3550
3753
  *
3551
- * Copyright (c) 2010-2011 Christian Johansen
3754
+ * Copyright (c) 2010-2013 Christian Johansen
3552
3755
  */
3553
3756
 
3554
3757
  (function () {
@@ -3628,7 +3831,7 @@ if (typeof module == "object" && typeof require == "function") {
3628
3831
  * @author Christian Johansen (christian@cjohansen.no)
3629
3832
  * @license BSD
3630
3833
  *
3631
- * Copyright (c) 2010-2011 Christian Johansen
3834
+ * Copyright (c) 2010-2013 Christian Johansen
3632
3835
  */
3633
3836
 
3634
3837
  if (typeof module == "object" && typeof require == "function") {
@@ -3752,7 +3955,7 @@ if (typeof module == "object" && typeof require == "function") {
3752
3955
  * @author Christian Johansen (christian@cjohansen.no)
3753
3956
  * @license BSD
3754
3957
  *
3755
- * Copyright (c) 2010-2011 Christian Johansen
3958
+ * Copyright (c) 2010-2013 Christian Johansen
3756
3959
  */
3757
3960
 
3758
3961
  (function (sinon) {
@@ -3782,7 +3985,15 @@ if (typeof module == "object" && typeof require == "function") {
3782
3985
 
3783
3986
  try {
3784
3987
  result = callback.apply(this, args);
3785
- } finally {
3988
+ } catch (e) {
3989
+ exception = e;
3990
+ }
3991
+
3992
+ if (typeof exception !== "undefined") {
3993
+ sandbox.restore();
3994
+ throw exception;
3995
+ }
3996
+ else {
3786
3997
  sandbox.verifyAndRestore();
3787
3998
  }
3788
3999
 
@@ -3817,7 +4028,7 @@ if (typeof module == "object" && typeof require == "function") {
3817
4028
  * @author Christian Johansen (christian@cjohansen.no)
3818
4029
  * @license BSD
3819
4030
  *
3820
- * Copyright (c) 2010-2011 Christian Johansen
4031
+ * Copyright (c) 2010-2013 Christian Johansen
3821
4032
  */
3822
4033
 
3823
4034
  (function (sinon) {
@@ -3914,7 +4125,7 @@ if (typeof module == "object" && typeof require == "function") {
3914
4125
  * @author Christian Johansen (christian@cjohansen.no)
3915
4126
  * @license BSD
3916
4127
  *
3917
- * Copyright (c) 2010-2011 Christian Johansen
4128
+ * Copyright (c) 2010-2013 Christian Johansen
3918
4129
  */
3919
4130
 
3920
4131
  (function (sinon, global) {
@@ -4007,7 +4218,14 @@ if (typeof module == "object" && typeof require == "function") {
4007
4218
  if (!sinon.calledInOrder(arguments)) {
4008
4219
  try {
4009
4220
  expected = [].join.call(arguments, ", ");
4010
- actual = sinon.orderByFirstCall(slice.call(arguments)).join(", ");
4221
+ var calls = slice.call(arguments);
4222
+ var i = calls.length;
4223
+ while (i) {
4224
+ if (!calls[--i].called) {
4225
+ calls.splice(i, 1);
4226
+ }
4227
+ }
4228
+ actual = sinon.orderByFirstCall(calls).join(", ");
4011
4229
  } catch (e) {
4012
4230
  // If this fails, we'll just fall back to the blank string
4013
4231
  }
@@ -4076,6 +4294,6 @@ if (typeof module == "object" && typeof require == "function") {
4076
4294
  } else {
4077
4295
  sinon.assert = assert;
4078
4296
  }
4079
- }(typeof sinon == "object" && sinon || null, typeof window != "undefined" ? window : global));
4297
+ }(typeof sinon == "object" && sinon || null, typeof window != "undefined" ? window : (typeof self != "undefined") ? self : global));
4080
4298
 
4081
- return sinon;}.call(typeof window != 'undefined' && window || {}));
4299
+ return sinon;}.call(typeof window != 'undefined' && window || {}));