sinon-rails 1.4.2.1 → 1.7.1.1

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