konacha-chai-matchers 0.1.3 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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