konacha-chai-matchers 0.1.7 → 0.1.8

Sign up to get free protection for your applications and to get access to all the features.
@@ -26,6 +26,13 @@
26
26
  typeof putativeSpy.calledWithExactly === "function";
27
27
  }
28
28
 
29
+ function timesInWords(count) {
30
+ return count === 1 ? "once" :
31
+ count === 2 ? "twice" :
32
+ count === 3 ? "thrice" :
33
+ (count || 0) + " times";
34
+ }
35
+
29
36
  function isCall(putativeCall) {
30
37
  return putativeCall && isSpy(putativeCall.proxy);
31
38
  }
@@ -62,6 +69,15 @@
62
69
  });
63
70
  }
64
71
 
72
+ function sinonPropertyAsBooleanMethod(name, action, nonNegatedSuffix) {
73
+ utils.addMethod(chai.Assertion.prototype, name, function (arg) {
74
+ assertCanWorkWith(this);
75
+
76
+ var messages = getMessages(this._obj, action, nonNegatedSuffix, false, [timesInWords(arg)]);
77
+ this.assert(this._obj[name] === arg, messages.affirmative, messages.negative);
78
+ });
79
+ }
80
+
65
81
  function createSinonMethodHandler(sinonName, action, nonNegatedSuffix) {
66
82
  return function () {
67
83
  assertCanWorkWith(this);
@@ -94,6 +110,7 @@
94
110
  });
95
111
 
96
112
  sinonProperty("called", "been called", " at least once, but it was never called");
113
+ sinonPropertyAsBooleanMethod("callCount", "been called exactly %1", ", but it was called %c%C");
97
114
  sinonProperty("calledOnce", "been called exactly once", ", but it was called %c%C");
98
115
  sinonProperty("calledTwice", "been called exactly twice", ", but it was called %c%C");
99
116
  sinonProperty("calledThrice", "been called exactly thrice", ", but it was called %c%C");
@@ -1,38 +1,3 @@
1
- /**
2
- * Sinon.JS 1.7.3, 2013/12/11
3
- *
4
- * @author Christian Johansen (christian@cjohansen.no)
5
- * @author Contributors: https://github.com/cjohansen/Sinon.JS/blob/master/AUTHORS
6
- *
7
- * (The BSD License)
8
- *
9
- * Copyright (c) 2010-2013, Christian Johansen, christian@cjohansen.no
10
- * All rights reserved.
11
- *
12
- * Redistribution and use in source and binary forms, with or without modification,
13
- * are permitted provided that the following conditions are met:
14
- *
15
- * * Redistributions of source code must retain the above copyright notice,
16
- * this list of conditions and the following disclaimer.
17
- * * Redistributions in binary form must reproduce the above copyright notice,
18
- * this list of conditions and the following disclaimer in the documentation
19
- * and/or other materials provided with the distribution.
20
- * * Neither the name of Christian Johansen nor the names of his contributors
21
- * may be used to endorse or promote products derived from this software
22
- * without specific prior written permission.
23
- *
24
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
25
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
26
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
27
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
28
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
30
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
31
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
32
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
33
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34
- */
35
-
36
1
  /*jslint eqeqeq: false, onevar: false, forin: true, nomen: false, regexp: false, plusplus: false*/
37
2
  /*global module, require, __dirname, document*/
38
3
  /**
@@ -43,6 +8,7 @@
43
8
  *
44
9
  * Copyright (c) 2010-2013 Christian Johansen
45
10
  */
11
+ "use strict";
46
12
 
