modularity-rails 0.15.0 → 0.16.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (89) hide show
  1. data/{LICENSE → MIT-LICENSE} +0 -0
  2. data/README.md +16 -15
  3. data/Rakefile +3 -14
  4. data/{vendor → app}/assets/javascripts/modularity/data/ajax_loader.coffee +0 -0
  5. data/{vendor → app}/assets/javascripts/modularity/data/cache.coffee +5 -0
  6. data/{vendor → app}/assets/javascripts/modularity/data/indexed_cache.coffee +8 -2
  7. data/{vendor → app}/assets/javascripts/modularity/data/persistence_manager.coffee +11 -0
  8. data/{vendor → app}/assets/javascripts/modularity/mixins/clickable.coffee +2 -2
  9. data/{vendor → app}/assets/javascripts/modularity/mixins/closable.coffee +0 -0
  10. data/{vendor/assets/javascripts/modularity.js.coffee → app/assets/javascripts/modularity/modularity.coffee} +3 -0
  11. data/{vendor → app}/assets/javascripts/modularity/modules/autogrow_textarea.coffee +2 -1
  12. data/{vendor → app}/assets/javascripts/modularity/modules/button.coffee +0 -0
  13. data/{vendor → app}/assets/javascripts/modularity/tools/array_tools.coffee +1 -0
  14. data/{vendor → app}/assets/javascripts/modularity/tools/object_tools.coffee +0 -0
  15. data/config/initializers/konacha.rb +6 -0
  16. data/lib/modularity-rails.rb +0 -1
  17. data/lib/modularity-rails/engine.rb +1 -0
  18. data/lib/modularity-rails/version.rb +1 -1
  19. metadata +80 -100
  20. data/.evergreen +0 -6
  21. data/.gitignore +0 -20
  22. data/.travis.yml +0 -8
  23. data/Gemfile +0 -4
  24. data/Guardfile +0 -8
  25. data/demo/.gitignore +0 -15
  26. data/demo/Gemfile +0 -23
  27. data/demo/README.rdoc +0 -261
  28. data/demo/Rakefile +0 -7
  29. data/demo/app/assets/images/rails.png +0 -0
  30. data/demo/app/assets/javascripts/application.coffee +0 -2
  31. data/demo/app/assets/stylesheets/application.css +0 -13
  32. data/demo/app/controllers/application_controller.rb +0 -3
  33. data/demo/app/helpers/application_helper.rb +0 -2
  34. data/demo/app/mailers/.gitkeep +0 -0
  35. data/demo/app/models/.gitkeep +0 -0
  36. data/demo/app/views/layouts/application.html.erb +0 -14
  37. data/demo/config.ru +0 -4
  38. data/demo/config/application.rb +0 -59
  39. data/demo/config/boot.rb +0 -6
  40. data/demo/config/database.yml +0 -25
  41. data/demo/config/environment.rb +0 -5
  42. data/demo/config/environments/development.rb +0 -37
  43. data/demo/config/environments/production.rb +0 -67
  44. data/demo/config/environments/test.rb +0 -37
  45. data/demo/config/initializers/backtrace_silencers.rb +0 -7
  46. data/demo/config/initializers/inflections.rb +0 -15
  47. data/demo/config/initializers/konacha.rb +0 -5
  48. data/demo/config/initializers/mime_types.rb +0 -5
  49. data/demo/config/initializers/secret_token.rb +0 -7
  50. data/demo/config/initializers/session_store.rb +0 -8
  51. data/demo/config/initializers/wrap_parameters.rb +0 -14
  52. data/demo/config/locales/en.yml +0 -5
  53. data/demo/config/routes.rb +0 -58
  54. data/demo/db/seeds.rb +0 -7
  55. data/demo/lib/assets/.gitkeep +0 -0
  56. data/demo/lib/tasks/.gitkeep +0 -0
  57. data/demo/log/.gitkeep +0 -0
  58. data/demo/public/404.html +0 -26
  59. data/demo/public/422.html +0 -26
  60. data/demo/public/500.html +0 -25
  61. data/demo/public/favicon.ico +0 -0
  62. data/demo/public/index.html +0 -241
  63. data/demo/public/robots.txt +0 -5
  64. data/demo/script/rails +0 -6
  65. data/demo/spec/javascripts/data/ajax_loader_spec.coffee +0 -132
  66. data/demo/spec/javascripts/data/cache_spec.coffee +0 -103
  67. data/demo/spec/javascripts/data/indexed_cache_spec.coffee +0 -51
  68. data/demo/spec/javascripts/data/persistence_manager_spec.coffee +0 -283
  69. data/demo/spec/javascripts/konacha_config.coffee +0 -2
  70. data/demo/spec/javascripts/mixins/closable_spec.coffee +0 -98
  71. data/demo/spec/javascripts/modularity_spec.coffee +0 -329
  72. data/demo/spec/javascripts/modules/autogrow_textarea_spec.coffee +0 -43
  73. data/demo/spec/javascripts/modules/button_spec.coffee +0 -39
  74. data/demo/spec/javascripts/modules/counter_button_spec.coffee +0 -57
  75. data/demo/spec/javascripts/sinon-chai.js +0 -116
  76. data/demo/spec/javascripts/sinon.js +0 -3555
  77. data/demo/spec/javascripts/spec_helper.coffee +0 -10
  78. data/demo/spec/javascripts/templates/autogrow_textarea.jst.ejs +0 -2
  79. data/demo/spec/javascripts/templates/button.jst.ejs +0 -3
  80. data/demo/spec/javascripts/templates/closable.jst.ejs +0 -14
  81. data/demo/spec/javascripts/templates/modularity.jst.ejs +0 -6
  82. data/demo/spec/javascripts/tools/array_tools_spec.coffee +0 -12
  83. data/demo/spec/javascripts/tools/object_tools_spec.coffee +0 -46
  84. data/demo/vendor/assets/javascripts/.gitkeep +0 -0
  85. data/demo/vendor/assets/stylesheets/.gitkeep +0 -0
  86. data/demo/vendor/plugins/.gitkeep +0 -0
  87. data/modularity-rails.gemspec +0 -22
  88. data/run_tests +0 -6
  89. data/vendor/assets/javascripts/modularity/modules/counter_button.coffee +0 -17
