konacha-chai-matchers 0.1.3 → 0.1.4

Sign up to get free protection for your applications and to get access to all the features.
data/VERSIONS CHANGED
@@ -6,7 +6,7 @@ chai-timers: 0.2.0
6
6
  chai-stats: 0.2.0
7
7
  chai-null: 0.1.0
8
8
  chai-factories: 0.1.0
9
- chai-changes: 1.3.1
9
+ chai-changes: 1.3.2
10
10
  chai-backbone: 0.9.2
11
11
  js-factories: 0.9.0
12
12
  mocha-as-promised: 1.4.0
@@ -1,7 +1,7 @@
1
1
  module Konacha
2
2
  module Chai
3
3
  module Matchers
4
- VERSION = "0.1.3"
4
+ VERSION = "0.1.4"
5
5
  end
6
6
  end
7
7
  end
@@ -1,6 +1,5 @@
1
- // Generated by CoffeeScript 1.3.3
1
+ // Generated by CoffeeScript 1.6.3
2
2
  (function() {
3
-
4
3
  (function(chaiChanges) {
5
4
  if (typeof require === "function" && typeof exports === "object" && typeof module === "object") {
6
5
  return module.exports = chaiChanges;
@@ -12,7 +11,7 @@
12
11
  return chai.use(chaiChanges);
13
12
  }
14
13
  })(function(chai, utils) {
15
- var byAtLeast, byAtMost, changeBy, changeByAssert, changeFrom, changeFromAssert, changeFromBeginAssert, changeTo, changeToAssert, changeToBeginAssert, flag, formatFunction, inspect, noChangeAssert;
14
+ var byAtLeast, byAtMost, changeBy, changeByAssert, changeFrom, changeFromAssert, changeFromBeginAssert, changeTo, changeToAssert, changeToBeginAssert, clone, flag, formatFunction, inspect, noChangeAssert;
16
15
  inspect = utils.inspect;
17
16
  flag = utils.flag;
18
17
  chai.Assertion.addMethod('when', function(val, options) {
@@ -38,7 +37,7 @@
38
37
  done = function() {};
39
38
  }
40
39
  promiseCallback = function() {
41
- var _j, _len1;
40
+ var error, _j, _len1;
42
41
  try {
43
42
  for (_j = 0, _len1 = definedActions.length; _j < _len1; _j++) {
44
43
  action = definedActions[_j];
@@ -47,7 +46,8 @@
47
46
  }
48
47
  }
49
48
  return done();
50
- } catch (error) {
49
+ } catch (_error) {
50
+ error = _error;
51
51
  done(error);
52
52
  throw error;
53
53
  }
@@ -90,13 +90,28 @@
90
90
  context.assert(this.expectedDelta === actualDelta, "expected `" + (formatFunction(object)) + "` to change by " + this.expectedDelta + ", but it changed by " + actualDelta, "expected `" + (formatFunction(object)) + "` not to change by " + this.expectedDelta + ", but it did");
91
91
  return flag(context, 'negate', negate);
92
92
  };
93
+ clone = function(obj) {
94
+ var key, result, value;
95
+ if (obj !== Object(obj)) {
96
+ return obj;
97
+ }
98
+ if (Array.isArray(obj)) {
99
+ return obj.slice();
100
+ }
101
+ result = {};
102
+ for (key in obj) {
103
+ value = obj[key];
104
+ result[key] = value;
105
+ }
106
+ return result;
107
+ };
93
108
  changeToBeginAssert = function(context) {
94
109
  var negate, object, result, startValue;
95
110
  negate = flag(context, 'negate');
96
111
  flag(context, 'negate', this.negate);
97
112
  object = flag(context, 'whenObject');
98
113
  startValue = object();
99
- flag(context, 'changeToStart', startValue);
114
+ flag(context, 'changeToStart', clone(startValue));
100
115
  result = !utils.eql(startValue, this.expectedEndValue);
101
116
  if (negate) {
102
117
  result = !result;
@@ -1,12 +1,12 @@
1
1
  /**
2
- * Sinon.JS 1.5.2, 2013/02/08
2
+ * Sinon.JS 1.7.3, 2013/07/24
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,
@@ -41,7 +41,7 @@
41
41
  * @author Christian Johansen (christian@cjohansen.no)
42
42
  * @license BSD
43
43
  *
44
- * Copyright (c) 2010-2011 Christian Johansen
44
+ * Copyright (c) 2010-2013 Christian Johansen
45
45
  */
46
46
 
47
47
  var sinon = (function (buster) {
@@ -83,6 +83,10 @@ var sinon = (function (buster) {
83
83
  }
84
84
  }
85
85
 
86
+ function isRestorable (obj) {
87
+ return typeof obj === "function" && typeof obj.restore === "function" && obj.restore.sinon;
88
+ }
89
+
86
90
  var sinon = {
87
91
  wrapMethod: function wrapMethod(object, property, method) {
88
92
  if (!object) {
@@ -195,6 +199,10 @@ var sinon = (function (buster) {
195
199
  return true;
196
200
  }
197
201
 
202
+ if (aString == "[object Date]") {
203
+ return a.valueOf() === b.valueOf();
204
+ }
205
+
198
206
  var prop, aLength = 0, bLength = 0;
199
207
 
200
208
  for (prop in a) {
@@ -209,11 +217,7 @@ var sinon = (function (buster) {
209
217
  bLength += 1;
210
218
  }
211
219
 
212
- if (aLength != bLength) {
213
- return false;
214
- }
215
-
216
- return true;
220
+ return aLength == bLength;
217
221
  },
218
222
 
219
223
  functionName: function functionName(func) {
@@ -284,7 +288,7 @@ var sinon = (function (buster) {
284
288
 
285
289
  calledInOrder: function (spies) {
286
290
  for (var i = 1, l = spies.length; i < l; i++) {
287
- if (!spies[i - 1].calledBefore(spies[i])) {
291
+ if (!spies[i - 1].calledBefore(spies[i]) || !spies[i].called) {
288
292
  return false;
289
293
  }
290
294
  }
@@ -333,6 +337,19 @@ var sinon = (function (buster) {
333
337
  throw new TypeError("The constructor should be a function.");
334
338
  }
335
339
  return sinon.stub(sinon.create(constructor.prototype));
340
+ },
341
+
342
+ restore: function (object) {
343
+ if (object !== null && typeof object === "object") {
344
+ for (var prop in object) {
345
+ if (isRestorable(object[prop])) {
346
+ object[prop].restore();
347
+ }
348
+ }
349
+ }
350
+ else if (isRestorable(object)) {
351
+ object.restore();
352
+ }
336
353
  }
337
354
  };
338
355
 
@@ -344,6 +361,7 @@ var sinon = (function (buster) {
344
361
  } catch (e) {}
345
362
  module.exports = sinon;
346
363
  module.exports.spy = require("./sinon/spy");
364
+ module.exports.spyCall = require("./sinon/call");
347
365
  module.exports.stub = require("./sinon/stub");
348
366
  module.exports.mock = require("./sinon/mock");
349
367
  module.exports.collection = require("./sinon/collection");
@@ -622,21 +640,18 @@ var sinon = (function (buster) {
622
640
  /*jslint eqeqeq: false, onevar: false, plusplus: false*/
623
641
  /*global module, require, sinon*/
624
642
  /**
625
- * Spy functions
643
+ * Spy calls
626
644
  *
627
645
  * @author Christian Johansen (christian@cjohansen.no)
646
+ * @author Maximilian Antoni (mail@maxantoni.de)
628
647
  * @license BSD
629
648
  *
630
- * Copyright (c) 2010-2011 Christian Johansen
649
+ * Copyright (c) 2010-2013 Christian Johansen
650
+ * Copyright (c) 2013 Maximilian Antoni
631
651
  */
632
652
 
633
653
  (function (sinon) {
634
654
  var commonJSModule = typeof module == "object" && typeof require == "function";
635
- var spyCall;
636
- var callId = 0;
637
- var push = [].push;
638
- var slice = Array.prototype.slice;
639
-
640
655
  if (!sinon && commonJSModule) {
641
656
  sinon = require("../sinon");
642
657
  }
@@ -645,536 +660,565 @@ var sinon = (function (buster) {
645
660
  return;
646
661
  }
647
662
 
648
- function spy(object, property) {
649
- if (!property && typeof object == "function") {
650
- return spy.create(object);
651
- }
652
-
653
- if (!object && !property) {
654
- return spy.create(function () { });
663
+ function throwYieldError(proxy, text, args) {
664
+ var msg = sinon.functionName(proxy) + text;
665
+ if (args.length) {
666
+ msg += " Received [" + slice.call(args).join(", ") + "]";
655
667
  }
656
-
657
- var method = object[property];
658
- return sinon.wrapMethod(object, property, spy.create(method));
668
+ throw new Error(msg);
659
669
  }
660
670
 
661
- sinon.extend(spy, (function () {
671
+ var slice = Array.prototype.slice;
662
672
 
663
- function delegateToCalls(api, method, matchAny, actual, notCalled) {
664
- api[method] = function () {
665
- if (!this.called) {
666
- if (notCalled) {
667
- return notCalled.apply(this, arguments);
668
- }
673
+ var callProto = {
674
+ calledOn: function calledOn(thisValue) {
675
+ if (sinon.match && sinon.match.isMatcher(thisValue)) {
676
+ return thisValue.test(this.thisValue);
677
+ }
678
+ return this.thisValue === thisValue;
679
+ },
680
+
681
+ calledWith: function calledWith() {
682
+ for (var i = 0, l = arguments.length; i < l; i += 1) {
683
+ if (!sinon.deepEqual(arguments[i], this.args[i])) {
669
684
  return false;
670
685
  }
686
+ }
687
+
688
+ return true;
689
+ },
671
690
 
672
- var currentCall;
673
- var matches = 0;
691
+ calledWithMatch: function calledWithMatch() {
692
+ for (var i = 0, l = arguments.length; i < l; i += 1) {
693
+ var actual = this.args[i];
694
+ var expectation = arguments[i];
695
+ if (!sinon.match || !sinon.match(expectation).test(actual)) {
696
+ return false;
697
+ }
698
+ }
699
+ return true;
700
+ },
674
701
 
675
- for (var i = 0, l = this.callCount; i < l; i += 1) {
676
- currentCall = this.getCall(i);
702
+ calledWithExactly: function calledWithExactly() {
703
+ return arguments.length == this.args.length &&
704
+ this.calledWith.apply(this, arguments);
705
+ },
677
706
 
678
- if (currentCall[actual || method].apply(currentCall, arguments)) {
679
- matches += 1;
707
+ notCalledWith: function notCalledWith() {
708
+ return !this.calledWith.apply(this, arguments);
709
+ },
680
710
 
681
- if (matchAny) {
682
- return true;
683
- }
684
- }
685
- }
711
+ notCalledWithMatch: function notCalledWithMatch() {
712
+ return !this.calledWithMatch.apply(this, arguments);
713
+ },
686
714
 
687
- return matches === this.callCount;
688
- };
689
- }
715
+ returned: function returned(value) {
716
+ return sinon.deepEqual(value, this.returnValue);
717
+ },
690
718
 
691
- function matchingFake(fakes, args, strict) {
692
- if (!fakes) {
693
- return;
719
+ threw: function threw(error) {
720
+ if (typeof error === "undefined" || !this.exception) {
721
+ return !!this.exception;
694
722
  }
695
723
 
696
- var alen = args.length;
724
+ return this.exception === error || this.exception.name === error;
725
+ },
697
726
 
698
- for (var i = 0, l = fakes.length; i < l; i++) {
699
- if (fakes[i].matches(args, strict)) {
700
- return fakes[i];
701
- }
702
- }
703
- }
727
+ calledWithNew: function calledWithNew(thisValue) {
728
+ return this.thisValue instanceof this.proxy;
729
+ },
704
730
 
705
- function incrementCallCount() {
706
- this.called = true;
707
- this.callCount += 1;
708
- this.notCalled = false;
709
- this.calledOnce = this.callCount == 1;
710
- this.calledTwice = this.callCount == 2;
711
- this.calledThrice = this.callCount == 3;
712
- }
731
+ calledBefore: function (other) {
732
+ return this.callId < other.callId;
733
+ },
713
734
 
714
- function createCallProperties() {
715
- this.firstCall = this.getCall(0);
716
- this.secondCall = this.getCall(1);
717
- this.thirdCall = this.getCall(2);
718
- this.lastCall = this.getCall(this.callCount - 1);
719
- }
735
+ calledAfter: function (other) {
736
+ return this.callId > other.callId;
737
+ },
720
738
 
721
- var vars = "a,b,c,d,e,f,g,h,i,j,k,l";
722
- function createProxy(func) {
723
- // Retain the function length:
724
- var p;
725
- if (func.length) {
726
- eval("p = (function proxy(" + vars.substring(0, func.length * 2 - 1) +
727
- ") { return p.invoke(func, this, slice.call(arguments)); });");
728
- }
729
- else {
730
- p = function proxy() {
731
- return p.invoke(func, this, slice.call(arguments));
732
- };
733
- }
734
- return p;
735
- }
736
-
737
- var uuid = 0;
738
-
739
- // Public API
740
- var spyApi = {
741
- reset: function () {
742
- this.called = false;
743
- this.notCalled = true;
744
- this.calledOnce = false;
745
- this.calledTwice = false;
746
- this.calledThrice = false;
747
- this.callCount = 0;
748
- this.firstCall = null;
749
- this.secondCall = null;
750
- this.thirdCall = null;
751
- this.lastCall = null;
752
- this.args = [];
753
- this.returnValues = [];
754
- this.thisValues = [];
755
- this.exceptions = [];
756
- this.callIds = [];
757
- if (this.fakes) {
758
- for (var i = 0; i < this.fakes.length; i++) {
759
- this.fakes[i].reset();
760
- }
761
- }
762
- },
739
+ callArg: function (pos) {
740
+ this.args[pos]();
741
+ },
763
742
 
764
- create: function create(func) {
765
- var name;
743
+ callArgOn: function (pos, thisValue) {
744
+ this.args[pos].apply(thisValue);
745
+ },
766
746
 
767
- if (typeof func != "function") {
768
- func = function () { };
769
- } else {
770
- name = sinon.functionName(func);
747
+ callArgWith: function (pos) {
748
+ this.callArgOnWith.apply(this, [pos, null].concat(slice.call(arguments, 1)));
749
+ },
750
+
751
+ callArgOnWith: function (pos, thisValue) {
752
+ var args = slice.call(arguments, 2);
753
+ this.args[pos].apply(thisValue, args);
754
+ },
755
+
756
+ "yield": function () {
757
+ this.yieldOn.apply(this, [null].concat(slice.call(arguments, 0)));
758
+ },
759
+
760
+ yieldOn: function (thisValue) {
761
+ var args = this.args;
762
+ for (var i = 0, l = args.length; i < l; ++i) {
763
+ if (typeof args[i] === "function") {
764
+ args[i].apply(thisValue, slice.call(arguments, 1));
765
+ return;
771
766
  }
767
+ }
768
+ throwYieldError(this.proxy, " cannot yield since no callback was passed.", args);
769
+ },
772
770
 
773
- var proxy = createProxy(func);
771
+ yieldTo: function (prop) {
772
+ this.yieldToOn.apply(this, [prop, null].concat(slice.call(arguments, 1)));
773
+ },
774
774
 
775
- sinon.extend(proxy, spy);
776
- delete proxy.create;
777
- sinon.extend(proxy, func);
775
+ yieldToOn: function (prop, thisValue) {
776
+ var args = this.args;
777
+ for (var i = 0, l = args.length; i < l; ++i) {
778
+ if (args[i] && typeof args[i][prop] === "function") {
779
+ args[i][prop].apply(thisValue, slice.call(arguments, 2));
780
+ return;
781
+ }
782
+ }
783
+ throwYieldError(this.proxy, " cannot yield to '" + prop +
784
+ "' since no callback was passed.", args);
785
+ },
778
786
 
779
- proxy.reset();
780
- proxy.prototype = func.prototype;
781
- proxy.displayName = name || "spy";
782
- proxy.toString = sinon.functionToString;
783
- proxy._create = sinon.spy.create;
784
- proxy.id = "spy#" + uuid++;
787
+ toString: function () {
788
+ var callStr = this.proxy.toString() + "(";
789
+ var args = [];
785
790
 
786
- return proxy;
787
- },
791
+ for (var i = 0, l = this.args.length; i < l; ++i) {
792
+ args.push(sinon.format(this.args[i]));
793
+ }
788
794
 
789
- invoke: function invoke(func, thisValue, args) {
790
- var matching = matchingFake(this.fakes, args);
791
- var exception, returnValue;
795
+ callStr = callStr + args.join(", ") + ")";
792
796
 
793
- incrementCallCount.call(this);
794
- push.call(this.thisValues, thisValue);
795
- push.call(this.args, args);
796
- push.call(this.callIds, callId++);
797
+ if (typeof this.returnValue != "undefined") {
798
+ callStr += " => " + sinon.format(this.returnValue);
799
+ }
797
800
 
798
- try {
799
- if (matching) {
800
- returnValue = matching.invoke(func, thisValue, args);
801
- } else {
802
- returnValue = (this.func || func).apply(thisValue, args);
803
- }
804
- } catch (e) {
805
- push.call(this.returnValues, undefined);
806
- exception = e;
807
- throw e;
808
- } finally {
809
- push.call(this.exceptions, exception);
801
+ if (this.exception) {
802
+ callStr += " !" + this.exception.name;
803
+
804
+ if (this.exception.message) {
805
+ callStr += "(" + this.exception.message + ")";
810
806
  }
807
+ }
811
808
 
812
- push.call(this.returnValues, returnValue);
809
+ return callStr;
810
+ }
811
+ };
813
812
 
814
- createCallProperties.call(this);
813
+ callProto.invokeCallback = callProto.yield;
815
814
 
816
- return returnValue;
817
- },
815
+ function createSpyCall(spy, thisValue, args, returnValue, exception, id) {
816
+ if (typeof id !== "number") {
817
+ throw new TypeError("Call id is not a number");
818
+ }
819
+ var proxyCall = sinon.create(callProto);
820
+ proxyCall.proxy = spy;
821
+ proxyCall.thisValue = thisValue;
822
+ proxyCall.args = args;
823
+ proxyCall.returnValue = returnValue;
824
+ proxyCall.exception = exception;
825
+ proxyCall.callId = id;
818
826
 
819
- getCall: function getCall(i) {
820
- if (i < 0 || i >= this.callCount) {
821
- return null;
822
- }
827
+ return proxyCall;
828
+ };
829
+ createSpyCall.toString = callProto.toString; // used by mocks
823
830
 
824
- return spyCall.create(this, this.thisValues[i], this.args[i],
825
- this.returnValues[i], this.exceptions[i],
826
- this.callIds[i]);
827
- },
831
+ if (commonJSModule) {
832
+ module.exports = createSpyCall;
833
+ } else {
834
+ sinon.spyCall = createSpyCall;
835
+ }
836
+ }(typeof sinon == "object" && sinon || null));
828
837
 
829
- calledBefore: function calledBefore(spyFn) {
830
- if (!this.called) {
831
- return false;
832
- }
833
838
 
834
- if (!spyFn.called) {
835
- return true;
836
- }
839
+ /**
840
+ * @depend ../sinon.js
841
+ * @depend call.js
842
+ */
843
+ /*jslint eqeqeq: false, onevar: false, plusplus: false*/
844
+ /*global module, require, sinon*/
845
+ /**
846
+ * Spy functions
847
+ *
848
+ * @author Christian Johansen (christian@cjohansen.no)
849
+ * @license BSD
850
+ *
851
+ * Copyright (c) 2010-2013 Christian Johansen
852
+ */
837
853
 
838
- return this.callIds[0] < spyFn.callIds[spyFn.callIds.length - 1];
839
- },
854
+ (function (sinon) {
855
+ var commonJSModule = typeof module == "object" && typeof require == "function";
856
+ var push = Array.prototype.push;
857
+ var slice = Array.prototype.slice;
858
+ var callId = 0;
840
859
 
841
- calledAfter: function calledAfter(spyFn) {
842
- if (!this.called || !spyFn.called) {
843
- return false;
844
- }
860
+ if (!sinon && commonJSModule) {
861
+ sinon = require("../sinon");
862
+ }
845
863
 
846
- return this.callIds[this.callCount - 1] > spyFn.callIds[spyFn.callCount - 1];
847
- },
864
+ if (!sinon) {
865
+ return;
866
+ }
848
867
 
849
- withArgs: function () {
850
- var args = slice.call(arguments);
868
+ function spy(object, property) {
869
+ if (!property && typeof object == "function") {
870
+ return spy.create(object);
871
+ }
851
872
 
852
- if (this.fakes) {
853
- var match = matchingFake(this.fakes, args, true);
873
+ if (!object && !property) {
874
+ return spy.create(function () { });
875
+ }
854
876
 
855
- if (match) {
856
- return match;
857
- }
858
- } else {
859
- this.fakes = [];
860
- }
877
+ var method = object[property];
878
+ return sinon.wrapMethod(object, property, spy.create(method));
879
+ }
861
880
 
862
- var original = this;
863
- var fake = this._create();
864
- fake.matchingAguments = args;
865
- push.call(this.fakes, fake);
881
+ function matchingFake(fakes, args, strict) {
882
+ if (!fakes) {
883
+ return;
884
+ }
866
885
 
867
- fake.withArgs = function () {
868
- return original.withArgs.apply(original, arguments);
869
- };
886
+ var alen = args.length;
870
887
 
871
- for (var i = 0; i < this.args.length; i++) {
872
- if (fake.matches(this.args[i])) {
873
- incrementCallCount.call(fake);
874
- push.call(fake.thisValues, this.thisValues[i]);
875
- push.call(fake.args, this.args[i]);
876
- push.call(fake.returnValues, this.returnValues[i]);
877
- push.call(fake.exceptions, this.exceptions[i]);
878
- push.call(fake.callIds, this.callIds[i]);
879
- }
880
- }
881
- createCallProperties.call(fake);
888
+ for (var i = 0, l = fakes.length; i < l; i++) {
889
+ if (fakes[i].matches(args, strict)) {
890
+ return fakes[i];
891
+ }
892
+ }
893
+ }
882
894
 
883
- return fake;
884
- },
895
+ function incrementCallCount() {
896
+ this.called = true;
897
+ this.callCount += 1;
898
+ this.notCalled = false;
899
+ this.calledOnce = this.callCount == 1;
900
+ this.calledTwice = this.callCount == 2;
901
+ this.calledThrice = this.callCount == 3;
902
+ }
885
903
 
886
- matches: function (args, strict) {
887
- var margs = this.matchingAguments;
904
+ function createCallProperties() {
905
+ this.firstCall = this.getCall(0);
906
+ this.secondCall = this.getCall(1);
907
+ this.thirdCall = this.getCall(2);
908
+ this.lastCall = this.getCall(this.callCount - 1);
909
+ }
888
910
 
889
- if (margs.length <= args.length &&
890
- sinon.deepEqual(margs, args.slice(0, margs.length))) {
891
- return !strict || margs.length == args.length;
892
- }
893
- },
911
+ var vars = "a,b,c,d,e,f,g,h,i,j,k,l";
912
+ function createProxy(func) {
913
+ // Retain the function length:
914
+ var p;
915
+ if (func.length) {
916
+ eval("p = (function proxy(" + vars.substring(0, func.length * 2 - 1) +
917
+ ") { return p.invoke(func, this, slice.call(arguments)); });");
918
+ }
919
+ else {
920
+ p = function proxy() {
921
+ return p.invoke(func, this, slice.call(arguments));
922
+ };
923
+ }
924
+ return p;
925
+ }
894
926
 
895
- printf: function (format) {
896
- var spy = this;
897
- var args = slice.call(arguments, 1);
898
- var formatter;
927
+ var uuid = 0;
899
928
 
900
- return (format || "").replace(/%(.)/g, function (match, specifyer) {
901
- formatter = spyApi.formatters[specifyer];
929
+ // Public API
930
+ var spyApi = {
931
+ reset: function () {
932
+ this.called = false;
933
+ this.notCalled = true;
934
+ this.calledOnce = false;
935
+ this.calledTwice = false;
936
+ this.calledThrice = false;
937
+ this.callCount = 0;
938
+ this.firstCall = null;
939
+ this.secondCall = null;
940
+ this.thirdCall = null;
941
+ this.lastCall = null;
942
+ this.args = [];
943
+ this.returnValues = [];
944
+ this.thisValues = [];
945
+ this.exceptions = [];
946
+ this.callIds = [];
947
+ if (this.fakes) {
948
+ for (var i = 0; i < this.fakes.length; i++) {
949
+ this.fakes[i].reset();
950
+ }
951
+ }
952
+ },
902
953
 
903
- if (typeof formatter == "function") {
904
- return formatter.call(null, spy, args);
905
- } else if (!isNaN(parseInt(specifyer), 10)) {
906
- return sinon.format(args[specifyer - 1]);
907
- }
954
+ create: function create(func) {
955
+ var name;
908
956
 
909
- return "%" + specifyer;
910
- });
957
+ if (typeof func != "function") {
958
+ func = function () { };
959
+ } else {
960
+ name = sinon.functionName(func);
911
961
  }
912
- };
913
962
 
914
- delegateToCalls(spyApi, "calledOn", true);
915
- delegateToCalls(spyApi, "alwaysCalledOn", false, "calledOn");
916
- delegateToCalls(spyApi, "calledWith", true);
917
- delegateToCalls(spyApi, "calledWithMatch", true);
918
- delegateToCalls(spyApi, "alwaysCalledWith", false, "calledWith");
919
- delegateToCalls(spyApi, "alwaysCalledWithMatch", false, "calledWithMatch");
920
- delegateToCalls(spyApi, "calledWithExactly", true);
921
- delegateToCalls(spyApi, "alwaysCalledWithExactly", false, "calledWithExactly");
922
- delegateToCalls(spyApi, "neverCalledWith", false, "notCalledWith",
923
- function () { return true; });
924
- delegateToCalls(spyApi, "neverCalledWithMatch", false, "notCalledWithMatch",
925
- function () { return true; });
926
- delegateToCalls(spyApi, "threw", true);
927
- delegateToCalls(spyApi, "alwaysThrew", false, "threw");
928
- delegateToCalls(spyApi, "returned", true);
929
- delegateToCalls(spyApi, "alwaysReturned", false, "returned");
930
- delegateToCalls(spyApi, "calledWithNew", true);
931
- delegateToCalls(spyApi, "alwaysCalledWithNew", false, "calledWithNew");
932
- delegateToCalls(spyApi, "callArg", false, "callArgWith", function () {
933
- throw new Error(this.toString() + " cannot call arg since it was not yet invoked.");
934
- });
935
- spyApi.callArgWith = spyApi.callArg;
936
- delegateToCalls(spyApi, "callArgOn", false, "callArgOnWith", function () {
937
- throw new Error(this.toString() + " cannot call arg since it was not yet invoked.");
938
- });
939
- spyApi.callArgOnWith = spyApi.callArgOn;
940
- delegateToCalls(spyApi, "yield", false, "yield", function () {
941
- throw new Error(this.toString() + " cannot yield since it was not yet invoked.");
942
- });
943
- // "invokeCallback" is an alias for "yield" since "yield" is invalid in strict mode.
944
- spyApi.invokeCallback = spyApi.yield;
945
- delegateToCalls(spyApi, "yieldOn", false, "yieldOn", function () {
946
- throw new Error(this.toString() + " cannot yield since it was not yet invoked.");
947
- });
948
- delegateToCalls(spyApi, "yieldTo", false, "yieldTo", function (property) {
949
- throw new Error(this.toString() + " cannot yield to '" + property +
950
- "' since it was not yet invoked.");
951
- });
952
- delegateToCalls(spyApi, "yieldToOn", false, "yieldToOn", function (property) {
953
- throw new Error(this.toString() + " cannot yield to '" + property +
954
- "' since it was not yet invoked.");
955
- });
956
-
957
- spyApi.formatters = {
958
- "c": function (spy) {
959
- return sinon.timesInWords(spy.callCount);
960
- },
963
+ var proxy = createProxy(func);
961
964
 
962
- "n": function (spy) {
963
- return spy.toString();
964
- },
965
+ sinon.extend(proxy, spy);
966
+ delete proxy.create;
967
+ sinon.extend(proxy, func);
965
968
 
966
- "C": function (spy) {
967
- var calls = [];
969
+ proxy.reset();
970
+ proxy.prototype = func.prototype;
971
+ proxy.displayName = name || "spy";
972
+ proxy.toString = sinon.functionToString;
973
+ proxy._create = sinon.spy.create;
974
+ proxy.id = "spy#" + uuid++;
968
975
 
969
- for (var i = 0, l = spy.callCount; i < l; ++i) {
970
- var stringifiedCall = " " + spy.getCall(i).toString();
971
- if (/\n/.test(calls[i - 1])) {
972
- stringifiedCall = "\n" + stringifiedCall;
973
- }
974
- push.call(calls, stringifiedCall);
975
- }
976
+ return proxy;
977
+ },
976
978
 
977
- return calls.length > 0 ? "\n" + calls.join("\n") : "";
978
- },
979
+ invoke: function invoke(func, thisValue, args) {
980
+ var matching = matchingFake(this.fakes, args);
981
+ var exception, returnValue;
979
982
 
980
- "t": function (spy) {
981
- var objects = [];
983
+ incrementCallCount.call(this);
984
+ push.call(this.thisValues, thisValue);
985
+ push.call(this.args, args);
986
+ push.call(this.callIds, callId++);
982
987
 
983
- for (var i = 0, l = spy.callCount; i < l; ++i) {
984
- push.call(objects, sinon.format(spy.thisValues[i]));
988
+ try {
989
+ if (matching) {
990
+ returnValue = matching.invoke(func, thisValue, args);
991
+ } else {
992
+ returnValue = (this.func || func).apply(thisValue, args);
985
993
  }
994
+ } catch (e) {
995
+ push.call(this.returnValues, undefined);
996
+ exception = e;
997
+ throw e;
998
+ } finally {
999
+ push.call(this.exceptions, exception);
1000
+ }
986
1001
 
987
- return objects.join(", ");
988
- },
1002
+ push.call(this.returnValues, returnValue);
989
1003
 
990
- "*": function (spy, args) {
991
- var formatted = [];
1004
+ createCallProperties.call(this);
992
1005
 
993
- for (var i = 0, l = args.length; i < l; ++i) {
994
- push.call(formatted, sinon.format(args[i]));
995
- }
1006
+ return returnValue;
1007
+ },
996
1008
 
997
- return formatted.join(", ");
1009
+ getCall: function getCall(i) {
1010
+ if (i < 0 || i >= this.callCount) {
1011
+ return null;
998
1012
  }
999
- };
1000
1013
 
1001
- return spyApi;
1002
- }()));
1014
+ return sinon.spyCall(this, this.thisValues[i], this.args[i],
1015
+ this.returnValues[i], this.exceptions[i],
1016
+ this.callIds[i]);
1017
+ },
1003
1018
 
1004
- spyCall = (function () {
1019
+ calledBefore: function calledBefore(spyFn) {
1020
+ if (!this.called) {
1021
+ return false;
1022
+ }
1005
1023
 
1006
- function throwYieldError(proxy, text, args) {
1007
- var msg = sinon.functionName(proxy) + text;
1008
- if (args.length) {
1009
- msg += " Received [" + slice.call(args).join(", ") + "]";
1024
+ if (!spyFn.called) {
1025
+ return true;
1010
1026
  }
1011
- throw new Error(msg);
1012
- }
1013
1027
 
1014
- var callApi = {
1015
- create: function create(spy, thisValue, args, returnValue, exception, id) {
1016
- var proxyCall = sinon.create(spyCall);
1017
- delete proxyCall.create;
1018
- proxyCall.proxy = spy;
1019
- proxyCall.thisValue = thisValue;
1020
- proxyCall.args = args;
1021
- proxyCall.returnValue = returnValue;
1022
- proxyCall.exception = exception;
1023
- proxyCall.callId = typeof id == "number" && id || callId++;
1028
+ return this.callIds[0] < spyFn.callIds[spyFn.callIds.length - 1];
1029
+ },
1024
1030
 
1025
- return proxyCall;
1026
- },
1031
+ calledAfter: function calledAfter(spyFn) {
1032
+ if (!this.called || !spyFn.called) {
1033
+ return false;
1034
+ }
1027
1035
 
1028
- calledOn: function calledOn(thisValue) {
1029
- if (sinon.match && sinon.match.isMatcher(thisValue)) {
1030
- return thisValue.test(this.thisValue);
1031
- }
1032
- return this.thisValue === thisValue;
1033
- },
1036
+ return this.callIds[this.callCount - 1] > spyFn.callIds[spyFn.callCount - 1];
1037
+ },
1034
1038
 
1035
- calledWith: function calledWith() {
1036
- for (var i = 0, l = arguments.length; i < l; i += 1) {
1037
- if (!sinon.deepEqual(arguments[i], this.args[i])) {
1038
- return false;
1039
- }
1040
- }
1039
+ withArgs: function () {
1040
+ var args = slice.call(arguments);
1041
1041
 
1042
- return true;
1043
- },
1042
+ if (this.fakes) {
1043
+ var match = matchingFake(this.fakes, args, true);
1044
1044
 
1045
- calledWithMatch: function calledWithMatch() {
1046
- for (var i = 0, l = arguments.length; i < l; i += 1) {
1047
- var actual = this.args[i];
1048
- var expectation = arguments[i];
1049
- if (!sinon.match || !sinon.match(expectation).test(actual)) {
1050
- return false;
1051
- }
1045
+ if (match) {
1046
+ return match;
1052
1047
  }
1053
- return true;
1054
- },
1055
-
1056
- calledWithExactly: function calledWithExactly() {
1057
- return arguments.length == this.args.length &&
1058
- this.calledWith.apply(this, arguments);
1059
- },
1060
-
1061
- notCalledWith: function notCalledWith() {
1062
- return !this.calledWith.apply(this, arguments);
1063
- },
1048
+ } else {
1049
+ this.fakes = [];
1050
+ }
1064
1051
 
1065
- notCalledWithMatch: function notCalledWithMatch() {
1066
- return !this.calledWithMatch.apply(this, arguments);
1067
- },
1052
+ var original = this;
1053
+ var fake = this._create();
1054
+ fake.matchingAguments = args;
1055
+ push.call(this.fakes, fake);
1068
1056
 
1069
- returned: function returned(value) {
1070
- return sinon.deepEqual(value, this.returnValue);
1071
- },
1057
+ fake.withArgs = function () {
1058
+ return original.withArgs.apply(original, arguments);
1059
+ };
1072
1060
 
1073
- threw: function threw(error) {
1074
- if (typeof error == "undefined" || !this.exception) {
1075
- return !!this.exception;
1061
+ for (var i = 0; i < this.args.length; i++) {
1062
+ if (fake.matches(this.args[i])) {
1063
+ incrementCallCount.call(fake);
1064
+ push.call(fake.thisValues, this.thisValues[i]);
1065
+ push.call(fake.args, this.args[i]);
1066
+ push.call(fake.returnValues, this.returnValues[i]);
1067
+ push.call(fake.exceptions, this.exceptions[i]);
1068
+ push.call(fake.callIds, this.callIds[i]);
1076
1069
  }
1070
+ }
1071
+ createCallProperties.call(fake);
1077
1072
 
1078
- if (typeof error == "string") {
1079
- return this.exception.name == error;
1080
- }
1073
+ return fake;
1074
+ },
1081
1075
 
1082
- return this.exception === error;
1083
- },
1076
+ matches: function (args, strict) {
1077
+ var margs = this.matchingAguments;
1084
1078
 
1085
- calledWithNew: function calledWithNew(thisValue) {
1086
- return this.thisValue instanceof this.proxy;
1087
- },
1079
+ if (margs.length <= args.length &&
1080
+ sinon.deepEqual(margs, args.slice(0, margs.length))) {
1081
+ return !strict || margs.length == args.length;
1082
+ }
1083
+ },
1088
1084
 
1089
- calledBefore: function (other) {
1090
- return this.callId < other.callId;
1091
- },
1085
+ printf: function (format) {
1086
+ var spy = this;
1087
+ var args = slice.call(arguments, 1);
1088
+ var formatter;
1092
1089
 
1093
- calledAfter: function (other) {
1094
- return this.callId > other.callId;
1095
- },
1090
+ return (format || "").replace(/%(.)/g, function (match, specifyer) {
1091
+ formatter = spyApi.formatters[specifyer];
1096
1092
 
1097
- callArg: function (pos) {
1098
- this.args[pos]();
1099
- },
1093
+ if (typeof formatter == "function") {
1094
+ return formatter.call(null, spy, args);
1095
+ } else if (!isNaN(parseInt(specifyer), 10)) {
1096
+ return sinon.format(args[specifyer - 1]);
1097
+ }
1100
1098
 
1101
- callArgOn: function (pos, thisValue) {
1102
- this.args[pos].apply(thisValue);
1103
- },
1099
+ return "%" + specifyer;
1100
+ });
1101
+ }
1102
+ };
1104
1103
 
1105
- callArgWith: function (pos) {
1106
- this.callArgOnWith.apply(this, [pos, null].concat(slice.call(arguments, 1)));
1107
- },
1104
+ function delegateToCalls(method, matchAny, actual, notCalled) {
1105
+ spyApi[method] = function () {
1106
+ if (!this.called) {
1107
+ if (notCalled) {
1108
+ return notCalled.apply(this, arguments);
1109
+ }
1110
+ return false;
1111
+ }
1108
1112
 
1109
- callArgOnWith: function (pos, thisValue) {
1110
- var args = slice.call(arguments, 2);
1111
- this.args[pos].apply(thisValue, args);
1112
- },
1113
+ var currentCall;
1114
+ var matches = 0;
1113
1115
 
1114
- "yield": function () {
1115
- this.yieldOn.apply(this, [null].concat(slice.call(arguments, 0)));
1116
- },
1116
+ for (var i = 0, l = this.callCount; i < l; i += 1) {
1117
+ currentCall = this.getCall(i);
1117
1118
 
1118
- yieldOn: function (thisValue) {
1119
- var args = this.args;
1120
- for (var i = 0, l = args.length; i < l; ++i) {
1121
- if (typeof args[i] === "function") {
1122
- args[i].apply(thisValue, slice.call(arguments, 1));
1123
- return;
1119
+ if (currentCall[actual || method].apply(currentCall, arguments)) {
1120
+ matches += 1;
1121
+
1122
+ if (matchAny) {
1123
+ return true;
1124
1124
  }
1125
1125
  }
1126
- throwYieldError(this.proxy, " cannot yield since no callback was passed.", args);
1127
- },
1126
+ }
1128
1127
 
1129
- yieldTo: function (prop) {
1130
- this.yieldToOn.apply(this, [prop, null].concat(slice.call(arguments, 1)));
1131
- },
1128
+ return matches === this.callCount;
1129
+ };
1130
+ }
1132
1131
 
1133
- yieldToOn: function (prop, thisValue) {
1134
- var args = this.args;
1135
- for (var i = 0, l = args.length; i < l; ++i) {
1136
- if (args[i] && typeof args[i][prop] === "function") {
1137
- args[i][prop].apply(thisValue, slice.call(arguments, 2));
1138
- return;
1139
- }
1140
- }
1141
- throwYieldError(this.proxy, " cannot yield to '" + prop +
1142
- "' since no callback was passed.", args);
1143
- },
1132
+ delegateToCalls("calledOn", true);
1133
+ delegateToCalls("alwaysCalledOn", false, "calledOn");
1134
+ delegateToCalls("calledWith", true);
1135
+ delegateToCalls("calledWithMatch", true);
1136
+ delegateToCalls("alwaysCalledWith", false, "calledWith");
1137
+ delegateToCalls("alwaysCalledWithMatch", false, "calledWithMatch");
1138
+ delegateToCalls("calledWithExactly", true);
1139
+ delegateToCalls("alwaysCalledWithExactly", false, "calledWithExactly");
1140
+ delegateToCalls("neverCalledWith", false, "notCalledWith",
1141
+ function () { return true; });
1142
+ delegateToCalls("neverCalledWithMatch", false, "notCalledWithMatch",
1143
+ function () { return true; });
1144
+ delegateToCalls("threw", true);
1145
+ delegateToCalls("alwaysThrew", false, "threw");
1146
+ delegateToCalls("returned", true);
1147
+ delegateToCalls("alwaysReturned", false, "returned");
1148
+ delegateToCalls("calledWithNew", true);
1149
+ delegateToCalls("alwaysCalledWithNew", false, "calledWithNew");
1150
+ delegateToCalls("callArg", false, "callArgWith", function () {
1151
+ throw new Error(this.toString() + " cannot call arg since it was not yet invoked.");
1152
+ });
1153
+ spyApi.callArgWith = spyApi.callArg;
1154
+ delegateToCalls("callArgOn", false, "callArgOnWith", function () {
1155
+ throw new Error(this.toString() + " cannot call arg since it was not yet invoked.");
1156
+ });
1157
+ spyApi.callArgOnWith = spyApi.callArgOn;
1158
+ delegateToCalls("yield", false, "yield", function () {
1159
+ throw new Error(this.toString() + " cannot yield since it was not yet invoked.");
1160
+ });
1161
+ // "invokeCallback" is an alias for "yield" since "yield" is invalid in strict mode.
1162
+ spyApi.invokeCallback = spyApi.yield;
1163
+ delegateToCalls("yieldOn", false, "yieldOn", function () {
1164
+ throw new Error(this.toString() + " cannot yield since it was not yet invoked.");
1165
+ });
1166
+ delegateToCalls("yieldTo", false, "yieldTo", function (property) {
1167
+ throw new Error(this.toString() + " cannot yield to '" + property +
1168
+ "' since it was not yet invoked.");
1169
+ });
1170
+ delegateToCalls("yieldToOn", false, "yieldToOn", function (property) {
1171
+ throw new Error(this.toString() + " cannot yield to '" + property +
1172
+ "' since it was not yet invoked.");
1173
+ });
1144
1174
 
1145
- toString: function () {
1146
- var callStr = this.proxy.toString() + "(";
1147
- var args = [];
1175
+ spyApi.formatters = {
1176
+ "c": function (spy) {
1177
+ return sinon.timesInWords(spy.callCount);
1178
+ },
1148
1179
 
1149
- for (var i = 0, l = this.args.length; i < l; ++i) {
1150
- push.call(args, sinon.format(this.args[i]));
1151
- }
1180
+ "n": function (spy) {
1181
+ return spy.toString();
1182
+ },
1152
1183
 
1153
- callStr = callStr + args.join(", ") + ")";
1184
+ "C": function (spy) {
1185
+ var calls = [];
1154
1186
 
1155
- if (typeof this.returnValue != "undefined") {
1156
- callStr += " => " + sinon.format(this.returnValue);
1187
+ for (var i = 0, l = spy.callCount; i < l; ++i) {
1188
+ var stringifiedCall = " " + spy.getCall(i).toString();
1189
+ if (/\n/.test(calls[i - 1])) {
1190
+ stringifiedCall = "\n" + stringifiedCall;
1157
1191
  }
1192
+ push.call(calls, stringifiedCall);
1193
+ }
1158
1194
 
1159
- if (this.exception) {
1160
- callStr += " !" + this.exception.name;
1195
+ return calls.length > 0 ? "\n" + calls.join("\n") : "";
1196
+ },
1161
1197
 
1162
- if (this.exception.message) {
1163
- callStr += "(" + this.exception.message + ")";
1164
- }
1165
- }
1198
+ "t": function (spy) {
1199
+ var objects = [];
1166
1200
 
1167
- return callStr;
1201
+ for (var i = 0, l = spy.callCount; i < l; ++i) {
1202
+ push.call(objects, sinon.format(spy.thisValues[i]));
1168
1203
  }
1169
- };
1170
- callApi.invokeCallback = callApi.yield;
1171
- return callApi;
1172
- }());
1173
1204
 
1174
- spy.spyCall = spyCall;
1205
+ return objects.join(", ");
1206
+ },
1207
+
1208
+ "*": function (spy, args) {
1209
+ var formatted = [];
1210
+
1211
+ for (var i = 0, l = args.length; i < l; ++i) {
1212
+ push.call(formatted, sinon.format(args[i]));
1213
+ }
1214
+
1215
+ return formatted.join(", ");
1216
+ }
1217
+ };
1175
1218
 
1176
- // This steps outside the module sandbox and will be removed
1177
- sinon.spyCall = spyCall;
1219
+ sinon.extend(spy, spyApi);
1220
+
1221
+ spy.spyCall = sinon.spyCall;
1178
1222
 
1179
1223
  if (commonJSModule) {
1180
1224
  module.exports = spy;
@@ -1195,7 +1239,7 @@ var sinon = (function (buster) {
1195
1239
  * @author Christian Johansen (christian@cjohansen.no)
1196
1240
  * @license BSD
1197
1241
  *
1198
- * Copyright (c) 2010-2011 Christian Johansen
1242
+ * Copyright (c) 2010-2013 Christian Johansen
1199
1243
  */
1200
1244
 
1201
1245
  (function (sinon) {
@@ -1566,7 +1610,7 @@ var sinon = (function (buster) {
1566
1610
  * @author Christian Johansen (christian@cjohansen.no)
1567
1611
  * @license BSD
1568
1612
  *
1569
- * Copyright (c) 2010-2011 Christian Johansen
1613
+ * Copyright (c) 2010-2013 Christian Johansen
1570
1614
  */
1571
1615
 
1572
1616
  (function (sinon) {
@@ -1991,7 +2035,7 @@ var sinon = (function (buster) {
1991
2035
  * @author Christian Johansen (christian@cjohansen.no)
1992
2036
  * @license BSD
1993
2037
  *
1994
- * Copyright (c) 2010-2011 Christian Johansen
2038
+ * Copyright (c) 2010-2013 Christian Johansen
1995
2039
  */
1996
2040
 
1997
2041
  (function (sinon) {
@@ -2148,7 +2192,7 @@ var sinon = (function (buster) {
2148
2192
  * @author Christian Johansen (christian@cjohansen.no)
2149
2193
  * @license BSD
2150
2194
  *
2151
- * Copyright (c) 2010-2011 Christian Johansen
2195
+ * Copyright (c) 2010-2013 Christian Johansen
2152
2196
  */
2153
2197
 
2154
2198
  if (typeof sinon == "undefined") {
@@ -2504,15 +2548,16 @@ if (typeof sinon == "undefined") {
2504
2548
  (function () {
2505
2549
  var push = [].push;
2506
2550
 
2507
- sinon.Event = function Event(type, bubbles, cancelable) {
2508
- this.initEvent(type, bubbles, cancelable);
2551
+ sinon.Event = function Event(type, bubbles, cancelable, target) {
2552
+ this.initEvent(type, bubbles, cancelable, target);
2509
2553
  };
2510
2554
 
2511
2555
  sinon.Event.prototype = {
2512
- initEvent: function(type, bubbles, cancelable) {
2556
+ initEvent: function(type, bubbles, cancelable, target) {
2513
2557
  this.type = type;
2514
2558
  this.bubbles = bubbles;
2515
2559
  this.cancelable = cancelable;
2560
+ this.target = target;
2516
2561
  },
2517
2562
 
2518
2563
  stopPropagation: function () {},
@@ -2568,7 +2613,7 @@ if (typeof sinon == "undefined") {
2568
2613
  * @author Christian Johansen (christian@cjohansen.no)
2569
2614
  * @license BSD
2570
2615
  *
2571
- * Copyright (c) 2010-2011 Christian Johansen
2616
+ * Copyright (c) 2010-2013 Christian Johansen
2572
2617
  */
2573
2618
 
2574
2619
  if (typeof sinon == "undefined") {
@@ -2616,6 +2661,23 @@ sinon.xhr = { XMLHttpRequest: this.XMLHttpRequest };
2616
2661
  this.status = 0;
2617
2662
  this.statusText = "";
2618
2663
 
2664
+ var xhr = this;
2665
+ var events = ["loadstart", "load", "abort", "loadend"];
2666
+
2667
+ function addEventListener(eventName) {
2668
+ xhr.addEventListener(eventName, function (event) {
2669
+ var listener = xhr["on" + eventName];
2670
+
2671
+ if (listener && typeof listener == "function") {
2672
+ listener(event);
2673
+ }
2674
+ });
2675
+ }
2676
+
2677
+ for (var i = events.length - 1; i >= 0; i--) {
2678
+ addEventListener(events[i]);
2679
+ }
2680
+
2619
2681
  if (typeof FakeXMLHttpRequest.onCreate == "function") {
2620
2682
  FakeXMLHttpRequest.onCreate(this);
2621
2683
  }
@@ -2769,6 +2831,13 @@ sinon.xhr = { XMLHttpRequest: this.XMLHttpRequest };
2769
2831
  }
2770
2832
 
2771
2833
  this.dispatchEvent(new sinon.Event("readystatechange"));
2834
+
2835
+ switch (this.readyState) {
2836
+ case FakeXMLHttpRequest.DONE:
2837
+ this.dispatchEvent(new sinon.Event("load", false, false, this));
2838
+ this.dispatchEvent(new sinon.Event("loadend", false, false, this));
2839
+ break;
2840
+ }
2772
2841
  },
2773
2842
 
2774
2843
  setRequestHeader: function setRequestHeader(header, value) {
@@ -2824,6 +2893,8 @@ sinon.xhr = { XMLHttpRequest: this.XMLHttpRequest };
2824
2893
  if (typeof this.onSend == "function") {
2825
2894
  this.onSend(this);
2826
2895
  }
2896
+
2897
+ this.dispatchEvent(new sinon.Event("loadstart", false, false, this));
2827
2898
  },
2828
2899
 
2829
2900
  abort: function abort() {
@@ -2838,6 +2909,11 @@ sinon.xhr = { XMLHttpRequest: this.XMLHttpRequest };
2838
2909
  }
2839
2910
 
2840
2911
  this.readyState = sinon.FakeXMLHttpRequest.UNSENT;
2912
+
2913
+ this.dispatchEvent(new sinon.Event("abort", false, false, this));
2914
+ if (typeof this.onerror === "function") {
2915
+ this.onerror();
2916
+ }
2841
2917
  },
2842
2918
 
2843
2919
  getResponseHeader: function getResponseHeader(header) {
@@ -2918,6 +2994,10 @@ sinon.xhr = { XMLHttpRequest: this.XMLHttpRequest };
2918
2994
  this.status = typeof status == "number" ? status : 200;
2919
2995
  this.statusText = FakeXMLHttpRequest.statusCodes[this.status];
2920
2996
  this.setResponseBody(body || "");
2997
+ if (typeof this.onload === "function"){
2998
+ this.onload();
2999
+ }
3000
+
2921
3001
  }
2922
3002
  });
2923
3003
 
@@ -3044,7 +3124,7 @@ if (typeof module == "object" && typeof require == "function") {
3044
3124
  * @author Christian Johansen (christian@cjohansen.no)
3045
3125
  * @license BSD
3046
3126
  *
3047
- * Copyright (c) 2010-2011 Christian Johansen
3127
+ * Copyright (c) 2010-2013 Christian Johansen
3048
3128
  */
3049
3129
 
3050
3130
  if (typeof sinon == "undefined") {
@@ -3098,7 +3178,7 @@ sinon.fakeServer = (function () {
3098
3178
  if (matchOne(response, this.getHTTPMethod(request), requestUrl)) {
3099
3179
  if (typeof response.response == "function") {
3100
3180
  var ru = response.url;
3101
- var args = [request].concat(!ru ? [] : requestUrl.match(ru).slice(1));
3181
+ var args = [request].concat(ru && typeof ru.exec == "function" ? ru.exec(requestUrl).slice(1) : []);
3102
3182
  return response.response.apply(response, args);
3103
3183
  }
3104
3184
 
@@ -3260,7 +3340,7 @@ if (typeof module == "object" && typeof require == "function") {
3260
3340
  * @author Christian Johansen (christian@cjohansen.no)
3261
3341
  * @license BSD
3262
3342
  *
3263
- * Copyright (c) 2010-2011 Christian Johansen
3343
+ * Copyright (c) 2010-2013 Christian Johansen
3264
3344
  */
3265
3345
 
3266
3346
  (function () {
@@ -3340,7 +3420,7 @@ if (typeof module == "object" && typeof require == "function") {
3340
3420
  * @author Christian Johansen (christian@cjohansen.no)
3341
3421
  * @license BSD
3342
3422
  *
3343
- * Copyright (c) 2010-2011 Christian Johansen
3423
+ * Copyright (c) 2010-2013 Christian Johansen
3344
3424
  */
3345
3425
 
3346
3426
  if (typeof module == "object" && typeof require == "function") {
@@ -3464,7 +3544,7 @@ if (typeof module == "object" && typeof require == "function") {
3464
3544
  * @author Christian Johansen (christian@cjohansen.no)
3465
3545
  * @license BSD
3466
3546
  *
3467
- * Copyright (c) 2010-2011 Christian Johansen
3547
+ * Copyright (c) 2010-2013 Christian Johansen
3468
3548
  */
3469
3549
 
3470
3550
  (function (sinon) {
@@ -3537,7 +3617,7 @@ if (typeof module == "object" && typeof require == "function") {
3537
3617
  * @author Christian Johansen (christian@cjohansen.no)
3538
3618
  * @license BSD
3539
3619
  *
3540
- * Copyright (c) 2010-2011 Christian Johansen
3620
+ * Copyright (c) 2010-2013 Christian Johansen
3541
3621
  */
3542
3622
 
3543
3623
  (function (sinon) {
@@ -3634,7 +3714,7 @@ if (typeof module == "object" && typeof require == "function") {
3634
3714
  * @author Christian Johansen (christian@cjohansen.no)
3635
3715
  * @license BSD
3636
3716
  *
3637
- * Copyright (c) 2010-2011 Christian Johansen
3717
+ * Copyright (c) 2010-2013 Christian Johansen
3638
3718
  */
3639
3719
 
3640
3720
  (function (sinon, global) {
@@ -3727,7 +3807,14 @@ if (typeof module == "object" && typeof require == "function") {
3727
3807
  if (!sinon.calledInOrder(arguments)) {
3728
3808
  try {
3729
3809
  expected = [].join.call(arguments, ", ");
3730
- actual = sinon.orderByFirstCall(slice.call(arguments)).join(", ");
3810
+ var calls = slice.call(arguments);
3811
+ var i = calls.length;
3812
+ while (i) {
3813
+ if (!calls[--i].called) {
3814
+ calls.splice(i, 1);
3815
+ }
3816
+ }
3817
+ actual = sinon.orderByFirstCall(calls).join(", ");
3731
3818
  } catch (e) {
3732
3819
  // If this fails, we'll just fall back to the blank string
3733
3820
  }
@@ -3796,5 +3883,5 @@ if (typeof module == "object" && typeof require == "function") {
3796
3883
  } else {
3797
3884
  sinon.assert = assert;
3798
3885
  }
3799
- }(typeof sinon == "object" && sinon || null, typeof window != "undefined" ? window : global));
3886
+ }(typeof sinon == "object" && sinon || null, typeof window != "undefined" ? window : (typeof self != "undefined") ? self : global));
3800
3887