47
13
  var sinon = (function (buster) {
48
14
  var div = typeof document != "undefined" && document.createElement("div");
@@ -97,37 +63,26 @@ var sinon = (function (buster) {
97
63
  throw new TypeError("Method wrapper should be function");
98
64
  }
99
65
 
100
- var wrappedMethod = object[property],
101
- error;
66
+ var wrappedMethod = object[property];
102
67
 
103
68
  if (!isFunction(wrappedMethod)) {
104
- error = new TypeError("Attempted to wrap " + (typeof wrappedMethod) + " property " +
69
+ throw new TypeError("Attempted to wrap " + (typeof wrappedMethod) + " property " +
105
70
  property + " as function");
106
71
  }
107
72
 
108
73
  if (wrappedMethod.restore && wrappedMethod.restore.sinon) {
109
- error = new TypeError("Attempted to wrap " + property + " which is already wrapped");
74
+ throw new TypeError("Attempted to wrap " + property + " which is already wrapped");
110
75
  }
111
76
 
112
77
  if (wrappedMethod.calledBefore) {
113
78
  var verb = !!wrappedMethod.returns ? "stubbed" : "spied on";
114
- error = new TypeError("Attempted to wrap " + property + " which is already " + verb);
115
- }
116
-
117
- if (error) {
118
- if (wrappedMethod._stack) {
119
- error.stack += '\n--------------\n' + wrappedMethod._stack;
120
- }
121
- throw error;
79
+ throw new TypeError("Attempted to wrap " + property + " which is already " + verb);
122
80
  }
123
81
 
124
82
  // IE 8 does not support hasOwnProperty on the window object.
125
83
  var owned = hasOwn.call(object, property);
126
84
  object[property] = method;
127
85
  method.displayName = property;
128
- // Set up a stack trace which can be used later to find what line of
129
- // code the original method was created on.
130
- method._stack = (new Error('Stack Trace for original')).stack;
131
86
 
132
87
  method.restore = function () {
133
88
  // For prototype properties try to reset by delete first.
@@ -196,16 +151,26 @@ var sinon = (function (buster) {
196
151
  return false;
197
152
  }
198
153
 
154
+ if (aString == "[object Array]") {
155
+ if (a.length !== b.length) {
156
+ return false;
157
+ }
158
+
159
+ for (var i = 0, l = a.length; i < l; i += 1) {
160
+ if (!deepEqual(a[i], b[i])) {
161
+ return false;
162
+ }
163
+ }
164
+
165
+ return true;
166
+ }
167
+
199
168
  if (aString == "[object Date]") {
200
169
  return a.valueOf() === b.valueOf();
201
170
  }
202
171
 
203
172
  var prop, aLength = 0, bLength = 0;
204
173
 
205
- if (aString == "[object Array]" && a.length !== b.length) {
206
- return false;
207
- }
208
-
209
174
  for (prop in a) {
210
175
  aLength += 1;
211
176
 
@@ -354,21 +319,15 @@ var sinon = (function (buster) {
354
319
  }
355
320
  };
356
321
 
357
- var isNode = typeof module !== "undefined" && module.exports;
358
- var isAMD = typeof define === 'function' && typeof define.amd === 'object' && define.amd;
322
+ var isNode = typeof module == "object" && typeof require == "function";
359
323
 
360
- if (isAMD) {
361
- define(function(){
362
- return sinon;
363
- });
364
- } else if (isNode) {
324
+ if (isNode) {
365
325
  try {
366
326
  buster = { format: require("buster-format") };
367
327
  } catch (e) {}
368
328
  module.exports = sinon;
369
329
  module.exports.spy = require("./sinon/spy");
370
330
  module.exports.spyCall = require("./sinon/call");
371
- module.exports.behavior = require("./sinon/behavior");
372
331
  module.exports.stub = require("./sinon/stub");
373
332
  module.exports.mock = require("./sinon/mock");
374
333
  module.exports.collection = require("./sinon/collection");
@@ -400,3690 +359,3 @@ var sinon = (function (buster) {
400
359
 
401
360
  return sinon;
402
361
  }(typeof buster == "object" && buster));
403
-
404
- /* @depend ../sinon.js */
405
- /*jslint eqeqeq: false, onevar: false, plusplus: false*/
406
- /*global module, require, sinon*/
407
- /**
408
- * Match functions
409
- *
410
- * @author Maximilian Antoni (mail@maxantoni.de)
411
- * @license BSD
412
- *
413
- * Copyright (c) 2012 Maximilian Antoni
414
- */
415
-
416
- (function (sinon) {
417
- var commonJSModule = typeof module !== 'undefined' && module.exports;
418
-
419
- if (!sinon && commonJSModule) {
420
- sinon = require("../sinon");
421
- }
422
-
423
- if (!sinon) {
424
- return;
425
- }
426
-
427
- function assertType(value, type, name) {
428
- var actual = sinon.typeOf(value);
429
- if (actual !== type) {
430
- throw new TypeError("Expected type of " + name + " to be " +
431
- type + ", but was " + actual);
432
- }
433
- }
434
-
435
- var matcher = {
436
- toString: function () {
437
- return this.message;
438
- }
439
- };
440
-
441
- function isMatcher(object) {
442
- return matcher.isPrototypeOf(object);
443
- }
444
-
445
- function matchObject(expectation, actual) {
446
- if (actual === null || actual === undefined) {
447
- return false;
448
- }
449
- for (var key in expectation) {
450
- if (expectation.hasOwnProperty(key)) {
451
- var exp = expectation[key];
452
- var act = actual[key];
453
- if (match.isMatcher(exp)) {
454
- if (!exp.test(act)) {
455
- return false;
456
- }
457
- } else if (sinon.typeOf(exp) === "object") {
458
- if (!matchObject(exp, act)) {
459
- return false;
460
- }
461
- } else if (!sinon.deepEqual(exp, act)) {
462
- return false;
463
- }
464
- }
465
- }
466
- return true;
467
- }
468
-
469
- matcher.or = function (m2) {
470
- if (!isMatcher(m2)) {
471
- throw new TypeError("Matcher expected");
472
- }
473
- var m1 = this;
474
- var or = sinon.create(matcher);
475
- or.test = function (actual) {
476
- return m1.test(actual) || m2.test(actual);
477
- };
478
- or.message = m1.message + ".or(" + m2.message + ")";
479
- return or;
480
- };
481
-
482
- matcher.and = function (m2) {
483
- if (!isMatcher(m2)) {
484
- throw new TypeError("Matcher expected");
485
- }
486
- var m1 = this;
487
- var and = sinon.create(matcher);
488
- and.test = function (actual) {
489
- return m1.test(actual) && m2.test(actual);
490
- };
491
- and.message = m1.message + ".and(" + m2.message + ")";
492
- return and;
493
- };
494
-
495
- var match = function (expectation, message) {
496
- var m = sinon.create(matcher);
497
- var type = sinon.typeOf(expectation);
498
- switch (type) {
499
- case "object":
500
- if (typeof expectation.test === "function") {
501
- m.test = function (actual) {
502
- return expectation.test(actual) === true;
503
- };
504
- m.message = "match(" + sinon.functionName(expectation.test) + ")";
505
- return m;
506
- }
507
- var str = [];
508
- for (var key in expectation) {
509
- if (expectation.hasOwnProperty(key)) {
510
- str.push(key + ": " + expectation[key]);
511
- }
512
- }
513
- m.test = function (actual) {
514
- return matchObject(expectation, actual);
515
- };
516
- m.message = "match(" + str.join(", ") + ")";
517
- break;
518
- case "number":
519
- m.test = function (actual) {
520
- return expectation == actual;
521
- };
522
- break;
523
- case "string":
524
- m.test = function (actual) {
525
- if (typeof actual !== "string") {
526
- return false;
527
- }
528
- return actual.indexOf(expectation) !== -1;
529
- };
530
- m.message = "match(\"" + expectation + "\")";
531
- break;
532
- case "regexp":
533
- m.test = function (actual) {
534
- if (typeof actual !== "string") {
535
- return false;
536
- }
537
- return expectation.test(actual);
538
- };
539
- break;
540
- case "function":
541
- m.test = expectation;
542
- if (message) {
543
- m.message = message;
544
- } else {
545
- m.message = "match(" + sinon.functionName(expectation) + ")";
546
- }
547
- break;
548
- default:
549
- m.test = function (actual) {
550
- return sinon.deepEqual(expectation, actual);
551
- };
552
- }
553
- if (!m.message) {
554
- m.message = "match(" + expectation + ")";
555
- }
556
- return m;
557
- };
558
-
559
- match.isMatcher = isMatcher;
560
-
561
- match.any = match(function () {
562
- return true;
563
- }, "any");
564
-
565
- match.defined = match(function (actual) {
566
- return actual !== null && actual !== undefined;
567
- }, "defined");
568
-
569
- match.truthy = match(function (actual) {
570
- return !!actual;
571
- }, "truthy");
572
-
573
- match.falsy = match(function (actual) {
574
- return !actual;
575
- }, "falsy");
576
-
577
- match.same = function (expectation) {
578
- return match(function (actual) {
579
- return expectation === actual;
580
- }, "same(" + expectation + ")");
581
- };
582
-
583
- match.typeOf = function (type) {
584
- assertType(type, "string", "type");
585
- return match(function (actual) {
586
- return sinon.typeOf(actual) === type;
587
- }, "typeOf(\"" + type + "\")");
588
- };
589
-
590
- match.instanceOf = function (type) {
591
- assertType(type, "function", "type");
592
- return match(function (actual) {
593
- return actual instanceof type;
594
- }, "instanceOf(" + sinon.functionName(type) + ")");
595
- };
596
-
597
- function createPropertyMatcher(propertyTest, messagePrefix) {
598
- return function (property, value) {
599
- assertType(property, "string", "property");
600
- var onlyProperty = arguments.length === 1;
601
- var message = messagePrefix + "(\"" + property + "\"";
602
- if (!onlyProperty) {
603
- message += ", " + value;
604
- }
605
- message += ")";
606
- return match(function (actual) {
607
- if (actual === undefined || actual === null ||
608
- !propertyTest(actual, property)) {
609
- return false;
610
- }
611
- return onlyProperty || sinon.deepEqual(value, actual[property]);
612
- }, message);
613
- };
614
- }
615
-
616
- match.has = createPropertyMatcher(function (actual, property) {
617
- if (typeof actual === "object") {
618
- return property in actual;
619
- }
620
- return actual[property] !== undefined;
621
- }, "has");
622
-
623
- match.hasOwn = createPropertyMatcher(function (actual, property) {
624
- return actual.hasOwnProperty(property);
625
- }, "hasOwn");
626
-
627
- match.bool = match.typeOf("boolean");
628
- match.number = match.typeOf("number");
629
- match.string = match.typeOf("string");
630
- match.object = match.typeOf("object");
631
- match.func = match.typeOf("function");
632
- match.array = match.typeOf("array");
633
- match.regexp = match.typeOf("regexp");
634
- match.date = match.typeOf("date");
635
-
636
- if (commonJSModule) {
637
- module.exports = match;
638
- } else {
639
- sinon.match = match;
640
- }
641
- }(typeof sinon == "object" && sinon || null));
642
-
643
- /**
644
- * @depend ../sinon.js
645
- * @depend match.js
646
- */
647
- /*jslint eqeqeq: false, onevar: false, plusplus: false*/
648
- /*global module, require, sinon*/
649
- /**
650
- * Spy calls
651
- *
652
- * @author Christian Johansen (christian@cjohansen.no)
653
- * @author Maximilian Antoni (mail@maxantoni.de)
654
- * @license BSD
655
- *
656
- * Copyright (c) 2010-2013 Christian Johansen
657
- * Copyright (c) 2013 Maximilian Antoni
658
- */
659
-
660
- (function (sinon) {
661
- var commonJSModule = typeof module !== 'undefined' && module.exports;
662
- if (!sinon && commonJSModule) {
663
- sinon = require("../sinon");
664
- }
665
-
666
- if (!sinon) {
667
- return;
668
- }
669
-
670
- function throwYieldError(proxy, text, args) {
671
- var msg = sinon.functionName(proxy) + text;
672
- if (args.length) {
673
- msg += " Received [" + slice.call(args).join(", ") + "]";
674
- }
675
- throw new Error(msg);
676
- }
677
-
678
- var slice = Array.prototype.slice;
679
-
680
- var callProto = {
681
- calledOn: function calledOn(thisValue) {
682
- if (sinon.match && sinon.match.isMatcher(thisValue)) {
683
- return thisValue.test(this.thisValue);
684
- }
685
- return this.thisValue === thisValue;
686
- },
687
-
688
- calledWith: function calledWith() {
689
- for (var i = 0, l = arguments.length; i < l; i += 1) {
690
- if (!sinon.deepEqual(arguments[i], this.args[i])) {
691
- return false;
692
- }
693
- }
694
-
695
- return true;
696
- },
697
-
698
- calledWithMatch: function calledWithMatch() {
699
- for (var i = 0, l = arguments.length; i < l; i += 1) {
700
- var actual = this.args[i];
701
- var expectation = arguments[i];
702
- if (!sinon.match || !sinon.match(expectation).test(actual)) {
703
- return false;
704
- }
705
- }
706
- return true;
707
- },
708
-
709
- calledWithExactly: function calledWithExactly() {
710
- return arguments.length == this.args.length &&
711
- this.calledWith.apply(this, arguments);
712
- },
713
-
714
- notCalledWith: function notCalledWith() {
715
- return !this.calledWith.apply(this, arguments);
716
- },
717
-
718
- notCalledWithMatch: function notCalledWithMatch() {
719
- return !this.calledWithMatch.apply(this, arguments);
720
- },
721
-
722
- returned: function returned(value) {
723
- return sinon.deepEqual(value, this.returnValue);
724
- },
725
-
726
- threw: function threw(error) {
727
- if (typeof error === "undefined" || !this.exception) {
728
- return !!this.exception;
729
- }
730
-
731
- return this.exception === error || this.exception.name === error;
732
- },
733
-
734
- calledWithNew: function calledWithNew(thisValue) {
735
- return this.thisValue instanceof this.proxy;
736
- },
737
-
738
- calledBefore: function (other) {
739
- return this.callId < other.callId;
740
- },
741
-
742
- calledAfter: function (other) {
743
- return this.callId > other.callId;
744
- },
745
-
746
- callArg: function (pos) {
747
- this.args[pos]();
748
- },
749
-
750
- callArgOn: function (pos, thisValue) {
751
- this.args[pos].apply(thisValue);
752
- },
753
-
754
- callArgWith: function (pos) {
755
- this.callArgOnWith.apply(this, [pos, null].concat(slice.call(arguments, 1)));
756
- },
757
-
758
- callArgOnWith: function (pos, thisValue) {
759
- var args = slice.call(arguments, 2);
760
- this.args[pos].apply(thisValue, args);
761
- },
762
-
763
- "yield": function () {
764
- this.yieldOn.apply(this, [null].concat(slice.call(arguments, 0)));
765
- },
766
-
767
- yieldOn: function (thisValue) {
768
- var args = this.args;
769
- for (var i = 0, l = args.length; i < l; ++i) {
770
- if (typeof args[i] === "function") {
771
- args[i].apply(thisValue, slice.call(arguments, 1));
772
- return;
773
- }
774
- }
775
- throwYieldError(this.proxy, " cannot yield since no callback was passed.", args);
776
- },
777
-
778
- yieldTo: function (prop) {
779
- this.yieldToOn.apply(this, [prop, null].concat(slice.call(arguments, 1)));
780
- },
781
-
782
- yieldToOn: function (prop, thisValue) {
783
- var args = this.args;
784
- for (var i = 0, l = args.length; i < l; ++i) {
785
- if (args[i] && typeof args[i][prop] === "function") {
786
- args[i][prop].apply(thisValue, slice.call(arguments, 2));
787
- return;
788
- }
789
- }
790
- throwYieldError(this.proxy, " cannot yield to '" + prop +
791
- "' since no callback was passed.", args);
792
- },
793
-
794
- toString: function () {
795
- var callStr = this.proxy.toString() + "(";
796
- var args = [];
797
-
798
- for (var i = 0, l = this.args.length; i < l; ++i) {
799
- args.push(sinon.format(this.args[i]));
800
- }
801
-
802
- callStr = callStr + args.join(", ") + ")";
803
-
804
- if (typeof this.returnValue != "undefined") {
805
- callStr += " => " + sinon.format(this.returnValue);
806
- }
807
-
808
- if (this.exception) {
809
- callStr += " !" + this.exception.name;
810
-
811
- if (this.exception.message) {
812
- callStr += "(" + this.exception.message + ")";
813
- }
814
- }
815
-
816
- return callStr;
817
- }
818
- };
819
-
820
- callProto.invokeCallback = callProto.yield;
821
-
822
- function createSpyCall(spy, thisValue, args, returnValue, exception, id) {
823
- if (typeof id !== "number") {
824
- throw new TypeError("Call id is not a number");
825
- }
826
- var proxyCall = sinon.create(callProto);
827
- proxyCall.proxy = spy;
828
- proxyCall.thisValue = thisValue;
829
- proxyCall.args = args;
830
- proxyCall.returnValue = returnValue;
831
- proxyCall.exception = exception;
832
- proxyCall.callId = id;
833
-
834
- return proxyCall;
835
- };
836
- createSpyCall.toString = callProto.toString; // used by mocks
837
-
838
- if (commonJSModule) {
839
- module.exports = createSpyCall;
840
- } else {
841
- sinon.spyCall = createSpyCall;
842
- }
843
- }(typeof sinon == "object" && sinon || null));
844
-
845
-
846
- /**
847
- * @depend ../sinon.js
848
- * @depend call.js
849
- */
850
- /*jslint eqeqeq: false, onevar: false, plusplus: false*/
851
- /*global module, require, sinon*/
852
- /**
853
- * Spy functions
854
- *
855
- * @author Christian Johansen (christian@cjohansen.no)
856
- * @license BSD
857
- *
858
- * Copyright (c) 2010-2013 Christian Johansen
859
- */
860
-
861
- (function (sinon) {
862
- var commonJSModule = typeof module !== 'undefined' && module.exports;
863
- var push = Array.prototype.push;
864
- var slice = Array.prototype.slice;
865
- var callId = 0;
866
-
867
- if (!sinon && commonJSModule) {
868
- sinon = require("../sinon");
869
- }
870
-
871
- if (!sinon) {
872
- return;
873
- }
874
-
875
- function spy(object, property) {
876
- if (!property && typeof object == "function") {
877
- return spy.create(object);
878
- }
879
-
880
- if (!object && !property) {
881
- return spy.create(function () { });
882
- }
883
-
884
- var method = object[property];
885
- return sinon.wrapMethod(object, property, spy.create(method));
886
- }
887
-
888
- function matchingFake(fakes, args, strict) {
889
- if (!fakes) {
890
- return;
891
- }
892
-
893
- var alen = args.length;
894
-
895
- for (var i = 0, l = fakes.length; i < l; i++) {
896
- if (fakes[i].matches(args, strict)) {
897
- return fakes[i];
898
- }
899
- }
900
- }
901
-
902
- function incrementCallCount() {
903
- this.called = true;
904
- this.callCount += 1;
905
- this.notCalled = false;
906
- this.calledOnce = this.callCount == 1;
907
- this.calledTwice = this.callCount == 2;
908
- this.calledThrice = this.callCount == 3;
909
- }
910
-
911
- function createCallProperties() {
912
- this.firstCall = this.getCall(0);
913
- this.secondCall = this.getCall(1);
914
- this.thirdCall = this.getCall(2);
915
- this.lastCall = this.getCall(this.callCount - 1);
916
- }
917
-
918
- var vars = "a,b,c,d,e,f,g,h,i,j,k,l";
919
- function createProxy(func) {
920
- // Retain the function length:
921
- var p;
922
- if (func.length) {
923
- eval("p = (function proxy(" + vars.substring(0, func.length * 2 - 1) +
924
- ") { return p.invoke(func, this, slice.call(arguments)); });");
925
- }
926
- else {
927
- p = function proxy() {
928
- return p.invoke(func, this, slice.call(arguments));
929
- };
930
- }
931
- return p;
932
- }
933
-
934
- var uuid = 0;
935
-
936
- // Public API
937
- var spyApi = {
938
- reset: function () {
939
- this.called = false;
940
- this.notCalled = true;
941
- this.calledOnce = false;
942
- this.calledTwice = false;
943
- this.calledThrice = false;
944
- this.callCount = 0;
945
- this.firstCall = null;
946
- this.secondCall = null;
947
- this.thirdCall = null;
948
- this.lastCall = null;
949
- this.args = [];
950
- this.returnValues = [];
951
- this.thisValues = [];
952
- this.exceptions = [];
953
- this.callIds = [];
954
- if (this.fakes) {
955
- for (var i = 0; i < this.fakes.length; i++) {
956
- this.fakes[i].reset();
957
- }
958
- }
959
- },
960
-
961
- create: function create(func) {
962
- var name;
963
-
964
- if (typeof func != "function") {
965
- func = function () { };
966
- } else {
967
- name = sinon.functionName(func);
968
- }
969
-
970
- var proxy = createProxy(func);
971
-
972
- sinon.extend(proxy, spy);
973
- delete proxy.create;
974
- sinon.extend(proxy, func);
975
-
976
- proxy.reset();
977
- proxy.prototype = func.prototype;
978
- proxy.displayName = name || "spy";
979
- proxy.toString = sinon.functionToString;
980
- proxy._create = sinon.spy.create;
981
- proxy.id = "spy#" + uuid++;
982
-
983
- return proxy;
984
- },
985
-
986
- invoke: function invoke(func, thisValue, args) {
987
- var matching = matchingFake(this.fakes, args);
988
- var exception, returnValue;
989
-
990
- incrementCallCount.call(this);
991
- push.call(this.thisValues, thisValue);
992
- push.call(this.args, args);
993
- push.call(this.callIds, callId++);
994
-
995
- try {
996
- if (matching) {
997
- returnValue = matching.invoke(func, thisValue, args);
998
- } else {
999
- returnValue = (this.func || func).apply(thisValue, args);
1000
- }
1001
- } catch (e) {
1002
- push.call(this.returnValues, undefined);
1003
- exception = e;
1004
- throw e;
1005
- } finally {
1006
- push.call(this.exceptions, exception);
1007
- }
1008
-
1009
- push.call(this.returnValues, returnValue);
1010
-
1011
- createCallProperties.call(this);
1012
-
1013
- return returnValue;
1014
- },
1015
-
1016
- getCall: function getCall(i) {
1017
- if (i < 0 || i >= this.callCount) {
1018
- return null;
1019
- }
1020
-
1021
- return sinon.spyCall(this, this.thisValues[i], this.args[i],
1022
- this.returnValues[i], this.exceptions[i],
1023
- this.callIds[i]);
1024
- },
1025
-
1026
- getCalls: function () {
1027
- var calls = [];
1028
- var i;
1029
-
1030
- for (i = 0; i < this.callCount; i++) {
1031
- calls.push(this.getCall(i));
1032
- }
1033
-
1034
- return calls;
1035
- },
1036
-
1037
- calledBefore: function calledBefore(spyFn) {
1038
- if (!this.called) {
1039
- return false;
1040
- }
1041
-
1042
- if (!spyFn.called) {
1043
- return true;
1044
- }
1045
-
1046
- return this.callIds[0] < spyFn.callIds[spyFn.callIds.length - 1];
1047
- },
1048
-
1049
- calledAfter: function calledAfter(spyFn) {
1050
- if (!this.called || !spyFn.called) {
1051
- return false;
1052
- }
1053
-
1054
- return this.callIds[this.callCount - 1] > spyFn.callIds[spyFn.callCount - 1];
1055
- },
1056
-
1057
- withArgs: function () {
1058
- var args = slice.call(arguments);
1059
-
1060
- if (this.fakes) {
1061
- var match = matchingFake(this.fakes, args, true);
1062
-
1063
- if (match) {
1064
- return match;
1065
- }
1066
- } else {
1067
- this.fakes = [];
1068
- }
1069
-
1070
- var original = this;
1071
- var fake = this._create();
1072
- fake.matchingAguments = args;
1073
- fake.parent = this;
1074
- push.call(this.fakes, fake);
1075
-
1076
- fake.withArgs = function () {
1077
- return original.withArgs.apply(original, arguments);
1078
- };
1079
-
1080
- for (var i = 0; i < this.args.length; i++) {
1081
- if (fake.matches(this.args[i])) {
1082
- incrementCallCount.call(fake);
1083
- push.call(fake.thisValues, this.thisValues[i]);
1084
- push.call(fake.args, this.args[i]);
1085
- push.call(fake.returnValues, this.returnValues[i]);
1086
- push.call(fake.exceptions, this.exceptions[i]);
1087
- push.call(fake.callIds, this.callIds[i]);
1088
- }
1089
- }
1090
- createCallProperties.call(fake);
1091
-
1092
- return fake;
1093
- },
1094
-
1095
- matches: function (args, strict) {
1096
- var margs = this.matchingAguments;
1097
-
1098
- if (margs.length <= args.length &&
1099
- sinon.deepEqual(margs, args.slice(0, margs.length))) {
1100
- return !strict || margs.length == args.length;
1101
- }
1102
- },
1103
-
1104
- printf: function (format) {
1105
- var spy = this;
1106
- var args = slice.call(arguments, 1);
1107
- var formatter;
1108
-
1109
- return (format || "").replace(/%(.)/g, function (match, specifyer) {
1110
- formatter = spyApi.formatters[specifyer];
1111
-
1112
- if (typeof formatter == "function") {
1113
- return formatter.call(null, spy, args);
1114
- } else if (!isNaN(parseInt(specifyer, 10))) {
1115
- return sinon.format(args[specifyer - 1]);
1116
- }
1117
-
1118
- return "%" + specifyer;
1119
- });
1120
- }
1121
- };
1122
-
1123
- function delegateToCalls(method, matchAny, actual, notCalled) {
1124
- spyApi[method] = function () {
1125
- if (!this.called) {
1126
- if (notCalled) {
1127
- return notCalled.apply(this, arguments);
1128
- }
1129
- return false;
1130
- }
1131
-
1132
- var currentCall;
1133
- var matches = 0;
1134
-
1135
- for (var i = 0, l = this.callCount; i < l; i += 1) {
1136
- currentCall = this.getCall(i);
1137
-
1138
- if (currentCall[actual || method].apply(currentCall, arguments)) {
1139
- matches += 1;
1140
-
1141
- if (matchAny) {
1142
- return true;
1143
- }
1144
- }
1145
- }
1146
-
1147
- return matches === this.callCount;
1148
- };
1149
- }
1150
-
1151
- delegateToCalls("calledOn", true);
1152
- delegateToCalls("alwaysCalledOn", false, "calledOn");
1153
- delegateToCalls("calledWith", true);
1154
- delegateToCalls("calledWithMatch", true);
1155
- delegateToCalls("alwaysCalledWith", false, "calledWith");
1156
- delegateToCalls("alwaysCalledWithMatch", false, "calledWithMatch");
1157
- delegateToCalls("calledWithExactly", true);
1158
- delegateToCalls("alwaysCalledWithExactly", false, "calledWithExactly");
1159
- delegateToCalls("neverCalledWith", false, "notCalledWith",
1160
- function () { return true; });
1161
- delegateToCalls("neverCalledWithMatch", false, "notCalledWithMatch",
1162
- function () { return true; });
1163
- delegateToCalls("threw", true);
1164
- delegateToCalls("alwaysThrew", false, "threw");
1165
- delegateToCalls("returned", true);
1166
- delegateToCalls("alwaysReturned", false, "returned");
1167
- delegateToCalls("calledWithNew", true);
1168
- delegateToCalls("alwaysCalledWithNew", false, "calledWithNew");
1169
- delegateToCalls("callArg", false, "callArgWith", function () {
1170
- throw new Error(this.toString() + " cannot call arg since it was not yet invoked.");
1171
- });
1172
- spyApi.callArgWith = spyApi.callArg;
1173
- delegateToCalls("callArgOn", false, "callArgOnWith", function () {
1174
- throw new Error(this.toString() + " cannot call arg since it was not yet invoked.");
1175
- });
1176
- spyApi.callArgOnWith = spyApi.callArgOn;
1177
- delegateToCalls("yield", false, "yield", function () {
1178
- throw new Error(this.toString() + " cannot yield since it was not yet invoked.");
1179
- });
1180
- // "invokeCallback" is an alias for "yield" since "yield" is invalid in strict mode.
1181
- spyApi.invokeCallback = spyApi.yield;
1182
- delegateToCalls("yieldOn", false, "yieldOn", function () {
1183
- throw new Error(this.toString() + " cannot yield since it was not yet invoked.");
1184
- });
1185
- delegateToCalls("yieldTo", false, "yieldTo", function (property) {
1186
- throw new Error(this.toString() + " cannot yield to '" + property +
1187
- "' since it was not yet invoked.");
1188
- });
1189
- delegateToCalls("yieldToOn", false, "yieldToOn", function (property) {
1190
- throw new Error(this.toString() + " cannot yield to '" + property +
1191
- "' since it was not yet invoked.");
1192
- });
1193
-
1194
- spyApi.formatters = {
1195
- "c": function (spy) {
1196
- return sinon.timesInWords(spy.callCount);
1197
- },
1198
-
1199
- "n": function (spy) {
1200
- return spy.toString();
1201
- },
1202
-
1203
- "C": function (spy) {
1204
- var calls = [];
1205
-
1206
- for (var i = 0, l = spy.callCount; i < l; ++i) {
1207
- var stringifiedCall = " " + spy.getCall(i).toString();
1208
- if (/\n/.test(calls[i - 1])) {
1209
- stringifiedCall = "\n" + stringifiedCall;
1210
- }
1211
- push.call(calls, stringifiedCall);
1212
- }
1213
-
1214
- return calls.length > 0 ? "\n" + calls.join("\n") : "";
1215
- },
1216
-
1217
- "t": function (spy) {
1218
- var objects = [];
1219
-
1220
- for (var i = 0, l = spy.callCount; i < l; ++i) {
1221
- push.call(objects, sinon.format(spy.thisValues[i]));
1222
- }
1223
-
1224
- return objects.join(", ");
1225
- },
1226
-
1227
- "*": function (spy, args) {
1228
- var formatted = [];
1229
-
1230
- for (var i = 0, l = args.length; i < l; ++i) {
1231
- push.call(formatted, sinon.format(args[i]));
1232
- }
1233
-
1234
- return formatted.join(", ");
1235
- }
1236
- };
1237
-
1238
- sinon.extend(spy, spyApi);
1239
-
1240
- spy.spyCall = sinon.spyCall;
1241
-
1242
- if (commonJSModule) {
1243
- module.exports = spy;
1244
- } else {
1245
- sinon.spy = spy;
1246
- }
1247
- }(typeof sinon == "object" && sinon || null));
1248
-
1249
- /**
1250
- * @depend ../sinon.js
1251
- */
1252
- /*jslint eqeqeq: false, onevar: false*/
1253
- /*global module, require, sinon, process, setImmediate, setTimeout*/
1254
- /**
1255
- * Stub behavior
1256
- *
1257
- * @author Christian Johansen (christian@cjohansen.no)
1258
- * @author Tim Fischbach (mail@timfischbach.de)
1259
- * @license BSD
1260
- *
1261
- * Copyright (c) 2010-2013 Christian Johansen
1262
- */
1263
-
1264
- (function (sinon) {
1265
- var commonJSModule = typeof module !== 'undefined' && module.exports;
1266
-
1267
- if (!sinon && commonJSModule) {
1268
- sinon = require("../sinon");
1269
- }
1270
-
1271
- if (!sinon) {
1272
- return;
1273
- }
1274
-
1275
- var slice = Array.prototype.slice;
1276
- var join = Array.prototype.join;
1277
- var proto;
1278
-
1279
- var nextTick = (function () {
1280
- if (typeof process === "object" && typeof process.nextTick === "function") {
1281
- return process.nextTick;
1282
- } else if (typeof setImmediate === "function") {
1283
- return setImmediate;
1284
- } else {
1285
- return function (callback) {
1286
- setTimeout(callback, 0);
1287
- };
1288
- }
1289
- })();
1290
-
1291
- function throwsException(error, message) {
1292
- if (typeof error == "string") {
1293
- this.exception = new Error(message || "");
1294
- this.exception.name = error;
1295
- } else if (!error) {
1296
- this.exception = new Error("Error");
1297
- } else {
1298
- this.exception = error;
1299
- }
1300
-
1301
- return this;
1302
- }
1303
-
1304
- function getCallback(behavior, args) {
1305
- var callArgAt = behavior.callArgAt;
1306
-
1307
- if (callArgAt < 0) {
1308
- var callArgProp = behavior.callArgProp;
1309
-
1310
- for (var i = 0, l = args.length; i < l; ++i) {
1311
- if (!callArgProp && typeof args[i] == "function") {
1312
- return args[i];
1313
- }
1314
-
1315
- if (callArgProp && args[i] &&
1316
- typeof args[i][callArgProp] == "function") {
1317
- return args[i][callArgProp];
1318
- }
1319
- }
1320
-
1321
- return null;
1322
- }
1323
-
1324
- return args[callArgAt];
1325
- }
1326
-
1327
- function getCallbackError(behavior, func, args) {
1328
- if (behavior.callArgAt < 0) {
1329
- var msg;
1330
-
1331
- if (behavior.callArgProp) {
1332
- msg = sinon.functionName(behavior.stub) +
1333
- " expected to yield to '" + behavior.callArgProp +
1334
- "', but no object with such a property was passed.";
1335
- } else {
1336
- msg = sinon.functionName(behavior.stub) +
1337
- " expected to yield, but no callback was passed.";
1338
- }
1339
-
1340
- if (args.length > 0) {
1341
- msg += " Received [" + join.call(args, ", ") + "]";
1342
- }
1343
-
1344
- return msg;
1345
- }
1346
-
1347
- return "argument at index " + behavior.callArgAt + " is not a function: " + func;
1348
- }
1349
-
1350
- function callCallback(behavior, args) {
1351
- if (typeof behavior.callArgAt == "number") {
1352
- var func = getCallback(behavior, args);
1353
-
1354
- if (typeof func != "function") {
1355
- throw new TypeError(getCallbackError(behavior, func, args));
1356
- }
1357
-
1358
- if (behavior.callbackAsync) {
1359
- nextTick(function() {
1360
- func.apply(behavior.callbackContext, behavior.callbackArguments);
1361
- });
1362
- } else {
1363
- func.apply(behavior.callbackContext, behavior.callbackArguments);
1364
- }
1365
- }
1366
- }
1367
-
1368
- proto = {
1369
- create: function(stub) {
1370
- var behavior = sinon.extend({}, sinon.behavior);
1371
- delete behavior.create;
1372
- behavior.stub = stub;
1373
-
1374
- return behavior;
1375
- },
1376
-
1377
- isPresent: function() {
1378
- return (typeof this.callArgAt == 'number' ||
1379
- this.exception ||
1380
- typeof this.returnArgAt == 'number' ||
1381
- this.returnThis ||
1382
- this.returnValueDefined);
1383
- },
1384
-
1385
- invoke: function(context, args) {
1386
- callCallback(this, args);
1387
-
1388
- if (this.exception) {
1389
- throw this.exception;
1390
- } else if (typeof this.returnArgAt == 'number') {
1391
- return args[this.returnArgAt];
1392
- } else if (this.returnThis) {
1393
- return context;
1394
- }
1395
-
1396
- return this.returnValue;
1397
- },
1398
-
1399
- onCall: function(index) {
1400
- return this.stub.onCall(index);
1401
- },
1402
-
1403
- onFirstCall: function() {
1404
- return this.stub.onFirstCall();
1405
- },
1406
-
1407
- onSecondCall: function() {
1408
- return this.stub.onSecondCall();
1409
- },
1410
-
1411
- onThirdCall: function() {
1412
- return this.stub.onThirdCall();
1413
- },
1414
-
1415
- withArgs: function(/* arguments */) {
1416
- throw new Error('Defining a stub by invoking "stub.onCall(...).withArgs(...)" is not supported. ' +
1417
- 'Use "stub.withArgs(...).onCall(...)" to define sequential behavior for calls with certain arguments.');
1418
- },
1419
-
1420
- callsArg: function callsArg(pos) {
1421
- if (typeof pos != "number") {
1422
- throw new TypeError("argument index is not number");
1423
- }
1424
-
1425
- this.callArgAt = pos;
1426
- this.callbackArguments = [];
1427
- this.callbackContext = undefined;
1428
- this.callArgProp = undefined;
1429
- this.callbackAsync = false;
1430
-
1431
- return this;
1432
- },
1433
-
1434
- callsArgOn: function callsArgOn(pos, context) {
1435
- if (typeof pos != "number") {
1436
- throw new TypeError("argument index is not number");
1437
- }
1438
- if (typeof context != "object") {
1439
- throw new TypeError("argument context is not an object");
1440
- }
1441
-
1442
- this.callArgAt = pos;
1443
- this.callbackArguments = [];
1444
- this.callbackContext = context;
1445
- this.callArgProp = undefined;
1446
- this.callbackAsync = false;
1447
-
1448
- return this;
1449
- },
1450
-
1451
- callsArgWith: function callsArgWith(pos) {
1452
- if (typeof pos != "number") {
1453
- throw new TypeError("argument index is not number");
1454
- }
1455
-
1456
- this.callArgAt = pos;
1457
- this.callbackArguments = slice.call(arguments, 1);
1458
- this.callbackContext = undefined;
1459
- this.callArgProp = undefined;
1460
- this.callbackAsync = false;
1461
-
1462
- return this;
1463
- },
1464
-
1465
- callsArgOnWith: function callsArgWith(pos, context) {
1466
- if (typeof pos != "number") {
1467
- throw new TypeError("argument index is not number");
1468
- }
1469
- if (typeof context != "object") {
1470
- throw new TypeError("argument context is not an object");
1471
- }
1472
-
1473
- this.callArgAt = pos;
1474
- this.callbackArguments = slice.call(arguments, 2);
1475
- this.callbackContext = context;
1476
- this.callArgProp = undefined;
1477
- this.callbackAsync = false;
1478
-
1479
- return this;
1480
- },
1481
-
1482
- yields: function () {
1483
- this.callArgAt = -1;
1484
- this.callbackArguments = slice.call(arguments, 0);
1485
- this.callbackContext = undefined;
1486
- this.callArgProp = undefined;
1487
- this.callbackAsync = false;
1488
-
1489
- return this;
1490
- },
1491
-
1492
- yieldsOn: function (context) {
1493
- if (typeof context != "object") {
1494
- throw new TypeError("argument context is not an object");
1495
- }
1496
-
1497
- this.callArgAt = -1;
1498
- this.callbackArguments = slice.call(arguments, 1);
1499
- this.callbackContext = context;
1500
- this.callArgProp = undefined;
1501
- this.callbackAsync = false;
1502
-
1503
- return this;
1504
- },
1505
-
1506
- yieldsTo: function (prop) {
1507
- this.callArgAt = -1;
1508
- this.callbackArguments = slice.call(arguments, 1);
1509
- this.callbackContext = undefined;
1510
- this.callArgProp = prop;
1511
- this.callbackAsync = false;
1512
-
1513
- return this;
1514
- },
1515
-
1516
- yieldsToOn: function (prop, context) {
1517
- if (typeof context != "object") {
1518
- throw new TypeError("argument context is not an object");
1519
- }
1520
-
1521
- this.callArgAt = -1;
1522
- this.callbackArguments = slice.call(arguments, 2);
1523
- this.callbackContext = context;
1524
- this.callArgProp = prop;
1525
- this.callbackAsync = false;
1526
-
1527
- return this;
1528
- },
1529
-
1530
-
1531
- "throws": throwsException,
1532
- throwsException: throwsException,
1533
-
1534
- returns: function returns(value) {
1535
- this.returnValue = value;
1536
- this.returnValueDefined = true;
1537
-
1538
- return this;
1539
- },
1540
-
1541
- returnsArg: function returnsArg(pos) {
1542
- if (typeof pos != "number") {
1543
- throw new TypeError("argument index is not number");
1544
- }
1545
-
1546
- this.returnArgAt = pos;
1547
-
1548
- return this;
1549
- },
1550
-
1551
- returnsThis: function returnsThis() {
1552
- this.returnThis = true;
1553
-
1554
- return this;
1555
- }
1556
- };
1557
-
1558
- // create asynchronous versions of callsArg* and yields* methods
1559
- for (var method in proto) {
1560
- // need to avoid creating anotherasync versions of the newly added async methods
1561
- if (proto.hasOwnProperty(method) &&
1562
- method.match(/^(callsArg|yields)/) &&
1563
- !method.match(/Async/)) {
1564
- proto[method + 'Async'] = (function (syncFnName) {
1565
- return function () {
1566
- var result = this[syncFnName].apply(this, arguments);
1567
- this.callbackAsync = true;
1568
- return result;
1569
- };
1570
- })(method);
1571
- }
1572
- }
1573
-
1574
- if (commonJSModule) {
1575
- module.exports = proto;
1576
- } else {
1577
- sinon.behavior = proto;
1578
- }
1579
- }(typeof sinon == "object" && sinon || null));
1580
- /**
1581
- * @depend ../sinon.js
1582
- * @depend spy.js
1583
- * @depend behavior.js
1584
- */
1585
- /*jslint eqeqeq: false, onevar: false*/
1586
- /*global module, require, sinon*/
1587
- /**
1588
- * Stub functions
1589
- *
1590
- * @author Christian Johansen (christian@cjohansen.no)
1591
- * @license BSD
1592
- *
1593
- * Copyright (c) 2010-2013 Christian Johansen
1594
- */
1595
-
1596
- (function (sinon) {
1597
- var commonJSModule = typeof module !== 'undefined' && module.exports;
1598
-
1599
- if (!sinon && commonJSModule) {
1600
- sinon = require("../sinon");
1601
- }
1602
-
1603
- if (!sinon) {
1604
- return;
1605
- }
1606
-
1607
- function stub(object, property, func) {
1608
- if (!!func && typeof func != "function") {
1609
- throw new TypeError("Custom stub should be function");
1610
- }
1611
-
1612
- var wrapper;
1613
-
1614
- if (func) {
1615
- wrapper = sinon.spy && sinon.spy.create ? sinon.spy.create(func) : func;
1616
- } else {
1617
- wrapper = stub.create();
1618
- }
1619
-
1620
- if (!object && !property) {
1621
- return sinon.stub.create();
1622
- }
1623
-
1624
- if (!property && !!object && typeof object == "object") {
1625
- for (var prop in object) {
1626
- if (typeof object[prop] === "function") {
1627
- stub(object, prop);
1628
- }
1629
- }
1630
-
1631
- return object;
1632
- }
1633
-
1634
- return sinon.wrapMethod(object, property, wrapper);
1635
- }
1636
-
1637
- function getDefaultBehavior(stub) {
1638
- return stub.defaultBehavior || getParentBehaviour(stub) || sinon.behavior.create(stub);
1639
- }
1640
-
1641
- function getParentBehaviour(stub) {
1642
- return (stub.parent && getCurrentBehavior(stub.parent));
1643
- }
1644
-
1645
- function getCurrentBehavior(stub) {
1646
- var behavior = stub.behaviors[stub.callCount - 1];
1647
- return behavior && behavior.isPresent() ? behavior : getDefaultBehavior(stub);
1648
- }
1649
-
1650
- var uuid = 0;
1651
-
1652
- sinon.extend(stub, (function () {
1653
- var slice = Array.prototype.slice, proto;
1654
-
1655
- proto = {
1656
- create: function create() {
1657
- var functionStub = function () {
1658
- return getCurrentBehavior(functionStub).invoke(this, arguments);
1659
- };
1660
-
1661
- functionStub.id = "stub#" + uuid++;
1662
- var orig = functionStub;
1663
- functionStub = sinon.spy.create(functionStub);
1664
- functionStub.func = orig;
1665
-
1666
- sinon.extend(functionStub, stub);
1667
- functionStub._create = sinon.stub.create;
1668
- functionStub.displayName = "stub";
1669
- functionStub.toString = sinon.functionToString;
1670
-
1671
- functionStub.defaultBehavior = null;
1672
- functionStub.behaviors = [];
1673
-
1674
- return functionStub;
1675
- },
1676
-
1677
- resetBehavior: function () {
1678
- var i;
1679
-
1680
- this.defaultBehavior = null;
1681
- this.behaviors = [];
1682
-
1683
- delete this.returnValue;
1684
- delete this.returnArgAt;
1685
- this.returnThis = false;
1686
-
1687
- if (this.fakes) {
1688
- for (i = 0; i < this.fakes.length; i++) {
1689
- this.fakes[i].resetBehavior();
1690
- }
1691
- }
1692
- },
1693
-
1694
- onCall: function(index) {
1695
- if (!this.behaviors[index]) {
1696
- this.behaviors[index] = sinon.behavior.create(this);
1697
- }
1698
-
1699
- return this.behaviors[index];
1700
- },
1701
-
1702
- onFirstCall: function() {
1703
- return this.onCall(0);
1704
- },
1705
-
1706
- onSecondCall: function() {
1707
- return this.onCall(1);
1708
- },
1709
-
1710
- onThirdCall: function() {
1711
- return this.onCall(2);
1712
- }
1713
- };
1714
-
1715
- for (var method in sinon.behavior) {
1716
- if (sinon.behavior.hasOwnProperty(method) &&
1717
- !proto.hasOwnProperty(method) &&
1718
- method != 'create' &&
1719
- method != 'withArgs' &&
1720
- method != 'invoke') {
1721
- proto[method] = (function(behaviorMethod) {
1722
- return function() {
1723
- this.defaultBehavior = this.defaultBehavior || sinon.behavior.create(this);
1724
- this.defaultBehavior[behaviorMethod].apply(this.defaultBehavior, arguments);
1725
- return this;
1726
- };
1727
- }(method));
1728
- }
1729
- }
1730
-
1731
- return proto;
1732
- }()));
1733
-
1734
- if (commonJSModule) {
1735
- module.exports = stub;
1736
- } else {
1737
- sinon.stub = stub;
1738
- }
1739
- }(typeof sinon == "object" && sinon || null));
1740
-
1741
- /**
1742
- * @depend ../sinon.js
1743
- * @depend stub.js
1744
- */
1745
- /*jslint eqeqeq: false, onevar: false, nomen: false*/
1746
- /*global module, require, sinon*/
1747
- /**
1748
- * Mock functions.
1749
- *
1750
- * @author Christian Johansen (christian@cjohansen.no)
1751
- * @license BSD
1752
- *
1753
- * Copyright (c) 2010-2013 Christian Johansen
1754
- */
1755
-
1756
- (function (sinon) {
1757
- var commonJSModule = typeof module !== 'undefined' && module.exports;
1758
- var push = [].push;
1759
- var match;
1760
-
1761
- if (!sinon && commonJSModule) {
1762
- sinon = require("../sinon");
1763
- }
1764
-
1765
- if (!sinon) {
1766
- return;
1767
- }
1768
-
1769
- match = sinon.match;
1770
-
1771
- if (!match && commonJSModule) {
1772
- match = require("./match");
1773
- }
1774
-
1775
- function mock(object) {
1776
- if (!object) {
1777
- return sinon.expectation.create("Anonymous mock");
1778
- }
1779
-
1780
- return mock.create(object);
1781
- }
1782
-
1783
- sinon.mock = mock;
1784
-
1785
- sinon.extend(mock, (function () {
1786
- function each(collection, callback) {
1787
- if (!collection) {
1788
- return;
1789
- }
1790
-
1791
- for (var i = 0, l = collection.length; i < l; i += 1) {
1792
- callback(collection[i]);
1793
- }
1794
- }
1795
-
1796
- return {
1797
- create: function create(object) {
1798
- if (!object) {
1799
- throw new TypeError("object is null");
1800
- }
1801
-
1802
- var mockObject = sinon.extend({}, mock);
1803
- mockObject.object = object;
1804
- delete mockObject.create;
1805
-
1806
- return mockObject;
1807
- },
1808
-
1809
- expects: function expects(method) {
1810
- if (!method) {
1811
- throw new TypeError("method is falsy");
1812
- }
1813
-
1814
- if (!this.expectations) {
1815
- this.expectations = {};
1816
- this.proxies = [];
1817
- }
1818
-
1819
- if (!this.expectations[method]) {
1820
- this.expectations[method] = [];
1821
- var mockObject = this;
1822
-
1823
- sinon.wrapMethod(this.object, method, function () {
1824
- return mockObject.invokeMethod(method, this, arguments);
1825
- });
1826
-
1827
- push.call(this.proxies, method);
1828
- }
1829
-
1830
- var expectation = sinon.expectation.create(method);
1831
- push.call(this.expectations[method], expectation);
1832
-
1833
- return expectation;
1834
- },
1835
-
1836
- restore: function restore() {
1837
- var object = this.object;
1838
-
1839
- each(this.proxies, function (proxy) {
1840
- if (typeof object[proxy].restore == "function") {
1841
- object[proxy].restore();
1842
- }
1843
- });
1844
- },
1845
-
1846
- verify: function verify() {
1847
- var expectations = this.expectations || {};
1848
- var messages = [], met = [];
1849
-
1850
- each(this.proxies, function (proxy) {
1851
- each(expectations[proxy], function (expectation) {
1852
- if (!expectation.met()) {
1853
- push.call(messages, expectation.toString());
1854
- } else {
1855
- push.call(met, expectation.toString());
1856
- }
1857
- });
1858
- });
1859
-
1860
- this.restore();
1861
-
1862
- if (messages.length > 0) {
1863
- sinon.expectation.fail(messages.concat(met).join("\n"));
1864
- } else {
1865
- sinon.expectation.pass(messages.concat(met).join("\n"));
1866
- }
1867
-
1868
- return true;
1869
- },
1870
-
1871
- invokeMethod: function invokeMethod(method, thisValue, args) {
1872
- var expectations = this.expectations && this.expectations[method];
1873
- var length = expectations && expectations.length || 0, i;
1874
-
1875
- for (i = 0; i < length; i += 1) {
1876
- if (!expectations[i].met() &&
1877
- expectations[i].allowsCall(thisValue, args)) {
1878
- return expectations[i].apply(thisValue, args);
1879
- }
1880
- }
1881
-
1882
- var messages = [], available, exhausted = 0;
1883
-
1884
- for (i = 0; i < length; i += 1) {
1885
- if (expectations[i].allowsCall(thisValue, args)) {
1886
- available = available || expectations[i];
1887
- } else {
1888
- exhausted += 1;
1889
- }
1890
- push.call(messages, " " + expectations[i].toString());
1891
- }
1892
-
1893
- if (exhausted === 0) {
1894
- return available.apply(thisValue, args);
1895
- }
1896
-
1897
- messages.unshift("Unexpected call: " + sinon.spyCall.toString.call({
1898
- proxy: method,
1899
- args: args
1900
- }));
1901
-
1902
- sinon.expectation.fail(messages.join("\n"));
1903
- }
1904
- };
1905
- }()));
1906
-
1907
- var times = sinon.timesInWords;
1908
-
1909
- sinon.expectation = (function () {
1910
- var slice = Array.prototype.slice;
1911
- var _invoke = sinon.spy.invoke;
1912
-
1913
- function callCountInWords(callCount) {
1914
- if (callCount == 0) {
1915
- return "never called";
1916
- } else {
1917
- return "called " + times(callCount);
1918
- }
1919
- }
1920
-
1921
- function expectedCallCountInWords(expectation) {
1922
- var min = expectation.minCalls;
1923
- var max = expectation.maxCalls;
1924
-
1925
- if (typeof min == "number" && typeof max == "number") {
1926
- var str = times(min);
1927
-
1928
- if (min != max) {
1929
- str = "at least " + str + " and at most " + times(max);
1930
- }
1931
-
1932
- return str;
1933
- }
1934
-
1935
- if (typeof min == "number") {
1936
- return "at least " + times(min);
1937
- }
1938
-
1939
- return "at most " + times(max);
1940
- }
1941
-
1942
- function receivedMinCalls(expectation) {
1943
- var hasMinLimit = typeof expectation.minCalls == "number";
1944
- return !hasMinLimit || expectation.callCount >= expectation.minCalls;
1945
- }
1946
-
1947
- function receivedMaxCalls(expectation) {
1948
- if (typeof expectation.maxCalls != "number") {
1949
- return false;
1950
- }
1951
-
1952
- return expectation.callCount == expectation.maxCalls;
1953
- }
1954
-
1955
- function verifyMatcher(possibleMatcher, arg){
1956
- if (match && match.isMatcher(possibleMatcher)) {
1957
- return possibleMatcher.test(arg);
1958
- } else {
1959
- return true;
1960
- }
1961
- }
1962
-
1963
- return {
1964
- minCalls: 1,
1965
- maxCalls: 1,
1966
-
1967
- create: function create(methodName) {
1968
- var expectation = sinon.extend(sinon.stub.create(), sinon.expectation);
1969
- delete expectation.create;
1970
- expectation.method = methodName;
1971
-
1972
- return expectation;
1973
- },
1974
-
1975
- invoke: function invoke(func, thisValue, args) {
1976
- this.verifyCallAllowed(thisValue, args);
1977
-
1978
- return _invoke.apply(this, arguments);
1979
- },
1980
-
1981
- atLeast: function atLeast(num) {
1982
- if (typeof num != "number") {
1983
- throw new TypeError("'" + num + "' is not number");
1984
- }
1985
-
1986
- if (!this.limitsSet) {
1987
- this.maxCalls = null;
1988
- this.limitsSet = true;
1989
- }
1990
-
1991
- this.minCalls = num;
1992
-
1993
- return this;
1994
- },
1995
-
1996
- atMost: function atMost(num) {
1997
- if (typeof num != "number") {
1998
- throw new TypeError("'" + num + "' is not number");
1999
- }
2000
-
2001
- if (!this.limitsSet) {
2002
- this.minCalls = null;
2003
- this.limitsSet = true;
2004
- }
2005
-
2006
- this.maxCalls = num;
2007
-
2008
- return this;
2009
- },
2010
-
2011
- never: function never() {
2012
- return this.exactly(0);
2013
- },
2014
-
2015
- once: function once() {
2016
- return this.exactly(1);
2017
- },
2018
-
2019
- twice: function twice() {
2020
- return this.exactly(2);
2021
- },
2022
-
2023
- thrice: function thrice() {
2024
- return this.exactly(3);
2025
- },
2026
-
2027
- exactly: function exactly(num) {
2028
- if (typeof num != "number") {
2029
- throw new TypeError("'" + num + "' is not a number");
2030
- }
2031
-
2032
- this.atLeast(num);
2033
- return this.atMost(num);
2034
- },
2035
-
2036
- met: function met() {
2037
- return !this.failed && receivedMinCalls(this);
2038
- },
2039
-
2040
- verifyCallAllowed: function verifyCallAllowed(thisValue, args) {
2041
- if (receivedMaxCalls(this)) {
2042
- this.failed = true;
2043
- sinon.expectation.fail(this.method + " already called " + times(this.maxCalls));
2044
- }
2045
-
2046
- if ("expectedThis" in this && this.expectedThis !== thisValue) {
2047
- sinon.expectation.fail(this.method + " called with " + thisValue + " as thisValue, expected " +
2048
- this.expectedThis);
2049
- }
2050
-
2051
- if (!("expectedArguments" in this)) {
2052
- return;
2053
- }
2054
-
2055
- if (!args) {
2056
- sinon.expectation.fail(this.method + " received no arguments, expected " +
2057
- sinon.format(this.expectedArguments));
2058
- }
2059
-
2060
- if (args.length < this.expectedArguments.length) {
2061
- sinon.expectation.fail(this.method + " received too few arguments (" + sinon.format(args) +
2062
- "), expected " + sinon.format(this.expectedArguments));
2063
- }
2064
-
2065
- if (this.expectsExactArgCount &&
2066
- args.length != this.expectedArguments.length) {
2067
- sinon.expectation.fail(this.method + " received too many arguments (" + sinon.format(args) +
2068
- "), expected " + sinon.format(this.expectedArguments));
2069
- }
2070
-
2071
- for (var i = 0, l = this.expectedArguments.length; i < l; i += 1) {
2072
-
2073
- if (!verifyMatcher(this.expectedArguments[i],args[i])) {
2074
- sinon.expectation.fail(this.method + " received wrong arguments " + sinon.format(args) +
2075
- ", didn't match " + this.expectedArguments.toString());
2076
- }
2077
-
2078
- if (!sinon.deepEqual(this.expectedArguments[i], args[i])) {
2079
- sinon.expectation.fail(this.method + " received wrong arguments " + sinon.format(args) +
2080
- ", expected " + sinon.format(this.expectedArguments));
2081
- }
2082
- }
2083
- },
2084
-
2085
- allowsCall: function allowsCall(thisValue, args) {
2086
- if (this.met() && receivedMaxCalls(this)) {
2087
- return false;
2088
- }
2089
-
2090
- if ("expectedThis" in this && this.expectedThis !== thisValue) {
2091
- return false;
2092
- }
2093
-
2094
- if (!("expectedArguments" in this)) {
2095
- return true;
2096
- }
2097
-
2098
- args = args || [];
2099
-
2100
- if (args.length < this.expectedArguments.length) {
2101
- return false;
2102
- }
2103
-
2104
- if (this.expectsExactArgCount &&
2105
- args.length != this.expectedArguments.length) {
2106
- return false;
2107
- }
2108
-
2109
- for (var i = 0, l = this.expectedArguments.length; i < l; i += 1) {
2110
- if (!verifyMatcher(this.expectedArguments[i],args[i])) {
2111
- return false;
2112
- }
2113
-
2114
- if (!sinon.deepEqual(this.expectedArguments[i], args[i])) {
2115
- return false;
2116
- }
2117
- }
2118
-
2119
- return true;
2120
- },
2121
-
2122
- withArgs: function withArgs() {
2123
- this.expectedArguments = slice.call(arguments);
2124
- return this;
2125
- },
2126
-
2127
- withExactArgs: function withExactArgs() {
2128
- this.withArgs.apply(this, arguments);
2129
- this.expectsExactArgCount = true;
2130
- return this;
2131
- },
2132
-
2133
- on: function on(thisValue) {
2134
- this.expectedThis = thisValue;
2135
- return this;
2136
- },
2137
-
2138
- toString: function () {
2139
- var args = (this.expectedArguments || []).slice();
2140
-
2141
- if (!this.expectsExactArgCount) {
2142
- push.call(args, "[...]");
2143
- }
2144
-
2145
- var callStr = sinon.spyCall.toString.call({
2146
- proxy: this.method || "anonymous mock expectation",
2147
- args: args
2148
- });
2149
-
2150
- var message = callStr.replace(", [...", "[, ...") + " " +
2151
- expectedCallCountInWords(this);
2152
-
2153
- if (this.met()) {
2154
- return "Expectation met: " + message;
2155
- }
2156
-
2157
- return "Expected " + message + " (" +
2158
- callCountInWords(this.callCount) + ")";
2159
- },
2160
-
2161
- verify: function verify() {
2162
- if (!this.met()) {
2163
- sinon.expectation.fail(this.toString());
2164
- } else {
2165
- sinon.expectation.pass(this.toString());
2166
- }
2167
-
2168
- return true;
2169
- },
2170
-
2171
- pass: function(message) {
2172
- sinon.assert.pass(message);
2173
- },
2174
- fail: function (message) {
2175
- var exception = new Error(message);
2176
- exception.name = "ExpectationError";
2177
-
2178
- throw exception;
2179
- }
2180
- };
2181
- }());
2182
-
2183
- if (commonJSModule) {
2184
- module.exports = mock;
2185
- } else {
2186
- sinon.mock = mock;
2187
- }
2188
- }(typeof sinon == "object" && sinon || null));
2189
-
2190
- /**
2191
- * @depend ../sinon.js
2192
- * @depend stub.js
2193
- * @depend mock.js
2194
- */
2195
- /*jslint eqeqeq: false, onevar: false, forin: true*/
2196
- /*global module, require, sinon*/
2197
- /**
2198
- * Collections of stubs, spies and mocks.
2199
- *
2200
- * @author Christian Johansen (christian@cjohansen.no)
2201
- * @license BSD
2202
- *
2203
- * Copyright (c) 2010-2013 Christian Johansen
2204
- */
2205
-
2206
- (function (sinon) {
2207
- var commonJSModule = typeof module !== 'undefined' && module.exports;
2208
- var push = [].push;
2209
- var hasOwnProperty = Object.prototype.hasOwnProperty;
2210
-
2211
- if (!sinon && commonJSModule) {
2212
- sinon = require("../sinon");
2213
- }
2214
-
2215
- if (!sinon) {
2216
- return;
2217
- }
2218
-
2219
- function getFakes(fakeCollection) {
2220
- if (!fakeCollection.fakes) {
2221
- fakeCollection.fakes = [];
2222
- }
2223
-
2224
- return fakeCollection.fakes;
2225
- }
2226
-
2227
- function each(fakeCollection, method) {
2228
- var fakes = getFakes(fakeCollection);
2229
-
2230
- for (var i = 0, l = fakes.length; i < l; i += 1) {
2231
- if (typeof fakes[i][method] == "function") {
2232
- fakes[i][method]();
2233
- }
2234
- }
2235
- }
2236
-
2237
- function compact(fakeCollection) {
2238
- var fakes = getFakes(fakeCollection);
2239
- var i = 0;
2240
- while (i < fakes.length) {
2241
- fakes.splice(i, 1);
2242
- }
2243
- }
2244
-
2245
- var collection = {
2246
- verify: function resolve() {
2247
- each(this, "verify");
2248
- },
2249
-
2250
- restore: function restore() {
2251
- each(this, "restore");
2252
- compact(this);
2253
- },
2254
-
2255
- verifyAndRestore: function verifyAndRestore() {
2256
- var exception;
2257
-
2258
- try {
2259
- this.verify();
2260
- } catch (e) {
2261
- exception = e;
2262
- }
2263
-
2264
- this.restore();
2265
-
2266
- if (exception) {
2267
- throw exception;
2268
- }
2269
- },
2270
-
2271
- add: function add(fake) {
2272
- push.call(getFakes(this), fake);
2273
- return fake;
2274
- },
2275
-
2276
- spy: function spy() {
2277
- return this.add(sinon.spy.apply(sinon, arguments));
2278
- },
2279
-
2280
- stub: function stub(object, property, value) {
2281
- if (property) {
2282
- var original = object[property];
2283
-
2284
- if (typeof original != "function") {
2285
- if (!hasOwnProperty.call(object, property)) {
2286
- throw new TypeError("Cannot stub non-existent own property " + property);
2287
- }
2288
-
2289
- object[property] = value;
2290
-
2291
- return this.add({
2292
- restore: function () {
2293
- object[property] = original;
2294
- }
2295
- });
2296
- }
2297
- }
2298
- if (!property && !!object && typeof object == "object") {
2299
- var stubbedObj = sinon.stub.apply(sinon, arguments);
2300
-
2301
- for (var prop in stubbedObj) {
2302
- if (typeof stubbedObj[prop] === "function") {
2303
- this.add(stubbedObj[prop]);
2304
- }
2305
- }
2306
-
2307
- return stubbedObj;
2308
- }
2309
-
2310
- return this.add(sinon.stub.apply(sinon, arguments));
2311
- },
2312
-
2313
- mock: function mock() {
2314
- return this.add(sinon.mock.apply(sinon, arguments));
2315
- },
2316
-
2317
- inject: function inject(obj) {
2318
- var col = this;
2319
-
2320
- obj.spy = function () {
2321
- return col.spy.apply(col, arguments);
2322
- };
2323
-
2324
- obj.stub = function () {
2325
- return col.stub.apply(col, arguments);
2326
- };
2327
-
2328
- obj.mock = function () {
2329
- return col.mock.apply(col, arguments);
2330
- };
2331
-
2332
- return obj;
2333
- }
2334
- };
2335
-
2336
- if (commonJSModule) {
2337
- module.exports = collection;
2338
- } else {
2339
- sinon.collection = collection;
2340
- }
2341
- }(typeof sinon == "object" && sinon || null));
2342
-
2343
- /*jslint eqeqeq: false, plusplus: false, evil: true, onevar: false, browser: true, forin: false*/
2344
- /*global module, require, window*/
2345
- /**
2346
- * Fake timer API
2347
- * setTimeout
2348
- * setInterval
2349
- * clearTimeout
2350
- * clearInterval
2351
- * tick
2352
- * reset
2353
- * Date
2354
- *
2355
- * Inspired by jsUnitMockTimeOut from JsUnit
2356
- *
2357
- * @author Christian Johansen (christian@cjohansen.no)
2358
- * @license BSD
2359
- *
2360
- * Copyright (c) 2010-2013 Christian Johansen
2361
- */
2362
-
2363
- if (typeof sinon == "undefined") {
2364
- var sinon = {};
2365
- }
2366
-
2367
- (function (global) {
2368
- var id = 1;
2369
-
2370
- function addTimer(args, recurring) {
2371
- if (args.length === 0) {
2372
- throw new Error("Function requires at least 1 parameter");
2373
- }
2374
-
2375
- var toId = id++;
2376
- var delay = args[1] || 0;
2377
-
2378
- if (!this.timeouts) {
2379
- this.timeouts = {};
2380
- }
2381
-
2382
- this.timeouts[toId] = {
2383
- id: toId,
2384
- func: args[0],
2385
- callAt: this.now + delay,
2386
- invokeArgs: Array.prototype.slice.call(args, 2)
2387
- };
2388
-
2389
- if (recurring === true) {
2390
- this.timeouts[toId].interval = delay;
2391
- }
2392
-
2393
- return toId;
2394
- }
2395
-
2396
- function parseTime(str) {
2397
- if (!str) {
2398
- return 0;
2399
- }
2400
-
2401
- var strings = str.split(":");
2402
- var l = strings.length, i = l;
2403
- var ms = 0, parsed;
2404
-
2405
- if (l > 3 || !/^(\d\d:){0,2}\d\d?$/.test(str)) {
2406
- throw new Error("tick only understands numbers and 'h:m:s'");
2407
- }
2408
-
2409
- while (i--) {
2410
- parsed = parseInt(strings[i], 10);
2411
-
2412
- if (parsed >= 60) {
2413
- throw new Error("Invalid time " + str);
2414
- }
2415
-
2416
- ms += parsed * Math.pow(60, (l - i - 1));
2417
- }
2418
-
2419
- return ms * 1000;
2420
- }
2421
-
2422
- function createObject(object) {
2423
- var newObject;
2424
-
2425
- if (Object.create) {
2426
- newObject = Object.create(object);
2427
- } else {
2428
- var F = function () {};
2429
- F.prototype = object;
2430
- newObject = new F();
2431
- }
2432
-
2433
- newObject.Date.clock = newObject;
2434
- return newObject;
2435
- }
2436
-
2437
- sinon.clock = {
2438
- now: 0,
2439
-
2440
- create: function create(now) {
2441
- var clock = createObject(this);
2442
-
2443
- if (typeof now == "number") {
2444
- clock.now = now;
2445
- }
2446
-
2447
- if (!!now && typeof now == "object") {
2448
- throw new TypeError("now should be milliseconds since UNIX epoch");
2449
- }
2450
-
2451
- return clock;
2452
- },
2453
-
2454
- setTimeout: function setTimeout(callback, timeout) {
2455
- return addTimer.call(this, arguments, false);
2456
- },
2457
-
2458
- clearTimeout: function clearTimeout(timerId) {
2459
- if (!this.timeouts) {
2460
- this.timeouts = [];
2461
- }
2462
-
2463
- if (timerId in this.timeouts) {
2464
- delete this.timeouts[timerId];
2465
- }
2466
- },
2467
-
2468
- setInterval: function setInterval(callback, timeout) {
2469
- return addTimer.call(this, arguments, true);
2470
- },
2471
-
2472
- clearInterval: function clearInterval(timerId) {
2473
- this.clearTimeout(timerId);
2474
- },
2475
-
2476
- tick: function tick(ms) {
2477
- ms = typeof ms == "number" ? ms : parseTime(ms);
2478
- var tickFrom = this.now, tickTo = this.now + ms, previous = this.now;
2479
- var timer = this.firstTimerInRange(tickFrom, tickTo);
2480
-
2481
- var firstException;
2482
- while (timer && tickFrom <= tickTo) {
2483
- if (this.timeouts[timer.id]) {
2484
- tickFrom = this.now = timer.callAt;
2485
- try {
2486
- this.callTimer(timer);
2487
- } catch (e) {
2488
- firstException = firstException || e;
2489
- }
2490
- }
2491
-
2492
- timer = this.firstTimerInRange(previous, tickTo);
2493
- previous = tickFrom;
2494
- }
2495
-
2496
- this.now = tickTo;
2497
-
2498
- if (firstException) {
2499
- throw firstException;
2500
- }
2501
-
2502
- return this.now;
2503
- },
2504
-
2505
- firstTimerInRange: function (from, to) {
2506
- var timer, smallest = null, originalTimer;
2507
-
2508
- for (var id in this.timeouts) {
2509
- if (this.timeouts.hasOwnProperty(id)) {
2510
- if (this.timeouts[id].callAt < from || this.timeouts[id].callAt > to) {
2511
- continue;
2512
- }
2513
-
2514
- if (smallest === null || this.timeouts[id].callAt < smallest) {
2515
- originalTimer = this.timeouts[id];
2516
- smallest = this.timeouts[id].callAt;
2517
-
2518
- timer = {
2519
- func: this.timeouts[id].func,
2520
- callAt: this.timeouts[id].callAt,
2521
- interval: this.timeouts[id].interval,
2522
- id: this.timeouts[id].id,
2523
- invokeArgs: this.timeouts[id].invokeArgs
2524
- };
2525
- }
2526
- }
2527
- }
2528
-
2529
- return timer || null;
2530
- },
2531
-
2532
- callTimer: function (timer) {
2533
- if (typeof timer.interval == "number") {
2534
- this.timeouts[timer.id].callAt += timer.interval;
2535
- } else {
2536
- delete this.timeouts[timer.id];
2537
- }
2538
-
2539
- try {
2540
- if (typeof timer.func == "function") {
2541
- timer.func.apply(null, timer.invokeArgs);
2542
- } else {
2543
- eval(timer.func);
2544
- }
2545
- } catch (e) {
2546
- var exception = e;
2547
- }
2548
-
2549
- if (!this.timeouts[timer.id]) {
2550
- if (exception) {
2551
- throw exception;
2552
- }
2553
- return;
2554
- }
2555
-
2556
- if (exception) {
2557
- throw exception;
2558
- }
2559
- },
2560
-
2561
- reset: function reset() {
2562
- this.timeouts = {};
2563
- },
2564
-
2565
- Date: (function () {
2566
- var NativeDate = Date;
2567
-
2568
- function ClockDate(year, month, date, hour, minute, second, ms) {
2569
- // Defensive and verbose to avoid potential harm in passing
2570
- // explicit undefined when user does not pass argument
2571
- switch (arguments.length) {
2572
- case 0:
2573
- return new NativeDate(ClockDate.clock.now);
2574
- case 1:
2575
- return new NativeDate(year);
2576
- case 2:
2577
- return new NativeDate(year, month);
2578
- case 3:
2579
- return new NativeDate(year, month, date);
2580
- case 4:
2581
- return new NativeDate(year, month, date, hour);
2582
- case 5:
2583
- return new NativeDate(year, month, date, hour, minute);
2584
- case 6:
2585
- return new NativeDate(year, month, date, hour, minute, second);
2586
- default:
2587
- return new NativeDate(year, month, date, hour, minute, second, ms);
2588
- }
2589
- }
2590
-
2591
- return mirrorDateProperties(ClockDate, NativeDate);
2592
- }())
2593
- };
2594
-
2595
- function mirrorDateProperties(target, source) {
2596
- if (source.now) {
2597
- target.now = function now() {
2598
- return target.clock.now;
2599
- };
2600
- } else {
2601
- delete target.now;
2602
- }
2603
-
2604
- if (source.toSource) {
2605
- target.toSource = function toSource() {
2606
- return source.toSource();
2607
- };
2608
- } else {
2609
- delete target.toSource;
2610
- }
2611
-
2612
- target.toString = function toString() {
2613
- return source.toString();
2614
- };
2615
-
2616
- target.prototype = source.prototype;
2617
- target.parse = source.parse;
2618
- target.UTC = source.UTC;
2619
- target.prototype.toUTCString = source.prototype.toUTCString;
2620
- return target;
2621
- }
2622
-
2623
- var methods = ["Date", "setTimeout", "setInterval",
2624
- "clearTimeout", "clearInterval"];
2625
-
2626
- function restore() {
2627
- var method;
2628
-
2629
- for (var i = 0, l = this.methods.length; i < l; i++) {
2630
- method = this.methods[i];
2631
- if (global[method].hadOwnProperty) {
2632
- global[method] = this["_" + method];
2633
- } else {
2634
- delete global[method];
2635
- }
2636
- }
2637
-
2638
- // Prevent multiple executions which will completely remove these props
2639
- this.methods = [];
2640
- }
2641
-
2642
- function stubGlobal(method, clock) {
2643
- clock[method].hadOwnProperty = Object.prototype.hasOwnProperty.call(global, method);
2644
- clock["_" + method] = global[method];
2645
-
2646
- if (method == "Date") {
2647
- var date = mirrorDateProperties(clock[method], global[method]);
2648
- global[method] = date;
2649
- } else {
2650
- global[method] = function () {
2651
- return clock[method].apply(clock, arguments);
2652
- };
2653
-
2654
- for (var prop in clock[method]) {
2655
- if (clock[method].hasOwnProperty(prop)) {
2656
- global[method][prop] = clock[method][prop];
2657
- }
2658
- }
2659
- }
2660
-
2661
- global[method].clock = clock;
2662
- }
2663
-
2664
- sinon.useFakeTimers = function useFakeTimers(now) {
2665
- var clock = sinon.clock.create(now);
2666
- clock.restore = restore;
2667
- clock.methods = Array.prototype.slice.call(arguments,
2668
- typeof now == "number" ? 1 : 0);
2669
-
2670
- if (clock.methods.length === 0) {
2671
- clock.methods = methods;
2672
- }
2673
-
2674
- for (var i = 0, l = clock.methods.length; i < l; i++) {
2675
- stubGlobal(clock.methods[i], clock);
2676
- }
2677
-
2678
- return clock;
2679
- };
2680
- }(typeof global != "undefined" && typeof global !== "function" ? global : this));
2681
-
2682
- sinon.timers = {
2683
- setTimeout: setTimeout,
2684
- clearTimeout: clearTimeout,
2685
- setInterval: setInterval,
2686
- clearInterval: clearInterval,
2687
- Date: Date
2688
- };
2689
-
2690
- if (typeof module !== 'undefined' && module.exports) {
2691
- module.exports = sinon;
2692
- }
2693
-
2694
- /*jslint eqeqeq: false, onevar: false*/
2695
- /*global sinon, module, require, ActiveXObject, XMLHttpRequest, DOMParser*/
2696
- /**
2697
- * Minimal Event interface implementation
2698
- *
2699
- * Original implementation by Sven Fuchs: https://gist.github.com/995028
2700
- * Modifications and tests by Christian Johansen.
2701
- *
2702
- * @author Sven Fuchs (svenfuchs@artweb-design.de)
2703
- * @author Christian Johansen (christian@cjohansen.no)
2704
- * @license BSD
2705
- *
2706
- * Copyright (c) 2011 Sven Fuchs, Christian Johansen
2707
- */
2708
-
2709
- if (typeof sinon == "undefined") {
2710
- this.sinon = {};
2711
- }
2712
-
2713
- (function () {
2714
- var push = [].push;
2715
-
2716
- sinon.Event = function Event(type, bubbles, cancelable, target) {
2717
- this.initEvent(type, bubbles, cancelable, target);
2718
- };
2719
-
2720
- sinon.Event.prototype = {
2721
- initEvent: function(type, bubbles, cancelable, target) {
2722
- this.type = type;
2723
- this.bubbles = bubbles;
2724
- this.cancelable = cancelable;
2725
- this.target = target;
2726
- },
2727
-
2728
- stopPropagation: function () {},
2729
-
2730
- preventDefault: function () {
2731
- this.defaultPrevented = true;
2732
- }
2733
- };
2734
-
2735
- sinon.EventTarget = {
2736
- addEventListener: function addEventListener(event, listener, useCapture) {
2737
- this.eventListeners = this.eventListeners || {};
2738
- this.eventListeners[event] = this.eventListeners[event] || [];
2739
- push.call(this.eventListeners[event], listener);
2740
- },
2741
-
2742
- removeEventListener: function removeEventListener(event, listener, useCapture) {
2743
- var listeners = this.eventListeners && this.eventListeners[event] || [];
2744
-
2745
- for (var i = 0, l = listeners.length; i < l; ++i) {
2746
- if (listeners[i] == listener) {
2747
- return listeners.splice(i, 1);
2748
- }
2749
- }
2750
- },
2751
-
2752
- dispatchEvent: function dispatchEvent(event) {
2753
- var type = event.type;
2754
- var listeners = this.eventListeners && this.eventListeners[type] || [];
2755
-
2756
- for (var i = 0; i < listeners.length; i++) {
2757
- if (typeof listeners[i] == "function") {
2758
- listeners[i].call(this, event);
2759
- } else {
2760
- listeners[i].handleEvent(event);
2761
- }
2762
- }
2763
-
2764
- return !!event.defaultPrevented;
2765
- }
2766
- };
2767
- }());
2768
-
2769
- /**
2770
- * @depend ../../sinon.js
2771
- * @depend event.js
2772
- */
2773
- /*jslint eqeqeq: false, onevar: false*/
2774
- /*global sinon, module, require, ActiveXObject, XMLHttpRequest, DOMParser*/
2775
- /**
2776
- * Fake XMLHttpRequest object
2777
- *
2778
- * @author Christian Johansen (christian@cjohansen.no)
2779
- * @license BSD
2780
- *
2781
- * Copyright (c) 2010-2013 Christian Johansen
2782
- */
2783
-
2784
- // wrapper for global
2785
- (function(global) {
2786
-
2787
- if (typeof sinon === "undefined") {
2788
- global.sinon = {};
2789
- }
2790
- sinon.xhr = { XMLHttpRequest: global.XMLHttpRequest };
2791
-
2792
- var xhr = sinon.xhr;
2793
- xhr.GlobalXMLHttpRequest = global.XMLHttpRequest;
2794
- xhr.GlobalActiveXObject = global.ActiveXObject;
2795
- xhr.supportsActiveX = typeof xhr.GlobalActiveXObject != "undefined";
2796
- xhr.supportsXHR = typeof xhr.GlobalXMLHttpRequest != "undefined";
2797
- xhr.workingXHR = xhr.supportsXHR ? xhr.GlobalXMLHttpRequest : xhr.supportsActiveX
2798
- ? function() { return new xhr.GlobalActiveXObject("MSXML2.XMLHTTP.3.0") } : false;
2799
-
2800
- /*jsl:ignore*/
2801
- var unsafeHeaders = {
2802
- "Accept-Charset": true,
2803
- "Accept-Encoding": true,
2804
- "Connection": true,
2805
- "Content-Length": true,
2806
- "Cookie": true,
2807
- "Cookie2": true,
2808
- "Content-Transfer-Encoding": true,
2809
- "Date": true,
2810
- "Expect": true,
2811
- "Host": true,
2812
- "Keep-Alive": true,
2813
- "Referer": true,
2814
- "TE": true,
2815
- "Trailer": true,
2816
- "Transfer-Encoding": true,
2817
- "Upgrade": true,
2818
- "User-Agent": true,
2819
- "Via": true
2820
- };
2821
- /*jsl:end*/
2822
-
2823
- function FakeXMLHttpRequest() {
2824
- this.readyState = FakeXMLHttpRequest.UNSENT;
2825
- this.requestHeaders = {};
2826
- this.requestBody = null;
2827
- this.status = 0;
2828
- this.statusText = "";
2829
- this.upload = new UploadProgress();
2830
-
2831
- var xhr = this;
2832
- var events = ["loadstart", "load", "abort", "loadend"];
2833
-
2834
- function addEventListener(eventName) {
2835
- xhr.addEventListener(eventName, function (event) {
2836
- var listener = xhr["on" + eventName];
2837
-
2838
- if (listener && typeof listener == "function") {
2839
- listener(event);
2840
- }
2841
- });
2842
- }
2843
-
2844
- for (var i = events.length - 1; i >= 0; i--) {
2845
- addEventListener(events[i]);
2846
- }
2847
-
2848
- if (typeof FakeXMLHttpRequest.onCreate == "function") {
2849
- FakeXMLHttpRequest.onCreate(this);
2850
- }
2851
- }
2852
-
2853
- // An upload object is created for each
2854
- // FakeXMLHttpRequest and allows upload
2855
- // events to be simulated using uploadProgress
2856
- // and uploadError.
2857
- function UploadProgress() {
2858
- this.eventListeners = {
2859
- "progress": [],
2860
- "load": [],
2861
- "abort": [],
2862
- "error": []
2863
- }
2864
- };
2865
-
2866
- UploadProgress.prototype.addEventListener = function(listenerName, callback) {
2867
- this.eventListeners[listenerName].push(callback);
2868
- };
2869
-
2870
- UploadProgress.prototype.dispatchEvent = function(event) {
2871
- var listeners = this.eventListeners[event.type] || [];
2872
-
2873
- for (var i = 0, listener; (listener = listeners[i]) != null; i++) {
2874
- listener(event);
2875
- }
2876
- };
2877
-
2878
- function verifyState(xhr) {
2879
- if (xhr.readyState !== FakeXMLHttpRequest.OPENED) {
2880
- throw new Error("INVALID_STATE_ERR");
2881
- }
2882
-
2883
- if (xhr.sendFlag) {
2884
- throw new Error("INVALID_STATE_ERR");
2885
- }
2886
- }
2887
-
2888
- // filtering to enable a white-list version of Sinon FakeXhr,
2889
- // where whitelisted requests are passed through to real XHR
2890
- function each(collection, callback) {
2891
- if (!collection) return;
2892
- for (var i = 0, l = collection.length; i < l; i += 1) {
2893
- callback(collection[i]);
2894
- }
2895
- }
2896
- function some(collection, callback) {
2897
- for (var index = 0; index < collection.length; index++) {
2898
- if(callback(collection[index]) === true) return true;
2899
- };
2900
- return false;
2901
- }
2902
- // largest arity in XHR is 5 - XHR#open
2903
- var apply = function(obj,method,args) {
2904
- switch(args.length) {
2905
- case 0: return obj[method]();
2906
- case 1: return obj[method](args[0]);
2907
- case 2: return obj[method](args[0],args[1]);
2908
- case 3: return obj[method](args[0],args[1],args[2]);
2909
- case 4: return obj[method](args[0],args[1],args[2],args[3]);
2910
- case 5: return obj[method](args[0],args[1],args[2],args[3],args[4]);
2911
- };
2912
- };
2913
-
2914
- FakeXMLHttpRequest.filters = [];
2915
- FakeXMLHttpRequest.addFilter = function(fn) {
2916
- this.filters.push(fn)
2917
- };
2918
- var IE6Re = /MSIE 6/;
2919
- FakeXMLHttpRequest.defake = function(fakeXhr,xhrArgs) {
2920
- var xhr = new sinon.xhr.workingXHR();
2921
- each(["open","setRequestHeader","send","abort","getResponseHeader",
2922
- "getAllResponseHeaders","addEventListener","overrideMimeType","removeEventListener"],
2923
- function(method) {
2924
- fakeXhr[method] = function() {
2925
- return apply(xhr,method,arguments);
2926
- };
2927
- });
2928
-
2929
- var copyAttrs = function(args) {
2930
- each(args, function(attr) {
2931
- try {
2932
- fakeXhr[attr] = xhr[attr]
2933
- } catch(e) {
2934
- if(!IE6Re.test(navigator.userAgent)) throw e;
2935
- }
2936
- });
2937
- };
2938
-
2939
- var stateChange = function() {
2940
- fakeXhr.readyState = xhr.readyState;
2941
- if(xhr.readyState >= FakeXMLHttpRequest.HEADERS_RECEIVED) {
2942
- copyAttrs(["status","statusText"]);
2943
- }
2944
- if(xhr.readyState >= FakeXMLHttpRequest.LOADING) {
2945
- copyAttrs(["responseText"]);
2946
- }
2947
- if(xhr.readyState === FakeXMLHttpRequest.DONE) {
2948
- copyAttrs(["responseXML"]);
2949
- }
2950
- if(fakeXhr.onreadystatechange) fakeXhr.onreadystatechange.call(fakeXhr);
2951
- };
2952
- if(xhr.addEventListener) {
2953
- for(var event in fakeXhr.eventListeners) {
2954
- if(fakeXhr.eventListeners.hasOwnProperty(event)) {
2955
- each(fakeXhr.eventListeners[event],function(handler) {
2956
- xhr.addEventListener(event, handler);
2957
- });
2958
- }
2959
- }
2960
- xhr.addEventListener("readystatechange",stateChange);
2961
- } else {
2962
- xhr.onreadystatechange = stateChange;
2963
- }
2964
- apply(xhr,"open",xhrArgs);
2965
- };
2966
- FakeXMLHttpRequest.useFilters = false;
2967
-
2968
- function verifyRequestSent(xhr) {
2969
- if (xhr.readyState == FakeXMLHttpRequest.DONE) {
2970
- throw new Error("Request done");
2971
- }
2972
- }
2973
-
2974
- function verifyHeadersReceived(xhr) {
2975
- if (xhr.async && xhr.readyState != FakeXMLHttpRequest.HEADERS_RECEIVED) {
2976
- throw new Error("No headers received");
2977
- }
2978
- }
2979
-
2980
- function verifyResponseBodyType(body) {
2981
- if (typeof body != "string") {
2982
- var error = new Error("Attempted to respond to fake XMLHttpRequest with " +
2983
- body + ", which is not a string.");
2984
- error.name = "InvalidBodyException";
2985
- throw error;
2986
- }
2987
- }
2988
-
2989
- sinon.extend(FakeXMLHttpRequest.prototype, sinon.EventTarget, {
2990
- async: true,
2991
-
2992
- open: function open(method, url, async, username, password) {
2993
- this.method = method;
2994
- this.url = url;
2995
- this.async = typeof async == "boolean" ? async : true;
2996
- this.username = username;
2997
- this.password = password;
2998
- this.responseText = null;
2999
- this.responseXML = null;
3000
- this.requestHeaders = {};
3001
- this.sendFlag = false;
3002
- if(sinon.FakeXMLHttpRequest.useFilters === true) {
3003
- var xhrArgs = arguments;
3004
- var defake = some(FakeXMLHttpRequest.filters,function(filter) {
3005
- return filter.apply(this,xhrArgs)
3006
- });
3007
- if (defake) {
3008
- return sinon.FakeXMLHttpRequest.defake(this,arguments);
3009
- }
3010
- }
3011
- this.readyStateChange(FakeXMLHttpRequest.OPENED);
3012
- },
3013
-
3014
- readyStateChange: function readyStateChange(state) {
3015
- this.readyState = state;
3016
-
3017
- if (typeof this.onreadystatechange == "function") {
3018
- try {
3019
- this.onreadystatechange();
3020
- } catch (e) {
3021
- sinon.logError("Fake XHR onreadystatechange handler", e);
3022
- }
3023
- }
3024
-
3025
- this.dispatchEvent(new sinon.Event("readystatechange"));
3026
-
3027
- switch (this.readyState) {
3028
- case FakeXMLHttpRequest.DONE:
3029
- this.dispatchEvent(new sinon.Event("load", false, false, this));
3030
- this.dispatchEvent(new sinon.Event("loadend", false, false, this));
3031
- this.upload.dispatchEvent(new sinon.Event("load", false, false, this));
3032
- this.upload.dispatchEvent(new ProgressEvent("progress", {loaded: 100, total: 100}));
3033
- break;
3034
- }
3035
- },
3036
-
3037
- setRequestHeader: function setRequestHeader(header, value) {
3038
- verifyState(this);
3039
-
3040
- if (unsafeHeaders[header] || /^(Sec-|Proxy-)/.test(header)) {
3041
- throw new Error("Refused to set unsafe header \"" + header + "\"");
3042
- }
3043
-
3044
- if (this.requestHeaders[header]) {
3045
- this.requestHeaders[header] += "," + value;
3046
- } else {
3047
- this.requestHeaders[header] = value;
3048
- }
3049
- },
3050
-
3051
- // Helps testing
3052
- setResponseHeaders: function setResponseHeaders(headers) {
3053
- this.responseHeaders = {};
3054
-
3055
- for (var header in headers) {
3056
- if (headers.hasOwnProperty(header)) {
3057
- this.responseHeaders[header] = headers[header];
3058
- }
3059
- }
3060
-
3061
- if (this.async) {
3062
- this.readyStateChange(FakeXMLHttpRequest.HEADERS_RECEIVED);
3063
- } else {
3064
- this.readyState = FakeXMLHttpRequest.HEADERS_RECEIVED;
3065
- }
3066
- },
3067
-
3068
- // Currently treats ALL data as a DOMString (i.e. no Document)
3069
- send: function send(data) {
3070
- verifyState(this);
3071
-
3072
- if (!/^(get|head)$/i.test(this.method)) {
3073
- if (this.requestHeaders["Content-Type"]) {
3074
- var value = this.requestHeaders["Content-Type"].split(";");
3075
- this.requestHeaders["Content-Type"] = value[0] + ";charset=utf-8";
3076
- } else {
3077
- this.requestHeaders["Content-Type"] = "text/plain;charset=utf-8";
3078
- }
3079
-
3080
- this.requestBody = data;
3081
- }
3082
-
3083
- this.errorFlag = false;
3084
- this.sendFlag = this.async;
3085
- this.readyStateChange(FakeXMLHttpRequest.OPENED);
3086
-
3087
- if (typeof this.onSend == "function") {
3088
- this.onSend(this);
3089
- }
3090
-
3091
- this.dispatchEvent(new sinon.Event("loadstart", false, false, this));
3092
- },
3093
-
3094
- abort: function abort() {
3095
- this.aborted = true;
3096
- this.responseText = null;
3097
- this.errorFlag = true;
3098
- this.requestHeaders = {};
3099
-
3100
- if (this.readyState > sinon.FakeXMLHttpRequest.UNSENT && this.sendFlag) {
3101
- this.readyStateChange(sinon.FakeXMLHttpRequest.DONE);
3102
- this.sendFlag = false;
3103
- }
3104
-
3105
- this.readyState = sinon.FakeXMLHttpRequest.UNSENT;
3106
-
3107
- this.dispatchEvent(new sinon.Event("abort", false, false, this));
3108
-
3109
- this.upload.dispatchEvent(new sinon.Event("abort", false, false, this));
3110
-
3111
- if (typeof this.onerror === "function") {
3112
- this.onerror();
3113
- }
3114
- },
3115
-
3116
- getResponseHeader: function getResponseHeader(header) {
3117
- if (this.readyState < FakeXMLHttpRequest.HEADERS_RECEIVED) {
3118
- return null;
3119
- }
3120
-
3121
- if (/^Set-Cookie2?$/i.test(header)) {
3122
- return null;
3123
- }
3124
-
3125
- header = header.toLowerCase();
3126
-
3127
- for (var h in this.responseHeaders) {
3128
- if (h.toLowerCase() == header) {
3129
- return this.responseHeaders[h];
3130
- }
3131
- }
3132
-
3133
- return null;
3134
- },
3135
-
3136
- getAllResponseHeaders: function getAllResponseHeaders() {
3137
- if (this.readyState < FakeXMLHttpRequest.HEADERS_RECEIVED) {
3138
- return "";
3139
- }
3140
-
3141
- var headers = "";
3142
-
3143
- for (var header in this.responseHeaders) {
3144
- if (this.responseHeaders.hasOwnProperty(header) &&
3145
- !/^Set-Cookie2?$/i.test(header)) {
3146
- headers += header + ": " + this.responseHeaders[header] + "\r\n";
3147
- }
3148
- }
3149
-
3150
- return headers;
3151
- },
3152
-
3153
- setResponseBody: function setResponseBody(body) {
3154
- verifyRequestSent(this);
3155
- verifyHeadersReceived(this);
3156
- verifyResponseBodyType(body);
3157
-
3158
- var chunkSize = this.chunkSize || 10;
3159
- var index = 0;
3160
- this.responseText = "";
3161
-
3162
- do {
3163
- if (this.async) {
3164
- this.readyStateChange(FakeXMLHttpRequest.LOADING);
3165
- }
3166
-
3167
- this.responseText += body.substring(index, index + chunkSize);
3168
- index += chunkSize;
3169
- } while (index < body.length);
3170
-
3171
- var type = this.getResponseHeader("Content-Type");
3172
-
3173
- if (this.responseText &&
3174
- (!type || /(text\/xml)|(application\/xml)|(\+xml)/.test(type))) {
3175
- try {
3176
- this.responseXML = FakeXMLHttpRequest.parseXML(this.responseText);
3177
- } catch (e) {
3178
- // Unable to parse XML - no biggie
3179
- }
3180
- }
3181
-
3182
- if (this.async) {
3183
- this.readyStateChange(FakeXMLHttpRequest.DONE);
3184
- } else {
3185
- this.readyState = FakeXMLHttpRequest.DONE;
3186
- }
3187
- },
3188
-
3189
- respond: function respond(status, headers, body) {
3190
- this.setResponseHeaders(headers || {});
3191
- this.status = typeof status == "number" ? status : 200;
3192
- this.statusText = FakeXMLHttpRequest.statusCodes[this.status];
3193
- this.setResponseBody(body || "");
3194
- },
3195
-
3196
- uploadProgress: function uploadProgress(progressEventRaw) {
3197
- this.upload.dispatchEvent(new ProgressEvent("progress", progressEventRaw));
3198
- },
3199
-
3200
- uploadError: function uploadError(error) {
3201
- this.upload.dispatchEvent(new CustomEvent("error", {"detail": error}));
3202
- }
3203
- });
3204
-
3205
- sinon.extend(FakeXMLHttpRequest, {
3206
- UNSENT: 0,
3207
- OPENED: 1,
3208
- HEADERS_RECEIVED: 2,
3209
- LOADING: 3,
3210
- DONE: 4
3211
- });
3212
-
3213
- // Borrowed from JSpec
3214
- FakeXMLHttpRequest.parseXML = function parseXML(text) {
3215
- var xmlDoc;
3216
-
3217
- if (typeof DOMParser != "undefined") {
3218
- var parser = new DOMParser();
3219
- xmlDoc = parser.parseFromString(text, "text/xml");
3220
- } else {
3221
- xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
3222
- xmlDoc.async = "false";
3223
- xmlDoc.loadXML(text);
3224
- }
3225
-
3226
- return xmlDoc;
3227
- };
3228
-
3229
- FakeXMLHttpRequest.statusCodes = {
3230
- 100: "Continue",
3231
- 101: "Switching Protocols",
3232
- 200: "OK",
3233
- 201: "Created",
3234
- 202: "Accepted",
3235
- 203: "Non-Authoritative Information",
3236
- 204: "No Content",
3237
- 205: "Reset Content",
3238
- 206: "Partial Content",
3239
- 300: "Multiple Choice",
3240
- 301: "Moved Permanently",
3241
- 302: "Found",
3242
- 303: "See Other",
3243
- 304: "Not Modified",
3244
- 305: "Use Proxy",
3245
- 307: "Temporary Redirect",
3246
- 400: "Bad Request",
3247
- 401: "Unauthorized",
3248
- 402: "Payment Required",
3249
- 403: "Forbidden",
3250
- 404: "Not Found",
3251
- 405: "Method Not Allowed",
3252
- 406: "Not Acceptable",
3253
- 407: "Proxy Authentication Required",
3254
- 408: "Request Timeout",
3255
- 409: "Conflict",
3256
- 410: "Gone",
3257
- 411: "Length Required",
3258
- 412: "Precondition Failed",
3259
- 413: "Request Entity Too Large",
3260
- 414: "Request-URI Too Long",
3261
- 415: "Unsupported Media Type",
3262
- 416: "Requested Range Not Satisfiable",
3263
- 417: "Expectation Failed",
3264
- 422: "Unprocessable Entity",
3265
- 500: "Internal Server Error",
3266
- 501: "Not Implemented",
3267
- 502: "Bad Gateway",
3268
- 503: "Service Unavailable",
3269
- 504: "Gateway Timeout",
3270
- 505: "HTTP Version Not Supported"
3271
- };
3272
-
3273
- sinon.useFakeXMLHttpRequest = function () {
3274
- sinon.FakeXMLHttpRequest.restore = function restore(keepOnCreate) {
3275
- if (xhr.supportsXHR) {
3276
- global.XMLHttpRequest = xhr.GlobalXMLHttpRequest;
3277
- }
3278
-
3279
- if (xhr.supportsActiveX) {
3280
- global.ActiveXObject = xhr.GlobalActiveXObject;
3281
- }
3282
-
3283
- delete sinon.FakeXMLHttpRequest.restore;
3284
-
3285
- if (keepOnCreate !== true) {
3286
- delete sinon.FakeXMLHttpRequest.onCreate;
3287
- }
3288
- };
3289
- if (xhr.supportsXHR) {
3290
- global.XMLHttpRequest = sinon.FakeXMLHttpRequest;
3291
- }
3292
-
3293
- if (xhr.supportsActiveX) {
3294
- global.ActiveXObject = function ActiveXObject(objId) {
3295
- if (objId == "Microsoft.XMLHTTP" || /^Msxml2\.XMLHTTP/i.test(objId)) {
3296
-
3297
- return new sinon.FakeXMLHttpRequest();
3298
- }
3299
-
3300
- return new xhr.GlobalActiveXObject(objId);
3301
- };
3302
- }
3303
-
3304
- return sinon.FakeXMLHttpRequest;
3305
- };
3306
-
3307
- sinon.FakeXMLHttpRequest = FakeXMLHttpRequest;
3308
-
3309
- })(typeof global === "object" ? global : this);
3310
-
3311
- if (typeof module !== 'undefined' && module.exports) {
3312
- module.exports = sinon;
3313
- }
3314
-
3315
- /**
3316
- * @depend fake_xml_http_request.js
3317
- */
3318
- /*jslint eqeqeq: false, onevar: false, regexp: false, plusplus: false*/
3319
- /*global module, require, window*/
3320
- /**
3321
- * The Sinon "server" mimics a web server that receives requests from
3322
- * sinon.FakeXMLHttpRequest and provides an API to respond to those requests,
3323
- * both synchronously and asynchronously. To respond synchronuously, canned
3324
- * answers have to be provided upfront.
3325
- *
3326
- * @author Christian Johansen (christian@cjohansen.no)
3327
- * @license BSD
3328
- *
3329
- * Copyright (c) 2010-2013 Christian Johansen
3330
- */
3331
-
3332
- if (typeof sinon == "undefined") {
3333
- var sinon = {};
3334
- }
3335
-
3336
- sinon.fakeServer = (function () {
3337
- var push = [].push;
3338
- function F() {}
3339
-
3340
- function create(proto) {
3341
- F.prototype = proto;
3342
- return new F();
3343
- }
3344
-
3345
- function responseArray(handler) {
3346
- var response = handler;
3347
-
3348
- if (Object.prototype.toString.call(handler) != "[object Array]") {
3349
- response = [200, {}, handler];
3350
- }
3351
-
3352
- if (typeof response[2] != "string") {
3353
- throw new TypeError("Fake server response body should be string, but was " +
3354
- typeof response[2]);
3355
- }
3356
-
3357
- return response;
3358
- }
3359
-
3360
- var wloc = typeof window !== "undefined" ? window.location : {};
3361
- var rCurrLoc = new RegExp("^" + wloc.protocol + "//" + wloc.host);
3362
-
3363
- function matchOne(response, reqMethod, reqUrl) {
3364
- var rmeth = response.method;
3365
- var matchMethod = !rmeth || rmeth.toLowerCase() == reqMethod.toLowerCase();
3366
- var url = response.url;
3367
- var matchUrl = !url || url == reqUrl || (typeof url.test == "function" && url.test(reqUrl));
3368
-
3369
- return matchMethod && matchUrl;
3370
- }
3371
-
3372
- function match(response, request) {
3373
- var requestMethod = this.getHTTPMethod(request);
3374
- var requestUrl = request.url;
3375
-
3376
- if (!/^https?:\/\//.test(requestUrl) || rCurrLoc.test(requestUrl)) {
3377
- requestUrl = requestUrl.replace(rCurrLoc, "");
3378
- }
3379
-
3380
- if (matchOne(response, this.getHTTPMethod(request), requestUrl)) {
3381
- if (typeof response.response == "function") {
3382
- var ru = response.url;
3383
- var args = [request].concat(ru && typeof ru.exec == "function" ? ru.exec(requestUrl).slice(1) : []);
3384
- return response.response.apply(response, args);
3385
- }
3386
-
3387
- return true;
3388
- }
3389
-
3390
- return false;
3391
- }
3392
-
3393
- function log(response, request) {
3394
- var str;
3395
-
3396
- str = "Request:\n" + sinon.format(request) + "\n\n";
3397
- str += "Response:\n" + sinon.format(response) + "\n\n";
3398
-
3399
- sinon.log(str);
3400
- }
3401
-
3402
- return {
3403
- create: function () {
3404
- var server = create(this);
3405
- this.xhr = sinon.useFakeXMLHttpRequest();
3406
- server.requests = [];
3407
-
3408
- this.xhr.onCreate = function (xhrObj) {
3409
- server.addRequest(xhrObj);
3410
- };
3411
-
3412
- return server;
3413
- },
3414
-
3415
- addRequest: function addRequest(xhrObj) {
3416
- var server = this;
3417
- push.call(this.requests, xhrObj);
3418
-
3419
- xhrObj.onSend = function () {
3420
- server.handleRequest(this);
3421
-
3422
- if (server.autoRespond && !server.responding) {
3423
- setTimeout(function () {
3424
- server.responding = false;
3425
- server.respond();
3426
- }, server.autoRespondAfter || 10);
3427
-
3428
- server.responding = true;
3429
- }
3430
- };
3431
- },
3432
-
3433
- getHTTPMethod: function getHTTPMethod(request) {
3434
- if (this.fakeHTTPMethods && /post/i.test(request.method)) {
3435
- var matches = (request.requestBody || "").match(/_method=([^\b;]+)/);
3436
- return !!matches ? matches[1] : request.method;
3437
- }
3438
-
3439
- return request.method;
3440
- },
3441
-
3442
- handleRequest: function handleRequest(xhr) {
3443
- if (xhr.async) {
3444
- if (!this.queue) {
3445
- this.queue = [];
3446
- }
3447
-
3448
- push.call(this.queue, xhr);
3449
- } else {
3450
- this.processRequest(xhr);
3451
- }
3452
- },
3453
-
3454
- respondWith: function respondWith(method, url, body) {
3455
- if (arguments.length == 1 && typeof method != "function") {
3456
- this.response = responseArray(method);
3457
- return;
3458
- }
3459
-
3460
- if (!this.responses) { this.responses = []; }
3461
-
3462
- if (arguments.length == 1) {
3463
- body = method;
3464
- url = method = null;
3465
- }
3466
-
3467
- if (arguments.length == 2) {
3468
- body = url;
3469
- url = method;
3470
- method = null;
3471
- }
3472
-
3473
- push.call(this.responses, {
3474
- method: method,
3475
- url: url,
3476
- response: typeof body == "function" ? body : responseArray(body)
3477
- });
3478
- },
3479
-
3480
- respond: function respond() {
3481
- if (arguments.length > 0) this.respondWith.apply(this, arguments);
3482
- var queue = this.queue || [];
3483
- var request;
3484
-
3485
- while(request = queue.shift()) {
3486
- this.processRequest(request);
3487
- }
3488
- },
3489
-
3490
- processRequest: function processRequest(request) {
3491
- try {
3492
- if (request.aborted) {
3493
- return;
3494
- }
3495
-
3496
- var response = this.response || [404, {}, ""];
3497
-
3498
- if (this.responses) {
3499
- for (var i = 0, l = this.responses.length; i < l; i++) {
3500
- if (match.call(this, this.responses[i], request)) {
3501
- response = this.responses[i].response;
3502
- break;
3503
- }
3504
- }
3505
- }
3506
-
3507
- if (request.readyState != 4) {
3508
- log(response, request);
3509
-
3510
- request.respond(response[0], response[1], response[2]);
3511
- }
3512
- } catch (e) {
3513
- sinon.logError("Fake server request processing", e);
3514
- }
3515
- },
3516
-
3517
- restore: function restore() {
3518
- return this.xhr.restore && this.xhr.restore.apply(this.xhr, arguments);
3519
- }
3520
- };
3521
- }());
3522
-
3523
- if (typeof module !== 'undefined' && module.exports) {
3524
- module.exports = sinon;
3525
- }
3526
-
3527
- /**
3528
- * @depend fake_server.js
3529
- * @depend fake_timers.js
3530
- */
3531
- /*jslint browser: true, eqeqeq: false, onevar: false*/
3532
- /*global sinon*/
3533
- /**
3534
- * Add-on for sinon.fakeServer that automatically handles a fake timer along with
3535
- * the FakeXMLHttpRequest. The direct inspiration for this add-on is jQuery
3536
- * 1.3.x, which does not use xhr object's onreadystatehandler at all - instead,
3537
- * it polls the object for completion with setInterval. Dispite the direct
3538
- * motivation, there is nothing jQuery-specific in this file, so it can be used
3539
- * in any environment where the ajax implementation depends on setInterval or
3540
- * setTimeout.
3541
- *
3542
- * @author Christian Johansen (christian@cjohansen.no)
3543
- * @license BSD
3544
- *
3545
- * Copyright (c) 2010-2013 Christian Johansen
3546
- */
3547
-
3548
- (function () {
3549
- function Server() {}
3550
- Server.prototype = sinon.fakeServer;
3551
-
3552
- sinon.fakeServerWithClock = new Server();
3553
-
3554
- sinon.fakeServerWithClock.addRequest = function addRequest(xhr) {
3555
- if (xhr.async) {
3556
- if (typeof setTimeout.clock == "object") {
3557
- this.clock = setTimeout.clock;
3558
- } else {
3559
- this.clock = sinon.useFakeTimers();
3560
- this.resetClock = true;
3561
- }
3562
-
3563
- if (!this.longestTimeout) {
3564
- var clockSetTimeout = this.clock.setTimeout;
3565
- var clockSetInterval = this.clock.setInterval;
3566
- var server = this;
3567
-
3568
- this.clock.setTimeout = function (fn, timeout) {
3569
- server.longestTimeout = Math.max(timeout, server.longestTimeout || 0);
3570
-
3571
- return clockSetTimeout.apply(this, arguments);
3572
- };
3573
-
3574
- this.clock.setInterval = function (fn, timeout) {
3575
- server.longestTimeout = Math.max(timeout, server.longestTimeout || 0);
3576
-
3577
- return clockSetInterval.apply(this, arguments);
3578
- };
3579
- }
3580
- }
3581
-
3582
- return sinon.fakeServer.addRequest.call(this, xhr);
3583
- };
3584
-
3585
- sinon.fakeServerWithClock.respond = function respond() {
3586
- var returnVal = sinon.fakeServer.respond.apply(this, arguments);
3587
-
3588
- if (this.clock) {
3589
- this.clock.tick(this.longestTimeout || 0);
3590
- this.longestTimeout = 0;
3591
-
3592
- if (this.resetClock) {
3593
- this.clock.restore();
3594
- this.resetClock = false;
3595
- }
3596
- }
3597
-
3598
- return returnVal;
3599
- };
3600
-
3601
- sinon.fakeServerWithClock.restore = function restore() {
3602
- if (this.clock) {
3603
- this.clock.restore();
3604
- }
3605
-
3606
- return sinon.fakeServer.restore.apply(this, arguments);
3607
- };
3608
- }());
3609
-
3610
- /**
3611
- * @depend ../sinon.js
3612
- * @depend collection.js
3613
- * @depend util/fake_timers.js
3614
- * @depend util/fake_server_with_clock.js
3615
- */
3616
- /*jslint eqeqeq: false, onevar: false, plusplus: false*/
3617
- /*global require, module*/
3618
- /**
3619
- * Manages fake collections as well as fake utilities such as Sinon's
3620
- * timers and fake XHR implementation in one convenient object.
3621
- *
3622
- * @author Christian Johansen (christian@cjohansen.no)
3623
- * @license BSD
3624
- *
3625
- * Copyright (c) 2010-2013 Christian Johansen
3626
- */
3627
-
3628
- if (typeof module !== 'undefined' && module.exports) {
3629
- var sinon = require("../sinon");
3630
- sinon.extend(sinon, require("./util/fake_timers"));
3631
- }
3632
-
3633
- (function () {
3634
- var push = [].push;
3635
-
3636
- function exposeValue(sandbox, config, key, value) {
3637
- if (!value) {
3638
- return;
3639
- }
3640
-
3641
- if (config.injectInto) {
3642
- config.injectInto[key] = value;
3643
- } else {
3644
- push.call(sandbox.args, value);
3645
- }
3646
- }
3647
-
3648
- function prepareSandboxFromConfig(config) {
3649
- var sandbox = sinon.create(sinon.sandbox);
3650
-
3651
- if (config.useFakeServer) {
3652
- if (typeof config.useFakeServer == "object") {
3653
- sandbox.serverPrototype = config.useFakeServer;
3654
- }
3655
-
3656
- sandbox.useFakeServer();
3657
- }
3658
-
3659
- if (config.useFakeTimers) {
3660
- if (typeof config.useFakeTimers == "object") {
3661
- sandbox.useFakeTimers.apply(sandbox, config.useFakeTimers);
3662
- } else {
3663
- sandbox.useFakeTimers();
3664
- }
3665
- }
3666
-
3667
- return sandbox;
3668
- }
3669
-
3670
- sinon.sandbox = sinon.extend(sinon.create(sinon.collection), {
3671
- useFakeTimers: function useFakeTimers() {
3672
- this.clock = sinon.useFakeTimers.apply(sinon, arguments);
3673
-
3674
- return this.add(this.clock);
3675
- },
3676
-
3677
- serverPrototype: sinon.fakeServer,
3678
-
3679
- useFakeServer: function useFakeServer() {
3680
- var proto = this.serverPrototype || sinon.fakeServer;
3681
-
3682
- if (!proto || !proto.create) {
3683
- return null;
3684
- }
3685
-
3686
- this.server = proto.create();
3687
- return this.add(this.server);
3688
- },
3689
-
3690
- inject: function (obj) {
3691
- sinon.collection.inject.call(this, obj);
3692
-
3693
- if (this.clock) {
3694
- obj.clock = this.clock;
3695
- }
3696
-
3697
- if (this.server) {
3698
- obj.server = this.server;
3699
- obj.requests = this.server.requests;
3700
- }
3701
-
3702
- return obj;
3703
- },
3704
-
3705
- create: function (config) {
3706
- if (!config) {
3707
- return sinon.create(sinon.sandbox);
3708
- }
3709
-
3710
- var sandbox = prepareSandboxFromConfig(config);
3711
- sandbox.args = sandbox.args || [];
3712
- var prop, value, exposed = sandbox.inject({});
3713
-
3714
- if (config.properties) {
3715
- for (var i = 0, l = config.properties.length; i < l; i++) {
3716
- prop = config.properties[i];
3717
- value = exposed[prop] || prop == "sandbox" && sandbox;
3718
- exposeValue(sandbox, config, prop, value);
3719
- }
3720
- } else {
3721
- exposeValue(sandbox, config, "sandbox", value);
3722
- }
3723
-
3724
- return sandbox;
3725
- }
3726
- });
3727
-
3728
- sinon.sandbox.useFakeXMLHttpRequest = sinon.sandbox.useFakeServer;
3729
-
3730
- if (typeof module !== 'undefined' && module.exports) {
3731
- module.exports = sinon.sandbox;
3732
- }
3733
- }());
3734
-
3735
- /**
3736
- * @depend ../sinon.js
3737
- * @depend stub.js
3738
- * @depend mock.js
3739
- * @depend sandbox.js
3740
- */
3741
- /*jslint eqeqeq: false, onevar: false, forin: true, plusplus: false*/
3742
- /*global module, require, sinon*/
3743
- /**
3744
- * Test function, sandboxes fakes
3745
- *
3746
- * @author Christian Johansen (christian@cjohansen.no)
3747
- * @license BSD
3748
- *
3749
- * Copyright (c) 2010-2013 Christian Johansen
3750
- */
3751
-
3752
- (function (sinon) {
3753
- var commonJSModule = typeof module !== 'undefined' && module.exports;
3754
-
3755
- if (!sinon && commonJSModule) {
3756
- sinon = require("../sinon");
3757
- }
3758
-
3759
- if (!sinon) {
3760
- return;
3761
- }
3762
-
3763
- function test(callback) {
3764
- var type = typeof callback;
3765
-
3766
- if (type != "function") {
3767
- throw new TypeError("sinon.test needs to wrap a test function, got " + type);
3768
- }
3769
-
3770
- return function () {
3771
- var config = sinon.getConfig(sinon.config);
3772
- config.injectInto = config.injectIntoThis && this || config.injectInto;
3773
- var sandbox = sinon.sandbox.create(config);
3774
- var exception, result;
3775
- var args = Array.prototype.slice.call(arguments).concat(sandbox.args);
3776
-
3777
- try {
3778
- result = callback.apply(this, args);
3779
- } catch (e) {
3780
- exception = e;
3781
- }
3782
-
3783
- if (typeof exception !== "undefined") {
3784
- sandbox.restore();
3785
- throw exception;
3786
- }
3787
- else {
3788
- sandbox.verifyAndRestore();
3789
- }
3790
-
3791
- return result;
3792
- };
3793
- }
3794
-
3795
- test.config = {
3796
- injectIntoThis: true,
3797
- injectInto: null,
3798
- properties: ["spy", "stub", "mock", "clock", "server", "requests"],
3799
- useFakeTimers: true,
3800
- useFakeServer: true
3801
- };
3802
-
3803
- if (commonJSModule) {
3804
- module.exports = test;
3805
- } else {
3806
- sinon.test = test;
3807
- }
3808
- }(typeof sinon == "object" && sinon || null));
3809
-
3810
- /**
3811
- * @depend ../sinon.js
3812
- * @depend test.js
3813
- */
3814
- /*jslint eqeqeq: false, onevar: false, eqeqeq: false*/
3815
- /*global module, require, sinon*/
3816
- /**
3817
- * Test case, sandboxes all test functions
3818
- *
3819
- * @author Christian Johansen (christian@cjohansen.no)
3820
- * @license BSD
3821
- *
3822
- * Copyright (c) 2010-2013 Christian Johansen
3823
- */
3824
-
3825
- (function (sinon) {
3826
- var commonJSModule = typeof module !== 'undefined' && module.exports;
3827
-
3828
- if (!sinon && commonJSModule) {
3829
- sinon = require("../sinon");
3830
- }
3831
-
3832
- if (!sinon || !Object.prototype.hasOwnProperty) {
3833
- return;
3834
- }
3835
-
3836
- function createTest(property, setUp, tearDown) {
3837
- return function () {
3838
- if (setUp) {
3839
- setUp.apply(this, arguments);
3840
- }
3841
-
3842
- var exception, result;
3843
-
3844
- try {
3845
- result = property.apply(this, arguments);
3846
- } catch (e) {
3847
- exception = e;
3848
- }
3849
-
3850
- if (tearDown) {
3851
- tearDown.apply(this, arguments);
3852
- }
3853
-
3854
- if (exception) {
3855
- throw exception;
3856
- }
3857
-
3858
- return result;
3859
- };
3860
- }
3861
-
3862
- function testCase(tests, prefix) {
3863
- /*jsl:ignore*/
3864
- if (!tests || typeof tests != "object") {
3865
- throw new TypeError("sinon.testCase needs an object with test functions");
3866
- }
3867
- /*jsl:end*/
3868
-
3869
- prefix = prefix || "test";
3870
- var rPrefix = new RegExp("^" + prefix);
3871
- var methods = {}, testName, property, method;
3872
- var setUp = tests.setUp;
3873
- var tearDown = tests.tearDown;
3874
-
3875
- for (testName in tests) {
3876
- if (tests.hasOwnProperty(testName)) {
3877
- property = tests[testName];
3878
-
3879
- if (/^(setUp|tearDown)$/.test(testName)) {
3880
- continue;
3881
- }
3882
-
3883
- if (typeof property == "function" && rPrefix.test(testName)) {
3884
- method = property;
3885
-
3886
- if (setUp || tearDown) {
3887
- method = createTest(property, setUp, tearDown);
3888
- }
3889
-
3890
- methods[testName] = sinon.test(method);
3891
- } else {
3892
- methods[testName] = tests[testName];
3893
- }
3894
- }
3895
- }
3896
-
3897
- return methods;
3898
- }
3899
-
3900
- if (commonJSModule) {
3901
- module.exports = testCase;
3902
- } else {
3903
- sinon.testCase = testCase;
3904
- }
3905
- }(typeof sinon == "object" && sinon || null));
3906
-
3907
- /**
3908
- * @depend ../sinon.js
3909
- * @depend stub.js
3910
- */
3911
- /*jslint eqeqeq: false, onevar: false, nomen: false, plusplus: false*/
3912
- /*global module, require, sinon*/
3913
- /**
3914
- * Assertions matching the test spy retrieval interface.
3915
- *
3916
- * @author Christian Johansen (christian@cjohansen.no)
3917
- * @license BSD
3918
- *
3919
- * Copyright (c) 2010-2013 Christian Johansen
3920
- */
3921
-
3922
- (function (sinon, global) {
3923
- var commonJSModule = typeof module !== "undefined" && module.exports;
3924
- var slice = Array.prototype.slice;
3925
- var assert;
3926
-
3927
- if (!sinon && commonJSModule) {
3928
- sinon = require("../sinon");
3929
- }
3930
-
3931
- if (!sinon) {
3932
- return;
3933
- }
3934
-
3935
- function verifyIsStub() {
3936
- var method;
3937
-
3938
- for (var i = 0, l = arguments.length; i < l; ++i) {
3939
- method = arguments[i];
3940
-
3941
- if (!method) {
3942
- assert.fail("fake is not a spy");
3943
- }
3944
-
3945
- if (typeof method != "function") {
3946
- assert.fail(method + " is not a function");
3947
- }
3948
-
3949
- if (typeof method.getCall != "function") {
3950
- assert.fail(method + " is not stubbed");
3951
- }
3952
- }
3953
- }
3954
-
3955
- function failAssertion(object, msg) {
3956
- object = object || global;
3957
- var failMethod = object.fail || assert.fail;
3958
- failMethod.call(object, msg);
3959
- }
3960
-
3961
- function mirrorPropAsAssertion(name, method, message) {
3962
- if (arguments.length == 2) {
3963
- message = method;
3964
- method = name;
3965
- }
3966
-
3967
- assert[name] = function (fake) {
3968
- verifyIsStub(fake);
3969
-
3970
- var args = slice.call(arguments, 1);
3971
- var failed = false;
3972
-
3973
- if (typeof method == "function") {
3974
- failed = !method(fake);
3975
- } else {
3976
- failed = typeof fake[method] == "function" ?
3977
- !fake[method].apply(fake, args) : !fake[method];
3978
- }
3979
-
3980
- if (failed) {
3981
- failAssertion(this, fake.printf.apply(fake, [message].concat(args)));
3982
- } else {
3983
- assert.pass(name);
3984
- }
3985
- };
3986
- }
3987
-
3988
- function exposedName(prefix, prop) {
3989
- return !prefix || /^fail/.test(prop) ? prop :
3990
- prefix + prop.slice(0, 1).toUpperCase() + prop.slice(1);
3991
- };
3992
-
3993
- assert = {
3994
- failException: "AssertError",
3995
-
3996
- fail: function fail(message) {
3997
- var error = new Error(message);
3998
- error.name = this.failException || assert.failException;
3999
-
4000
- throw error;
4001
- },
4002
-
4003
- pass: function pass(assertion) {},
4004
-
4005
- callOrder: function assertCallOrder() {
4006
- verifyIsStub.apply(null, arguments);
4007
- var expected = "", actual = "";
4008
-
4009
- if (!sinon.calledInOrder(arguments)) {
4010
- try {
4011
- expected = [].join.call(arguments, ", ");
4012
- var calls = slice.call(arguments);
4013
- var i = calls.length;
4014
- while (i) {
4015
- if (!calls[--i].called) {
4016
- calls.splice(i, 1);
4017
- }
4018
- }
4019
- actual = sinon.orderByFirstCall(calls).join(", ");
4020
- } catch (e) {
4021
- // If this fails, we'll just fall back to the blank string
4022
- }
4023
-
4024
- failAssertion(this, "expected " + expected + " to be " +
4025
- "called in order but were called as " + actual);
4026
- } else {
4027
- assert.pass("callOrder");
4028
- }
4029
- },
4030
-
4031
- callCount: function assertCallCount(method, count) {
4032
- verifyIsStub(method);
4033
-
4034
- if (method.callCount != count) {
4035
- var msg = "expected %n to be called " + sinon.timesInWords(count) +
4036
- " but was called %c%C";
4037
- failAssertion(this, method.printf(msg));
4038
- } else {
4039
- assert.pass("callCount");
4040
- }
4041
- },
4042
-
4043
- expose: function expose(target, options) {
4044
- if (!target) {
4045
- throw new TypeError("target is null or undefined");
4046
- }
4047
-
4048
- var o = options || {};
4049
- var prefix = typeof o.prefix == "undefined" && "assert" || o.prefix;
4050
- var includeFail = typeof o.includeFail == "undefined" || !!o.includeFail;
4051
-
4052
- for (var method in this) {
4053
- if (method != "export" && (includeFail || !/^(fail)/.test(method))) {
4054
- target[exposedName(prefix, method)] = this[method];
4055
- }
4056
- }
4057
-
4058
- return target;
4059
- }
4060
- };
4061
-
4062
- mirrorPropAsAssertion("called", "expected %n to have been called at least once but was never called");
4063
- mirrorPropAsAssertion("notCalled", function (spy) { return !spy.called; },
4064
- "expected %n to not have been called but was called %c%C");
4065
- mirrorPropAsAssertion("calledOnce", "expected %n to be called once but was called %c%C");
4066
- mirrorPropAsAssertion("calledTwice", "expected %n to be called twice but was called %c%C");
4067
- mirrorPropAsAssertion("calledThrice", "expected %n to be called thrice but was called %c%C");
4068
- mirrorPropAsAssertion("calledOn", "expected %n to be called with %1 as this but was called with %t");
4069
- mirrorPropAsAssertion("alwaysCalledOn", "expected %n to always be called with %1 as this but was called with %t");
4070
- mirrorPropAsAssertion("calledWithNew", "expected %n to be called with new");
4071
- mirrorPropAsAssertion("alwaysCalledWithNew", "expected %n to always be called with new");
4072
- mirrorPropAsAssertion("calledWith", "expected %n to be called with arguments %*%C");
4073
- mirrorPropAsAssertion("calledWithMatch", "expected %n to be called with match %*%C");
4074
- mirrorPropAsAssertion("alwaysCalledWith", "expected %n to always be called with arguments %*%C");
4075
- mirrorPropAsAssertion("alwaysCalledWithMatch", "expected %n to always be called with match %*%C");
4076
- mirrorPropAsAssertion("calledWithExactly", "expected %n to be called with exact arguments %*%C");
4077
- mirrorPropAsAssertion("alwaysCalledWithExactly", "expected %n to always be called with exact arguments %*%C");
4078
- mirrorPropAsAssertion("neverCalledWith", "expected %n to never be called with arguments %*%C");
4079
- mirrorPropAsAssertion("neverCalledWithMatch", "expected %n to never be called with match %*%C");
4080
- mirrorPropAsAssertion("threw", "%n did not throw exception%C");
4081
- mirrorPropAsAssertion("alwaysThrew", "%n did not always throw exception%C");
4082
-
4083
- if (commonJSModule) {
4084
- module.exports = assert;
4085
- } else {
4086
- sinon.assert = assert;
4087
- }
4088
- }(typeof sinon == "object" && sinon || null, typeof window != "undefined" ? window : (typeof self != "undefined") ? self : global));
4089
-