@@ -1,39 +0,0 @@
1
- #= require spec_helper
2
- #= require modularity/modules/button
3
-
4
-
5
- describe 'Button', ->
6
-
7
- beforeEach ->
8
- template 'button'
9
-
10
- describe 'manual clicks', ->
11
-
12
- it 'fires when clicking on the container directly', ->
13
- button = new modularity.Button($('#konacha #button1'))
14
- button.bind_event('clicked', (spy = sinon.spy()))
15
-
16
- button.container.click()
17
-
18
- spy.should.have.been.calledOnce
19
-
20
-
21
- it 'fires when clicking embedded elements of the button', ->
22
- button = new modularity.Button($('#konacha #button2'))
23
- button.bind_event('clicked', (spy = sinon.spy()))
24
-
25
- button.container.find('.embedded').click()
26
-
27
- spy.should.have.been.calledOnce
28
-
29
-
30
- describe 'programmatic clicks', ->
31
-
32
- it 'programmatically clicks the button', ->
33
- button = new modularity.Button($('#konacha #button2'))
34
- spy = sinon.spy()
35
- button.bind_event('clicked', spy)
36
-
37
- button.click()
38
-
39
- spy.should.have.been.called
@@ -1,57 +0,0 @@
1
- #= require spec_helper
2
- #= require modularity/modules/counter_button
3
-
4
-
5
- describe 'CounterButton', ->
6
-
7
- beforeEach ->
8
- template 'button'
9
-
10
- describe 'standard button functionality', ->
11
-
12
- describe 'manual clicks', ->
13
-
14
- it 'fires when clicking on the container directly', ->
15
- button = new modularity.CounterButton('#konacha #button1')
16
- button.bind_event('clicked', (spy = sinon.spy()))
17
-
18
- button.container.click()
19
-
20
- spy.should.have.been.calledOnce
21
-
22
-
23
- it 'fires when clicking embedded elements of the button', ->
24
- button = new modularity.CounterButton('#konacha #button2')
25
- button.bind_event('clicked', (spy = sinon.spy()))
26
-
27
- button.container.find('.embedded').click()
28
-
29
- spy.should.have.been.calledOnce
30
-
31
- describe 'programmatic clicks', ->
32
-
33
- it 'programmatically clicks the button', ->
34
- button = new modularity.CounterButton('#konacha #button2')
35
- spy = sinon.spy()
36
- button.bind_event('clicked', spy)
37
-
38
- button.click()
39
-
40
- spy.should.have.been.called
41
-
42
- describe 'CounterButton specific functionality', ->
43
-
44
- it 'provides the click counter as the event payload', ->
45
- button = new modularity.CounterButton('#konacha #button1')
46
- button.bind_event('clicked', (spy = sinon.spy()))
47
-
48
- button.container.click()
49
- button.container.click()
50
- button.container.click()
51
-
52
- spy.should.have.been.calledThrice
53
- spy.args[0][1].should.equal 1
54
- spy.args[1][1].should.equal 2
55
- spy.args[2][1].should.equal 3
56
-
57
-
@@ -1,116 +0,0 @@
1
- (function (sinonChai) {
2
- "use strict";
3
-
4
- // Module systems magic dance.
5
-
6
- if (typeof require === "function" && typeof exports === "object" && typeof module === "object") {
7
- // NodeJS
8
- module.exports = sinonChai;
9
- } else if (typeof define === "function" && define.amd) {
10
- // AMD
11
- define(function () {
12
- return sinonChai;
13
- });
14
- } else {
15
- // Other environment (usually <script> tag): attach to global.
16
- var global = (new Function("return this"))();
17
- global.sinonChai = sinonChai;
18
- }
19
- }(function sinonChai(chai) {
20
- "use strict";
21
-
22
- var slice = Array.prototype.slice;
23
-
24
- function flagger(word) {
25
- Object.defineProperty(chai.Assertion.prototype, word, {
26
- get: function () {
27
- this["_" + word] = true;
28
- return this;
29
- },
30
- configurable: true
31
- });
32
- }
33
-
34
- function property(name, asserter) {
35
- Object.defineProperty(chai.Assertion.prototype, name, {
36
- get: function () {
37
- asserter.call(this);
38
- return this;
39
- },
40
- configurable: true
41
- });
42
- }
43
-
44
- function method(name, asserter) {
45
- chai.Assertion.prototype[name] = function () {
46
- asserter.apply(this, arguments);
47
- return this;
48
- };
49
- }
50
-
51
- function isSpy(putativeSpy) {
52
- return typeof putativeSpy === "function" &&
53
- typeof putativeSpy.getCall === "function" &&
54
- typeof putativeSpy.calledWithExactly === "function";
55
- }
56
-
57
- function assertIsAboutSpy(assertion) {
58
- if (!isSpy(assertion.obj)) {
59
- throw new TypeError(chai.inspect(assertion.obj) + " is not a spy!");
60
- }
61
- }
62
-
63
- function getMessages(spy, action, nonNegatedSuffix, always, args) {
64
- var verbPhrase = always ? "always have " : "have ";
65
- nonNegatedSuffix = nonNegatedSuffix || "";
66
-
67
- function printfArray(array) {
68
- return spy.printf.apply(spy, array);
69
- }
70
-
71
- return {
72
- affirmative: printfArray(["expected %n to " + verbPhrase + action + nonNegatedSuffix].concat(args)),
73
- negative: printfArray(["expected %n to not " + verbPhrase + action].concat(args))
74
- };
75
- }
76
-
77
- function sinonProperty(name, action, nonNegatedSuffix) {
78
- property(name, function () {
79
- assertIsAboutSpy(this);
80
-
81
- var messages = getMessages(this.obj, action, nonNegatedSuffix, false);
82
- this.assert(this.obj[name], messages.affirmative, messages.negative);
83
- });
84
- }
85
-
86
- function exceptionalSinonMethod(chaiName, sinonName, action, nonNegatedSuffix) {
87
- method(chaiName, function () {
88
- assertIsAboutSpy(this);
89
-
90
- var alwaysSinonMethod = "always" + sinonName[0].toUpperCase() + sinonName.substring(1);
91
- var shouldBeAlways = this._always && typeof this.obj[alwaysSinonMethod] === "function";
92
- var sinonMethod = shouldBeAlways ? alwaysSinonMethod : sinonName;
93
-
94
- var messages = getMessages(this.obj, action, nonNegatedSuffix, shouldBeAlways, slice.call(arguments));
95
- this.assert(this.obj[sinonMethod].apply(this.obj, arguments), messages.affirmative, messages.negative);
96
- });
97
- }
98
-
99
- function sinonMethod(name, action, nonNegatedSuffix) {
100
- exceptionalSinonMethod(name, name, action, nonNegatedSuffix);
101
- }
102
-
103
- flagger("always");
104
-
105
- sinonProperty("called", "been called", " at least once, but it was never called");
106
- sinonProperty("calledOnce", "been called exactly once", ", but it was called %c%C");
107
- sinonProperty("calledTwice", "been called exactly twice", ", but it was called %c%C");
108
- sinonProperty("calledThrice", "been called exactly thrice", ", but it was called %c%C");
109
- sinonMethod("calledBefore", "been called before %1");
110
- sinonMethod("calledAfter", "been called after %1");
111
- sinonMethod("calledOn", "been called with %1 as this", ", but it was called with %t instead");
112
- sinonMethod("calledWith", "been called with arguments %*", "%C");
113
- sinonMethod("calledWithExactly", "been called with exact arguments %*", "%C");
114
- sinonMethod("returned", "returned %1");
115
- exceptionalSinonMethod("thrown", "threw", "thrown %1");
116
- }));
@@ -1,3555 +0,0 @@
1
- /**
2
- * Sinon.JS 1.3.4, 2012/04/16
3
- *
4
- * @author Christian Johansen (christian@cjohansen.no)
5
- *
6
- * (The BSD License)
7
- *
8
- * Copyright (c) 2010-2011, Christian Johansen, christian@cjohansen.no
9
- * All rights reserved.
10
- *
11
- * Redistribution and use in source and binary forms, with or without modification,
12
- * are permitted provided that the following conditions are met:
13
- *
14
- * * Redistributions of source code must retain the above copyright notice,
15
- * this list of conditions and the following disclaimer.
16
- * * Redistributions in binary form must reproduce the above copyright notice,
17
- * this list of conditions and the following disclaimer in the documentation
18
- * and/or other materials provided with the distribution.
19
- * * Neither the name of Christian Johansen nor the names of his contributors
20
- * may be used to endorse or promote products derived from this software
21
- * without specific prior written permission.
22
- *
23
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
24
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
27
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
29
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
30
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
31
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
32
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33
- */
34
-
35
- "use strict";
36
- var sinon = (function () {
37
- var buster = (function (buster, setTimeout) {
38
- function extend(target) {
39
- if (!target) {
40
- return;
41
- }
42
-
43
- for (var i = 1, l = arguments.length, prop; i < l; ++i) {
44
- for (prop in arguments[i]) {
45
- target[prop] = arguments[i][prop];
46
- }
47
- }
48
-
49
- return target;
50
- }
51
-
52
- var div = typeof document != "undefined" && document.createElement("div");
53
-
54
- return extend(buster, {
55
- bind: function (obj, methOrProp) {
56
- var method = typeof methOrProp == "string" ? obj[methOrProp] : methOrProp;
57
- var args = Array.prototype.slice.call(arguments, 2);
58
-
59
- return function () {
60
- var allArgs = args.concat(Array.prototype.slice.call(arguments));
61
- return method.apply(obj, allArgs);
62
- };
63
- },
64
-
65
- create: (function () {
66
- function F() {}
67
-
68
- return function create(object) {
69
- F.prototype = object;
70
- return new F();
71
- }
72
- }()),
73
-
74
- extend: extend,
75
-
76
- nextTick: function (callback) {
77
- if (typeof process != "undefined" && process.nextTick) {
78
- return process.nextTick(callback);
79
- }
80
-
81
- setTimeout(callback, 0);
82
- },
83
-
84
- functionName: function (func) {
85
- if (!func) return "";
86
- if (func.displayName) return func.displayName;
87
- if (func.name) return func.name;
88
-
89
- var matches = func.toString().match(/function\s+([^\(]+)/m);
90
- return matches && matches[1] || "";
91
- },
92
-
93
- isNode: function (obj) {
94
- if (!div) return false;
95
-
96
- try {
97
- obj.appendChild(div);
98
- obj.removeChild(div);
99
- } catch (e) {
100
- return false;
101
- }
102
-
103
- return true;
104
- },
105
-
106
- isElement: function (obj) {
107
- return obj && buster.isNode(obj) && obj.nodeType === 1;
108
- }
109
- });
110
- }(buster || {}, setTimeout));
111
-
112
- if (typeof module == "object" && typeof require == "function") {
113
- module.exports = buster;
114
- buster.eventEmitter = require("./buster-event-emitter");
115
-
116
- Object.defineProperty(buster, "defineVersionGetter", {
117
- get: function () {
118
- return require("./define-version-getter");
119
- }
120
- });
121
- }
122
- if (typeof buster === "undefined") {
123
- var buster = {};
124
- }
125
-
126
- if (typeof module === "object" && typeof require === "function") {
127
- buster = require("buster-core");
128
- }
129
-
130
- buster.format = buster.format || {};
131
- buster.format.excludeConstructors = ["Object", /^.$/];
132
- buster.format.quoteStrings = true;
133
-
134
- buster.format.ascii = (function () {
135
-
136
- function keys(object) {
137
- var k = Object.keys && Object.keys(object) || [];
138
-
139
- if (k.length == 0) {
140
- for (var prop in object) {
141
- if (object.hasOwnProperty(prop)) {
142
- k.push(prop);
143
- }
144
- }
145
- }
146
-
147
- return k.sort();
148
- }
149
-
150
- function isCircular(object, objects) {
151
- if (typeof object != "object") {
152
- return false;
153
- }
154
-
155
- for (var i = 0, l = objects.length; i < l; ++i) {
156
- if (objects[i] === object) {
157
- return true;
158
- }
159
- }
160
-
161
- return false;
162
- }
163
-
164
- function ascii(object, processed, indent) {
165
- if (typeof object == "string") {
166
- var quote = typeof this.quoteStrings != "boolean" || this.quoteStrings;
167
- return processed || quote ? '"' + object + '"' : object;
168
- }
169
-
170
- if (typeof object == "function" && !(object instanceof RegExp)) {
171
- return ascii.func(object);
172
- }
173
-
174
- processed = processed || [];
175
-
176
- if (isCircular(object, processed)) {
177
- return "[Circular]";
178
- }
179
-
180
- if (Object.prototype.toString.call(object) == "[object Array]") {
181
- return ascii.array.call(this, object);
182
- }
183
-
184
- if (!object) {
185
- return "" + object;
186
- }
187
-
188
- if (buster.isElement(object)) {
189
- return ascii.element(object);
190
- }
191
-
192
- if (typeof object.toString == "function" &&
193
- object.toString !== Object.prototype.toString) {
194
- return object.toString();
195
- }
196
-
197
- return ascii.object.call(this, object, processed, indent);
198
- }
199
-
200
- ascii.func = function (func) {
201
- return "function " + buster.functionName(func) + "() {}";
202
- };
203
-
204
- ascii.array = function (array, processed) {
205
- processed = processed || [];
206
- processed.push(array);
207
- var pieces = [];
208
-
209
- for (var i = 0, l = array.length; i < l; ++i) {
210
- pieces.push(ascii.call(this, array[i], processed));
211
- }
212
-
213
- return "[" + pieces.join(", ") + "]";
214
- };
215
-
216
- ascii.object = function (object, processed, indent) {
217
- processed = processed || [];
218
- processed.push(object);
219
- indent = indent || 0;
220
- var pieces = [], properties = keys(object), prop, str, obj;
221
- var is = "";
222
- var length = 3;
223
-
224
- for (var i = 0, l = indent; i < l; ++i) {
225
- is += " ";
226
- }
227
-
228
- for (i = 0, l = properties.length; i < l; ++i) {
229
- prop = properties[i];
230
- obj = object[prop];
231
-
232
- if (isCircular(obj, processed)) {
233
- str = "[Circular]";
234
- } else {
235
- str = ascii.call(this, obj, processed, indent + 2);
236
- }
237
-
238
- str = (/\s/.test(prop) ? '"' + prop + '"' : prop) + ": " + str;
239
- length += str.length;
240
- pieces.push(str);
241
- }
242
-
243
- var cons = ascii.constructorName.call(this, object);
244
- var prefix = cons ? "[" + cons + "] " : ""
245
-
246
- return (length + indent) > 80 ?
247
- prefix + "{\n " + is + pieces.join(",\n " + is) + "\n" + is + "}" :
248
- prefix + "{ " + pieces.join(", ") + " }";
249
- };
250
-
251
- ascii.element = function (element) {
252
- var tagName = element.tagName.toLowerCase();
253
- var attrs = element.attributes, attribute, pairs = [], attrName;
254
-
255
- for (var i = 0, l = attrs.length; i < l; ++i) {
256
- attribute = attrs.item(i);
257
- attrName = attribute.nodeName.toLowerCase().replace("html:", "");
258
-
259
- if (attrName == "contenteditable" && attribute.nodeValue == "inherit") {
260
- continue;
261
- }
262
-
263
- if (!!attribute.nodeValue) {
264
- pairs.push(attrName + "=\"" + attribute.nodeValue + "\"");
265
- }
266
- }
267
-
268
- var formatted = "<" + tagName + (pairs.length > 0 ? " " : "");
269
- var content = element.innerHTML;
270
-
271
- if (content.length > 20) {
272
- content = content.substr(0, 20) + "[...]";
273
- }
274
-
275
- var res = formatted + pairs.join(" ") + ">" + content + "</" + tagName + ">";
276
-
277
- return res.replace(/ contentEditable="inherit"/, "");
278
- };
279
-
280
- ascii.constructorName = function (object) {
281
- var name = buster.functionName(object && object.constructor);
282
- var excludes = this.excludeConstructors || buster.format.excludeConstructors || [];
283
-
284
- for (var i = 0, l = excludes.length; i < l; ++i) {
285
- if (typeof excludes[i] == "string" && excludes[i] == name) {
286
- return "";
287
- } else if (excludes[i].test && excludes[i].test(name)) {
288
- return "";
289
- }
290
- }
291
-
292
- return name;
293
- };
294
-
295
- return ascii;
296
- }());
297
-
298
- if (typeof module != "undefined") {
299
- module.exports = buster.format;
300
- }
301
- /*jslint eqeqeq: false, onevar: false, forin: true, nomen: false, regexp: false, plusplus: false*/
302
- /*global module, require, __dirname, document*/
303
- /**
304
- * Sinon core utilities. For internal use only.
305
- *
306
- * @author Christian Johansen (christian@cjohansen.no)
307
- * @license BSD
308
- *
309
- * Copyright (c) 2010-2011 Christian Johansen
310
- */
311
-
312
- var sinon = (function (buster) {
313
- var div = typeof document != "undefined" && document.createElement("div");
314
- var hasOwn = Object.prototype.hasOwnProperty;
315
-
316
- function isDOMNode(obj) {
317
- var success = false;
318
-
319
- try {
320
- obj.appendChild(div);
321
- success = div.parentNode == obj;
322
- } catch (e) {
323
- return false;
324
- } finally {
325
- try {
326
- obj.removeChild(div);
327
- } catch (e) {
328
- // Remove failed, not much we can do about that
329
- }
330
- }
331
-
332
- return success;
333
- }
334
-
335
- function isElement(obj) {
336
- return div && obj && obj.nodeType === 1 && isDOMNode(obj);
337
- }
338
-
339
- function isFunction(obj) {
340
- return !!(obj && obj.constructor && obj.call && obj.apply);
341
- }
342
-
343
- function mirrorProperties(target, source) {
344
- for (var prop in source) {
345
- if (!hasOwn.call(target, prop)) {
346
- target[prop] = source[prop];
347
- }
348
- }
349
- }
350
-
351
- var sinon = {
352
- wrapMethod: function wrapMethod(object, property, method) {
353
- if (!object) {
354
- throw new TypeError("Should wrap property of object");
355
- }
356
-
357
- if (typeof method != "function") {
358
- throw new TypeError("Method wrapper should be function");
359
- }
360
-
361
- var wrappedMethod = object[property];
362
-
363
- if (!isFunction(wrappedMethod)) {
364
- throw new TypeError("Attempted to wrap " + (typeof wrappedMethod) + " property " +
365
- property + " as function");
366
- }
367
-
368
- if (wrappedMethod.restore && wrappedMethod.restore.sinon) {
369
- throw new TypeError("Attempted to wrap " + property + " which is already wrapped");
370
- }
371
-
372
- if (wrappedMethod.calledBefore) {
373
- var verb = !!wrappedMethod.returns ? "stubbed" : "spied on";
374
- throw new TypeError("Attempted to wrap " + property + " which is already " + verb);
375
- }
376
-
377
- // IE 8 does not support hasOwnProperty on the window object.
378
- var owned = hasOwn.call(object, property);
379
- object[property] = method;
380
- method.displayName = property;
381
-
382
- method.restore = function () {
383
- if(owned) {
384
- object[property] = wrappedMethod;
385
- } else {
386
- delete object[property];
387
- }
388
- };
389
-
390
- method.restore.sinon = true;
391
- mirrorProperties(method, wrappedMethod);
392
-
393
- return method;
394
- },
395
-
396
- extend: function extend(target) {
397
- for (var i = 1, l = arguments.length; i < l; i += 1) {
398
- for (var prop in arguments[i]) {
399
- if (arguments[i].hasOwnProperty(prop)) {
400
- target[prop] = arguments[i][prop];
401
- }
402
-
403
- // DONT ENUM bug, only care about toString
404
- if (arguments[i].hasOwnProperty("toString") &&
405
- arguments[i].toString != target.toString) {
406
- target.toString = arguments[i].toString;
407
- }
408
- }
409
- }
410
-
411
- return target;
412
- },
413
-
414
- create: function create(proto) {
415
- var F = function () {};
416
- F.prototype = proto;
417
- return new F();
418
- },
419
-
420
- deepEqual: function deepEqual(a, b) {
421
- if (typeof a != "object" || typeof b != "object") {
422
- return a === b;
423
- }
424
-
425
- if (isElement(a) || isElement(b)) {
426
- return a === b;
427
- }
428
-
429
- if (a === b) {
430
- return true;
431
- }
432
-
433
- var aString = Object.prototype.toString.call(a);
434
- if (aString != Object.prototype.toString.call(b)) {
435
- return false;
436
- }
437
-
438
- if (aString == "[object Array]") {
439
- if (a.length !== b.length) {
440
- return false;
441
- }
442
-
443
- for (var i = 0, l = a.length; i < l; i += 1) {
444
- if (!deepEqual(a[i], b[i])) {
445
- return false;
446
- }
447
- }
448
-
449
- return true;
450
- }
451
-
452
- var prop, aLength = 0, bLength = 0;
453
-
454
- for (prop in a) {
455
- aLength += 1;
456
-
457
- if (!deepEqual(a[prop], b[prop])) {
458
- return false;
459
- }
460
- }
461
-
462
- for (prop in b) {
463
- bLength += 1;
464
- }
465
-
466
- if (aLength != bLength) {
467
- return false;
468
- }
469
-
470
- return true;
471
- },
472
-
473
- functionName: function functionName(func) {
474
- var name = func.displayName || func.name;
475
-
476
- // Use function decomposition as a last resort to get function
477
- // name. Does not rely on function decomposition to work - if it
478
- // doesn't debugging will be slightly less informative
479
- // (i.e. toString will say 'spy' rather than 'myFunc').
480
- if (!name) {
481
- var matches = func.toString().match(/function ([^\s\(]+)/);
482
- name = matches && matches[1];
483
- }
484
-
485
- return name;
486
- },
487
-
488
- functionToString: function toString() {
489
- if (this.getCall && this.callCount) {
490
- var thisValue, prop, i = this.callCount;
491
-
492
- while (i--) {
493
- thisValue = this.getCall(i).thisValue;
494
-
495
- for (prop in thisValue) {
496
- if (thisValue[prop] === this) {
497
- return prop;
498
- }
499
- }
500
- }
501
- }
502
-
503
- return this.displayName || "sinon fake";
504
- },
505
-
506
- getConfig: function (custom) {
507
- var config = {};
508
- custom = custom || {};
509
- var defaults = sinon.defaultConfig;
510
-
511
- for (var prop in defaults) {
512
- if (defaults.hasOwnProperty(prop)) {
513
- config[prop] = custom.hasOwnProperty(prop) ? custom[prop] : defaults[prop];
514
- }
515
- }
516
-
517
- return config;
518
- },
519
-
520
- format: function (val) {
521
- return "" + val;
522
- },
523
-
524
- defaultConfig: {
525
- injectIntoThis: true,
526
- injectInto: null,
527
- properties: ["spy", "stub", "mock", "clock", "server", "requests"],
528
- useFakeTimers: true,
529
- useFakeServer: true
530
- },
531
-
532
- timesInWords: function timesInWords(count) {
533
- return count == 1 && "once" ||
534
- count == 2 && "twice" ||
535
- count == 3 && "thrice" ||
536
- (count || 0) + " times";
537
- },
538
-
539
- calledInOrder: function (spies) {
540
- for (var i = 1, l = spies.length; i < l; i++) {
541
- if (!spies[i - 1].calledBefore(spies[i])) {
542
- return false;
543
- }
544
- }
545
-
546
- return true;
547
- },
548
-
549
- orderByFirstCall: function (spies) {
550
- return spies.sort(function (a, b) {
551
- // uuid, won't ever be equal
552
- var aCall = a.getCall(0);
553
- var bCall = b.getCall(0);
554
- var aId = aCall && aCall.callId || -1;
555
- var bId = bCall && bCall.callId || -1;
556
-
557
- return aId < bId ? -1 : 1;
558
- });
559
- },
560
-
561
- log: function () {},
562
-
563
- logError: function (label, err) {
564
- var msg = label + " threw exception: "
565
- sinon.log(msg + "[" + err.name + "] " + err.message);
566
- if (err.stack) { sinon.log(err.stack); }
567
-
568
- setTimeout(function () {
569
- err.message = msg + err.message;
570
- throw err;
571
- }, 0);
572
- }
573
- };
574
-
575
- var isNode = typeof module == "object" && typeof require == "function";
576
-
577
- if (isNode) {
578
- try {
579
- buster = { format: require("buster-format") };
580
- } catch (e) {}
581
- module.exports = sinon;
582
- module.exports.spy = require("./sinon/spy");
583
- module.exports.stub = require("./sinon/stub");
584
- module.exports.mock = require("./sinon/mock");
585
- module.exports.collection = require("./sinon/collection");
586
- module.exports.assert = require("./sinon/assert");
587
- module.exports.sandbox = require("./sinon/sandbox");
588
- module.exports.test = require("./sinon/test");
589
- module.exports.testCase = require("./sinon/test_case");
590
- module.exports.assert = require("./sinon/assert");
591
- }
592
-
593
- if (buster) {
594
- var formatter = sinon.create(buster.format);
595
- formatter.quoteStrings = false;
596
- sinon.format = function () {
597
- return formatter.ascii.apply(formatter, arguments);
598
- };
599
- } else if (isNode) {
600
- try {
601
- var util = require("util");
602
- sinon.format = function (value) {
603
- return typeof value == "object" ? util.inspect(value) : value;
604
- };
605
- } catch (e) {
606
- /* Node, but no util module - would be very old, but better safe than
607
- sorry */
608
- }
609
- }
610
-
611
- return sinon;
612
- }(typeof buster == "object" && buster));
613
-
614
- /* @depend ../sinon.js */
615
- /*jslint eqeqeq: false, onevar: false, plusplus: false*/
616
- /*global module, require, sinon*/
617
- /**
618
- * Spy functions
619
- *
620
- * @author Christian Johansen (christian@cjohansen.no)
621
- * @license BSD
622
- *
623
- * Copyright (c) 2010-2011 Christian Johansen
624
- */
625
-
626
- (function (sinon) {
627
- var commonJSModule = typeof module == "object" && typeof require == "function";
628
- var spyCall;
629
- var callId = 0;
630
- var push = [].push;
631
- var slice = Array.prototype.slice;
632
-
633
- if (!sinon && commonJSModule) {
634
- sinon = require("../sinon");
635
- }
636
-
637
- if (!sinon) {
638
- return;
639
- }
640
-
641
- function spy(object, property) {
642
- if (!property && typeof object == "function") {
643
- return spy.create(object);
644
- }
645
-
646
- if (!object || !property) {
647
- return spy.create(function () {});
648
- }
649
-
650
- var method = object[property];
651
- return sinon.wrapMethod(object, property, spy.create(method));
652
- }
653
-
654
- sinon.extend(spy, (function () {
655
-
656
- function delegateToCalls(api, method, matchAny, actual, notCalled) {
657
- api[method] = function () {
658
- if (!this.called) {
659
- if (notCalled) {
660
- return notCalled.apply(this, arguments);
661
- }
662
- return false;
663
- }
664
-
665
- var currentCall;
666
- var matches = 0;
667
-
668
- for (var i = 0, l = this.callCount; i < l; i += 1) {
669
- currentCall = this.getCall(i);
670
-
671
- if (currentCall[actual || method].apply(currentCall, arguments)) {
672
- matches += 1;
673
-
674
- if (matchAny) {
675
- return true;
676
- }
677
- }
678
- }
679
-
680
- return matches === this.callCount;
681
- };
682
- }
683
-
684
- function matchingFake(fakes, args, strict) {
685
- if (!fakes) {
686
- return;
687
- }
688
-
689
- var alen = args.length;
690
-
691
- for (var i = 0, l = fakes.length; i < l; i++) {
692
- if (fakes[i].matches(args, strict)) {
693
- return fakes[i];
694
- }
695
- }
696
- }
697
-
698
- function incrementCallCount() {
699
- this.called = true;
700
- this.callCount += 1;
701
- this.calledOnce = this.callCount == 1;
702
- this.calledTwice = this.callCount == 2;
703
- this.calledThrice = this.callCount == 3;
704
- }
705
-
706
- function createCallProperties() {
707
- this.firstCall = this.getCall(0);
708
- this.secondCall = this.getCall(1);
709
- this.thirdCall = this.getCall(2);
710
- this.lastCall = this.getCall(this.callCount - 1);
711
- }
712
-
713
- var uuid = 0;
714
-
715
- // Public API
716
- var spyApi = {
717
- reset: function () {
718
- this.called = false;
719
- this.calledOnce = false;
720
- this.calledTwice = false;
721
- this.calledThrice = false;
722
- this.callCount = 0;
723
- this.firstCall = null;
724
- this.secondCall = null;
725
- this.thirdCall = null;
726
- this.lastCall = null;
727
- this.args = [];
728
- this.returnValues = [];
729
- this.thisValues = [];
730
- this.exceptions = [];
731
- this.callIds = [];
732
- },
733
-
734
- create: function create(func) {
735
- var name;
736
-
737
- if (typeof func != "function") {
738
- func = function () {};
739
- } else {
740
- name = sinon.functionName(func);
741
- }
742
-
743
- function proxy() {
744
- return proxy.invoke(func, this, slice.call(arguments));
745
- }
746
-
747
- sinon.extend(proxy, spy);
748
- delete proxy.create;
749
- sinon.extend(proxy, func);
750
-
751
- proxy.reset();
752
- proxy.prototype = func.prototype;
753
- proxy.displayName = name || "spy";
754
- proxy.toString = sinon.functionToString;
755
- proxy._create = sinon.spy.create;
756
- proxy.id = "spy#" + uuid++;
757
-
758
- return proxy;
759
- },
760
-
761
- invoke: function invoke(func, thisValue, args) {
762
- var matching = matchingFake(this.fakes, args);
763
- var exception, returnValue;
764
-
765
- incrementCallCount.call(this);
766
- push.call(this.thisValues, thisValue);
767
- push.call(this.args, args);
768
- push.call(this.callIds, callId++);
769
-
770
- try {
771
- if (matching) {
772
- returnValue = matching.invoke(func, thisValue, args);
773
- } else {
774
- returnValue = (this.func || func).apply(thisValue, args);
775
- }
776
- } catch (e) {
777
- push.call(this.returnValues, undefined);
778
- exception = e;
779
- throw e;
780
- } finally {
781
- push.call(this.exceptions, exception);
782
- }
783
-
784
- push.call(this.returnValues, returnValue);
785
-
786
- createCallProperties.call(this);
787
-
788
- return returnValue;
789
- },
790
-
791
- getCall: function getCall(i) {
792
- if (i < 0 || i >= this.callCount) {
793
- return null;
794
- }
795
-
796
- return spyCall.create(this, this.thisValues[i], this.args[i],
797
- this.returnValues[i], this.exceptions[i],
798
- this.callIds[i]);
799
- },
800
-
801
- calledBefore: function calledBefore(spyFn) {
802
- if (!this.called) {
803
- return false;
804
- }
805
-
806
- if (!spyFn.called) {
807
- return true;
808
- }
809
-
810
- return this.callIds[0] < spyFn.callIds[spyFn.callIds.length - 1];
811
- },
812
-
813
- calledAfter: function calledAfter(spyFn) {
814
- if (!this.called || !spyFn.called) {
815
- return false;
816
- }
817
-
818
- return this.callIds[this.callCount - 1] > spyFn.callIds[spyFn.callCount - 1];
819
- },
820
-
821
- withArgs: function () {
822
- var args = slice.call(arguments);
823
-
824
- if (this.fakes) {
825
- var match = matchingFake(this.fakes, args, true);
826
-
827
- if (match) {
828
- return match;
829
- }
830
- } else {
831
- this.fakes = [];
832
- }
833
-
834
- var original = this;
835
- var fake = this._create();
836
- fake.matchingAguments = args;
837
- push.call(this.fakes, fake);
838
-
839
- fake.withArgs = function () {
840
- return original.withArgs.apply(original, arguments);
841
- };
842
-
843
- for (var i = 0; i < this.args.length; i++) {
844
- if (fake.matches(this.args[i])) {
845
- incrementCallCount.call(fake);
846
- push.call(fake.thisValues, this.thisValues[i]);
847
- push.call(fake.args, this.args[i]);
848
- push.call(fake.returnValues, this.returnValues[i]);
849
- push.call(fake.exceptions, this.exceptions[i]);
850
- push.call(fake.callIds, this.callIds[i]);
851
- }
852
- }
853
- createCallProperties.call(fake);
854
-
855
- return fake;
856
- },
857
-
858
- matches: function (args, strict) {
859
- var margs = this.matchingAguments;
860
-
861
- if (margs.length <= args.length &&
862
- sinon.deepEqual(margs, args.slice(0, margs.length))) {
863
- return !strict || margs.length == args.length;
864
- }
865
- },
866
-
867
- printf: function (format) {
868
- var spy = this;
869
- var args = slice.call(arguments, 1);
870
- var formatter;
871
-
872
- return (format || "").replace(/%(.)/g, function (match, specifyer) {
873
- formatter = spyApi.formatters[specifyer];
874
-
875
- if (typeof formatter == "function") {
876
- return formatter.call(null, spy, args);
877
- } else if (!isNaN(parseInt(specifyer), 10)) {
878
- return sinon.format(args[specifyer - 1]);
879
- }
880
-
881
- return "%" + specifyer;
882
- });
883
- }
884
- };
885
-
886
- delegateToCalls(spyApi, "calledOn", true);
887
- delegateToCalls(spyApi, "alwaysCalledOn", false, "calledOn");
888
- delegateToCalls(spyApi, "calledWith", true);
889
- delegateToCalls(spyApi, "alwaysCalledWith", false, "calledWith");
890
- delegateToCalls(spyApi, "calledWithExactly", true);
891
- delegateToCalls(spyApi, "alwaysCalledWithExactly", false, "calledWithExactly");
892
- delegateToCalls(spyApi, "neverCalledWith", false, "notCalledWith",
893
- function () { return true; });
894
- delegateToCalls(spyApi, "threw", true);
895
- delegateToCalls(spyApi, "alwaysThrew", false, "threw");
896
- delegateToCalls(spyApi, "returned", true);
897
- delegateToCalls(spyApi, "alwaysReturned", false, "returned");
898
- delegateToCalls(spyApi, "calledWithNew", true);
899
- delegateToCalls(spyApi, "alwaysCalledWithNew", false, "calledWithNew");
900
- delegateToCalls(spyApi, "callArg", false, "callArgWith", function () {
901
- throw new Error(this.toString() + " cannot call arg since it was not yet invoked.");
902
- });
903
- spyApi.callArgWith = spyApi.callArg;
904
- delegateToCalls(spyApi, "yield", false, "yield", function () {
905
- throw new Error(this.toString() + " cannot yield since it was not yet invoked.");
906
- });
907
- // "invokeCallback" is an alias for "yield" since "yield" is invalid in strict mode.
908
- spyApi.invokeCallback = spyApi.yield;
909
- delegateToCalls(spyApi, "yieldTo", false, "yieldTo", function (property) {
910
- throw new Error(this.toString() + " cannot yield to '" + property +
911
- "' since it was not yet invoked.");
912
- });
913
-
914
- spyApi.formatters = {
915
- "c": function (spy) {
916
- return sinon.timesInWords(spy.callCount);
917
- },
918
-
919
- "n": function (spy) {
920
- return spy.toString();
921
- },
922
-
923
- "C": function (spy) {
924
- var calls = [];
925
-
926
- for (var i = 0, l = spy.callCount; i < l; ++i) {
927
- push.call(calls, " " + spy.getCall(i).toString());
928
- }
929
-
930
- return calls.length > 0 ? "\n" + calls.join("\n") : "";
931
- },
932
-
933
- "t": function (spy) {
934
- var objects = [];
935
-
936
- for (var i = 0, l = spy.callCount; i < l; ++i) {
937
- push.call(objects, sinon.format(spy.thisValues[i]));
938
- }
939
-
940
- return objects.join(", ");
941
- },
942
-
943
- "*": function (spy, args) {
944
- return args.join(", ");
945
- }
946
- };
947
-
948
- return spyApi;
949
- }()));
950
-
951
- spyCall = (function () {
952
-
953
- function throwYieldError(proxy, text, args) {
954
- var msg = sinon.functionName(proxy) + text;
955
- if (args.length) {
956
- msg += " Received [" + slice.call(args).join(", ") + "]";
957
- }
958
- throw new Error(msg);
959
- }
960
-
961
- return {
962
- create: function create(spy, thisValue, args, returnValue, exception, id) {
963
- var proxyCall = sinon.create(spyCall);
964
- delete proxyCall.create;
965
- proxyCall.proxy = spy;
966
- proxyCall.thisValue = thisValue;
967
- proxyCall.args = args;
968
- proxyCall.returnValue = returnValue;
969
- proxyCall.exception = exception;
970
- proxyCall.callId = typeof id == "number" && id || callId++;
971
-
972
- return proxyCall;
973
- },
974
-
975
- calledOn: function calledOn(thisValue) {
976
- return this.thisValue === thisValue;
977
- },
978
-
979
- calledWith: function calledWith() {
980
- for (var i = 0, l = arguments.length; i < l; i += 1) {
981
- if (!sinon.deepEqual(arguments[i], this.args[i])) {
982
- return false;
983
- }
984
- }
985
-
986
- return true;
987
- },
988
-
989
- calledWithExactly: function calledWithExactly() {
990
- return arguments.length == this.args.length &&
991
- this.calledWith.apply(this, arguments);
992
- },
993
-
994
- notCalledWith: function notCalledWith() {
995
- for (var i = 0, l = arguments.length; i < l; i += 1) {
996
- if (!sinon.deepEqual(arguments[i], this.args[i])) {
997
- return true;
998
- }
999
- }
1000
- return false;
1001
- },
1002
-
1003
- returned: function returned(value) {
1004
- return this.returnValue === value;
1005
- },
1006
-
1007
- threw: function threw(error) {
1008
- if (typeof error == "undefined" || !this.exception) {
1009
- return !!this.exception;
1010
- }
1011
-
1012
- if (typeof error == "string") {
1013
- return this.exception.name == error;
1014
- }
1015
-
1016
- return this.exception === error;
1017
- },
1018
-
1019
- calledWithNew: function calledWithNew(thisValue) {
1020
- return this.thisValue instanceof this.proxy;
1021
- },
1022
-
1023
- calledBefore: function (other) {
1024
- return this.callId < other.callId;
1025
- },
1026
-
1027
- calledAfter: function (other) {
1028
- return this.callId > other.callId;
1029
- },
1030
-
1031
- callArg: function (pos) {
1032
- this.args[pos]();
1033
- },
1034
-
1035
- callArgWith: function (pos) {
1036
- var args = slice.call(arguments, 1);
1037
- this.args[pos].apply(null, args);
1038
- },
1039
-
1040
- "yield": function () {
1041
- var args = this.args;
1042
- for (var i = 0, l = args.length; i < l; ++i) {
1043
- if (typeof args[i] === "function") {
1044
- args[i].apply(null, slice.call(arguments));
1045
- return;
1046
- }
1047
- }
1048
- throwYieldError(this.proxy, " cannot yield since no callback was passed.", args);
1049
- },
1050
-
1051
- yieldTo: function (prop) {
1052
- var args = this.args;
1053
- for (var i = 0, l = args.length; i < l; ++i) {
1054
- if (args[i] && typeof args[i][prop] === "function") {
1055
- args[i][prop].apply(null, slice.call(arguments, 1));
1056
- return;
1057
- }
1058
- }
1059
- throwYieldError(this.proxy, " cannot yield to '" + prop +
1060
- "' since no callback was passed.", args);
1061
- },
1062
-
1063
- toString: function () {
1064
- var callStr = this.proxy.toString() + "(";
1065
- var args = [];
1066
-
1067
- for (var i = 0, l = this.args.length; i < l; ++i) {
1068
- push.call(args, sinon.format(this.args[i]));
1069
- }
1070
-
1071
- callStr = callStr + args.join(", ") + ")";
1072
-
1073
- if (typeof this.returnValue != "undefined") {
1074
- callStr += " => " + sinon.format(this.returnValue);
1075
- }
1076
-
1077
- if (this.exception) {
1078
- callStr += " !" + this.exception.name;
1079
-
1080
- if (this.exception.message) {
1081
- callStr += "(" + this.exception.message + ")";
1082
- }
1083
- }
1084
-
1085
- return callStr;
1086
- }
1087
- };
1088
- }());
1089
-
1090
- spy.spyCall = spyCall;
1091
-
1092
- // This steps outside the module sandbox and will be removed
1093
- sinon.spyCall = spyCall;
1094
-
1095
- if (commonJSModule) {
1096
- module.exports = spy;
1097
- } else {
1098
- sinon.spy = spy;
1099
- }
1100
- }(typeof sinon == "object" && sinon || null));
1101
-
1102
- /**
1103
- * @depend ../sinon.js
1104
- * @depend spy.js
1105
- */
1106
- /*jslint eqeqeq: false, onevar: false*/
1107
- /*global module, require, sinon*/
1108
- /**
1109
- * Stub functions
1110
- *
1111
- * @author Christian Johansen (christian@cjohansen.no)
1112
- * @license BSD
1113
- *
1114
- * Copyright (c) 2010-2011 Christian Johansen
1115
- */
1116
-
1117
- (function (sinon) {
1118
- var commonJSModule = typeof module == "object" && typeof require == "function";
1119
-
1120
- if (!sinon && commonJSModule) {
1121
- sinon = require("../sinon");
1122
- }
1123
-
1124
- if (!sinon) {
1125
- return;
1126
- }
1127
-
1128
- function stub(object, property, func) {
1129
- if (!!func && typeof func != "function") {
1130
- throw new TypeError("Custom stub should be function");
1131
- }
1132
-
1133
- var wrapper;
1134
-
1135
- if (func) {
1136
- wrapper = sinon.spy && sinon.spy.create ? sinon.spy.create(func) : func;
1137
- } else {
1138
- wrapper = stub.create();
1139
- }
1140
-
1141
- if (!object && !property) {
1142
- return sinon.stub.create();
1143
- }
1144
-
1145
- if (!property && !!object && typeof object == "object") {
1146
- for (var prop in object) {
1147
- if (typeof object[prop] === "function") {
1148
- stub(object, prop);
1149
- }
1150
- }
1151
-
1152
- return object;
1153
- }
1154
-
1155
- return sinon.wrapMethod(object, property, wrapper);
1156
- }
1157
-
1158
- function getCallback(stub, args) {
1159
- if (stub.callArgAt < 0) {
1160
- for (var i = 0, l = args.length; i < l; ++i) {
1161
- if (!stub.callArgProp && typeof args[i] == "function") {
1162
- return args[i];
1163
- }
1164
-
1165
- if (stub.callArgProp && args[i] &&
1166
- typeof args[i][stub.callArgProp] == "function") {
1167
- return args[i][stub.callArgProp];
1168
- }
1169
- }
1170
-
1171
- return null;
1172
- }
1173
-
1174
- return args[stub.callArgAt];
1175
- }
1176
-
1177
- var join = Array.prototype.join;
1178
-
1179
- function getCallbackError(stub, func, args) {
1180
- if (stub.callArgAt < 0) {
1181
- var msg;
1182
-
1183
- if (stub.callArgProp) {
1184
- msg = sinon.functionName(stub) +
1185
- " expected to yield to '" + stub.callArgProp +
1186
- "', but no object with such a property was passed."
1187
- } else {
1188
- msg = sinon.functionName(stub) +
1189
- " expected to yield, but no callback was passed."
1190
- }
1191
-
1192
- if (args.length > 0) {
1193
- msg += " Received [" + join.call(args, ", ") + "]";
1194
- }
1195
-
1196
- return msg;
1197
- }
1198
-
1199
- return "argument at index " + stub.callArgAt + " is not a function: " + func;
1200
- }
1201
-
1202
- function callCallback(stub, args) {
1203
- if (typeof stub.callArgAt == "number") {
1204
- var func = getCallback(stub, args);
1205
-
1206
- if (typeof func != "function") {
1207
- throw new TypeError(getCallbackError(stub, func, args));
1208
- }
1209
-
1210
- func.apply(stub.callbackContext, stub.callbackArguments);
1211
- }
1212
- }
1213
-
1214
- var uuid = 0;
1215
-
1216
- sinon.extend(stub, (function () {
1217
- var slice = Array.prototype.slice;
1218
-
1219
- function throwsException(error, message) {
1220
- if (typeof error == "string") {
1221
- this.exception = new Error(message || "");
1222
- this.exception.name = error;
1223
- } else if (!error) {
1224
- this.exception = new Error("Error");
1225
- } else {
1226
- this.exception = error;
1227
- }
1228
-
1229
- return this;
1230
- }
1231
-
1232
- return {
1233
- create: function create() {
1234
- var functionStub = function () {
1235
- if (functionStub.exception) {
1236
- throw functionStub.exception;
1237
- } else if (typeof functionStub.returnArgAt == 'number') {
1238
- return arguments[functionStub.returnArgAt];
1239
- }
1240
-
1241
- callCallback(functionStub, arguments);
1242
-
1243
- return functionStub.returnValue;
1244
- };
1245
-
1246
- functionStub.id = "stub#" + uuid++;
1247
- var orig = functionStub;
1248
- functionStub = sinon.spy.create(functionStub);
1249
- functionStub.func = orig;
1250
-
1251
- sinon.extend(functionStub, stub);
1252
- functionStub._create = sinon.stub.create;
1253
- functionStub.displayName = "stub";
1254
- functionStub.toString = sinon.functionToString;
1255
-
1256
- return functionStub;
1257
- },
1258
-
1259
- returns: function returns(value) {
1260
- this.returnValue = value;
1261
-
1262
- return this;
1263
- },
1264
-
1265
- returnsArg: function returnsArg(pos) {
1266
- if (typeof pos != "number") {
1267
- throw new TypeError("argument index is not number");
1268
- }
1269
-
1270
- this.returnArgAt = pos;
1271
-
1272
- return this;
1273
- },
1274
-
1275
- "throws": throwsException,
1276
- throwsException: throwsException,
1277
-
1278
- callsArg: function callsArg(pos) {
1279
- if (typeof pos != "number") {
1280
- throw new TypeError("argument index is not number");
1281
- }
1282
-
1283
- this.callArgAt = pos;
1284
- this.callbackArguments = [];
1285
-
1286
- return this;
1287
- },
1288
-
1289
- callsArgOn: function callsArgOn(pos, context) {
1290
- if (typeof pos != "number") {
1291
- throw new TypeError("argument index is not number");
1292
- }
1293
- if (typeof context != "object") {
1294
- throw new TypeError("argument context is not an object");
1295
- }
1296
-
1297
- this.callArgAt = pos;
1298
- this.callbackArguments = [];
1299
- this.callbackContext = context;
1300
-
1301
- return this;
1302
- },
1303
-
1304
- callsArgWith: function callsArgWith(pos) {
1305
- if (typeof pos != "number") {
1306
- throw new TypeError("argument index is not number");
1307
- }
1308
-
1309
- this.callArgAt = pos;
1310
- this.callbackArguments = slice.call(arguments, 1);
1311
-
1312
- return this;
1313
- },
1314
-
1315
- callsArgOnWith: function callsArgWith(pos, context) {
1316
- if (typeof pos != "number") {
1317
- throw new TypeError("argument index is not number");
1318
- }
1319
- if (typeof context != "object") {
1320
- throw new TypeError("argument context is not an object");
1321
- }
1322
-
1323
- this.callArgAt = pos;
1324
- this.callbackArguments = slice.call(arguments, 2);
1325
- this.callbackContext = context;
1326
-
1327
- return this;
1328
- },
1329
-
1330
- yields: function () {
1331
- this.callArgAt = -1;
1332
- this.callbackArguments = slice.call(arguments, 0);
1333
-
1334
- return this;
1335
- },
1336
-
1337
- yieldsOn: function (context) {
1338
- if (typeof context != "object") {
1339
- throw new TypeError("argument context is not an object");
1340
- }
1341
-
1342
- this.callArgAt = -1;
1343
- this.callbackArguments = slice.call(arguments, 1);
1344
- this.callbackContext = context;
1345
-
1346
- return this;
1347
- },
1348
-
1349
- yieldsTo: function (prop) {
1350
- this.callArgAt = -1;
1351
- this.callArgProp = prop;
1352
- this.callbackArguments = slice.call(arguments, 1);
1353
-
1354
- return this;
1355
- },
1356
-
1357
- yieldsToOn: function (prop, context) {
1358
- if (typeof context != "object") {
1359
- throw new TypeError("argument context is not an object");
1360
- }
1361
-
1362
- this.callArgAt = -1;
1363
- this.callArgProp = prop;
1364
- this.callbackArguments = slice.call(arguments, 2);
1365
- this.callbackContext = context;
1366
-
1367
- return this;
1368
- }
1369
- };
1370
- }()));
1371
-
1372
- if (commonJSModule) {
1373
- module.exports = stub;
1374
- } else {
1375
- sinon.stub = stub;
1376
- }
1377
- }(typeof sinon == "object" && sinon || null));
1378
-
1379
- /**
1380
- * @depend ../sinon.js
1381
- * @depend stub.js
1382
- */
1383
- /*jslint eqeqeq: false, onevar: false, nomen: false*/
1384
- /*global module, require, sinon*/
1385
- /**
1386
- * Mock functions.
1387
- *
1388
- * @author Christian Johansen (christian@cjohansen.no)
1389
- * @license BSD
1390
- *
1391
- * Copyright (c) 2010-2011 Christian Johansen
1392
- */
1393
-
1394
- (function (sinon) {
1395
- var commonJSModule = typeof module == "object" && typeof require == "function";
1396
- var push = [].push;
1397
-
1398
- if (!sinon && commonJSModule) {
1399
- sinon = require("../sinon");
1400
- }
1401
-
1402
- if (!sinon) {
1403
- return;
1404
- }
1405
-
1406
- function mock(object) {
1407
- if (!object) {
1408
- return sinon.expectation.create("Anonymous mock");
1409
- }
1410
-
1411
- return mock.create(object);
1412
- }
1413
-
1414
- sinon.mock = mock;
1415
-
1416
- sinon.extend(mock, (function () {
1417
- function each(collection, callback) {
1418
- if (!collection) {
1419
- return;
1420
- }
1421
-
1422
- for (var i = 0, l = collection.length; i < l; i += 1) {
1423
- callback(collection[i]);
1424
- }
1425
- }
1426
-
1427
- return {
1428
- create: function create(object) {
1429
- if (!object) {
1430
- throw new TypeError("object is null");
1431
- }
1432
-
1433
- var mockObject = sinon.extend({}, mock);
1434
- mockObject.object = object;
1435
- delete mockObject.create;
1436
-
1437
- return mockObject;
1438
- },
1439
-
1440
- expects: function expects(method) {
1441
- if (!method) {
1442
- throw new TypeError("method is falsy");
1443
- }
1444
-
1445
- if (!this.expectations) {
1446
- this.expectations = {};
1447
- this.proxies = [];
1448
- }
1449
-
1450
- if (!this.expectations[method]) {
1451
- this.expectations[method] = [];
1452
- var mockObject = this;
1453
-
1454
- sinon.wrapMethod(this.object, method, function () {
1455
- return mockObject.invokeMethod(method, this, arguments);
1456
- });
1457
-
1458
- push.call(this.proxies, method);
1459
- }
1460
-
1461
- var expectation = sinon.expectation.create(method);
1462
- push.call(this.expectations[method], expectation);
1463
-
1464
- return expectation;
1465
- },
1466
-
1467
- restore: function restore() {
1468
- var object = this.object;
1469
-
1470
- each(this.proxies, function (proxy) {
1471
- if (typeof object[proxy].restore == "function") {
1472
- object[proxy].restore();
1473
- }
1474
- });
1475
- },
1476
-
1477
- verify: function verify() {
1478
- var expectations = this.expectations || {};
1479
- var messages = [], met = [];
1480
-
1481
- each(this.proxies, function (proxy) {
1482
- each(expectations[proxy], function (expectation) {
1483
- if (!expectation.met()) {
1484
- push.call(messages, expectation.toString());
1485
- } else {
1486
- push.call(met, expectation.toString());
1487
- }
1488
- });
1489
- });
1490
-
1491
- this.restore();
1492
-
1493
- if (messages.length > 0) {
1494
- sinon.expectation.fail(messages.concat(met).join("\n"));
1495
- }
1496
-
1497
- return true;
1498
- },
1499
-
1500
- invokeMethod: function invokeMethod(method, thisValue, args) {
1501
- var expectations = this.expectations && this.expectations[method];
1502
- var length = expectations && expectations.length || 0;
1503
-
1504
- for (var i = 0; i < length; i += 1) {
1505
- if (!expectations[i].met() &&
1506
- expectations[i].allowsCall(thisValue, args)) {
1507
- return expectations[i].apply(thisValue, args);
1508
- }
1509
- }
1510
-
1511
- var messages = [];
1512
-
1513
- for (i = 0; i < length; i += 1) {
1514
- push.call(messages, " " + expectations[i].toString());
1515
- }
1516
-
1517
- messages.unshift("Unexpected call: " + sinon.spyCall.toString.call({
1518
- proxy: method,
1519
- args: args
1520
- }));
1521
-
1522
- sinon.expectation.fail(messages.join("\n"));
1523
- }
1524
- };
1525
- }()));
1526
-
1527
- var times = sinon.timesInWords;
1528
-
1529
- sinon.expectation = (function () {
1530
- var slice = Array.prototype.slice;
1531
- var _invoke = sinon.spy.invoke;
1532
-
1533
- function callCountInWords(callCount) {
1534
- if (callCount == 0) {
1535
- return "never called";
1536
- } else {
1537
- return "called " + times(callCount);
1538
- }
1539
- }
1540
-
1541
- function expectedCallCountInWords(expectation) {
1542
- var min = expectation.minCalls;
1543
- var max = expectation.maxCalls;
1544
-
1545
- if (typeof min == "number" && typeof max == "number") {
1546
- var str = times(min);
1547
-
1548
- if (min != max) {
1549
- str = "at least " + str + " and at most " + times(max);
1550
- }
1551
-
1552
- return str;
1553
- }
1554
-
1555
- if (typeof min == "number") {
1556
- return "at least " + times(min);
1557
- }
1558
-
1559
- return "at most " + times(max);
1560
- }
1561
-
1562
- function receivedMinCalls(expectation) {
1563
- var hasMinLimit = typeof expectation.minCalls == "number";
1564
- return !hasMinLimit || expectation.callCount >= expectation.minCalls;
1565
- }
1566
-
1567
- function receivedMaxCalls(expectation) {
1568
- if (typeof expectation.maxCalls != "number") {
1569
- return false;
1570
- }
1571
-
1572
- return expectation.callCount == expectation.maxCalls;
1573
- }
1574
-
1575
- return {
1576
- minCalls: 1,
1577
- maxCalls: 1,
1578
-
1579
- create: function create(methodName) {
1580
- var expectation = sinon.extend(sinon.stub.create(), sinon.expectation);
1581
- delete expectation.create;
1582
- expectation.method = methodName;
1583
-
1584
- return expectation;
1585
- },
1586
-
1587
- invoke: function invoke(func, thisValue, args) {
1588
- this.verifyCallAllowed(thisValue, args);
1589
-
1590
- return _invoke.apply(this, arguments);
1591
- },
1592
-
1593
- atLeast: function atLeast(num) {
1594
- if (typeof num != "number") {
1595
- throw new TypeError("'" + num + "' is not number");
1596
- }
1597
-
1598
- if (!this.limitsSet) {
1599
- this.maxCalls = null;
1600
- this.limitsSet = true;
1601
- }
1602
-
1603
- this.minCalls = num;
1604
-
1605
- return this;
1606
- },
1607
-
1608
- atMost: function atMost(num) {
1609
- if (typeof num != "number") {
1610
- throw new TypeError("'" + num + "' is not number");
1611
- }
1612
-
1613
- if (!this.limitsSet) {
1614
- this.minCalls = null;
1615
- this.limitsSet = true;
1616
- }
1617
-
1618
- this.maxCalls = num;
1619
-
1620
- return this;
1621
- },
1622
-
1623
- never: function never() {
1624
- return this.exactly(0);
1625
- },
1626
-
1627
- once: function once() {
1628
- return this.exactly(1);
1629
- },
1630
-
1631
- twice: function twice() {
1632
- return this.exactly(2);
1633
- },
1634
-
1635
- thrice: function thrice() {
1636
- return this.exactly(3);
1637
- },
1638
-
1639
- exactly: function exactly(num) {
1640
- if (typeof num != "number") {
1641
- throw new TypeError("'" + num + "' is not a number");
1642
- }
1643
-
1644
- this.atLeast(num);
1645
- return this.atMost(num);
1646
- },
1647
-
1648
- met: function met() {
1649
- return !this.failed && receivedMinCalls(this);
1650
- },
1651
-
1652
- verifyCallAllowed: function verifyCallAllowed(thisValue, args) {
1653
- if (receivedMaxCalls(this)) {
1654
- this.failed = true;
1655
- sinon.expectation.fail(this.method + " already called " + times(this.maxCalls));
1656
- }
1657
-
1658
- if ("expectedThis" in this && this.expectedThis !== thisValue) {
1659
- sinon.expectation.fail(this.method + " called with " + thisValue + " as thisValue, expected " +
1660
- this.expectedThis);
1661
- }
1662
-
1663
- if (!("expectedArguments" in this)) {
1664
- return;
1665
- }
1666
-
1667
- if (!args || args.length === 0) {
1668
- sinon.expectation.fail(this.method + " received no arguments, expected " +
1669
- this.expectedArguments.join());
1670
- }
1671
-
1672
- if (args.length < this.expectedArguments.length) {
1673
- sinon.expectation.fail(this.method + " received too few arguments (" + args.join() +
1674
- "), expected " + this.expectedArguments.join());
1675
- }
1676
-
1677
- if (this.expectsExactArgCount &&
1678
- args.length != this.expectedArguments.length) {
1679
- sinon.expectation.fail(this.method + " received too many arguments (" + args.join() +
1680
- "), expected " + this.expectedArguments.join());
1681
- }
1682
-
1683
- for (var i = 0, l = this.expectedArguments.length; i < l; i += 1) {
1684
- if (!sinon.deepEqual(this.expectedArguments[i], args[i])) {
1685
- sinon.expectation.fail(this.method + " received wrong arguments (" + args.join() +
1686
- "), expected " + this.expectedArguments.join());
1687
- }
1688
- }
1689
- },
1690
-
1691
- allowsCall: function allowsCall(thisValue, args) {
1692
- if (this.met()) {
1693
- return false;
1694
- }
1695
-
1696
- if ("expectedThis" in this && this.expectedThis !== thisValue) {
1697
- return false;
1698
- }
1699
-
1700
- if (!("expectedArguments" in this)) {
1701
- return true;
1702
- }
1703
-
1704
- args = args || [];
1705
-
1706
- if (args.length < this.expectedArguments.length) {
1707
- return false;
1708
- }
1709
-
1710
- if (this.expectsExactArgCount &&
1711
- args.length != this.expectedArguments.length) {
1712
- return false;
1713
- }
1714
-
1715
- for (var i = 0, l = this.expectedArguments.length; i < l; i += 1) {
1716
- if (!sinon.deepEqual(this.expectedArguments[i], args[i])) {
1717
- return false;
1718
- }
1719
- }
1720
-
1721
- return true;
1722
- },
1723
-
1724
- withArgs: function withArgs() {
1725
- this.expectedArguments = slice.call(arguments);
1726
- return this;
1727
- },
1728
-
1729
- withExactArgs: function withExactArgs() {
1730
- this.withArgs.apply(this, arguments);
1731
- this.expectsExactArgCount = true;
1732
- return this;
1733
- },
1734
-
1735
- on: function on(thisValue) {
1736
- this.expectedThis = thisValue;
1737
- return this;
1738
- },
1739
-
1740
- toString: function () {
1741
- var args = (this.expectedArguments || []).slice();
1742
-
1743
- if (!this.expectsExactArgCount) {
1744
- push.call(args, "[...]");
1745
- }
1746
-
1747
- var callStr = sinon.spyCall.toString.call({
1748
- proxy: this.method, args: args
1749
- });
1750
-
1751
- var message = callStr.replace(", [...", "[, ...") + " " +
1752
- expectedCallCountInWords(this);
1753
-
1754
- if (this.met()) {
1755
- return "Expectation met: " + message;
1756
- }
1757
-
1758
- return "Expected " + message + " (" +
1759
- callCountInWords(this.callCount) + ")";
1760
- },
1761
-
1762
- verify: function verify() {
1763
- if (!this.met()) {
1764
- sinon.expectation.fail(this.toString());
1765
- }
1766
-
1767
- return true;
1768
- },
1769
-
1770
- fail: function (message) {
1771
- var exception = new Error(message);
1772
- exception.name = "ExpectationError";
1773
-
1774
- throw exception;
1775
- }
1776
- };
1777
- }());
1778
-
1779
- if (commonJSModule) {
1780
- module.exports = mock;
1781
- } else {
1782
- sinon.mock = mock;
1783
- }
1784
- }(typeof sinon == "object" && sinon || null));
1785
-
1786
- /**
1787
- * @depend ../sinon.js
1788
- * @depend stub.js
1789
- * @depend mock.js
1790
- */
1791
- /*jslint eqeqeq: false, onevar: false, forin: true*/
1792
- /*global module, require, sinon*/
1793
- /**
1794
- * Collections of stubs, spies and mocks.
1795
- *
1796
- * @author Christian Johansen (christian@cjohansen.no)
1797
- * @license BSD
1798
- *
1799
- * Copyright (c) 2010-2011 Christian Johansen
1800
- */
1801
-
1802
- (function (sinon) {
1803
- var commonJSModule = typeof module == "object" && typeof require == "function";
1804
- var push = [].push;
1805
-
1806
- if (!sinon && commonJSModule) {
1807
- sinon = require("../sinon");
1808
- }
1809
-
1810
- if (!sinon) {
1811
- return;
1812
- }
1813
-
1814
- function getFakes(fakeCollection) {
1815
- if (!fakeCollection.fakes) {
1816
- fakeCollection.fakes = [];
1817
- }
1818
-
1819
- return fakeCollection.fakes;
1820
- }
1821
-
1822
- function each(fakeCollection, method) {
1823
- var fakes = getFakes(fakeCollection);
1824
-
1825
- for (var i = 0, l = fakes.length; i < l; i += 1) {
1826
- if (typeof fakes[i][method] == "function") {
1827
- fakes[i][method]();
1828
- }
1829
- }
1830
- }
1831
-
1832
- function compact(fakeCollection) {
1833
- var fakes = getFakes(fakeCollection);
1834
- var i = 0;
1835
- while (i < fakes.length) {
1836
- fakes.splice(i, 1);
1837
- }
1838
- }
1839
-
1840
- var collection = {
1841
- verify: function resolve() {
1842
- each(this, "verify");
1843
- },
1844
-
1845
- restore: function restore() {
1846
- each(this, "restore");
1847
- compact(this);
1848
- },
1849
-
1850
- verifyAndRestore: function verifyAndRestore() {
1851
- var exception;
1852
-
1853
- try {
1854
- this.verify();
1855
- } catch (e) {
1856
- exception = e;
1857
- }
1858
-
1859
- this.restore();
1860
-
1861
- if (exception) {
1862
- throw exception;
1863
- }
1864
- },
1865
-
1866
- add: function add(fake) {
1867
- push.call(getFakes(this), fake);
1868
- return fake;
1869
- },
1870
-
1871
- spy: function spy() {
1872
- return this.add(sinon.spy.apply(sinon, arguments));
1873
- },
1874
-
1875
- stub: function stub(object, property, value) {
1876
- if (property) {
1877
- var original = object[property];
1878
-
1879
- if (typeof original != "function") {
1880
- if (!object.hasOwnProperty(property)) {
1881
- throw new TypeError("Cannot stub non-existent own property " + property);
1882
- }
1883
-
1884
- object[property] = value;
1885
-
1886
- return this.add({
1887
- restore: function () {
1888
- object[property] = original;
1889
- }
1890
- });
1891
- }
1892
- }
1893
-
1894
- return this.add(sinon.stub.apply(sinon, arguments));
1895
- },
1896
-
1897
- mock: function mock() {
1898
- return this.add(sinon.mock.apply(sinon, arguments));
1899
- },
1900
-
1901
- inject: function inject(obj) {
1902
- var col = this;
1903
-
1904
- obj.spy = function () {
1905
- return col.spy.apply(col, arguments);
1906
- };
1907
-
1908
- obj.stub = function () {
1909
- return col.stub.apply(col, arguments);
1910
- };
1911
-
1912
- obj.mock = function () {
1913
- return col.mock.apply(col, arguments);
1914
- };
1915
-
1916
- return obj;
1917
- }
1918
- };
1919
-
1920
- if (commonJSModule) {
1921
- module.exports = collection;
1922
- } else {
1923
- sinon.collection = collection;
1924
- }
1925
- }(typeof sinon == "object" && sinon || null));
1926
-
1927
- /*jslint eqeqeq: false, plusplus: false, evil: true, onevar: false, browser: true, forin: false*/
1928
- /*global module, require, window*/
1929
- /**
1930
- * Fake timer API
1931
- * setTimeout
1932
- * setInterval
1933
- * clearTimeout
1934
- * clearInterval
1935
- * tick
1936
- * reset
1937
- * Date
1938
- *
1939
- * Inspired by jsUnitMockTimeOut from JsUnit
1940
- *
1941
- * @author Christian Johansen (christian@cjohansen.no)
1942
- * @license BSD
1943
- *
1944
- * Copyright (c) 2010-2011 Christian Johansen
1945
- */
1946
-
1947
- if (typeof sinon == "undefined") {
1948
- var sinon = {};
1949
- }
1950
-
1951
- (function (global) {
1952
- var id = 1;
1953
-
1954
- function addTimer(args, recurring) {
1955
- if (args.length === 0) {
1956
- throw new Error("Function requires at least 1 parameter");
1957
- }
1958
-
1959
- var toId = id++;
1960
- var delay = args[1] || 0;
1961
-
1962
- if (!this.timeouts) {
1963
- this.timeouts = {};
1964
- }
1965
-
1966
- this.timeouts[toId] = {
1967
- id: toId,
1968
- func: args[0],
1969
- callAt: this.now + delay
1970
- };
1971
-
1972
- if (recurring === true) {
1973
- this.timeouts[toId].interval = delay;
1974
- }
1975
-
1976
- return toId;
1977
- }
1978
-
1979
- function parseTime(str) {
1980
- if (!str) {
1981
- return 0;
1982
- }
1983
-
1984
- var strings = str.split(":");
1985
- var l = strings.length, i = l;
1986
- var ms = 0, parsed;
1987
-
1988
- if (l > 3 || !/^(\d\d:){0,2}\d\d?$/.test(str)) {
1989
- throw new Error("tick only understands numbers and 'h:m:s'");
1990
- }
1991
-
1992
- while (i--) {
1993
- parsed = parseInt(strings[i], 10);
1994
-
1995
- if (parsed >= 60) {
1996
- throw new Error("Invalid time " + str);
1997
- }
1998
-
1999
- ms += parsed * Math.pow(60, (l - i - 1));
2000
- }
2001
-
2002
- return ms * 1000;
2003
- }
2004
-
2005
- function createObject(object) {
2006
- var newObject;
2007
-
2008
- if (Object.create) {
2009
- newObject = Object.create(object);
2010
- } else {
2011
- var F = function () {};
2012
- F.prototype = object;
2013
- newObject = new F();
2014
- }
2015
-
2016
- newObject.Date.clock = newObject;
2017
- return newObject;
2018
- }
2019
-
2020
- sinon.clock = {
2021
- now: 0,
2022
-
2023
- create: function create(now) {
2024
- var clock = createObject(this);
2025
-
2026
- if (typeof now == "number") {
2027
- clock.now = now;
2028
- }
2029
-
2030
- if (!!now && typeof now == "object") {
2031
- throw new TypeError("now should be milliseconds since UNIX epoch");
2032
- }
2033
-
2034
- return clock;
2035
- },
2036
-
2037
- setTimeout: function setTimeout(callback, timeout) {
2038
- return addTimer.call(this, arguments, false);
2039
- },
2040
-
2041
- clearTimeout: function clearTimeout(timerId) {
2042
- if (!this.timeouts) {
2043
- this.timeouts = [];
2044
- }
2045
-
2046
- if (timerId in this.timeouts) {
2047
- delete this.timeouts[timerId];
2048
- }
2049
- },
2050
-
2051
- setInterval: function setInterval(callback, timeout) {
2052
- return addTimer.call(this, arguments, true);
2053
- },
2054
-
2055
- clearInterval: function clearInterval(timerId) {
2056
- this.clearTimeout(timerId);
2057
- },
2058
-
2059
- tick: function tick(ms) {
2060
- ms = typeof ms == "number" ? ms : parseTime(ms);
2061
- var tickFrom = this.now, tickTo = this.now + ms, previous = this.now;
2062
- var timer = this.firstTimerInRange(tickFrom, tickTo);
2063
-
2064
- var firstException;
2065
- while (timer && tickFrom <= tickTo) {
2066
- if (this.timeouts[timer.id]) {
2067
- tickFrom = this.now = timer.callAt;
2068
- try {
2069
- this.callTimer(timer);
2070
- } catch (e) {
2071
- firstException = firstException || e;
2072
- }
2073
- }
2074
-
2075
- timer = this.firstTimerInRange(previous, tickTo);
2076
- previous = tickFrom;
2077
- }
2078
-
2079
- this.now = tickTo;
2080
-
2081
- if (firstException) {
2082
- throw firstException;
2083
- }
2084
- },
2085
-
2086
- firstTimerInRange: function (from, to) {
2087
- var timer, smallest, originalTimer;
2088
-
2089
- for (var id in this.timeouts) {
2090
- if (this.timeouts.hasOwnProperty(id)) {
2091
- if (this.timeouts[id].callAt < from || this.timeouts[id].callAt > to) {
2092
- continue;
2093
- }
2094
-
2095
- if (!smallest || this.timeouts[id].callAt < smallest) {
2096
- originalTimer = this.timeouts[id];
2097
- smallest = this.timeouts[id].callAt;
2098
-
2099
- timer = {
2100
- func: this.timeouts[id].func,
2101
- callAt: this.timeouts[id].callAt,
2102
- interval: this.timeouts[id].interval,
2103
- id: this.timeouts[id].id
2104
- };
2105
- }
2106
- }
2107
- }
2108
-
2109
- return timer || null;
2110
- },
2111
-
2112
- callTimer: function (timer) {
2113
- try {
2114
- if (typeof timer.func == "function") {
2115
- timer.func.call(null);
2116
- } else {
2117
- eval(timer.func);
2118
- }
2119
- } catch (e) {
2120
- var exception = e;
2121
- }
2122
-
2123
- if (!this.timeouts[timer.id]) {
2124
- if (exception) {
2125
- throw exception;
2126
- }
2127
- return;
2128
- }
2129
-
2130
- if (typeof timer.interval == "number") {
2131
- this.timeouts[timer.id].callAt += timer.interval;
2132
- } else {
2133
- delete this.timeouts[timer.id];
2134
- }
2135
-
2136
- if (exception) {
2137
- throw exception;
2138
- }
2139
- },
2140
-
2141
- reset: function reset() {
2142
- this.timeouts = {};
2143
- },
2144
-
2145
- Date: (function () {
2146
- var NativeDate = Date;
2147
-
2148
- function ClockDate(year, month, date, hour, minute, second, ms) {
2149
- // Defensive and verbose to avoid potential harm in passing
2150
- // explicit undefined when user does not pass argument
2151
- switch (arguments.length) {
2152
- case 0:
2153
- return new NativeDate(ClockDate.clock.now);
2154
- case 1:
2155
- return new NativeDate(year);
2156
- case 2:
2157
- return new NativeDate(year, month);
2158
- case 3:
2159
- return new NativeDate(year, month, date);
2160
- case 4:
2161
- return new NativeDate(year, month, date, hour);
2162
- case 5:
2163
- return new NativeDate(year, month, date, hour, minute);
2164
- case 6:
2165
- return new NativeDate(year, month, date, hour, minute, second);
2166
- default:
2167
- return new NativeDate(year, month, date, hour, minute, second, ms);
2168
- }
2169
- }
2170
-
2171
- return mirrorDateProperties(ClockDate, NativeDate);
2172
- }())
2173
- };
2174
-
2175
- function mirrorDateProperties(target, source) {
2176
- if (source.now) {
2177
- target.now = function now() {
2178
- return target.clock.now;
2179
- };
2180
- } else {
2181
- delete target.now;
2182
- }
2183
-
2184
- if (source.toSource) {
2185
- target.toSource = function toSource() {
2186
- return source.toSource();
2187
- };
2188
- } else {
2189
- delete target.toSource;
2190
- }
2191
-
2192
- target.toString = function toString() {
2193
- return source.toString();
2194
- };
2195
-
2196
- target.prototype = source.prototype;
2197
- target.parse = source.parse;
2198
- target.UTC = source.UTC;
2199
- target.prototype.toUTCString = source.prototype.toUTCString;
2200
- return target;
2201
- }
2202
-
2203
- var methods = ["Date", "setTimeout", "setInterval",
2204
- "clearTimeout", "clearInterval"];
2205
-
2206
- function restore() {
2207
- var method;
2208
-
2209
- for (var i = 0, l = this.methods.length; i < l; i++) {
2210
- method = this.methods[i];
2211
- global[method] = this["_" + method];
2212
- }
2213
- }
2214
-
2215
- function stubGlobal(method, clock) {
2216
- clock["_" + method] = global[method];
2217
-
2218
- if (method == "Date") {
2219
- var date = mirrorDateProperties(clock[method], global[method]);
2220
- global[method] = date;
2221
- } else {
2222
- global[method] = function () {
2223
- return clock[method].apply(clock, arguments);
2224
- };
2225
-
2226
- for (var prop in clock[method]) {
2227
- if (clock[method].hasOwnProperty(prop)) {
2228
- global[method][prop] = clock[method][prop];
2229
- }
2230
- }
2231
- }
2232
-
2233
- global[method].clock = clock;
2234
- }
2235
-
2236
- sinon.useFakeTimers = function useFakeTimers(now) {
2237
- var clock = sinon.clock.create(now);
2238
- clock.restore = restore;
2239
- clock.methods = Array.prototype.slice.call(arguments,
2240
- typeof now == "number" ? 1 : 0);
2241
-
2242
- if (clock.methods.length === 0) {
2243
- clock.methods = methods;
2244
- }
2245
-
2246
- for (var i = 0, l = clock.methods.length; i < l; i++) {
2247
- stubGlobal(clock.methods[i], clock);
2248
- }
2249
-
2250
- return clock;
2251
- };
2252
- }(typeof global != "undefined" && typeof global !== "function" ? global : this));
2253
-
2254
- sinon.timers = {
2255
- setTimeout: setTimeout,
2256
- clearTimeout: clearTimeout,
2257
- setInterval: setInterval,
2258
- clearInterval: clearInterval,
2259
- Date: Date
2260
- };
2261
-
2262
- if (typeof module == "object" && typeof require == "function") {
2263
- module.exports = sinon;
2264
- }
2265
-
2266
- /*jslint eqeqeq: false, onevar: false*/
2267
- /*global sinon, module, require, ActiveXObject, XMLHttpRequest, DOMParser*/
2268
- /**
2269
- * Minimal Event interface implementation
2270
- *
2271
- * Original implementation by Sven Fuchs: https://gist.github.com/995028
2272
- * Modifications and tests by Christian Johansen.
2273
- *
2274
- * @author Sven Fuchs (svenfuchs@artweb-design.de)
2275
- * @author Christian Johansen (christian@cjohansen.no)
2276
- * @license BSD
2277
- *
2278
- * Copyright (c) 2011 Sven Fuchs, Christian Johansen
2279
- */
2280
-
2281
- if (typeof sinon == "undefined") {
2282
- this.sinon = {};
2283
- }
2284
-
2285
- (function () {
2286
- var push = [].push;
2287
-
2288
- sinon.Event = function Event(type, bubbles, cancelable) {
2289
- this.initEvent(type, bubbles, cancelable);
2290
- };
2291
-
2292
- sinon.Event.prototype = {
2293
- initEvent: function(type, bubbles, cancelable) {
2294
- this.type = type;
2295
- this.bubbles = bubbles;
2296
- this.cancelable = cancelable;
2297
- },
2298
-
2299
- stopPropagation: function () {},
2300
-
2301
- preventDefault: function () {
2302
- this.defaultPrevented = true;
2303
- }
2304
- };
2305
-
2306
- sinon.EventTarget = {
2307
- addEventListener: function addEventListener(event, listener, useCapture) {
2308
- this.eventListeners = this.eventListeners || {};
2309
- this.eventListeners[event] = this.eventListeners[event] || [];
2310
- push.call(this.eventListeners[event], listener);
2311
- },
2312
-
2313
- removeEventListener: function removeEventListener(event, listener, useCapture) {
2314
- var listeners = this.eventListeners && this.eventListeners[event] || [];
2315
-
2316
- for (var i = 0, l = listeners.length; i < l; ++i) {
2317
- if (listeners[i] == listener) {
2318
- return listeners.splice(i, 1);
2319
- }
2320
- }
2321
- },
2322
-
2323
- dispatchEvent: function dispatchEvent(event) {
2324
- var type = event.type;
2325
- var listeners = this.eventListeners && this.eventListeners[type] || [];
2326
-
2327
- for (var i = 0; i < listeners.length; i++) {
2328
- if (typeof listeners[i] == "function") {
2329
- listeners[i].call(this, event);
2330
- } else {
2331
- listeners[i].handleEvent(event);
2332
- }
2333
- }
2334
-
2335
- return !!event.defaultPrevented;
2336
- }
2337
- };
2338
- }());
2339
-
2340
- /**
2341
- * @depend event.js
2342
- */
2343
- /*jslint eqeqeq: false, onevar: false*/
2344
- /*global sinon, module, require, ActiveXObject, XMLHttpRequest, DOMParser*/
2345
- /**
2346
- * Fake XMLHttpRequest object
2347
- *
2348
- * @author Christian Johansen (christian@cjohansen.no)
2349
- * @license BSD
2350
- *
2351
- * Copyright (c) 2010-2011 Christian Johansen
2352
- */
2353
-
2354
- if (typeof sinon == "undefined") {
2355
- this.sinon = {};
2356
- }
2357
- sinon.xhr = { XMLHttpRequest: this.XMLHttpRequest };
2358
-
2359
- // wrapper for global
2360
- (function(global) {
2361
- var xhr = sinon.xhr;
2362
- xhr.GlobalXMLHttpRequest = global.XMLHttpRequest;
2363
- xhr.GlobalActiveXObject = global.ActiveXObject;
2364
- xhr.supportsActiveX = typeof xhr.GlobalActiveXObject != "undefined";
2365
- xhr.supportsXHR = typeof xhr.GlobalXMLHttpRequest != "undefined";
2366
- xhr.workingXHR = xhr.supportsXHR ? xhr.GlobalXMLHttpRequest : xhr.supportsActiveX
2367
- ? function() { return new xhr.GlobalActiveXObject("MSXML2.XMLHTTP.3.0") } : false;
2368
-
2369
- /*jsl:ignore*/
2370
- var unsafeHeaders = {
2371
- "Accept-Charset": true,
2372
- "Accept-Encoding": true,
2373
- "Connection": true,
2374
- "Content-Length": true,
2375
- "Cookie": true,
2376
- "Cookie2": true,
2377
- "Content-Transfer-Encoding": true,
2378
- "Date": true,
2379
- "Expect": true,
2380
- "Host": true,
2381
- "Keep-Alive": true,
2382
- "Referer": true,
2383
- "TE": true,
2384
- "Trailer": true,
2385
- "Transfer-Encoding": true,
2386
- "Upgrade": true,
2387
- "User-Agent": true,
2388
- "Via": true
2389
- };
2390
- /*jsl:end*/
2391
-
2392
- function FakeXMLHttpRequest() {
2393
- this.readyState = FakeXMLHttpRequest.UNSENT;
2394
- this.requestHeaders = {};
2395
- this.requestBody = null;
2396
- this.status = 0;
2397
- this.statusText = "";
2398
-
2399
- if (typeof FakeXMLHttpRequest.onCreate == "function") {
2400
- FakeXMLHttpRequest.onCreate(this);
2401
- }
2402
- }
2403
-
2404
- function verifyState(xhr) {
2405
- if (xhr.readyState !== FakeXMLHttpRequest.OPENED) {
2406
- throw new Error("INVALID_STATE_ERR");
2407
- }
2408
-
2409
- if (xhr.sendFlag) {
2410
- throw new Error("INVALID_STATE_ERR");
2411
- }
2412
- }
2413
-
2414
- // filtering to enable a white-list version of Sinon FakeXhr,
2415
- // where whitelisted requests are passed through to real XHR
2416
- function each(collection, callback) {
2417
- if (!collection) return;
2418
- for (var i = 0, l = collection.length; i < l; i += 1) {
2419
- callback(collection[i]);
2420
- }
2421
- }
2422
- function some(collection, callback) {
2423
- for (var index = 0; index < collection.length; index++) {
2424
- if(callback(collection[index]) === true) return true;
2425
- };
2426
- return false;
2427
- }
2428
- // largest arity in XHR is 5 - XHR#open
2429
- var apply = function(obj,method,args) {
2430
- switch(args.length) {
2431
- case 0: return obj[method]();
2432
- case 1: return obj[method](args[0]);
2433
- case 2: return obj[method](args[0],args[1]);
2434
- case 3: return obj[method](args[0],args[1],args[2]);
2435
- case 4: return obj[method](args[0],args[1],args[2],args[3]);
2436
- case 5: return obj[method](args[0],args[1],args[2],args[3],args[4]);
2437
- };
2438
- };
2439
-
2440
- FakeXMLHttpRequest.filters = [];
2441
- FakeXMLHttpRequest.addFilter = function(fn) {
2442
- this.filters.push(fn)
2443
- };
2444
- var IE6Re = /MSIE 6/;
2445
- FakeXMLHttpRequest.defake = function(fakeXhr,xhrArgs) {
2446
- var xhr = new sinon.xhr.workingXHR();
2447
- each(["open","setRequestHeader","send","abort","getResponseHeader",
2448
- "getAllResponseHeaders","addEventListener","overrideMimeType","removeEventListener"],
2449
- function(method) {
2450
- fakeXhr[method] = function() {
2451
- return apply(xhr,method,arguments);
2452
- };
2453
- });
2454
-
2455
- var copyAttrs = function(args) {
2456
- each(args, function(attr) {
2457
- try {
2458
- fakeXhr[attr] = xhr[attr]
2459
- } catch(e) {
2460
- if(!IE6Re.test(navigator.userAgent)) throw e;
2461
- }
2462
- });
2463
- };
2464
-
2465
- var stateChange = function() {
2466
- fakeXhr.readyState = xhr.readyState;
2467
- if(xhr.readyState >= FakeXMLHttpRequest.HEADERS_RECEIVED) {
2468
- copyAttrs(["status","statusText"]);
2469
- }
2470
- if(xhr.readyState >= FakeXMLHttpRequest.LOADING) {
2471
- copyAttrs(["responseText"]);
2472
- }
2473
- if(xhr.readyState === FakeXMLHttpRequest.DONE) {
2474
- copyAttrs(["responseXML"]);
2475
- }
2476
- if(fakeXhr.onreadystatechange) fakeXhr.onreadystatechange.call(fakeXhr);
2477
- };
2478
- if(xhr.addEventListener) {
2479
- for(var event in fakeXhr.eventListeners) {
2480
- if(fakeXhr.eventListeners.hasOwnProperty(event)) {
2481
- each(fakeXhr.eventListeners[event],function(handler) {
2482
- xhr.addEventListener(event, handler);
2483
- });
2484
- }
2485
- }
2486
- xhr.addEventListener("readystatechange",stateChange);
2487
- } else {
2488
- xhr.onreadystatechange = stateChange;
2489
- }
2490
- apply(xhr,"open",xhrArgs);
2491
- };
2492
- FakeXMLHttpRequest.useFilters = false;
2493
-
2494
- function verifyRequestSent(xhr) {
2495
- if (xhr.readyState == FakeXMLHttpRequest.DONE) {
2496
- throw new Error("Request done");
2497
- }
2498
- }
2499
-
2500
- function verifyHeadersReceived(xhr) {
2501
- if (xhr.async && xhr.readyState != FakeXMLHttpRequest.HEADERS_RECEIVED) {
2502
- throw new Error("No headers received");
2503
- }
2504
- }
2505
-
2506
- function verifyResponseBodyType(body) {
2507
- if (typeof body != "string") {
2508
- var error = new Error("Attempted to respond to fake XMLHttpRequest with " +
2509
- body + ", which is not a string.");
2510
- error.name = "InvalidBodyException";
2511
- throw error;
2512
- }
2513
- }
2514
-
2515
- sinon.extend(FakeXMLHttpRequest.prototype, sinon.EventTarget, {
2516
- async: true,
2517
-
2518
- open: function open(method, url, async, username, password) {
2519
- this.method = method;
2520
- this.url = url;
2521
- this.async = typeof async == "boolean" ? async : true;
2522
- this.username = username;
2523
- this.password = password;
2524
- this.responseText = null;
2525
- this.responseXML = null;
2526
- this.requestHeaders = {};
2527
- this.sendFlag = false;
2528
- if(sinon.FakeXMLHttpRequest.useFilters === true) {
2529
- var xhrArgs = arguments;
2530
- var defake = some(FakeXMLHttpRequest.filters,function(filter) {
2531
- return filter.apply(this,xhrArgs)
2532
- });
2533
- if (defake) {
2534
- return sinon.FakeXMLHttpRequest.defake(this,arguments);
2535
- }
2536
- }
2537
- this.readyStateChange(FakeXMLHttpRequest.OPENED);
2538
- },
2539
-
2540
- readyStateChange: function readyStateChange(state) {
2541
- this.readyState = state;
2542
-
2543
- if (typeof this.onreadystatechange == "function") {
2544
- try {
2545
- this.onreadystatechange();
2546
- } catch (e) {
2547
- sinon.logError("Fake XHR onreadystatechange handler", e);
2548
- }
2549
- }
2550
-
2551
- this.dispatchEvent(new sinon.Event("readystatechange"));
2552
- },
2553
-
2554
- setRequestHeader: function setRequestHeader(header, value) {
2555
- verifyState(this);
2556
-
2557
- if (unsafeHeaders[header] || /^(Sec-|Proxy-)/.test(header)) {
2558
- throw new Error("Refused to set unsafe header \"" + header + "\"");
2559
- }
2560
-
2561
- if (this.requestHeaders[header]) {
2562
- this.requestHeaders[header] += "," + value;
2563
- } else {
2564
- this.requestHeaders[header] = value;
2565
- }
2566
- },
2567
-
2568
- // Helps testing
2569
- setResponseHeaders: function setResponseHeaders(headers) {
2570
- this.responseHeaders = {};
2571
-
2572
- for (var header in headers) {
2573
- if (headers.hasOwnProperty(header)) {
2574
- this.responseHeaders[header] = headers[header];
2575
- }
2576
- }
2577
-
2578
- if (this.async) {
2579
- this.readyStateChange(FakeXMLHttpRequest.HEADERS_RECEIVED);
2580
- }
2581
- },
2582
-
2583
- // Currently treats ALL data as a DOMString (i.e. no Document)
2584
- send: function send(data) {
2585
- verifyState(this);
2586
-
2587
- if (!/^(get|head)$/i.test(this.method)) {
2588
- if (this.requestHeaders["Content-Type"]) {
2589
- var value = this.requestHeaders["Content-Type"].split(";");
2590
- this.requestHeaders["Content-Type"] = value[0] + ";charset=utf-8";
2591
- } else {
2592
- this.requestHeaders["Content-Type"] = "text/plain;charset=utf-8";
2593
- }
2594
-
2595
- this.requestBody = data;
2596
- }
2597
-
2598
- this.errorFlag = false;
2599
- this.sendFlag = this.async;
2600
- this.readyStateChange(FakeXMLHttpRequest.OPENED);
2601
-
2602
- if (typeof this.onSend == "function") {
2603
- this.onSend(this);
2604
- }
2605
- },
2606
-
2607
- abort: function abort() {
2608
- this.aborted = true;
2609
- this.responseText = null;
2610
- this.errorFlag = true;
2611
- this.requestHeaders = {};
2612
-
2613
- if (this.readyState > sinon.FakeXMLHttpRequest.UNSENT && this.sendFlag) {
2614
- this.readyStateChange(sinon.FakeXMLHttpRequest.DONE);
2615
- this.sendFlag = false;
2616
- }
2617
-
2618
- this.readyState = sinon.FakeXMLHttpRequest.UNSENT;
2619
- },
2620
-
2621
- getResponseHeader: function getResponseHeader(header) {
2622
- if (this.readyState < FakeXMLHttpRequest.HEADERS_RECEIVED) {
2623
- return null;
2624
- }
2625
-
2626
- if (/^Set-Cookie2?$/i.test(header)) {
2627
- return null;
2628
- }
2629
-
2630
- header = header.toLowerCase();
2631
-
2632
- for (var h in this.responseHeaders) {
2633
- if (h.toLowerCase() == header) {
2634
- return this.responseHeaders[h];
2635
- }
2636
- }
2637
-
2638
- return null;
2639
- },
2640
-
2641
- getAllResponseHeaders: function getAllResponseHeaders() {
2642
- if (this.readyState < FakeXMLHttpRequest.HEADERS_RECEIVED) {
2643
- return "";
2644
- }
2645
-
2646
- var headers = "";
2647
-
2648
- for (var header in this.responseHeaders) {
2649
- if (this.responseHeaders.hasOwnProperty(header) &&
2650
- !/^Set-Cookie2?$/i.test(header)) {
2651
- headers += header + ": " + this.responseHeaders[header] + "\r\n";
2652
- }
2653
- }
2654
-
2655
- return headers;
2656
- },
2657
-
2658
- setResponseBody: function setResponseBody(body) {
2659
- verifyRequestSent(this);
2660
- verifyHeadersReceived(this);
2661
- verifyResponseBodyType(body);
2662
-
2663
- var chunkSize = this.chunkSize || 10;
2664
- var index = 0;
2665
- this.responseText = "";
2666
-
2667
- do {
2668
- if (this.async) {
2669
- this.readyStateChange(FakeXMLHttpRequest.LOADING);
2670
- }
2671
-
2672
- this.responseText += body.substring(index, index + chunkSize);
2673
- index += chunkSize;
2674
- } while (index < body.length);
2675
-
2676
- var type = this.getResponseHeader("Content-Type");
2677
-
2678
- if (this.responseText &&
2679
- (!type || /(text\/xml)|(application\/xml)|(\+xml)/.test(type))) {
2680
- try {
2681
- this.responseXML = FakeXMLHttpRequest.parseXML(this.responseText);
2682
- } catch (e) {
2683
- // Unable to parse XML - no biggie
2684
- }
2685
- }
2686
-
2687
- if (this.async) {
2688
- this.readyStateChange(FakeXMLHttpRequest.DONE);
2689
- } else {
2690
- this.readyState = FakeXMLHttpRequest.DONE;
2691
- }
2692
- },
2693
-
2694
- respond: function respond(status, headers, body) {
2695
- this.setResponseHeaders(headers || {});
2696
- this.status = typeof status == "number" ? status : 200;
2697
- this.statusText = FakeXMLHttpRequest.statusCodes[this.status];
2698
- this.setResponseBody(body || "");
2699
- }
2700
- });
2701
-
2702
- sinon.extend(FakeXMLHttpRequest, {
2703
- UNSENT: 0,
2704
- OPENED: 1,
2705
- HEADERS_RECEIVED: 2,
2706
- LOADING: 3,
2707
- DONE: 4
2708
- });
2709
-
2710
- // Borrowed from JSpec
2711
- FakeXMLHttpRequest.parseXML = function parseXML(text) {
2712
- var xmlDoc;
2713
-
2714
- if (typeof DOMParser != "undefined") {
2715
- var parser = new DOMParser();
2716
- xmlDoc = parser.parseFromString(text, "text/xml");
2717
- } else {
2718
- xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
2719
- xmlDoc.async = "false";
2720
- xmlDoc.loadXML(text);
2721
- }
2722
-
2723
- return xmlDoc;
2724
- };
2725
-
2726
- FakeXMLHttpRequest.statusCodes = {
2727
- 100: "Continue",
2728
- 101: "Switching Protocols",
2729
- 200: "OK",
2730
- 201: "Created",
2731
- 202: "Accepted",
2732
- 203: "Non-Authoritative Information",
2733
- 204: "No Content",
2734
- 205: "Reset Content",
2735
- 206: "Partial Content",
2736
- 300: "Multiple Choice",
2737
- 301: "Moved Permanently",
2738
- 302: "Found",
2739
- 303: "See Other",
2740
- 304: "Not Modified",
2741
- 305: "Use Proxy",
2742
- 307: "Temporary Redirect",
2743
- 400: "Bad Request",
2744
- 401: "Unauthorized",
2745
- 402: "Payment Required",
2746
- 403: "Forbidden",
2747
- 404: "Not Found",
2748
- 405: "Method Not Allowed",
2749
- 406: "Not Acceptable",
2750
- 407: "Proxy Authentication Required",
2751
- 408: "Request Timeout",
2752
- 409: "Conflict",
2753
- 410: "Gone",
2754
- 411: "Length Required",
2755
- 412: "Precondition Failed",
2756
- 413: "Request Entity Too Large",
2757
- 414: "Request-URI Too Long",
2758
- 415: "Unsupported Media Type",
2759
- 416: "Requested Range Not Satisfiable",
2760
- 417: "Expectation Failed",
2761
- 422: "Unprocessable Entity",
2762
- 500: "Internal Server Error",
2763
- 501: "Not Implemented",
2764
- 502: "Bad Gateway",
2765
- 503: "Service Unavailable",
2766
- 504: "Gateway Timeout",
2767
- 505: "HTTP Version Not Supported"
2768
- };
2769
-
2770
- sinon.useFakeXMLHttpRequest = function () {
2771
- sinon.FakeXMLHttpRequest.restore = function restore(keepOnCreate) {
2772
- if (xhr.supportsXHR) {
2773
- global.XMLHttpRequest = xhr.GlobalXMLHttpRequest;
2774
- }
2775
-
2776
- if (xhr.supportsActiveX) {
2777
- global.ActiveXObject = xhr.GlobalActiveXObject;
2778
- }
2779
-
2780
- delete sinon.FakeXMLHttpRequest.restore;
2781
-
2782
- if (keepOnCreate !== true) {
2783
- delete sinon.FakeXMLHttpRequest.onCreate;
2784
- }
2785
- };
2786
- if (xhr.supportsXHR) {
2787
- global.XMLHttpRequest = sinon.FakeXMLHttpRequest;
2788
- }
2789
-
2790
- if (xhr.supportsActiveX) {
2791
- global.ActiveXObject = function ActiveXObject(objId) {
2792
- if (objId == "Microsoft.XMLHTTP" || /^Msxml2\.XMLHTTP/i.test(objId)) {
2793
-
2794
- return new sinon.FakeXMLHttpRequest();
2795
- }
2796
-
2797
- return new xhr.GlobalActiveXObject(objId);
2798
- };
2799
- }
2800
-
2801
- return sinon.FakeXMLHttpRequest;
2802
- };
2803
-
2804
- sinon.FakeXMLHttpRequest = FakeXMLHttpRequest;
2805
- })(this);
2806
-
2807
- if (typeof module == "object" && typeof require == "function") {
2808
- module.exports = sinon;
2809
- }
2810
-
2811
- /**
2812
- * @depend fake_xml_http_request.js
2813
- */
2814
- /*jslint eqeqeq: false, onevar: false, regexp: false, plusplus: false*/
2815
- /*global module, require, window*/
2816
- /**
2817
- * The Sinon "server" mimics a web server that receives requests from
2818
- * sinon.FakeXMLHttpRequest and provides an API to respond to those requests,
2819
- * both synchronously and asynchronously. To respond synchronuously, canned
2820
- * answers have to be provided upfront.
2821
- *
2822
- * @author Christian Johansen (christian@cjohansen.no)
2823
- * @license BSD
2824
- *
2825
- * Copyright (c) 2010-2011 Christian Johansen
2826
- */
2827
-
2828
- if (typeof sinon == "undefined") {
2829
- var sinon = {};
2830
- }
2831
-
2832
- sinon.fakeServer = (function () {
2833
- var push = [].push;
2834
- function F() {}
2835
-
2836
- function create(proto) {
2837
- F.prototype = proto;
2838
- return new F();
2839
- }
2840
-
2841
- function responseArray(handler) {
2842
- var response = handler;
2843
-
2844
- if (Object.prototype.toString.call(handler) != "[object Array]") {
2845
- response = [200, {}, handler];
2846
- }
2847
-
2848
- if (typeof response[2] != "string") {
2849
- throw new TypeError("Fake server response body should be string, but was " +
2850
- typeof response[2]);
2851
- }
2852
-
2853
- return response;
2854
- }
2855
-
2856
- var wloc = window.location;
2857
- var rCurrLoc = new RegExp("^" + wloc.protocol + "//" + wloc.host);
2858
-
2859
- function matchOne(response, reqMethod, reqUrl) {
2860
- var rmeth = response.method;
2861
- var matchMethod = !rmeth || rmeth.toLowerCase() == reqMethod.toLowerCase();
2862
- var url = response.url;
2863
- var matchUrl = !url || url == reqUrl || (typeof url.test == "function" && url.test(reqUrl));
2864
-
2865
- return matchMethod && matchUrl;
2866
- }
2867
-
2868
- function match(response, request) {
2869
- var requestMethod = this.getHTTPMethod(request);
2870
- var requestUrl = request.url;
2871
-
2872
- if (!/^https?:\/\//.test(requestUrl) || rCurrLoc.test(requestUrl)) {
2873
- requestUrl = requestUrl.replace(rCurrLoc, "");
2874
- }
2875
-
2876
- if (matchOne(response, this.getHTTPMethod(request), requestUrl)) {
2877
- if (typeof response.response == "function") {
2878
- var ru = response.url;
2879
- var args = [request].concat(!ru ? [] : requestUrl.match(ru).slice(1));
2880
- return response.response.apply(response, args);
2881
- }
2882
-
2883
- return true;
2884
- }
2885
-
2886
- return false;
2887
- }
2888
-
2889
- return {
2890
- create: function () {
2891
- var server = create(this);
2892
- this.xhr = sinon.useFakeXMLHttpRequest();
2893
- server.requests = [];
2894
-
2895
- this.xhr.onCreate = function (xhrObj) {
2896
- server.addRequest(xhrObj);
2897
- };
2898
-
2899
- return server;
2900
- },
2901
-
2902
- addRequest: function addRequest(xhrObj) {
2903
- var server = this;
2904
- push.call(this.requests, xhrObj);
2905
-
2906
- xhrObj.onSend = function () {
2907
- server.handleRequest(this);
2908
- };
2909
-
2910
- if (this.autoRespond && !this.responding) {
2911
- setTimeout(function () {
2912
- server.responding = false;
2913
- server.respond();
2914
- }, this.autoRespondAfter || 10);
2915
-
2916
- this.responding = true;
2917
- }
2918
- },
2919
-
2920
- getHTTPMethod: function getHTTPMethod(request) {
2921
- if (this.fakeHTTPMethods && /post/i.test(request.method)) {
2922
- var matches = (request.requestBody || "").match(/_method=([^\b;]+)/);
2923
- return !!matches ? matches[1] : request.method;
2924
- }
2925
-
2926
- return request.method;
2927
- },
2928
-
2929
- handleRequest: function handleRequest(xhr) {
2930
- if (xhr.async) {
2931
- if (!this.queue) {
2932
- this.queue = [];
2933
- }
2934
-
2935
- push.call(this.queue, xhr);
2936
- } else {
2937
- this.processRequest(xhr);
2938
- }
2939
- },
2940
-
2941
- respondWith: function respondWith(method, url, body) {
2942
- if (arguments.length == 1 && typeof method != "function") {
2943
- this.response = responseArray(method);
2944
- return;
2945
- }
2946
-
2947
- if (!this.responses) { this.responses = []; }
2948
-
2949
- if (arguments.length == 1) {
2950
- body = method;
2951
- url = method = null;
2952
- }
2953
-
2954
- if (arguments.length == 2) {
2955
- body = url;
2956
- url = method;
2957
- method = null;
2958
- }
2959
-
2960
- push.call(this.responses, {
2961
- method: method,
2962
- url: url,
2963
- response: typeof body == "function" ? body : responseArray(body)
2964
- });
2965
- },
2966
-
2967
- respond: function respond() {
2968
- if (arguments.length > 0) this.respondWith.apply(this, arguments);
2969
- var queue = this.queue || [];
2970
- var request;
2971
-
2972
- while(request = queue.shift()) {
2973
- this.processRequest(request);
2974
- }
2975
- },
2976
-
2977
- processRequest: function processRequest(request) {
2978
- try {
2979
- if (request.aborted) {
2980
- return;
2981
- }
2982
-
2983
- var response = this.response || [404, {}, ""];
2984
-
2985
- if (this.responses) {
2986
- for (var i = 0, l = this.responses.length; i < l; i++) {
2987
- if (match.call(this, this.responses[i], request)) {
2988
- response = this.responses[i].response;
2989
- break;
2990
- }
2991
- }
2992
- }
2993
-
2994
- if (request.readyState != 4) {
2995
- request.respond(response[0], response[1], response[2]);
2996
- }
2997
- } catch (e) {
2998
- sinon.logError("Fake server request processing", e);
2999
- }
3000
- },
3001
-
3002
- restore: function restore() {
3003
- return this.xhr.restore && this.xhr.restore.apply(this.xhr, arguments);
3004
- }
3005
- };
3006
- }());
3007
-
3008
- if (typeof module == "object" && typeof require == "function") {
3009
- module.exports = sinon;
3010
- }
3011
-
3012
- /**
3013
- * @depend fake_server.js
3014
- * @depend fake_timers.js
3015
- */
3016
- /*jslint browser: true, eqeqeq: false, onevar: false*/
3017
- /*global sinon*/
3018
- /**
3019
- * Add-on for sinon.fakeServer that automatically handles a fake timer along with
3020
- * the FakeXMLHttpRequest. The direct inspiration for this add-on is jQuery
3021
- * 1.3.x, which does not use xhr object's onreadystatehandler at all - instead,
3022
- * it polls the object for completion with setInterval. Dispite the direct
3023
- * motivation, there is nothing jQuery-specific in this file, so it can be used
3024
- * in any environment where the ajax implementation depends on setInterval or
3025
- * setTimeout.
3026
- *
3027
- * @author Christian Johansen (christian@cjohansen.no)
3028
- * @license BSD
3029
- *
3030
- * Copyright (c) 2010-2011 Christian Johansen
3031
- */
3032
-
3033
- (function () {
3034
- function Server() {}
3035
- Server.prototype = sinon.fakeServer;
3036
-
3037
- sinon.fakeServerWithClock = new Server();
3038
-
3039
- sinon.fakeServerWithClock.addRequest = function addRequest(xhr) {
3040
- if (xhr.async) {
3041
- if (typeof setTimeout.clock == "object") {
3042
- this.clock = setTimeout.clock;
3043
- } else {
3044
- this.clock = sinon.useFakeTimers();
3045
- this.resetClock = true;
3046
- }
3047
-
3048
- if (!this.longestTimeout) {
3049
- var clockSetTimeout = this.clock.setTimeout;
3050
- var clockSetInterval = this.clock.setInterval;
3051
- var server = this;
3052
-
3053
- this.clock.setTimeout = function (fn, timeout) {
3054
- server.longestTimeout = Math.max(timeout, server.longestTimeout || 0);
3055
-
3056
- return clockSetTimeout.apply(this, arguments);
3057
- };
3058
-
3059
- this.clock.setInterval = function (fn, timeout) {
3060
- server.longestTimeout = Math.max(timeout, server.longestTimeout || 0);
3061
-
3062
- return clockSetInterval.apply(this, arguments);
3063
- };
3064
- }
3065
- }
3066
-
3067
- return sinon.fakeServer.addRequest.call(this, xhr);
3068
- };
3069
-
3070
- sinon.fakeServerWithClock.respond = function respond() {
3071
- var returnVal = sinon.fakeServer.respond.apply(this, arguments);
3072
-
3073
- if (this.clock) {
3074
- this.clock.tick(this.longestTimeout || 0);
3075
- this.longestTimeout = 0;
3076
-
3077
- if (this.resetClock) {
3078
- this.clock.restore();
3079
- this.resetClock = false;
3080
- }
3081
- }
3082
-
3083
- return returnVal;
3084
- };
3085
-
3086
- sinon.fakeServerWithClock.restore = function restore() {
3087
- if (this.clock) {
3088
- this.clock.restore();
3089
- }
3090
-
3091
- return sinon.fakeServer.restore.apply(this, arguments);
3092
- };
3093
- }());
3094
-
3095
- /**
3096
- * @depend ../sinon.js
3097
- * @depend collection.js
3098
- * @depend util/fake_timers.js
3099
- * @depend util/fake_server_with_clock.js
3100
- */
3101
- /*jslint eqeqeq: false, onevar: false, plusplus: false*/
3102
- /*global require, module*/
3103
- /**
3104
- * Manages fake collections as well as fake utilities such as Sinon's
3105
- * timers and fake XHR implementation in one convenient object.
3106
- *
3107
- * @author Christian Johansen (christian@cjohansen.no)
3108
- * @license BSD
3109
- *
3110
- * Copyright (c) 2010-2011 Christian Johansen
3111
- */
3112
-
3113
- if (typeof module == "object" && typeof require == "function") {
3114
- var sinon = require("../sinon");
3115
- sinon.extend(sinon, require("./util/fake_timers"));
3116
- }
3117
-
3118
- (function () {
3119
- var push = [].push;
3120
-
3121
- function exposeValue(sandbox, config, key, value) {
3122
- if (!value) {
3123
- return;
3124
- }
3125
-
3126
- if (config.injectInto) {
3127
- config.injectInto[key] = value;
3128
- } else {
3129
- push.call(sandbox.args, value);
3130
- }
3131
- }
3132
-
3133
- function prepareSandboxFromConfig(config) {
3134
- var sandbox = sinon.create(sinon.sandbox);
3135
-
3136
- if (config.useFakeServer) {
3137
- if (typeof config.useFakeServer == "object") {
3138
- sandbox.serverPrototype = config.useFakeServer;
3139
- }
3140
-
3141
- sandbox.useFakeServer();
3142
- }
3143
-
3144
- if (config.useFakeTimers) {
3145
- if (typeof config.useFakeTimers == "object") {
3146
- sandbox.useFakeTimers.apply(sandbox, config.useFakeTimers);
3147
- } else {
3148
- sandbox.useFakeTimers();
3149
- }
3150
- }
3151
-
3152
- return sandbox;
3153
- }
3154
-
3155
- sinon.sandbox = sinon.extend(sinon.create(sinon.collection), {
3156
- useFakeTimers: function useFakeTimers() {
3157
- this.clock = sinon.useFakeTimers.apply(sinon, arguments);
3158
-
3159
- return this.add(this.clock);
3160
- },
3161
-
3162
- serverPrototype: sinon.fakeServer,
3163
-
3164
- useFakeServer: function useFakeServer() {
3165
- var proto = this.serverPrototype || sinon.fakeServer;
3166
-
3167
- if (!proto || !proto.create) {
3168
- return null;
3169
- }
3170
-
3171
- this.server = proto.create();
3172
- return this.add(this.server);
3173
- },
3174
-
3175
- inject: function (obj) {
3176
- sinon.collection.inject.call(this, obj);
3177
-
3178
- if (this.clock) {
3179
- obj.clock = this.clock;
3180
- }
3181
-
3182
- if (this.server) {
3183
- obj.server = this.server;
3184
- obj.requests = this.server.requests;
3185
- }
3186
-
3187
- return obj;
3188
- },
3189
-
3190
- create: function (config) {
3191
- if (!config) {
3192
- return sinon.create(sinon.sandbox);
3193
- }
3194
-
3195
- var sandbox = prepareSandboxFromConfig(config);
3196
- sandbox.args = sandbox.args || [];
3197
- var prop, value, exposed = sandbox.inject({});
3198
-
3199
- if (config.properties) {
3200
- for (var i = 0, l = config.properties.length; i < l; i++) {
3201
- prop = config.properties[i];
3202
- value = exposed[prop] || prop == "sandbox" && sandbox;
3203
- exposeValue(sandbox, config, prop, value);
3204
- }
3205
- } else {
3206
- exposeValue(sandbox, config, "sandbox", value);
3207
- }
3208
-
3209
- return sandbox;
3210
- }
3211
- });
3212
-
3213
- sinon.sandbox.useFakeXMLHttpRequest = sinon.sandbox.useFakeServer;
3214
-
3215
- if (typeof module == "object" && typeof require == "function") {
3216
- module.exports = sinon.sandbox;
3217
- }
3218
- }());
3219
-
3220
- /**
3221
- * @depend ../sinon.js
3222
- * @depend stub.js
3223
- * @depend mock.js
3224
- * @depend sandbox.js
3225
- */
3226
- /*jslint eqeqeq: false, onevar: false, forin: true, plusplus: false*/
3227
- /*global module, require, sinon*/
3228
- /**
3229
- * Test function, sandboxes fakes
3230
- *
3231
- * @author Christian Johansen (christian@cjohansen.no)
3232
- * @license BSD
3233
- *
3234
- * Copyright (c) 2010-2011 Christian Johansen
3235
- */
3236
-
3237
- (function (sinon) {
3238
- var commonJSModule = typeof module == "object" && typeof require == "function";
3239
-
3240
- if (!sinon && commonJSModule) {
3241
- sinon = require("../sinon");
3242
- }
3243
-
3244
- if (!sinon) {
3245
- return;
3246
- }
3247
-
3248
- function test(callback) {
3249
- var type = typeof callback;
3250
-
3251
- if (type != "function") {
3252
- throw new TypeError("sinon.test needs to wrap a test function, got " + type);
3253
- }
3254
-
3255
- return function () {
3256
- var config = sinon.getConfig(sinon.config);
3257
- config.injectInto = config.injectIntoThis && this || config.injectInto;
3258
- var sandbox = sinon.sandbox.create(config);
3259
- var exception, result;
3260
- var args = Array.prototype.slice.call(arguments).concat(sandbox.args);
3261
-
3262
- try {
3263
- result = callback.apply(this, args);
3264
- } finally {
3265
- sandbox.verifyAndRestore();
3266
- }
3267
-
3268
- return result;
3269
- };
3270
- }
3271
-
3272
- test.config = {
3273
- injectIntoThis: true,
3274
- injectInto: null,
3275
- properties: ["spy", "stub", "mock", "clock", "server", "requests"],
3276
- useFakeTimers: true,
3277
- useFakeServer: true
3278
- };
3279
-
3280
- if (commonJSModule) {
3281
- module.exports = test;
3282
- } else {
3283
- sinon.test = test;
3284
- }
3285
- }(typeof sinon == "object" && sinon || null));
3286
-
3287
- /**
3288
- * @depend ../sinon.js
3289
- * @depend test.js
3290
- */
3291
- /*jslint eqeqeq: false, onevar: false, eqeqeq: false*/
3292
- /*global module, require, sinon*/
3293
- /**
3294
- * Test case, sandboxes all test functions
3295
- *
3296
- * @author Christian Johansen (christian@cjohansen.no)
3297
- * @license BSD
3298
- *
3299
- * Copyright (c) 2010-2011 Christian Johansen
3300
- */
3301
-
3302
- (function (sinon) {
3303
- var commonJSModule = typeof module == "object" && typeof require == "function";
3304
-
3305
- if (!sinon && commonJSModule) {
3306
- sinon = require("../sinon");
3307
- }
3308
-
3309
- if (!sinon || !Object.prototype.hasOwnProperty) {
3310
- return;
3311
- }
3312
-
3313
- function createTest(property, setUp, tearDown) {
3314
- return function () {
3315
- if (setUp) {
3316
- setUp.apply(this, arguments);
3317
- }
3318
-
3319
- var exception, result;
3320
-
3321
- try {
3322
- result = property.apply(this, arguments);
3323
- } catch (e) {
3324
- exception = e;
3325
- }
3326
-
3327
- if (tearDown) {
3328
- tearDown.apply(this, arguments);
3329
- }
3330
-
3331
- if (exception) {
3332
- throw exception;
3333
- }
3334
-
3335
- return result;
3336
- };
3337
- }
3338
-
3339
- function testCase(tests, prefix) {
3340
- /*jsl:ignore*/
3341
- if (!tests || typeof tests != "object") {
3342
- throw new TypeError("sinon.testCase needs an object with test functions");
3343
- }
3344
- /*jsl:end*/
3345
-
3346
- prefix = prefix || "test";
3347
- var rPrefix = new RegExp("^" + prefix);
3348
- var methods = {}, testName, property, method;
3349
- var setUp = tests.setUp;
3350
- var tearDown = tests.tearDown;
3351
-
3352
- for (testName in tests) {
3353
- if (tests.hasOwnProperty(testName)) {
3354
- property = tests[testName];
3355
-
3356
- if (/^(setUp|tearDown)$/.test(testName)) {
3357
- continue;
3358
- }
3359
-
3360
- if (typeof property == "function" && rPrefix.test(testName)) {
3361
- method = property;
3362
-
3363
- if (setUp || tearDown) {
3364
- method = createTest(property, setUp, tearDown);
3365
- }
3366
-
3367
- methods[testName] = sinon.test(method);
3368
- } else {
3369
- methods[testName] = tests[testName];
3370
- }
3371
- }
3372
- }
3373
-
3374
- return methods;
3375
- }
3376
-
3377
- if (commonJSModule) {
3378
- module.exports = testCase;
3379
- } else {
3380
- sinon.testCase = testCase;
3381
- }
3382
- }(typeof sinon == "object" && sinon || null));
3383
-
3384
- /**
3385
- * @depend ../sinon.js
3386
- * @depend stub.js
3387
- */
3388
- /*jslint eqeqeq: false, onevar: false, nomen: false, plusplus: false*/
3389
- /*global module, require, sinon*/
3390
- /**
3391
- * Assertions matching the test spy retrieval interface.
3392
- *
3393
- * @author Christian Johansen (christian@cjohansen.no)
3394
- * @license BSD
3395
- *
3396
- * Copyright (c) 2010-2011 Christian Johansen
3397
- */
3398
-
3399
- (function (sinon, global) {
3400
- var commonJSModule = typeof module == "object" && typeof require == "function";
3401
- var slice = Array.prototype.slice;
3402
- var assert;
3403
-
3404
- if (!sinon && commonJSModule) {
3405
- sinon = require("../sinon");
3406
- }
3407
-
3408
- if (!sinon) {
3409
- return;
3410
- }
3411
-
3412
- function verifyIsStub() {
3413
- var method;
3414
-
3415
- for (var i = 0, l = arguments.length; i < l; ++i) {
3416
- method = arguments[i];
3417
-
3418
- if (!method) {
3419
- assert.fail("fake is not a spy");
3420
- }
3421
-
3422
- if (typeof method != "function") {
3423
- assert.fail(method + " is not a function");
3424
- }
3425
-
3426
- if (typeof method.getCall != "function") {
3427
- assert.fail(method + " is not stubbed");
3428
- }
3429
- }
3430
- }
3431
-
3432
- function failAssertion(object, msg) {
3433
- object = object || global;
3434
- var failMethod = object.fail || assert.fail;
3435
- failMethod.call(object, msg);
3436
- }
3437
-
3438
- function mirrorPropAsAssertion(name, method, message) {
3439
- if (arguments.length == 2) {
3440
- message = method;
3441
- method = name;
3442
- }
3443
-
3444
- assert[name] = function (fake) {
3445
- verifyIsStub(fake);
3446
-
3447
- var args = slice.call(arguments, 1);
3448
- var failed = false;
3449
-
3450
- if (typeof method == "function") {
3451
- failed = !method(fake);
3452
- } else {
3453
- failed = typeof fake[method] == "function" ?
3454
- !fake[method].apply(fake, args) : !fake[method];
3455
- }
3456
-
3457
- if (failed) {
3458
- failAssertion(this, fake.printf.apply(fake, [message].concat(args)));
3459
- } else {
3460
- assert.pass(name);
3461
- }
3462
- };
3463
- }
3464
-
3465
- function exposedName(prefix, prop) {
3466
- return !prefix || /^fail/.test(prop) ? prop :
3467
- prefix + prop.slice(0, 1).toUpperCase() + prop.slice(1);
3468
- };
3469
-
3470
- assert = {
3471
- failException: "AssertError",
3472
-
3473
- fail: function fail(message) {
3474
- var error = new Error(message);
3475
- error.name = this.failException || assert.failException;
3476
-
3477
- throw error;
3478
- },
3479
-
3480
- pass: function pass(assertion) {},
3481
-
3482
- callOrder: function assertCallOrder() {
3483
- verifyIsStub.apply(null, arguments);
3484
- var expected = "", actual = "";
3485
-
3486
- if (!sinon.calledInOrder(arguments)) {
3487
- try {
3488
- expected = [].join.call(arguments, ", ");
3489
- actual = sinon.orderByFirstCall(slice.call(arguments)).join(", ");
3490
- } catch (e) {
3491
- // If this fails, we'll just fall back to the blank string
3492
- }
3493
-
3494
- failAssertion(this, "expected " + expected + " to be " +
3495
- "called in order but were called as " + actual);
3496
- } else {
3497
- assert.pass("callOrder");
3498
- }
3499
- },
3500
-
3501
- callCount: function assertCallCount(method, count) {
3502
- verifyIsStub(method);
3503
-
3504
- if (method.callCount != count) {
3505
- var msg = "expected %n to be called " + sinon.timesInWords(count) +
3506
- " but was called %c%C";
3507
- failAssertion(this, method.printf(msg));
3508
- } else {
3509
- assert.pass("callCount");
3510
- }
3511
- },
3512
-
3513
- expose: function expose(target, options) {
3514
- if (!target) {
3515
- throw new TypeError("target is null or undefined");
3516
- }
3517
-
3518
- var o = options || {};
3519
- var prefix = typeof o.prefix == "undefined" && "assert" || o.prefix;
3520
- var includeFail = typeof o.includeFail == "undefined" || !!o.includeFail;
3521
-
3522
- for (var method in this) {
3523
- if (method != "export" && (includeFail || !/^(fail)/.test(method))) {
3524
- target[exposedName(prefix, method)] = this[method];
3525
- }
3526
- }
3527
-
3528
- return target;
3529
- }
3530
- };
3531
-
3532
- mirrorPropAsAssertion("called", "expected %n to have been called at least once but was never called");
3533
- mirrorPropAsAssertion("notCalled", function (spy) { return !spy.called; },
3534
- "expected %n to not have been called but was called %c%C");
3535
- mirrorPropAsAssertion("calledOnce", "expected %n to be called once but was called %c%C");
3536
- mirrorPropAsAssertion("calledTwice", "expected %n to be called twice but was called %c%C");
3537
- mirrorPropAsAssertion("calledThrice", "expected %n to be called thrice but was called %c%C");
3538
- mirrorPropAsAssertion("calledOn", "expected %n to be called with %1 as this but was called with %t");
3539
- mirrorPropAsAssertion("alwaysCalledOn", "expected %n to always be called with %1 as this but was called with %t");
3540
- mirrorPropAsAssertion("calledWith", "expected %n to be called with arguments %*%C");
3541
- mirrorPropAsAssertion("alwaysCalledWith", "expected %n to always be called with arguments %*%C");
3542
- mirrorPropAsAssertion("calledWithExactly", "expected %n to be called with exact arguments %*%C");
3543
- mirrorPropAsAssertion("alwaysCalledWithExactly", "expected %n to always be called with exact arguments %*%C");
3544
- mirrorPropAsAssertion("neverCalledWith", "expected %n to never be called with arguments %*%C");
3545
- mirrorPropAsAssertion("threw", "%n did not throw exception%C");
3546
- mirrorPropAsAssertion("alwaysThrew", "%n did not always throw exception%C");
3547
-
3548
- if (commonJSModule) {
3549
- module.exports = assert;
3550
- } else {
3551
- sinon.assert = assert;
3552
- }
3553
- }(typeof sinon == "object" && sinon || null, typeof window != "undefined" ? window : global));
3554
-
3555
- return sinon;}.call(typeof window != 'undefined' && window || {}));