1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 |
|
18 |
|
19 |
|
20 |
|
21 |
|
22 |
|
23 |
|
24 |
|
25 |
|
26 |
|
27 |
|
28 |
|
29 |
|
30 |
|
31 |
|
32 |
|
33 |
|
34 |
|
35 |
|
36 | this.sinon = (function () {
|
37 | var samsam, formatio;
|
38 | function define(mod, deps, fn) { if (mod == "samsam") { samsam = deps(); } else { formatio = fn(samsam); } }
|
39 | define.amd = true;
|
40 | ((typeof define === "function" && define.amd && function (m) { define("samsam", m); }) ||
|
41 | (typeof module === "object" &&
|
42 | function (m) { module.exports = m(); }) ||
|
43 | function (m) { this.samsam = m(); }
|
44 | )(function () {
|
45 | var o = Object.prototype;
|
46 | var div = typeof document !== "undefined" && document.createElement("div");
|
47 |
|
48 | function isNaN(value) {
|
49 |
|
50 |
|
51 |
|
52 | var val = value;
|
53 | return typeof value === "number" && value !== val;
|
54 | }
|
55 |
|
56 | function getClass(value) {
|
57 |
|
58 |
|
59 |
|
60 | return o.toString.call(value).split(/[ \]]/)[1];
|
61 | }
|
62 |
|
63 | |
64 |
|
65 |
|
66 |
|
67 |
|
68 |
|
69 |
|
70 | function isArguments(object) {
|
71 | if (typeof object !== "object" || typeof object.length !== "number" ||
|
72 | getClass(object) === "Array") {
|
73 | return false;
|
74 | }
|
75 | if (typeof object.callee == "function") { return true; }
|
76 | try {
|
77 | object[object.length] = 6;
|
78 | delete object[object.length];
|
79 | } catch (e) {
|
80 | return true;
|
81 | }
|
82 | return false;
|
83 | }
|
84 |
|
85 | |
86 |
|
87 |
|
88 |
|
89 |
|
90 |
|
91 |
|
92 |
|
93 |
|
94 | function isElement(object) {
|
95 | if (!object || object.nodeType !== 1 || !div) { return false; }
|
96 | try {
|
97 | object.appendChild(div);
|
98 | object.removeChild(div);
|
99 | } catch (e) {
|
100 | return false;
|
101 | }
|
102 | return true;
|
103 | }
|
104 |
|
105 | |
106 |
|
107 |
|
108 |
|
109 |
|
110 |
|
111 | function keys(object) {
|
112 | var ks = [], prop;
|
113 | for (prop in object) {
|
114 | if (o.hasOwnProperty.call(object, prop)) { ks.push(prop); }
|
115 | }
|
116 | return ks;
|
117 | }
|
118 |
|
119 | |
120 |
|
121 |
|
122 |
|
123 |
|
124 |
|
125 |
|
126 |
|
127 |
|
128 | function isDate(value) {
|
129 | return typeof value.getTime == "function" &&
|
130 | value.getTime() == value.valueOf();
|
131 | }
|
132 |
|
133 | |
134 |
|
135 |
|
136 |
|
137 |
|
138 |
|
139 | function isNegZero(value) {
|
140 | return value === 0 && 1 / value === -Infinity;
|
141 | }
|
142 |
|
143 | |
144 |
|
145 |
|
146 |
|
147 |
|
148 |
|
149 |
|
150 |
|
151 |
|
152 |
|
153 |
|
154 | function identical(obj1, obj2) {
|
155 | if (obj1 === obj2 || (isNaN(obj1) && isNaN(obj2))) {
|
156 | return obj1 !== 0 || isNegZero(obj1) === isNegZero(obj2);
|
157 | }
|
158 | }
|
159 |
|
160 |
|
161 | |
162 |
|
163 |
|
164 |
|
165 |
|
166 |
|
167 |
|
168 |
|
169 |
|
170 |
|
171 |
|
172 |
|
173 |
|
174 |
|
175 |
|
176 | function deepEqualCyclic(obj1, obj2) {
|
177 |
|
178 |
|
179 |
|
180 | var objects1 = [],
|
181 | objects2 = [],
|
182 |
|
183 |
|
184 |
|
185 | paths1 = [],
|
186 | paths2 = [],
|
187 |
|
188 |
|
189 | compared = {};
|
190 |
|
191 | |
192 |
|
193 |
|
194 |
|
195 |
|
196 | function isObject(value) {
|
197 |
|
198 | if (typeof value === 'object' && value !== null &&
|
199 | !(value instanceof Boolean) &&
|
200 | !(value instanceof Date) &&
|
201 | !(value instanceof Number) &&
|
202 | !(value instanceof RegExp) &&
|
203 | !(value instanceof String)) {
|
204 |
|
205 | return true;
|
206 | }
|
207 |
|
208 | return false;
|
209 | }
|
210 |
|
211 | |
212 |
|
213 |
|
214 |
|
215 |
|
216 | function getIndex(objects, obj) {
|
217 |
|
218 | var i;
|
219 | for (i = 0; i < objects.length; i++) {
|
220 | if (objects[i] === obj) {
|
221 | return i;
|
222 | }
|
223 | }
|
224 |
|
225 | return -1;
|
226 | }
|
227 |
|
228 |
|
229 | return (function deepEqual(obj1, obj2, path1, path2) {
|
230 | var type1 = typeof obj1;
|
231 | var type2 = typeof obj2;
|
232 |
|
233 |
|
234 | if (obj1 === obj2 ||
|
235 | isNaN(obj1) || isNaN(obj2) ||
|
236 | obj1 == null || obj2 == null ||
|
237 | type1 !== "object" || type2 !== "object") {
|
238 |
|
239 | return identical(obj1, obj2);
|
240 | }
|
241 |
|
242 |
|
243 | if (isElement(obj1) || isElement(obj2)) { return false; }
|
244 |
|
245 | var isDate1 = isDate(obj1), isDate2 = isDate(obj2);
|
246 | if (isDate1 || isDate2) {
|
247 | if (!isDate1 || !isDate2 || obj1.getTime() !== obj2.getTime()) {
|
248 | return false;
|
249 | }
|
250 | }
|
251 |
|
252 | if (obj1 instanceof RegExp && obj2 instanceof RegExp) {
|
253 | if (obj1.toString() !== obj2.toString()) { return false; }
|
254 | }
|
255 |
|
256 | var class1 = getClass(obj1);
|
257 | var class2 = getClass(obj2);
|
258 | var keys1 = keys(obj1);
|
259 | var keys2 = keys(obj2);
|
260 |
|
261 | if (isArguments(obj1) || isArguments(obj2)) {
|
262 | if (obj1.length !== obj2.length) { return false; }
|
263 | } else {
|
264 | if (type1 !== type2 || class1 !== class2 ||
|
265 | keys1.length !== keys2.length) {
|
266 | return false;
|
267 | }
|
268 | }
|
269 |
|
270 | var key, i, l,
|
271 |
|
272 | value1, value2,
|
273 | isObject1, isObject2,
|
274 | index1, index2,
|
275 | newPath1, newPath2;
|
276 |
|
277 | for (i = 0, l = keys1.length; i < l; i++) {
|
278 | key = keys1[i];
|
279 | if (!o.hasOwnProperty.call(obj2, key)) {
|
280 | return false;
|
281 | }
|
282 |
|
283 |
|
284 |
|
285 | value1 = obj1[key];
|
286 | value2 = obj2[key];
|
287 |
|
288 | isObject1 = isObject(value1);
|
289 | isObject2 = isObject(value2);
|
290 |
|
291 |
|
292 |
|
293 |
|
294 | index1 = isObject1 ? getIndex(objects1, value1) : -1;
|
295 | index2 = isObject2 ? getIndex(objects2, value2) : -1;
|
296 |
|
297 |
|
298 |
|
299 |
|
300 |
|
301 | newPath1 = index1 !== -1
|
302 | ? paths1[index1]
|
303 | : path1 + '[' + JSON.stringify(key) + ']';
|
304 | newPath2 = index2 !== -1
|
305 | ? paths2[index2]
|
306 | : path2 + '[' + JSON.stringify(key) + ']';
|
307 |
|
308 |
|
309 | if (compared[newPath1 + newPath2]) {
|
310 | return true;
|
311 | }
|
312 |
|
313 |
|
314 | if (index1 === -1 && isObject1) {
|
315 | objects1.push(value1);
|
316 | paths1.push(newPath1);
|
317 | }
|
318 | if (index2 === -1 && isObject2) {
|
319 | objects2.push(value2);
|
320 | paths2.push(newPath2);
|
321 | }
|
322 |
|
323 |
|
324 | if (isObject1 && isObject2) {
|
325 | compared[newPath1 + newPath2] = true;
|
326 | }
|
327 |
|
328 |
|
329 |
|
330 |
|
331 |
|
332 | if (!deepEqual(value1, value2, newPath1, newPath2)) {
|
333 | return false;
|
334 | }
|
335 | }
|
336 |
|
337 | return true;
|
338 |
|
339 | }(obj1, obj2, '$1', '$2'));
|
340 | }
|
341 |
|
342 | var match;
|
343 |
|
344 | function arrayContains(array, subset) {
|
345 | if (subset.length === 0) { return true; }
|
346 | var i, l, j, k;
|
347 | for (i = 0, l = array.length; i < l; ++i) {
|
348 | if (match(array[i], subset[0])) {
|
349 | for (j = 0, k = subset.length; j < k; ++j) {
|
350 | if (!match(array[i + j], subset[j])) { return false; }
|
351 | }
|
352 | return true;
|
353 | }
|
354 | }
|
355 | return false;
|
356 | }
|
357 |
|
358 | |
359 |
|
360 |
|
361 |
|
362 |
|
363 |
|
364 |
|
365 | match = function match(object, matcher) {
|
366 | if (matcher && typeof matcher.test === "function") {
|
367 | return matcher.test(object);
|
368 | }
|
369 |
|
370 | if (typeof matcher === "function") {
|
371 | return matcher(object) === true;
|
372 | }
|
373 |
|
374 | if (typeof matcher === "string") {
|
375 | matcher = matcher.toLowerCase();
|
376 | var notNull = typeof object === "string" || !!object;
|
377 | return notNull &&
|
378 | (String(object)).toLowerCase().indexOf(matcher) >= 0;
|
379 | }
|
380 |
|
381 | if (typeof matcher === "number") {
|
382 | return matcher === object;
|
383 | }
|
384 |
|
385 | if (typeof matcher === "boolean") {
|
386 | return matcher === object;
|
387 | }
|
388 |
|
389 | if (getClass(object) === "Array" && getClass(matcher) === "Array") {
|
390 | return arrayContains(object, matcher);
|
391 | }
|
392 |
|
393 | if (matcher && typeof matcher === "object") {
|
394 | var prop;
|
395 | for (prop in matcher) {
|
396 | if (!match(object[prop], matcher[prop])) {
|
397 | return false;
|
398 | }
|
399 | }
|
400 | return true;
|
401 | }
|
402 |
|
403 | throw new Error("Matcher was not a string, a number, a " +
|
404 | "function, a boolean or an object");
|
405 | };
|
406 |
|
407 | return {
|
408 | isArguments: isArguments,
|
409 | isElement: isElement,
|
410 | isDate: isDate,
|
411 | isNegZero: isNegZero,
|
412 | identical: identical,
|
413 | deepEqual: deepEqualCyclic,
|
414 | match: match,
|
415 | keys: keys
|
416 | };
|
417 | });
|
418 | ((typeof define === "function" && define.amd && function (m) {
|
419 | define("formatio", ["samsam"], m);
|
420 | }) || (typeof module === "object" && function (m) {
|
421 | module.exports = m(require("samsam"));
|
422 | }) || function (m) { this.formatio = m(this.samsam); }
|
423 | )(function (samsam) {
|
424 |
|
425 | var formatio = {
|
426 | excludeConstructors: ["Object", /^.$/],
|
427 | quoteStrings: true
|
428 | };
|
429 |
|
430 | var hasOwn = Object.prototype.hasOwnProperty;
|
431 |
|
432 | var specialObjects = [];
|
433 | if (typeof global !== "undefined") {
|
434 | specialObjects.push({ object: global, value: "[object global]" });
|
435 | }
|
436 | if (typeof document !== "undefined") {
|
437 | specialObjects.push({
|
438 | object: document,
|
439 | value: "[object HTMLDocument]"
|
440 | });
|
441 | }
|
442 | if (typeof window !== "undefined") {
|
443 | specialObjects.push({ object: window, value: "[object Window]" });
|
444 | }
|
445 |
|
446 | function functionName(func) {
|
447 | if (!func) { return ""; }
|
448 | if (func.displayName) { return func.displayName; }
|
449 | if (func.name) { return func.name; }
|
450 | var matches = func.toString().match(/function\s+([^\(]+)/m);
|
451 | return (matches && matches[1]) || "";
|
452 | }
|
453 |
|
454 | function constructorName(f, object) {
|
455 | var name = functionName(object && object.constructor);
|
456 | var excludes = f.excludeConstructors ||
|
457 | formatio.excludeConstructors || [];
|
458 |
|
459 | var i, l;
|
460 | for (i = 0, l = excludes.length; i < l; ++i) {
|
461 | if (typeof excludes[i] === "string" && excludes[i] === name) {
|
462 | return "";
|
463 | } else if (excludes[i].test && excludes[i].test(name)) {
|
464 | return "";
|
465 | }
|
466 | }
|
467 |
|
468 | return name;
|
469 | }
|
470 |
|
471 | function isCircular(object, objects) {
|
472 | if (typeof object !== "object") { return false; }
|
473 | var i, l;
|
474 | for (i = 0, l = objects.length; i < l; ++i) {
|
475 | if (objects[i] === object) { return true; }
|
476 | }
|
477 | return false;
|
478 | }
|
479 |
|
480 | function ascii(f, object, processed, indent) {
|
481 | if (typeof object === "string") {
|
482 | var qs = f.quoteStrings;
|
483 | var quote = typeof qs !== "boolean" || qs;
|
484 | return processed || quote ? '"' + object + '"' : object;
|
485 | }
|
486 |
|
487 | if (typeof object === "function" && !(object instanceof RegExp)) {
|
488 | return ascii.func(object);
|
489 | }
|
490 |
|
491 | processed = processed || [];
|
492 |
|
493 | if (isCircular(object, processed)) { return "[Circular]"; }
|
494 |
|
495 | if (Object.prototype.toString.call(object) === "[object Array]") {
|
496 | return ascii.array.call(f, object, processed);
|
497 | }
|
498 |
|
499 | if (!object) { return String((1/object) === -Infinity ? "-0" : object); }
|
500 | if (samsam.isElement(object)) { return ascii.element(object); }
|
501 |
|
502 | if (typeof object.toString === "function" &&
|
503 | object.toString !== Object.prototype.toString) {
|
504 | return object.toString();
|
505 | }
|
506 |
|
507 | var i, l;
|
508 | for (i = 0, l = specialObjects.length; i < l; i++) {
|
509 | if (object === specialObjects[i].object) {
|
510 | return specialObjects[i].value;
|
511 | }
|
512 | }
|
513 |
|
514 | return ascii.object.call(f, object, processed, indent);
|
515 | }
|
516 |
|
517 | ascii.func = function (func) {
|
518 | return "function " + functionName(func) + "() {}";
|
519 | };
|
520 |
|
521 | ascii.array = function (array, processed) {
|
522 | processed = processed || [];
|
523 | processed.push(array);
|
524 | var i, l, pieces = [];
|
525 | for (i = 0, l = array.length; i < l; ++i) {
|
526 | pieces.push(ascii(this, array[i], processed));
|
527 | }
|
528 | return "[" + pieces.join(", ") + "]";
|
529 | };
|
530 |
|
531 | ascii.object = function (object, processed, indent) {
|
532 | processed = processed || [];
|
533 | processed.push(object);
|
534 | indent = indent || 0;
|
535 | var pieces = [], properties = samsam.keys(object).sort();
|
536 | var length = 3;
|
537 | var prop, str, obj, i, l;
|
538 |
|
539 | for (i = 0, l = properties.length; i < l; ++i) {
|
540 | prop = properties[i];
|
541 | obj = object[prop];
|
542 |
|
543 | if (isCircular(obj, processed)) {
|
544 | str = "[Circular]";
|
545 | } else {
|
546 | str = ascii(this, obj, processed, indent + 2);
|
547 | }
|
548 |
|
549 | str = (/\s/.test(prop) ? '"' + prop + '"' : prop) + ": " + str;
|
550 | length += str.length;
|
551 | pieces.push(str);
|
552 | }
|
553 |
|
554 | var cons = constructorName(this, object);
|
555 | var prefix = cons ? "[" + cons + "] " : "";
|
556 | var is = "";
|
557 | for (i = 0, l = indent; i < l; ++i) { is += " "; }
|
558 |
|
559 | if (length + indent > 80) {
|
560 | return prefix + "{\n " + is + pieces.join(",\n " + is) + "\n" +
|
561 | is + "}";
|
562 | }
|
563 | return prefix + "{ " + pieces.join(", ") + " }";
|
564 | };
|
565 |
|
566 | ascii.element = function (element) {
|
567 | var tagName = element.tagName.toLowerCase();
|
568 | var attrs = element.attributes, attr, pairs = [], attrName, i, l, val;
|
569 |
|
570 | for (i = 0, l = attrs.length; i < l; ++i) {
|
571 | attr = attrs.item(i);
|
572 | attrName = attr.nodeName.toLowerCase().replace("html:", "");
|
573 | val = attr.nodeValue;
|
574 | if (attrName !== "contenteditable" || val !== "inherit") {
|
575 | if (!!val) { pairs.push(attrName + "=\"" + val + "\""); }
|
576 | }
|
577 | }
|
578 |
|
579 | var formatted = "<" + tagName + (pairs.length > 0 ? " " : "");
|
580 | var content = element.innerHTML;
|
581 |
|
582 | if (content.length > 20) {
|
583 | content = content.substr(0, 20) + "[...]";
|
584 | }
|
585 |
|
586 | var res = formatted + pairs.join(" ") + ">" + content +
|
587 | "</" + tagName + ">";
|
588 |
|
589 | return res.replace(/ contentEditable="inherit"/, "");
|
590 | };
|
591 |
|
592 | function Formatio(options) {
|
593 | for (var opt in options) {
|
594 | this[opt] = options[opt];
|
595 | }
|
596 | }
|
597 |
|
598 | Formatio.prototype = {
|
599 | functionName: functionName,
|
600 |
|
601 | configure: function (options) {
|
602 | return new Formatio(options);
|
603 | },
|
604 |
|
605 | constructorName: function (object) {
|
606 | return constructorName(this, object);
|
607 | },
|
608 |
|
609 | ascii: function (object, processed, indent) {
|
610 | return ascii(this, object, processed, indent);
|
611 | }
|
612 | };
|
613 |
|
614 | return Formatio.prototype;
|
615 | });
|
616 |
|
617 |
|
618 |
|
619 |
|
620 |
|
621 |
|
622 |
|
623 |
|
624 |
|
625 |
|
626 |
|
627 | var sinon = (function (formatio) {
|
628 | var div = typeof document != "undefined" && document.createElement("div");
|
629 | var hasOwn = Object.prototype.hasOwnProperty;
|
630 |
|
631 | function isDOMNode(obj) {
|
632 | var success = false;
|
633 |
|
634 | try {
|
635 | obj.appendChild(div);
|
636 | success = div.parentNode == obj;
|
637 | } catch (e) {
|
638 | return false;
|
639 | } finally {
|
640 | try {
|
641 | obj.removeChild(div);
|
642 | } catch (e) {
|
643 |
|
644 | }
|
645 | }
|
646 |
|
647 | return success;
|
648 | }
|
649 |
|
650 | function isElement(obj) {
|
651 | return div && obj && obj.nodeType === 1 && isDOMNode(obj);
|
652 | }
|
653 |
|
654 | function isFunction(obj) {
|
655 | return typeof obj === "function" || !!(obj && obj.constructor && obj.call && obj.apply);
|
656 | }
|
657 |
|
658 | function isReallyNaN(val) {
|
659 | return typeof val === 'number' && isNaN(val);
|
660 | }
|
661 |
|
662 | function mirrorProperties(target, source) {
|
663 | for (var prop in source) {
|
664 | if (!hasOwn.call(target, prop)) {
|
665 | target[prop] = source[prop];
|
666 | }
|
667 | }
|
668 | }
|
669 |
|
670 | function isRestorable (obj) {
|
671 | return typeof obj === "function" && typeof obj.restore === "function" && obj.restore.sinon;
|
672 | }
|
673 |
|
674 | var sinon = {
|
675 | wrapMethod: function wrapMethod(object, property, method) {
|
676 | if (!object) {
|
677 | throw new TypeError("Should wrap property of object");
|
678 | }
|
679 |
|
680 | if (typeof method != "function") {
|
681 | throw new TypeError("Method wrapper should be function");
|
682 | }
|
683 |
|
684 | var wrappedMethod = object[property],
|
685 | error;
|
686 |
|
687 | if (!isFunction(wrappedMethod)) {
|
688 | error = new TypeError("Attempted to wrap " + (typeof wrappedMethod) + " property " +
|
689 | property + " as function");
|
690 | }
|
691 |
|
692 | if (wrappedMethod.restore && wrappedMethod.restore.sinon) {
|
693 | error = new TypeError("Attempted to wrap " + property + " which is already wrapped");
|
694 | }
|
695 |
|
696 | if (wrappedMethod.calledBefore) {
|
697 | var verb = !!wrappedMethod.returns ? "stubbed" : "spied on";
|
698 | error = new TypeError("Attempted to wrap " + property + " which is already " + verb);
|
699 | }
|
700 |
|
701 | if (error) {
|
702 | if (wrappedMethod._stack) {
|
703 | error.stack += '\n--------------\n' + wrappedMethod._stack;
|
704 | }
|
705 | throw error;
|
706 | }
|
707 |
|
708 |
|
709 |
|
710 | var owned = object.hasOwnProperty ? object.hasOwnProperty(property) : hasOwn.call(object, property);
|
711 | object[property] = method;
|
712 | method.displayName = property;
|
713 |
|
714 |
|
715 | method._stack = (new Error('Stack Trace for original')).stack;
|
716 |
|
717 | method.restore = function () {
|
718 |
|
719 |
|
720 |
|
721 | if (!owned) {
|
722 | delete object[property];
|
723 | }
|
724 | if (object[property] === method) {
|
725 | object[property] = wrappedMethod;
|
726 | }
|
727 | };
|
728 |
|
729 | method.restore.sinon = true;
|
730 | mirrorProperties(method, wrappedMethod);
|
731 |
|
732 | return method;
|
733 | },
|
734 |
|
735 | extend: function extend(target) {
|
736 | for (var i = 1, l = arguments.length; i < l; i += 1) {
|
737 | for (var prop in arguments[i]) {
|
738 | if (arguments[i].hasOwnProperty(prop)) {
|
739 | target[prop] = arguments[i][prop];
|
740 | }
|
741 |
|
742 |
|
743 | if (arguments[i].hasOwnProperty("toString") &&
|
744 | arguments[i].toString != target.toString) {
|
745 | target.toString = arguments[i].toString;
|
746 | }
|
747 | }
|
748 | }
|
749 |
|
750 | return target;
|
751 | },
|
752 |
|
753 | create: function create(proto) {
|
754 | var F = function () {};
|
755 | F.prototype = proto;
|
756 | return new F();
|
757 | },
|
758 |
|
759 | deepEqual: function deepEqual(a, b) {
|
760 | if (sinon.match && sinon.match.isMatcher(a)) {
|
761 | return a.test(b);
|
762 | }
|
763 |
|
764 | if (typeof a != 'object' || typeof b != 'object') {
|
765 | if (isReallyNaN(a) && isReallyNaN(b)) {
|
766 | return true;
|
767 | } else {
|
768 | return a === b;
|
769 | }
|
770 | }
|
771 |
|
772 | if (isElement(a) || isElement(b)) {
|
773 | return a === b;
|
774 | }
|
775 |
|
776 | if (a === b) {
|
777 | return true;
|
778 | }
|
779 |
|
780 | if ((a === null && b !== null) || (a !== null && b === null)) {
|
781 | return false;
|
782 | }
|
783 |
|
784 | if (a instanceof RegExp && b instanceof RegExp) {
|
785 | return (a.source === b.source) && (a.global === b.global) &&
|
786 | (a.ignoreCase === b.ignoreCase) && (a.multiline === b.multiline);
|
787 | }
|
788 |
|
789 | var aString = Object.prototype.toString.call(a);
|
790 | if (aString != Object.prototype.toString.call(b)) {
|
791 | return false;
|
792 | }
|
793 |
|
794 | if (aString == "[object Date]") {
|
795 | return a.valueOf() === b.valueOf();
|
796 | }
|
797 |
|
798 | var prop, aLength = 0, bLength = 0;
|
799 |
|
800 | if (aString == "[object Array]" && a.length !== b.length) {
|
801 | return false;
|
802 | }
|
803 |
|
804 | for (prop in a) {
|
805 | aLength += 1;
|
806 |
|
807 | if (!deepEqual(a[prop], b[prop])) {
|
808 | return false;
|
809 | }
|
810 | }
|
811 |
|
812 | for (prop in b) {
|
813 | bLength += 1;
|
814 | }
|
815 |
|
816 | return aLength == bLength;
|
817 | },
|
818 |
|
819 | functionName: function functionName(func) {
|
820 | var name = func.displayName || func.name;
|
821 |
|
822 |
|
823 |
|
824 |
|
825 |
|
826 | if (!name) {
|
827 | var matches = func.toString().match(/function ([^\s\(]+)/);
|
828 | name = matches && matches[1];
|
829 | }
|
830 |
|
831 | return name;
|
832 | },
|
833 |
|
834 | functionToString: function toString() {
|
835 | if (this.getCall && this.callCount) {
|
836 | var thisValue, prop, i = this.callCount;
|
837 |
|
838 | while (i--) {
|
839 | thisValue = this.getCall(i).thisValue;
|
840 |
|
841 | for (prop in thisValue) {
|
842 | if (thisValue[prop] === this) {
|
843 | return prop;
|
844 | }
|
845 | }
|
846 | }
|
847 | }
|
848 |
|
849 | return this.displayName || "sinon fake";
|
850 | },
|
851 |
|
852 | getConfig: function (custom) {
|
853 | var config = {};
|
854 | custom = custom || {};
|
855 | var defaults = sinon.defaultConfig;
|
856 |
|
857 | for (var prop in defaults) {
|
858 | if (defaults.hasOwnProperty(prop)) {
|
859 | config[prop] = custom.hasOwnProperty(prop) ? custom[prop] : defaults[prop];
|
860 | }
|
861 | }
|
862 |
|
863 | return config;
|
864 | },
|
865 |
|
866 | format: function (val) {
|
867 | return "" + val;
|
868 | },
|
869 |
|
870 | defaultConfig: {
|
871 | injectIntoThis: true,
|
872 | injectInto: null,
|
873 | properties: ["spy", "stub", "mock", "clock", "server", "requests"],
|
874 | useFakeTimers: true,
|
875 | useFakeServer: true
|
876 | },
|
877 |
|
878 | timesInWords: function timesInWords(count) {
|
879 | return count == 1 && "once" ||
|
880 | count == 2 && "twice" ||
|
881 | count == 3 && "thrice" ||
|
882 | (count || 0) + " times";
|
883 | },
|
884 |
|
885 | calledInOrder: function (spies) {
|
886 | for (var i = 1, l = spies.length; i < l; i++) {
|
887 | if (!spies[i - 1].calledBefore(spies[i]) || !spies[i].called) {
|
888 | return false;
|
889 | }
|
890 | }
|
891 |
|
892 | return true;
|
893 | },
|
894 |
|
895 | orderByFirstCall: function (spies) {
|
896 | return spies.sort(function (a, b) {
|
897 |
|
898 | var aCall = a.getCall(0);
|
899 | var bCall = b.getCall(0);
|
900 | var aId = aCall && aCall.callId || -1;
|
901 | var bId = bCall && bCall.callId || -1;
|
902 |
|
903 | return aId < bId ? -1 : 1;
|
904 | });
|
905 | },
|
906 |
|
907 | log: function () {},
|
908 |
|
909 | logError: function (label, err) {
|
910 | var msg = label + " threw exception: ";
|
911 | sinon.log(msg + "[" + err.name + "] " + err.message);
|
912 | if (err.stack) { sinon.log(err.stack); }
|
913 |
|
914 | setTimeout(function () {
|
915 | err.message = msg + err.message;
|
916 | throw err;
|
917 | }, 0);
|
918 | },
|
919 |
|
920 | typeOf: function (value) {
|
921 | if (value === null) {
|
922 | return "null";
|
923 | }
|
924 | else if (value === undefined) {
|
925 | return "undefined";
|
926 | }
|
927 | var string = Object.prototype.toString.call(value);
|
928 | return string.substring(8, string.length - 1).toLowerCase();
|
929 | },
|
930 |
|
931 | createStubInstance: function (constructor) {
|
932 | if (typeof constructor !== "function") {
|
933 | throw new TypeError("The constructor should be a function.");
|
934 | }
|
935 | return sinon.stub(sinon.create(constructor.prototype));
|
936 | },
|
937 |
|
938 | restore: function (object) {
|
939 | if (object !== null && typeof object === "object") {
|
940 | for (var prop in object) {
|
941 | if (isRestorable(object[prop])) {
|
942 | object[prop].restore();
|
943 | }
|
944 | }
|
945 | }
|
946 | else if (isRestorable(object)) {
|
947 | object.restore();
|
948 | }
|
949 | }
|
950 | };
|
951 |
|
952 | var isNode = typeof module !== "undefined" && module.exports;
|
953 | var isAMD = typeof define === 'function' && typeof define.amd === 'object' && define.amd;
|
954 |
|
955 | if (isAMD) {
|
956 | define(function(){
|
957 | return sinon;
|
958 | });
|
959 | } else if (isNode) {
|
960 | try {
|
961 | formatio = require("formatio");
|
962 | } catch (e) {}
|
963 | module.exports = sinon;
|
964 | module.exports.spy = require("./sinon/spy");
|
965 | module.exports.spyCall = require("./sinon/call");
|
966 | module.exports.behavior = require("./sinon/behavior");
|
967 | module.exports.stub = require("./sinon/stub");
|
968 | module.exports.mock = require("./sinon/mock");
|
969 | module.exports.collection = require("./sinon/collection");
|
970 | module.exports.assert = require("./sinon/assert");
|
971 | module.exports.sandbox = require("./sinon/sandbox");
|
972 | module.exports.test = require("./sinon/test");
|
973 | module.exports.testCase = require("./sinon/test_case");
|
974 | module.exports.assert = require("./sinon/assert");
|
975 | module.exports.match = require("./sinon/match");
|
976 | }
|
977 |
|
978 | if (formatio) {
|
979 | var formatter = formatio.configure({ quoteStrings: false });
|
980 | sinon.format = function () {
|
981 | return formatter.ascii.apply(formatter, arguments);
|
982 | };
|
983 | } else if (isNode) {
|
984 | try {
|
985 | var util = require("util");
|
986 | sinon.format = function (value) {
|
987 | return typeof value == "object" && value.toString === Object.prototype.toString ? util.inspect(value) : value;
|
988 | };
|
989 | } catch (e) {
|
990 | |
991 |
|
992 | }
|
993 | }
|
994 |
|
995 | return sinon;
|
996 | }(typeof formatio == "object" && formatio));
|
997 |
|
998 |
|
999 |
|
1000 |
|
1001 |
|
1002 |
|
1003 |
|
1004 |
|
1005 |
|
1006 |
|
1007 |
|
1008 |
|
1009 |
|
1010 | (function (sinon) {
|
1011 | var commonJSModule = typeof module !== 'undefined' && module.exports;
|
1012 |
|
1013 | if (!sinon && commonJSModule) {
|
1014 | sinon = require("../sinon");
|
1015 | }
|
1016 |
|
1017 | if (!sinon) {
|
1018 | return;
|
1019 | }
|
1020 |
|
1021 | function assertType(value, type, name) {
|
1022 | var actual = sinon.typeOf(value);
|
1023 | if (actual !== type) {
|
1024 | throw new TypeError("Expected type of " + name + " to be " +
|
1025 | type + ", but was " + actual);
|
1026 | }
|
1027 | }
|
1028 |
|
1029 | var matcher = {
|
1030 | toString: function () {
|
1031 | return this.message;
|
1032 | }
|
1033 | };
|
1034 |
|
1035 | function isMatcher(object) {
|
1036 | return matcher.isPrototypeOf(object);
|
1037 | }
|
1038 |
|
1039 | function matchObject(expectation, actual) {
|
1040 | if (actual === null || actual === undefined) {
|
1041 | return false;
|
1042 | }
|
1043 | for (var key in expectation) {
|
1044 | if (expectation.hasOwnProperty(key)) {
|
1045 | var exp = expectation[key];
|
1046 | var act = actual[key];
|
1047 | if (match.isMatcher(exp)) {
|
1048 | if (!exp.test(act)) {
|
1049 | return false;
|
1050 | }
|
1051 | } else if (sinon.typeOf(exp) === "object") {
|
1052 | if (!matchObject(exp, act)) {
|
1053 | return false;
|
1054 | }
|
1055 | } else if (!sinon.deepEqual(exp, act)) {
|
1056 | return false;
|
1057 | }
|
1058 | }
|
1059 | }
|
1060 | return true;
|
1061 | }
|
1062 |
|
1063 | matcher.or = function (m2) {
|
1064 | if (!arguments.length) {
|
1065 | throw new TypeError("Matcher expected");
|
1066 | } else if (!isMatcher(m2)) {
|
1067 | m2 = match(m2);
|
1068 | }
|
1069 | var m1 = this;
|
1070 | var or = sinon.create(matcher);
|
1071 | or.test = function (actual) {
|
1072 | return m1.test(actual) || m2.test(actual);
|
1073 | };
|
1074 | or.message = m1.message + ".or(" + m2.message + ")";
|
1075 | return or;
|
1076 | };
|
1077 |
|
1078 | matcher.and = function (m2) {
|
1079 | if (!arguments.length) {
|
1080 | throw new TypeError("Matcher expected");
|
1081 | } else if (!isMatcher(m2)) {
|
1082 | m2 = match(m2);
|
1083 | }
|
1084 | var m1 = this;
|
1085 | var and = sinon.create(matcher);
|
1086 | and.test = function (actual) {
|
1087 | return m1.test(actual) && m2.test(actual);
|
1088 | };
|
1089 | and.message = m1.message + ".and(" + m2.message + ")";
|
1090 | return and;
|
1091 | };
|
1092 |
|
1093 | var match = function (expectation, message) {
|
1094 | var m = sinon.create(matcher);
|
1095 | var type = sinon.typeOf(expectation);
|
1096 | switch (type) {
|
1097 | case "object":
|
1098 | if (typeof expectation.test === "function") {
|
1099 | m.test = function (actual) {
|
1100 | return expectation.test(actual) === true;
|
1101 | };
|
1102 | m.message = "match(" + sinon.functionName(expectation.test) + ")";
|
1103 | return m;
|
1104 | }
|
1105 | var str = [];
|
1106 | for (var key in expectation) {
|
1107 | if (expectation.hasOwnProperty(key)) {
|
1108 | str.push(key + ": " + expectation[key]);
|
1109 | }
|
1110 | }
|
1111 | m.test = function (actual) {
|
1112 | return matchObject(expectation, actual);
|
1113 | };
|
1114 | m.message = "match(" + str.join(", ") + ")";
|
1115 | break;
|
1116 | case "number":
|
1117 | m.test = function (actual) {
|
1118 | return expectation == actual;
|
1119 | };
|
1120 | break;
|
1121 | case "string":
|
1122 | m.test = function (actual) {
|
1123 | if (typeof actual !== "string") {
|
1124 | return false;
|
1125 | }
|
1126 | return actual.indexOf(expectation) !== -1;
|
1127 | };
|
1128 | m.message = "match(\"" + expectation + "\")";
|
1129 | break;
|
1130 | case "regexp":
|
1131 | m.test = function (actual) {
|
1132 | if (typeof actual !== "string") {
|
1133 | return false;
|
1134 | }
|
1135 | return expectation.test(actual);
|
1136 | };
|
1137 | break;
|
1138 | case "function":
|
1139 | m.test = expectation;
|
1140 | if (message) {
|
1141 | m.message = message;
|
1142 | } else {
|
1143 | m.message = "match(" + sinon.functionName(expectation) + ")";
|
1144 | }
|
1145 | break;
|
1146 | default:
|
1147 | m.test = function (actual) {
|
1148 | return sinon.deepEqual(expectation, actual);
|
1149 | };
|
1150 | }
|
1151 | if (!m.message) {
|
1152 | m.message = "match(" + expectation + ")";
|
1153 | }
|
1154 | return m;
|
1155 | };
|
1156 |
|
1157 | match.isMatcher = isMatcher;
|
1158 |
|
1159 | match.any = match(function () {
|
1160 | return true;
|
1161 | }, "any");
|
1162 |
|
1163 | match.defined = match(function (actual) {
|
1164 | return actual !== null && actual !== undefined;
|
1165 | }, "defined");
|
1166 |
|
1167 | match.truthy = match(function (actual) {
|
1168 | return !!actual;
|
1169 | }, "truthy");
|
1170 |
|
1171 | match.falsy = match(function (actual) {
|
1172 | return !actual;
|
1173 | }, "falsy");
|
1174 |
|
1175 | match.same = function (expectation) {
|
1176 | return match(function (actual) {
|
1177 | return expectation === actual;
|
1178 | }, "same(" + expectation + ")");
|
1179 | };
|
1180 |
|
1181 | match.typeOf = function (type) {
|
1182 | assertType(type, "string", "type");
|
1183 | return match(function (actual) {
|
1184 | return sinon.typeOf(actual) === type;
|
1185 | }, "typeOf(\"" + type + "\")");
|
1186 | };
|
1187 |
|
1188 | match.instanceOf = function (type) {
|
1189 | assertType(type, "function", "type");
|
1190 | return match(function (actual) {
|
1191 | return actual instanceof type;
|
1192 | }, "instanceOf(" + sinon.functionName(type) + ")");
|
1193 | };
|
1194 |
|
1195 | function createPropertyMatcher(propertyTest, messagePrefix) {
|
1196 | return function (property, value) {
|
1197 | assertType(property, "string", "property");
|
1198 | var onlyProperty = arguments.length === 1;
|
1199 | var message = messagePrefix + "(\"" + property + "\"";
|
1200 | if (!onlyProperty) {
|
1201 | message += ", " + value;
|
1202 | }
|
1203 | message += ")";
|
1204 | return match(function (actual) {
|
1205 | if (actual === undefined || actual === null ||
|
1206 | !propertyTest(actual, property)) {
|
1207 | return false;
|
1208 | }
|
1209 | return onlyProperty || sinon.deepEqual(value, actual[property]);
|
1210 | }, message);
|
1211 | };
|
1212 | }
|
1213 |
|
1214 | match.has = createPropertyMatcher(function (actual, property) {
|
1215 | if (typeof actual === "object") {
|
1216 | return property in actual;
|
1217 | }
|
1218 | return actual[property] !== undefined;
|
1219 | }, "has");
|
1220 |
|
1221 | match.hasOwn = createPropertyMatcher(function (actual, property) {
|
1222 | return actual.hasOwnProperty(property);
|
1223 | }, "hasOwn");
|
1224 |
|
1225 | match.bool = match.typeOf("boolean");
|
1226 | match.number = match.typeOf("number");
|
1227 | match.string = match.typeOf("string");
|
1228 | match.object = match.typeOf("object");
|
1229 | match.func = match.typeOf("function");
|
1230 | match.array = match.typeOf("array");
|
1231 | match.regexp = match.typeOf("regexp");
|
1232 | match.date = match.typeOf("date");
|
1233 |
|
1234 | if (commonJSModule) {
|
1235 | module.exports = match;
|
1236 | } else {
|
1237 | sinon.match = match;
|
1238 | }
|
1239 | }(typeof sinon == "object" && sinon || null));
|
1240 |
|
1241 |
|
1242 |
|
1243 |
|
1244 |
|
1245 |
|
1246 |
|
1247 |
|
1248 |
|
1249 |
|
1250 |
|
1251 |
|
1252 |
|
1253 |
|
1254 |
|
1255 |
|
1256 |
|
1257 |
|
1258 | (function (sinon) {
|
1259 | var commonJSModule = typeof module !== 'undefined' && module.exports;
|
1260 | if (!sinon && commonJSModule) {
|
1261 | sinon = require("../sinon");
|
1262 | }
|
1263 |
|
1264 | if (!sinon) {
|
1265 | return;
|
1266 | }
|
1267 |
|
1268 | function throwYieldError(proxy, text, args) {
|
1269 | var msg = sinon.functionName(proxy) + text;
|
1270 | if (args.length) {
|
1271 | msg += " Received [" + slice.call(args).join(", ") + "]";
|
1272 | }
|
1273 | throw new Error(msg);
|
1274 | }
|
1275 |
|
1276 | var slice = Array.prototype.slice;
|
1277 |
|
1278 | var callProto = {
|
1279 | calledOn: function calledOn(thisValue) {
|
1280 | if (sinon.match && sinon.match.isMatcher(thisValue)) {
|
1281 | return thisValue.test(this.thisValue);
|
1282 | }
|
1283 | return this.thisValue === thisValue;
|
1284 | },
|
1285 |
|
1286 | calledWith: function calledWith() {
|
1287 | for (var i = 0, l = arguments.length; i < l; i += 1) {
|
1288 | if (!sinon.deepEqual(arguments[i], this.args[i])) {
|
1289 | return false;
|
1290 | }
|
1291 | }
|
1292 |
|
1293 | return true;
|
1294 | },
|
1295 |
|
1296 | calledWithMatch: function calledWithMatch() {
|
1297 | for (var i = 0, l = arguments.length; i < l; i += 1) {
|
1298 | var actual = this.args[i];
|
1299 | var expectation = arguments[i];
|
1300 | if (!sinon.match || !sinon.match(expectation).test(actual)) {
|
1301 | return false;
|
1302 | }
|
1303 | }
|
1304 | return true;
|
1305 | },
|
1306 |
|
1307 | calledWithExactly: function calledWithExactly() {
|
1308 | return arguments.length == this.args.length &&
|
1309 | this.calledWith.apply(this, arguments);
|
1310 | },
|
1311 |
|
1312 | notCalledWith: function notCalledWith() {
|
1313 | return !this.calledWith.apply(this, arguments);
|
1314 | },
|
1315 |
|
1316 | notCalledWithMatch: function notCalledWithMatch() {
|
1317 | return !this.calledWithMatch.apply(this, arguments);
|
1318 | },
|
1319 |
|
1320 | returned: function returned(value) {
|
1321 | return sinon.deepEqual(value, this.returnValue);
|
1322 | },
|
1323 |
|
1324 | threw: function threw(error) {
|
1325 | if (typeof error === "undefined" || !this.exception) {
|
1326 | return !!this.exception;
|
1327 | }
|
1328 |
|
1329 | return this.exception === error || this.exception.name === error;
|
1330 | },
|
1331 |
|
1332 | calledWithNew: function calledWithNew() {
|
1333 | return this.proxy.prototype && this.thisValue instanceof this.proxy;
|
1334 | },
|
1335 |
|
1336 | calledBefore: function (other) {
|
1337 | return this.callId < other.callId;
|
1338 | },
|
1339 |
|
1340 | calledAfter: function (other) {
|
1341 | return this.callId > other.callId;
|
1342 | },
|
1343 |
|
1344 | callArg: function (pos) {
|
1345 | this.args[pos]();
|
1346 | },
|
1347 |
|
1348 | callArgOn: function (pos, thisValue) {
|
1349 | this.args[pos].apply(thisValue);
|
1350 | },
|
1351 |
|
1352 | callArgWith: function (pos) {
|
1353 | this.callArgOnWith.apply(this, [pos, null].concat(slice.call(arguments, 1)));
|
1354 | },
|
1355 |
|
1356 | callArgOnWith: function (pos, thisValue) {
|
1357 | var args = slice.call(arguments, 2);
|
1358 | this.args[pos].apply(thisValue, args);
|
1359 | },
|
1360 |
|
1361 | "yield": function () {
|
1362 | this.yieldOn.apply(this, [null].concat(slice.call(arguments, 0)));
|
1363 | },
|
1364 |
|
1365 | yieldOn: function (thisValue) {
|
1366 | var args = this.args;
|
1367 | for (var i = 0, l = args.length; i < l; ++i) {
|
1368 | if (typeof args[i] === "function") {
|
1369 | args[i].apply(thisValue, slice.call(arguments, 1));
|
1370 | return;
|
1371 | }
|
1372 | }
|
1373 | throwYieldError(this.proxy, " cannot yield since no callback was passed.", args);
|
1374 | },
|
1375 |
|
1376 | yieldTo: function (prop) {
|
1377 | this.yieldToOn.apply(this, [prop, null].concat(slice.call(arguments, 1)));
|
1378 | },
|
1379 |
|
1380 | yieldToOn: function (prop, thisValue) {
|
1381 | var args = this.args;
|
1382 | for (var i = 0, l = args.length; i < l; ++i) {
|
1383 | if (args[i] && typeof args[i][prop] === "function") {
|
1384 | args[i][prop].apply(thisValue, slice.call(arguments, 2));
|
1385 | return;
|
1386 | }
|
1387 | }
|
1388 | throwYieldError(this.proxy, " cannot yield to '" + prop +
|
1389 | "' since no callback was passed.", args);
|
1390 | },
|
1391 |
|
1392 | toString: function () {
|
1393 | var callStr = this.proxy.toString() + "(";
|
1394 | var args = [];
|
1395 |
|
1396 | for (var i = 0, l = this.args.length; i < l; ++i) {
|
1397 | args.push(sinon.format(this.args[i]));
|
1398 | }
|
1399 |
|
1400 | callStr = callStr + args.join(", ") + ")";
|
1401 |
|
1402 | if (typeof this.returnValue != "undefined") {
|
1403 | callStr += " => " + sinon.format(this.returnValue);
|
1404 | }
|
1405 |
|
1406 | if (this.exception) {
|
1407 | callStr += " !" + this.exception.name;
|
1408 |
|
1409 | if (this.exception.message) {
|
1410 | callStr += "(" + this.exception.message + ")";
|
1411 | }
|
1412 | }
|
1413 |
|
1414 | return callStr;
|
1415 | }
|
1416 | };
|
1417 |
|
1418 | callProto.invokeCallback = callProto.yield;
|
1419 |
|
1420 | function createSpyCall(spy, thisValue, args, returnValue, exception, id) {
|
1421 | if (typeof id !== "number") {
|
1422 | throw new TypeError("Call id is not a number");
|
1423 | }
|
1424 | var proxyCall = sinon.create(callProto);
|
1425 | proxyCall.proxy = spy;
|
1426 | proxyCall.thisValue = thisValue;
|
1427 | proxyCall.args = args;
|
1428 | proxyCall.returnValue = returnValue;
|
1429 | proxyCall.exception = exception;
|
1430 | proxyCall.callId = id;
|
1431 |
|
1432 | return proxyCall;
|
1433 | }
|
1434 | createSpyCall.toString = callProto.toString;
|
1435 |
|
1436 | if (commonJSModule) {
|
1437 | module.exports = createSpyCall;
|
1438 | } else {
|
1439 | sinon.spyCall = createSpyCall;
|
1440 | }
|
1441 | }(typeof sinon == "object" && sinon || null));
|
1442 |
|
1443 |
|
1444 |
|
1445 |
|
1446 |
|
1447 |
|
1448 |
|
1449 |
|
1450 |
|
1451 |
|
1452 |
|
1453 |
|
1454 |
|
1455 |
|
1456 |
|
1457 |
|
1458 |
|
1459 | (function (sinon) {
|
1460 | var commonJSModule = typeof module !== 'undefined' && module.exports;
|
1461 | var push = Array.prototype.push;
|
1462 | var slice = Array.prototype.slice;
|
1463 | var callId = 0;
|
1464 |
|
1465 | if (!sinon && commonJSModule) {
|
1466 | sinon = require("../sinon");
|
1467 | }
|
1468 |
|
1469 | if (!sinon) {
|
1470 | return;
|
1471 | }
|
1472 |
|
1473 | function spy(object, property) {
|
1474 | if (!property && typeof object == "function") {
|
1475 | return spy.create(object);
|
1476 | }
|
1477 |
|
1478 | if (!object && !property) {
|
1479 | return spy.create(function () { });
|
1480 | }
|
1481 |
|
1482 | var method = object[property];
|
1483 | return sinon.wrapMethod(object, property, spy.create(method));
|
1484 | }
|
1485 |
|
1486 | function matchingFake(fakes, args, strict) {
|
1487 | if (!fakes) {
|
1488 | return;
|
1489 | }
|
1490 |
|
1491 | for (var i = 0, l = fakes.length; i < l; i++) {
|
1492 | if (fakes[i].matches(args, strict)) {
|
1493 | return fakes[i];
|
1494 | }
|
1495 | }
|
1496 | }
|
1497 |
|
1498 | function incrementCallCount() {
|
1499 | this.called = true;
|
1500 | this.callCount += 1;
|
1501 | this.notCalled = false;
|
1502 | this.calledOnce = this.callCount == 1;
|
1503 | this.calledTwice = this.callCount == 2;
|
1504 | this.calledThrice = this.callCount == 3;
|
1505 | }
|
1506 |
|
1507 | function createCallProperties() {
|
1508 | this.firstCall = this.getCall(0);
|
1509 | this.secondCall = this.getCall(1);
|
1510 | this.thirdCall = this.getCall(2);
|
1511 | this.lastCall = this.getCall(this.callCount - 1);
|
1512 | }
|
1513 |
|
1514 | var vars = "a,b,c,d,e,f,g,h,i,j,k,l";
|
1515 | function createProxy(func) {
|
1516 |
|
1517 | var p;
|
1518 | if (func.length) {
|
1519 | eval("p = (function proxy(" + vars.substring(0, func.length * 2 - 1) +
|
1520 | ") { return p.invoke(func, this, slice.call(arguments)); });");
|
1521 | }
|
1522 | else {
|
1523 | p = function proxy() {
|
1524 | return p.invoke(func, this, slice.call(arguments));
|
1525 | };
|
1526 | }
|
1527 | return p;
|
1528 | }
|
1529 |
|
1530 | var uuid = 0;
|
1531 |
|
1532 |
|
1533 | var spyApi = {
|
1534 | reset: function () {
|
1535 | this.called = false;
|
1536 | this.notCalled = true;
|
1537 | this.calledOnce = false;
|
1538 | this.calledTwice = false;
|
1539 | this.calledThrice = false;
|
1540 | this.callCount = 0;
|
1541 | this.firstCall = null;
|
1542 | this.secondCall = null;
|
1543 | this.thirdCall = null;
|
1544 | this.lastCall = null;
|
1545 | this.args = [];
|
1546 | this.returnValues = [];
|
1547 | this.thisValues = [];
|
1548 | this.exceptions = [];
|
1549 | this.callIds = [];
|
1550 | if (this.fakes) {
|
1551 | for (var i = 0; i < this.fakes.length; i++) {
|
1552 | this.fakes[i].reset();
|
1553 | }
|
1554 | }
|
1555 | },
|
1556 |
|
1557 | create: function create(func) {
|
1558 | var name;
|
1559 |
|
1560 | if (typeof func != "function") {
|
1561 | func = function () { };
|
1562 | } else {
|
1563 | name = sinon.functionName(func);
|
1564 | }
|
1565 |
|
1566 | var proxy = createProxy(func);
|
1567 |
|
1568 | sinon.extend(proxy, spy);
|
1569 | delete proxy.create;
|
1570 | sinon.extend(proxy, func);
|
1571 |
|
1572 | proxy.reset();
|
1573 | proxy.prototype = func.prototype;
|
1574 | proxy.displayName = name || "spy";
|
1575 | proxy.toString = sinon.functionToString;
|
1576 | proxy._create = sinon.spy.create;
|
1577 | proxy.id = "spy#" + uuid++;
|
1578 |
|
1579 | return proxy;
|
1580 | },
|
1581 |
|
1582 | invoke: function invoke(func, thisValue, args) {
|
1583 | var matching = matchingFake(this.fakes, args);
|
1584 | var exception, returnValue;
|
1585 |
|
1586 | incrementCallCount.call(this);
|
1587 | push.call(this.thisValues, thisValue);
|
1588 | push.call(this.args, args);
|
1589 | push.call(this.callIds, callId++);
|
1590 |
|
1591 | try {
|
1592 | if (matching) {
|
1593 | returnValue = matching.invoke(func, thisValue, args);
|
1594 | } else {
|
1595 | returnValue = (this.func || func).apply(thisValue, args);
|
1596 | }
|
1597 |
|
1598 | var thisCall = this.getCall(this.callCount - 1);
|
1599 | if (thisCall.calledWithNew() && typeof returnValue !== 'object') {
|
1600 | returnValue = thisValue;
|
1601 | }
|
1602 | } catch (e) {
|
1603 | exception = e;
|
1604 | }
|
1605 |
|
1606 | push.call(this.exceptions, exception);
|
1607 | push.call(this.returnValues, returnValue);
|
1608 |
|
1609 | createCallProperties.call(this);
|
1610 |
|
1611 | if (exception !== undefined) {
|
1612 | throw exception;
|
1613 | }
|
1614 |
|
1615 | return returnValue;
|
1616 | },
|
1617 |
|
1618 | getCall: function getCall(i) {
|
1619 | if (i < 0 || i >= this.callCount) {
|
1620 | return null;
|
1621 | }
|
1622 |
|
1623 | return sinon.spyCall(this, this.thisValues[i], this.args[i],
|
1624 | this.returnValues[i], this.exceptions[i],
|
1625 | this.callIds[i]);
|
1626 | },
|
1627 |
|
1628 | getCalls: function () {
|
1629 | var calls = [];
|
1630 | var i;
|
1631 |
|
1632 | for (i = 0; i < this.callCount; i++) {
|
1633 | calls.push(this.getCall(i));
|
1634 | }
|
1635 |
|
1636 | return calls;
|
1637 | },
|
1638 |
|
1639 | calledBefore: function calledBefore(spyFn) {
|
1640 | if (!this.called) {
|
1641 | return false;
|
1642 | }
|
1643 |
|
1644 | if (!spyFn.called) {
|
1645 | return true;
|
1646 | }
|
1647 |
|
1648 | return this.callIds[0] < spyFn.callIds[spyFn.callIds.length - 1];
|
1649 | },
|
1650 |
|
1651 | calledAfter: function calledAfter(spyFn) {
|
1652 | if (!this.called || !spyFn.called) {
|
1653 | return false;
|
1654 | }
|
1655 |
|
1656 | return this.callIds[this.callCount - 1] > spyFn.callIds[spyFn.callCount - 1];
|
1657 | },
|
1658 |
|
1659 | withArgs: function () {
|
1660 | var args = slice.call(arguments);
|
1661 |
|
1662 | if (this.fakes) {
|
1663 | var match = matchingFake(this.fakes, args, true);
|
1664 |
|
1665 | if (match) {
|
1666 | return match;
|
1667 | }
|
1668 | } else {
|
1669 | this.fakes = [];
|
1670 | }
|
1671 |
|
1672 | var original = this;
|
1673 | var fake = this._create();
|
1674 | fake.matchingArguments = args;
|
1675 | fake.parent = this;
|
1676 | push.call(this.fakes, fake);
|
1677 |
|
1678 | fake.withArgs = function () {
|
1679 | return original.withArgs.apply(original, arguments);
|
1680 | };
|
1681 |
|
1682 | for (var i = 0; i < this.args.length; i++) {
|
1683 | if (fake.matches(this.args[i])) {
|
1684 | incrementCallCount.call(fake);
|
1685 | push.call(fake.thisValues, this.thisValues[i]);
|
1686 | push.call(fake.args, this.args[i]);
|
1687 | push.call(fake.returnValues, this.returnValues[i]);
|
1688 | push.call(fake.exceptions, this.exceptions[i]);
|
1689 | push.call(fake.callIds, this.callIds[i]);
|
1690 | }
|
1691 | }
|
1692 | createCallProperties.call(fake);
|
1693 |
|
1694 | return fake;
|
1695 | },
|
1696 |
|
1697 | matches: function (args, strict) {
|
1698 | var margs = this.matchingArguments;
|
1699 |
|
1700 | if (margs.length <= args.length &&
|
1701 | sinon.deepEqual(margs, args.slice(0, margs.length))) {
|
1702 | return !strict || margs.length == args.length;
|
1703 | }
|
1704 | },
|
1705 |
|
1706 | printf: function (format) {
|
1707 | var spy = this;
|
1708 | var args = slice.call(arguments, 1);
|
1709 | var formatter;
|
1710 |
|
1711 | return (format || "").replace(/%(.)/g, function (match, specifier) {
|
1712 | formatter = spyApi.formatters[specifier];
|
1713 |
|
1714 | if (typeof formatter == "function") {
|
1715 | return formatter.call(null, spy, args);
|
1716 | } else if (!isNaN(parseInt(specifier, 10))) {
|
1717 | return sinon.format(args[specifier - 1]);
|
1718 | }
|
1719 |
|
1720 | return "%" + specifier;
|
1721 | });
|
1722 | }
|
1723 | };
|
1724 |
|
1725 | function delegateToCalls(method, matchAny, actual, notCalled) {
|
1726 | spyApi[method] = function () {
|
1727 | if (!this.called) {
|
1728 | if (notCalled) {
|
1729 | return notCalled.apply(this, arguments);
|
1730 | }
|
1731 | return false;
|
1732 | }
|
1733 |
|
1734 | var currentCall;
|
1735 | var matches = 0;
|
1736 |
|
1737 | for (var i = 0, l = this.callCount; i < l; i += 1) {
|
1738 | currentCall = this.getCall(i);
|
1739 |
|
1740 | if (currentCall[actual || method].apply(currentCall, arguments)) {
|
1741 | matches += 1;
|
1742 |
|
1743 | if (matchAny) {
|
1744 | return true;
|
1745 | }
|
1746 | }
|
1747 | }
|
1748 |
|
1749 | return matches === this.callCount;
|
1750 | };
|
1751 | }
|
1752 |
|
1753 | delegateToCalls("calledOn", true);
|
1754 | delegateToCalls("alwaysCalledOn", false, "calledOn");
|
1755 | delegateToCalls("calledWith", true);
|
1756 | delegateToCalls("calledWithMatch", true);
|
1757 | delegateToCalls("alwaysCalledWith", false, "calledWith");
|
1758 | delegateToCalls("alwaysCalledWithMatch", false, "calledWithMatch");
|
1759 | delegateToCalls("calledWithExactly", true);
|
1760 | delegateToCalls("alwaysCalledWithExactly", false, "calledWithExactly");
|
1761 | delegateToCalls("neverCalledWith", false, "notCalledWith",
|
1762 | function () { return true; });
|
1763 | delegateToCalls("neverCalledWithMatch", false, "notCalledWithMatch",
|
1764 | function () { return true; });
|
1765 | delegateToCalls("threw", true);
|
1766 | delegateToCalls("alwaysThrew", false, "threw");
|
1767 | delegateToCalls("returned", true);
|
1768 | delegateToCalls("alwaysReturned", false, "returned");
|
1769 | delegateToCalls("calledWithNew", true);
|
1770 | delegateToCalls("alwaysCalledWithNew", false, "calledWithNew");
|
1771 | delegateToCalls("callArg", false, "callArgWith", function () {
|
1772 | throw new Error(this.toString() + " cannot call arg since it was not yet invoked.");
|
1773 | });
|
1774 | spyApi.callArgWith = spyApi.callArg;
|
1775 | delegateToCalls("callArgOn", false, "callArgOnWith", function () {
|
1776 | throw new Error(this.toString() + " cannot call arg since it was not yet invoked.");
|
1777 | });
|
1778 | spyApi.callArgOnWith = spyApi.callArgOn;
|
1779 | delegateToCalls("yield", false, "yield", function () {
|
1780 | throw new Error(this.toString() + " cannot yield since it was not yet invoked.");
|
1781 | });
|
1782 |
|
1783 | spyApi.invokeCallback = spyApi.yield;
|
1784 | delegateToCalls("yieldOn", false, "yieldOn", function () {
|
1785 | throw new Error(this.toString() + " cannot yield since it was not yet invoked.");
|
1786 | });
|
1787 | delegateToCalls("yieldTo", false, "yieldTo", function (property) {
|
1788 | throw new Error(this.toString() + " cannot yield to '" + property +
|
1789 | "' since it was not yet invoked.");
|
1790 | });
|
1791 | delegateToCalls("yieldToOn", false, "yieldToOn", function (property) {
|
1792 | throw new Error(this.toString() + " cannot yield to '" + property +
|
1793 | "' since it was not yet invoked.");
|
1794 | });
|
1795 |
|
1796 | spyApi.formatters = {
|
1797 | "c": function (spy) {
|
1798 | return sinon.timesInWords(spy.callCount);
|
1799 | },
|
1800 |
|
1801 | "n": function (spy) {
|
1802 | return spy.toString();
|
1803 | },
|
1804 |
|
1805 | "C": function (spy) {
|
1806 | var calls = [];
|
1807 |
|
1808 | for (var i = 0, l = spy.callCount; i < l; ++i) {
|
1809 | var stringifiedCall = " " + spy.getCall(i).toString();
|
1810 | if (/\n/.test(calls[i - 1])) {
|
1811 | stringifiedCall = "\n" + stringifiedCall;
|
1812 | }
|
1813 | push.call(calls, stringifiedCall);
|
1814 | }
|
1815 |
|
1816 | return calls.length > 0 ? "\n" + calls.join("\n") : "";
|
1817 | },
|
1818 |
|
1819 | "t": function (spy) {
|
1820 | var objects = [];
|
1821 |
|
1822 | for (var i = 0, l = spy.callCount; i < l; ++i) {
|
1823 | push.call(objects, sinon.format(spy.thisValues[i]));
|
1824 | }
|
1825 |
|
1826 | return objects.join(", ");
|
1827 | },
|
1828 |
|
1829 | "*": function (spy, args) {
|
1830 | var formatted = [];
|
1831 |
|
1832 | for (var i = 0, l = args.length; i < l; ++i) {
|
1833 | push.call(formatted, sinon.format(args[i]));
|
1834 | }
|
1835 |
|
1836 | return formatted.join(", ");
|
1837 | }
|
1838 | };
|
1839 |
|
1840 | sinon.extend(spy, spyApi);
|
1841 |
|
1842 | spy.spyCall = sinon.spyCall;
|
1843 |
|
1844 | if (commonJSModule) {
|
1845 | module.exports = spy;
|
1846 | } else {
|
1847 | sinon.spy = spy;
|
1848 | }
|
1849 | }(typeof sinon == "object" && sinon || null));
|
1850 |
|
1851 |
|
1852 |
|
1853 |
|
1854 |
|
1855 |
|
1856 |
|
1857 |
|
1858 |
|
1859 |
|
1860 |
|
1861 |
|
1862 |
|
1863 |
|
1864 |
|
1865 |
|
1866 | (function (sinon) {
|
1867 | var commonJSModule = typeof module !== 'undefined' && module.exports;
|
1868 |
|
1869 | if (!sinon && commonJSModule) {
|
1870 | sinon = require("../sinon");
|
1871 | }
|
1872 |
|
1873 | if (!sinon) {
|
1874 | return;
|
1875 | }
|
1876 |
|
1877 | var slice = Array.prototype.slice;
|
1878 | var join = Array.prototype.join;
|
1879 | var proto;
|
1880 |
|
1881 | var nextTick = (function () {
|
1882 | if (typeof process === "object" && typeof process.nextTick === "function") {
|
1883 | return process.nextTick;
|
1884 | } else if (typeof setImmediate === "function") {
|
1885 | return setImmediate;
|
1886 | } else {
|
1887 | return function (callback) {
|
1888 | setTimeout(callback, 0);
|
1889 | };
|
1890 | }
|
1891 | })();
|
1892 |
|
1893 | function throwsException(error, message) {
|
1894 | if (typeof error == "string") {
|
1895 | this.exception = new Error(message || "");
|
1896 | this.exception.name = error;
|
1897 | } else if (!error) {
|
1898 | this.exception = new Error("Error");
|
1899 | } else {
|
1900 | this.exception = error;
|
1901 | }
|
1902 |
|
1903 | return this;
|
1904 | }
|
1905 |
|
1906 | function getCallback(behavior, args) {
|
1907 | var callArgAt = behavior.callArgAt;
|
1908 |
|
1909 | if (callArgAt < 0) {
|
1910 | var callArgProp = behavior.callArgProp;
|
1911 |
|
1912 | for (var i = 0, l = args.length; i < l; ++i) {
|
1913 | if (!callArgProp && typeof args[i] == "function") {
|
1914 | return args[i];
|
1915 | }
|
1916 |
|
1917 | if (callArgProp && args[i] &&
|
1918 | typeof args[i][callArgProp] == "function") {
|
1919 | return args[i][callArgProp];
|
1920 | }
|
1921 | }
|
1922 |
|
1923 | return null;
|
1924 | }
|
1925 |
|
1926 | return args[callArgAt];
|
1927 | }
|
1928 |
|
1929 | function getCallbackError(behavior, func, args) {
|
1930 | if (behavior.callArgAt < 0) {
|
1931 | var msg;
|
1932 |
|
1933 | if (behavior.callArgProp) {
|
1934 | msg = sinon.functionName(behavior.stub) +
|
1935 | " expected to yield to '" + behavior.callArgProp +
|
1936 | "', but no object with such a property was passed.";
|
1937 | } else {
|
1938 | msg = sinon.functionName(behavior.stub) +
|
1939 | " expected to yield, but no callback was passed.";
|
1940 | }
|
1941 |
|
1942 | if (args.length > 0) {
|
1943 | msg += " Received [" + join.call(args, ", ") + "]";
|
1944 | }
|
1945 |
|
1946 | return msg;
|
1947 | }
|
1948 |
|
1949 | return "argument at index " + behavior.callArgAt + " is not a function: " + func;
|
1950 | }
|
1951 |
|
1952 | function callCallback(behavior, args) {
|
1953 | if (typeof behavior.callArgAt == "number") {
|
1954 | var func = getCallback(behavior, args);
|
1955 |
|
1956 | if (typeof func != "function") {
|
1957 | throw new TypeError(getCallbackError(behavior, func, args));
|
1958 | }
|
1959 |
|
1960 | if (behavior.callbackAsync) {
|
1961 | nextTick(function() {
|
1962 | func.apply(behavior.callbackContext, behavior.callbackArguments);
|
1963 | });
|
1964 | } else {
|
1965 | func.apply(behavior.callbackContext, behavior.callbackArguments);
|
1966 | }
|
1967 | }
|
1968 | }
|
1969 |
|
1970 | proto = {
|
1971 | create: function(stub) {
|
1972 | var behavior = sinon.extend({}, sinon.behavior);
|
1973 | delete behavior.create;
|
1974 | behavior.stub = stub;
|
1975 |
|
1976 | return behavior;
|
1977 | },
|
1978 |
|
1979 | isPresent: function() {
|
1980 | return (typeof this.callArgAt == 'number' ||
|
1981 | this.exception ||
|
1982 | typeof this.returnArgAt == 'number' ||
|
1983 | this.returnThis ||
|
1984 | this.returnValueDefined);
|
1985 | },
|
1986 |
|
1987 | invoke: function(context, args) {
|
1988 | callCallback(this, args);
|
1989 |
|
1990 | if (this.exception) {
|
1991 | throw this.exception;
|
1992 | } else if (typeof this.returnArgAt == 'number') {
|
1993 | return args[this.returnArgAt];
|
1994 | } else if (this.returnThis) {
|
1995 | return context;
|
1996 | }
|
1997 |
|
1998 | return this.returnValue;
|
1999 | },
|
2000 |
|
2001 | onCall: function(index) {
|
2002 | return this.stub.onCall(index);
|
2003 | },
|
2004 |
|
2005 | onFirstCall: function() {
|
2006 | return this.stub.onFirstCall();
|
2007 | },
|
2008 |
|
2009 | onSecondCall: function() {
|
2010 | return this.stub.onSecondCall();
|
2011 | },
|
2012 |
|
2013 | onThirdCall: function() {
|
2014 | return this.stub.onThirdCall();
|
2015 | },
|
2016 |
|
2017 | withArgs: function(/* arguments */) {
|
2018 | throw new Error('Defining a stub by invoking "stub.onCall(...).withArgs(...)" is not supported. ' +
|
2019 | 'Use "stub.withArgs(...).onCall(...)" to define sequential behavior for calls with certain arguments.');
|
2020 | },
|
2021 |
|
2022 | callsArg: function callsArg(pos) {
|
2023 | if (typeof pos != "number") {
|
2024 | throw new TypeError("argument index is not number");
|
2025 | }
|
2026 |
|
2027 | this.callArgAt = pos;
|
2028 | this.callbackArguments = [];
|
2029 | this.callbackContext = undefined;
|
2030 | this.callArgProp = undefined;
|
2031 | this.callbackAsync = false;
|
2032 |
|
2033 | return this;
|
2034 | },
|
2035 |
|
2036 | callsArgOn: function callsArgOn(pos, context) {
|
2037 | if (typeof pos != "number") {
|
2038 | throw new TypeError("argument index is not number");
|
2039 | }
|
2040 | if (typeof context != "object") {
|
2041 | throw new TypeError("argument context is not an object");
|
2042 | }
|
2043 |
|
2044 | this.callArgAt = pos;
|
2045 | this.callbackArguments = [];
|
2046 | this.callbackContext = context;
|
2047 | this.callArgProp = undefined;
|
2048 | this.callbackAsync = false;
|
2049 |
|
2050 | return this;
|
2051 | },
|
2052 |
|
2053 | callsArgWith: function callsArgWith(pos) {
|
2054 | if (typeof pos != "number") {
|
2055 | throw new TypeError("argument index is not number");
|
2056 | }
|
2057 |
|
2058 | this.callArgAt = pos;
|
2059 | this.callbackArguments = slice.call(arguments, 1);
|
2060 | this.callbackContext = undefined;
|
2061 | this.callArgProp = undefined;
|
2062 | this.callbackAsync = false;
|
2063 |
|
2064 | return this;
|
2065 | },
|
2066 |
|
2067 | callsArgOnWith: function callsArgWith(pos, context) {
|
2068 | if (typeof pos != "number") {
|
2069 | throw new TypeError("argument index is not number");
|
2070 | }
|
2071 | if (typeof context != "object") {
|
2072 | throw new TypeError("argument context is not an object");
|
2073 | }
|
2074 |
|
2075 | this.callArgAt = pos;
|
2076 | this.callbackArguments = slice.call(arguments, 2);
|
2077 | this.callbackContext = context;
|
2078 | this.callArgProp = undefined;
|
2079 | this.callbackAsync = false;
|
2080 |
|
2081 | return this;
|
2082 | },
|
2083 |
|
2084 | yields: function () {
|
2085 | this.callArgAt = -1;
|
2086 | this.callbackArguments = slice.call(arguments, 0);
|
2087 | this.callbackContext = undefined;
|
2088 | this.callArgProp = undefined;
|
2089 | this.callbackAsync = false;
|
2090 |
|
2091 | return this;
|
2092 | },
|
2093 |
|
2094 | yieldsOn: function (context) {
|
2095 | if (typeof context != "object") {
|
2096 | throw new TypeError("argument context is not an object");
|
2097 | }
|
2098 |
|
2099 | this.callArgAt = -1;
|
2100 | this.callbackArguments = slice.call(arguments, 1);
|
2101 | this.callbackContext = context;
|
2102 | this.callArgProp = undefined;
|
2103 | this.callbackAsync = false;
|
2104 |
|
2105 | return this;
|
2106 | },
|
2107 |
|
2108 | yieldsTo: function (prop) {
|
2109 | this.callArgAt = -1;
|
2110 | this.callbackArguments = slice.call(arguments, 1);
|
2111 | this.callbackContext = undefined;
|
2112 | this.callArgProp = prop;
|
2113 | this.callbackAsync = false;
|
2114 |
|
2115 | return this;
|
2116 | },
|
2117 |
|
2118 | yieldsToOn: function (prop, context) {
|
2119 | if (typeof context != "object") {
|
2120 | throw new TypeError("argument context is not an object");
|
2121 | }
|
2122 |
|
2123 | this.callArgAt = -1;
|
2124 | this.callbackArguments = slice.call(arguments, 2);
|
2125 | this.callbackContext = context;
|
2126 | this.callArgProp = prop;
|
2127 | this.callbackAsync = false;
|
2128 |
|
2129 | return this;
|
2130 | },
|
2131 |
|
2132 |
|
2133 | "throws": throwsException,
|
2134 | throwsException: throwsException,
|
2135 |
|
2136 | returns: function returns(value) {
|
2137 | this.returnValue = value;
|
2138 | this.returnValueDefined = true;
|
2139 |
|
2140 | return this;
|
2141 | },
|
2142 |
|
2143 | returnsArg: function returnsArg(pos) {
|
2144 | if (typeof pos != "number") {
|
2145 | throw new TypeError("argument index is not number");
|
2146 | }
|
2147 |
|
2148 | this.returnArgAt = pos;
|
2149 |
|
2150 | return this;
|
2151 | },
|
2152 |
|
2153 | returnsThis: function returnsThis() {
|
2154 | this.returnThis = true;
|
2155 |
|
2156 | return this;
|
2157 | }
|
2158 | };
|
2159 |
|
2160 |
|
2161 | for (var method in proto) {
|
2162 |
|
2163 | if (proto.hasOwnProperty(method) &&
|
2164 | method.match(/^(callsArg|yields)/) &&
|
2165 | !method.match(/Async/)) {
|
2166 | proto[method + 'Async'] = (function (syncFnName) {
|
2167 | return function () {
|
2168 | var result = this[syncFnName].apply(this, arguments);
|
2169 | this.callbackAsync = true;
|
2170 | return result;
|
2171 | };
|
2172 | })(method);
|
2173 | }
|
2174 | }
|
2175 |
|
2176 | if (commonJSModule) {
|
2177 | module.exports = proto;
|
2178 | } else {
|
2179 | sinon.behavior = proto;
|
2180 | }
|
2181 | }(typeof sinon == "object" && sinon || null));
|
2182 |
|
2183 |
|
2184 |
|
2185 |
|
2186 |
|
2187 |
|
2188 |
|
2189 |
|
2190 |
|
2191 |
|
2192 |
|
2193 |
|
2194 |
|
2195 |
|
2196 |
|
2197 |
|
2198 | (function (sinon) {
|
2199 | var commonJSModule = typeof module !== 'undefined' && module.exports;
|
2200 |
|
2201 | if (!sinon && commonJSModule) {
|
2202 | sinon = require("../sinon");
|
2203 | }
|
2204 |
|
2205 | if (!sinon) {
|
2206 | return;
|
2207 | }
|
2208 |
|
2209 | function stub(object, property, func) {
|
2210 | if (!!func && typeof func != "function") {
|
2211 | throw new TypeError("Custom stub should be function");
|
2212 | }
|
2213 |
|
2214 | var wrapper;
|
2215 |
|
2216 | if (func) {
|
2217 | wrapper = sinon.spy && sinon.spy.create ? sinon.spy.create(func) : func;
|
2218 | } else {
|
2219 | wrapper = stub.create();
|
2220 | }
|
2221 |
|
2222 | if (!object && typeof property === "undefined") {
|
2223 | return sinon.stub.create();
|
2224 | }
|
2225 |
|
2226 | if (typeof property === "undefined" && typeof object == "object") {
|
2227 | for (var prop in object) {
|
2228 | if (typeof object[prop] === "function") {
|
2229 | stub(object, prop);
|
2230 | }
|
2231 | }
|
2232 |
|
2233 | return object;
|
2234 | }
|
2235 |
|
2236 | return sinon.wrapMethod(object, property, wrapper);
|
2237 | }
|
2238 |
|
2239 | function getDefaultBehavior(stub) {
|
2240 | return stub.defaultBehavior || getParentBehaviour(stub) || sinon.behavior.create(stub);
|
2241 | }
|
2242 |
|
2243 | function getParentBehaviour(stub) {
|
2244 | return (stub.parent && getCurrentBehavior(stub.parent));
|
2245 | }
|
2246 |
|
2247 | function getCurrentBehavior(stub) {
|
2248 | var behavior = stub.behaviors[stub.callCount - 1];
|
2249 | return behavior && behavior.isPresent() ? behavior : getDefaultBehavior(stub);
|
2250 | }
|
2251 |
|
2252 | var uuid = 0;
|
2253 |
|
2254 | sinon.extend(stub, (function () {
|
2255 | var proto = {
|
2256 | create: function create() {
|
2257 | var functionStub = function () {
|
2258 | return getCurrentBehavior(functionStub).invoke(this, arguments);
|
2259 | };
|
2260 |
|
2261 | functionStub.id = "stub#" + uuid++;
|
2262 | var orig = functionStub;
|
2263 | functionStub = sinon.spy.create(functionStub);
|
2264 | functionStub.func = orig;
|
2265 |
|
2266 | sinon.extend(functionStub, stub);
|
2267 | functionStub._create = sinon.stub.create;
|
2268 | functionStub.displayName = "stub";
|
2269 | functionStub.toString = sinon.functionToString;
|
2270 |
|
2271 | functionStub.defaultBehavior = null;
|
2272 | functionStub.behaviors = [];
|
2273 |
|
2274 | return functionStub;
|
2275 | },
|
2276 |
|
2277 | resetBehavior: function () {
|
2278 | var i;
|
2279 |
|
2280 | this.defaultBehavior = null;
|
2281 | this.behaviors = [];
|
2282 |
|
2283 | delete this.returnValue;
|
2284 | delete this.returnArgAt;
|
2285 | this.returnThis = false;
|
2286 |
|
2287 | if (this.fakes) {
|
2288 | for (i = 0; i < this.fakes.length; i++) {
|
2289 | this.fakes[i].resetBehavior();
|
2290 | }
|
2291 | }
|
2292 | },
|
2293 |
|
2294 | onCall: function(index) {
|
2295 | if (!this.behaviors[index]) {
|
2296 | this.behaviors[index] = sinon.behavior.create(this);
|
2297 | }
|
2298 |
|
2299 | return this.behaviors[index];
|
2300 | },
|
2301 |
|
2302 | onFirstCall: function() {
|
2303 | return this.onCall(0);
|
2304 | },
|
2305 |
|
2306 | onSecondCall: function() {
|
2307 | return this.onCall(1);
|
2308 | },
|
2309 |
|
2310 | onThirdCall: function() {
|
2311 | return this.onCall(2);
|
2312 | }
|
2313 | };
|
2314 |
|
2315 | for (var method in sinon.behavior) {
|
2316 | if (sinon.behavior.hasOwnProperty(method) &&
|
2317 | !proto.hasOwnProperty(method) &&
|
2318 | method != 'create' &&
|
2319 | method != 'withArgs' &&
|
2320 | method != 'invoke') {
|
2321 | proto[method] = (function(behaviorMethod) {
|
2322 | return function() {
|
2323 | this.defaultBehavior = this.defaultBehavior || sinon.behavior.create(this);
|
2324 | this.defaultBehavior[behaviorMethod].apply(this.defaultBehavior, arguments);
|
2325 | return this;
|
2326 | };
|
2327 | }(method));
|
2328 | }
|
2329 | }
|
2330 |
|
2331 | return proto;
|
2332 | }()));
|
2333 |
|
2334 | if (commonJSModule) {
|
2335 | module.exports = stub;
|
2336 | } else {
|
2337 | sinon.stub = stub;
|
2338 | }
|
2339 | }(typeof sinon == "object" && sinon || null));
|
2340 |
|
2341 |
|
2342 |
|
2343 |
|
2344 |
|
2345 |
|
2346 |
|
2347 |
|
2348 |
|
2349 |
|
2350 |
|
2351 |
|
2352 |
|
2353 |
|
2354 |
|
2355 |
|
2356 | (function (sinon) {
|
2357 | var commonJSModule = typeof module !== 'undefined' && module.exports;
|
2358 | var push = [].push;
|
2359 | var match;
|
2360 |
|
2361 | if (!sinon && commonJSModule) {
|
2362 | sinon = require("../sinon");
|
2363 | }
|
2364 |
|
2365 | if (!sinon) {
|
2366 | return;
|
2367 | }
|
2368 |
|
2369 | match = sinon.match;
|
2370 |
|
2371 | if (!match && commonJSModule) {
|
2372 | match = require("./match");
|
2373 | }
|
2374 |
|
2375 | function mock(object) {
|
2376 | if (!object) {
|
2377 | return sinon.expectation.create("Anonymous mock");
|
2378 | }
|
2379 |
|
2380 | return mock.create(object);
|
2381 | }
|
2382 |
|
2383 | sinon.mock = mock;
|
2384 |
|
2385 | sinon.extend(mock, (function () {
|
2386 | function each(collection, callback) {
|
2387 | if (!collection) {
|
2388 | return;
|
2389 | }
|
2390 |
|
2391 | for (var i = 0, l = collection.length; i < l; i += 1) {
|
2392 | callback(collection[i]);
|
2393 | }
|
2394 | }
|
2395 |
|
2396 | return {
|
2397 | create: function create(object) {
|
2398 | if (!object) {
|
2399 | throw new TypeError("object is null");
|
2400 | }
|
2401 |
|
2402 | var mockObject = sinon.extend({}, mock);
|
2403 | mockObject.object = object;
|
2404 | delete mockObject.create;
|
2405 |
|
2406 | return mockObject;
|
2407 | },
|
2408 |
|
2409 | expects: function expects(method) {
|
2410 | if (!method) {
|
2411 | throw new TypeError("method is falsy");
|
2412 | }
|
2413 |
|
2414 | if (!this.expectations) {
|
2415 | this.expectations = {};
|
2416 | this.proxies = [];
|
2417 | }
|
2418 |
|
2419 | if (!this.expectations[method]) {
|
2420 | this.expectations[method] = [];
|
2421 | var mockObject = this;
|
2422 |
|
2423 | sinon.wrapMethod(this.object, method, function () {
|
2424 | return mockObject.invokeMethod(method, this, arguments);
|
2425 | });
|
2426 |
|
2427 | push.call(this.proxies, method);
|
2428 | }
|
2429 |
|
2430 | var expectation = sinon.expectation.create(method);
|
2431 | push.call(this.expectations[method], expectation);
|
2432 |
|
2433 | return expectation;
|
2434 | },
|
2435 |
|
2436 | restore: function restore() {
|
2437 | var object = this.object;
|
2438 |
|
2439 | each(this.proxies, function (proxy) {
|
2440 | if (typeof object[proxy].restore == "function") {
|
2441 | object[proxy].restore();
|
2442 | }
|
2443 | });
|
2444 | },
|
2445 |
|
2446 | verify: function verify() {
|
2447 | var expectations = this.expectations || {};
|
2448 | var messages = [], met = [];
|
2449 |
|
2450 | each(this.proxies, function (proxy) {
|
2451 | each(expectations[proxy], function (expectation) {
|
2452 | if (!expectation.met()) {
|
2453 | push.call(messages, expectation.toString());
|
2454 | } else {
|
2455 | push.call(met, expectation.toString());
|
2456 | }
|
2457 | });
|
2458 | });
|
2459 |
|
2460 | this.restore();
|
2461 |
|
2462 | if (messages.length > 0) {
|
2463 | sinon.expectation.fail(messages.concat(met).join("\n"));
|
2464 | } else {
|
2465 | sinon.expectation.pass(messages.concat(met).join("\n"));
|
2466 | }
|
2467 |
|
2468 | return true;
|
2469 | },
|
2470 |
|
2471 | invokeMethod: function invokeMethod(method, thisValue, args) {
|
2472 | var expectations = this.expectations && this.expectations[method];
|
2473 | var length = expectations && expectations.length || 0, i;
|
2474 |
|
2475 | for (i = 0; i < length; i += 1) {
|
2476 | if (!expectations[i].met() &&
|
2477 | expectations[i].allowsCall(thisValue, args)) {
|
2478 | return expectations[i].apply(thisValue, args);
|
2479 | }
|
2480 | }
|
2481 |
|
2482 | var messages = [], available, exhausted = 0;
|
2483 |
|
2484 | for (i = 0; i < length; i += 1) {
|
2485 | if (expectations[i].allowsCall(thisValue, args)) {
|
2486 | available = available || expectations[i];
|
2487 | } else {
|
2488 | exhausted += 1;
|
2489 | }
|
2490 | push.call(messages, " " + expectations[i].toString());
|
2491 | }
|
2492 |
|
2493 | if (exhausted === 0) {
|
2494 | return available.apply(thisValue, args);
|
2495 | }
|
2496 |
|
2497 | messages.unshift("Unexpected call: " + sinon.spyCall.toString.call({
|
2498 | proxy: method,
|
2499 | args: args
|
2500 | }));
|
2501 |
|
2502 | sinon.expectation.fail(messages.join("\n"));
|
2503 | }
|
2504 | };
|
2505 | }()));
|
2506 |
|
2507 | var times = sinon.timesInWords;
|
2508 |
|
2509 | sinon.expectation = (function () {
|
2510 | var slice = Array.prototype.slice;
|
2511 | var _invoke = sinon.spy.invoke;
|
2512 |
|
2513 | function callCountInWords(callCount) {
|
2514 | if (callCount == 0) {
|
2515 | return "never called";
|
2516 | } else {
|
2517 | return "called " + times(callCount);
|
2518 | }
|
2519 | }
|
2520 |
|
2521 | function expectedCallCountInWords(expectation) {
|
2522 | var min = expectation.minCalls;
|
2523 | var max = expectation.maxCalls;
|
2524 |
|
2525 | if (typeof min == "number" && typeof max == "number") {
|
2526 | var str = times(min);
|
2527 |
|
2528 | if (min != max) {
|
2529 | str = "at least " + str + " and at most " + times(max);
|
2530 | }
|
2531 |
|
2532 | return str;
|
2533 | }
|
2534 |
|
2535 | if (typeof min == "number") {
|
2536 | return "at least " + times(min);
|
2537 | }
|
2538 |
|
2539 | return "at most " + times(max);
|
2540 | }
|
2541 |
|
2542 | function receivedMinCalls(expectation) {
|
2543 | var hasMinLimit = typeof expectation.minCalls == "number";
|
2544 | return !hasMinLimit || expectation.callCount >= expectation.minCalls;
|
2545 | }
|
2546 |
|
2547 | function receivedMaxCalls(expectation) {
|
2548 | if (typeof expectation.maxCalls != "number") {
|
2549 | return false;
|
2550 | }
|
2551 |
|
2552 | return expectation.callCount == expectation.maxCalls;
|
2553 | }
|
2554 |
|
2555 | function verifyMatcher(possibleMatcher, arg){
|
2556 | if (match && match.isMatcher(possibleMatcher)) {
|
2557 | return possibleMatcher.test(arg);
|
2558 | } else {
|
2559 | return true;
|
2560 | }
|
2561 | }
|
2562 |
|
2563 | return {
|
2564 | minCalls: 1,
|
2565 | maxCalls: 1,
|
2566 |
|
2567 | create: function create(methodName) {
|
2568 | var expectation = sinon.extend(sinon.stub.create(), sinon.expectation);
|
2569 | delete expectation.create;
|
2570 | expectation.method = methodName;
|
2571 |
|
2572 | return expectation;
|
2573 | },
|
2574 |
|
2575 | invoke: function invoke(func, thisValue, args) {
|
2576 | this.verifyCallAllowed(thisValue, args);
|
2577 |
|
2578 | return _invoke.apply(this, arguments);
|
2579 | },
|
2580 |
|
2581 | atLeast: function atLeast(num) {
|
2582 | if (typeof num != "number") {
|
2583 | throw new TypeError("'" + num + "' is not number");
|
2584 | }
|
2585 |
|
2586 | if (!this.limitsSet) {
|
2587 | this.maxCalls = null;
|
2588 | this.limitsSet = true;
|
2589 | }
|
2590 |
|
2591 | this.minCalls = num;
|
2592 |
|
2593 | return this;
|
2594 | },
|
2595 |
|
2596 | atMost: function atMost(num) {
|
2597 | if (typeof num != "number") {
|
2598 | throw new TypeError("'" + num + "' is not number");
|
2599 | }
|
2600 |
|
2601 | if (!this.limitsSet) {
|
2602 | this.minCalls = null;
|
2603 | this.limitsSet = true;
|
2604 | }
|
2605 |
|
2606 | this.maxCalls = num;
|
2607 |
|
2608 | return this;
|
2609 | },
|
2610 |
|
2611 | never: function never() {
|
2612 | return this.exactly(0);
|
2613 | },
|
2614 |
|
2615 | once: function once() {
|
2616 | return this.exactly(1);
|
2617 | },
|
2618 |
|
2619 | twice: function twice() {
|
2620 | return this.exactly(2);
|
2621 | },
|
2622 |
|
2623 | thrice: function thrice() {
|
2624 | return this.exactly(3);
|
2625 | },
|
2626 |
|
2627 | exactly: function exactly(num) {
|
2628 | if (typeof num != "number") {
|
2629 | throw new TypeError("'" + num + "' is not a number");
|
2630 | }
|
2631 |
|
2632 | this.atLeast(num);
|
2633 | return this.atMost(num);
|
2634 | },
|
2635 |
|
2636 | met: function met() {
|
2637 | return !this.failed && receivedMinCalls(this);
|
2638 | },
|
2639 |
|
2640 | verifyCallAllowed: function verifyCallAllowed(thisValue, args) {
|
2641 | if (receivedMaxCalls(this)) {
|
2642 | this.failed = true;
|
2643 | sinon.expectation.fail(this.method + " already called " + times(this.maxCalls));
|
2644 | }
|
2645 |
|
2646 | if ("expectedThis" in this && this.expectedThis !== thisValue) {
|
2647 | sinon.expectation.fail(this.method + " called with " + thisValue + " as thisValue, expected " +
|
2648 | this.expectedThis);
|
2649 | }
|
2650 |
|
2651 | if (!("expectedArguments" in this)) {
|
2652 | return;
|
2653 | }
|
2654 |
|
2655 | if (!args) {
|
2656 | sinon.expectation.fail(this.method + " received no arguments, expected " +
|
2657 | sinon.format(this.expectedArguments));
|
2658 | }
|
2659 |
|
2660 | if (args.length < this.expectedArguments.length) {
|
2661 | sinon.expectation.fail(this.method + " received too few arguments (" + sinon.format(args) +
|
2662 | "), expected " + sinon.format(this.expectedArguments));
|
2663 | }
|
2664 |
|
2665 | if (this.expectsExactArgCount &&
|
2666 | args.length != this.expectedArguments.length) {
|
2667 | sinon.expectation.fail(this.method + " received too many arguments (" + sinon.format(args) +
|
2668 | "), expected " + sinon.format(this.expectedArguments));
|
2669 | }
|
2670 |
|
2671 | for (var i = 0, l = this.expectedArguments.length; i < l; i += 1) {
|
2672 |
|
2673 | if (!verifyMatcher(this.expectedArguments[i],args[i])) {
|
2674 | sinon.expectation.fail(this.method + " received wrong arguments " + sinon.format(args) +
|
2675 | ", didn't match " + this.expectedArguments.toString());
|
2676 | }
|
2677 |
|
2678 | if (!sinon.deepEqual(this.expectedArguments[i], args[i])) {
|
2679 | sinon.expectation.fail(this.method + " received wrong arguments " + sinon.format(args) +
|
2680 | ", expected " + sinon.format(this.expectedArguments));
|
2681 | }
|
2682 | }
|
2683 | },
|
2684 |
|
2685 | allowsCall: function allowsCall(thisValue, args) {
|
2686 | if (this.met() && receivedMaxCalls(this)) {
|
2687 | return false;
|
2688 | }
|
2689 |
|
2690 | if ("expectedThis" in this && this.expectedThis !== thisValue) {
|
2691 | return false;
|
2692 | }
|
2693 |
|
2694 | if (!("expectedArguments" in this)) {
|
2695 | return true;
|
2696 | }
|
2697 |
|
2698 | args = args || [];
|
2699 |
|
2700 | if (args.length < this.expectedArguments.length) {
|
2701 | return false;
|
2702 | }
|
2703 |
|
2704 | if (this.expectsExactArgCount &&
|
2705 | args.length != this.expectedArguments.length) {
|
2706 | return false;
|
2707 | }
|
2708 |
|
2709 | for (var i = 0, l = this.expectedArguments.length; i < l; i += 1) {
|
2710 | if (!verifyMatcher(this.expectedArguments[i],args[i])) {
|
2711 | return false;
|
2712 | }
|
2713 |
|
2714 | if (!sinon.deepEqual(this.expectedArguments[i], args[i])) {
|
2715 | return false;
|
2716 | }
|
2717 | }
|
2718 |
|
2719 | return true;
|
2720 | },
|
2721 |
|
2722 | withArgs: function withArgs() {
|
2723 | this.expectedArguments = slice.call(arguments);
|
2724 | return this;
|
2725 | },
|
2726 |
|
2727 | withExactArgs: function withExactArgs() {
|
2728 | this.withArgs.apply(this, arguments);
|
2729 | this.expectsExactArgCount = true;
|
2730 | return this;
|
2731 | },
|
2732 |
|
2733 | on: function on(thisValue) {
|
2734 | this.expectedThis = thisValue;
|
2735 | return this;
|
2736 | },
|
2737 |
|
2738 | toString: function () {
|
2739 | var args = (this.expectedArguments || []).slice();
|
2740 |
|
2741 | if (!this.expectsExactArgCount) {
|
2742 | push.call(args, "[...]");
|
2743 | }
|
2744 |
|
2745 | var callStr = sinon.spyCall.toString.call({
|
2746 | proxy: this.method || "anonymous mock expectation",
|
2747 | args: args
|
2748 | });
|
2749 |
|
2750 | var message = callStr.replace(", [...", "[, ...") + " " +
|
2751 | expectedCallCountInWords(this);
|
2752 |
|
2753 | if (this.met()) {
|
2754 | return "Expectation met: " + message;
|
2755 | }
|
2756 |
|
2757 | return "Expected " + message + " (" +
|
2758 | callCountInWords(this.callCount) + ")";
|
2759 | },
|
2760 |
|
2761 | verify: function verify() {
|
2762 | if (!this.met()) {
|
2763 | sinon.expectation.fail(this.toString());
|
2764 | } else {
|
2765 | sinon.expectation.pass(this.toString());
|
2766 | }
|
2767 |
|
2768 | return true;
|
2769 | },
|
2770 |
|
2771 | pass: function(message) {
|
2772 | sinon.assert.pass(message);
|
2773 | },
|
2774 | fail: function (message) {
|
2775 | var exception = new Error(message);
|
2776 | exception.name = "ExpectationError";
|
2777 |
|
2778 | throw exception;
|
2779 | }
|
2780 | };
|
2781 | }());
|
2782 |
|
2783 | if (commonJSModule) {
|
2784 | module.exports = mock;
|
2785 | } else {
|
2786 | sinon.mock = mock;
|
2787 | }
|
2788 | }(typeof sinon == "object" && sinon || null));
|
2789 |
|
2790 |
|
2791 |
|
2792 |
|
2793 |
|
2794 |
|
2795 |
|
2796 |
|
2797 |
|
2798 |
|
2799 |
|
2800 |
|
2801 |
|
2802 |
|
2803 |
|
2804 |
|
2805 |
|
2806 | (function (sinon) {
|
2807 | var commonJSModule = typeof module !== 'undefined' && module.exports;
|
2808 | var push = [].push;
|
2809 | var hasOwnProperty = Object.prototype.hasOwnProperty;
|
2810 |
|
2811 | if (!sinon && commonJSModule) {
|
2812 | sinon = require("../sinon");
|
2813 | }
|
2814 |
|
2815 | if (!sinon) {
|
2816 | return;
|
2817 | }
|
2818 |
|
2819 | function getFakes(fakeCollection) {
|
2820 | if (!fakeCollection.fakes) {
|
2821 | fakeCollection.fakes = [];
|
2822 | }
|
2823 |
|
2824 | return fakeCollection.fakes;
|
2825 | }
|
2826 |
|
2827 | function each(fakeCollection, method) {
|
2828 | var fakes = getFakes(fakeCollection);
|
2829 |
|
2830 | for (var i = 0, l = fakes.length; i < l; i += 1) {
|
2831 | if (typeof fakes[i][method] == "function") {
|
2832 | fakes[i][method]();
|
2833 | }
|
2834 | }
|
2835 | }
|
2836 |
|
2837 | function compact(fakeCollection) {
|
2838 | var fakes = getFakes(fakeCollection);
|
2839 | var i = 0;
|
2840 | while (i < fakes.length) {
|
2841 | fakes.splice(i, 1);
|
2842 | }
|
2843 | }
|
2844 |
|
2845 | var collection = {
|
2846 | verify: function resolve() {
|
2847 | each(this, "verify");
|
2848 | },
|
2849 |
|
2850 | restore: function restore() {
|
2851 | each(this, "restore");
|
2852 | compact(this);
|
2853 | },
|
2854 |
|
2855 | verifyAndRestore: function verifyAndRestore() {
|
2856 | var exception;
|
2857 |
|
2858 | try {
|
2859 | this.verify();
|
2860 | } catch (e) {
|
2861 | exception = e;
|
2862 | }
|
2863 |
|
2864 | this.restore();
|
2865 |
|
2866 | if (exception) {
|
2867 | throw exception;
|
2868 | }
|
2869 | },
|
2870 |
|
2871 | add: function add(fake) {
|
2872 | push.call(getFakes(this), fake);
|
2873 | return fake;
|
2874 | },
|
2875 |
|
2876 | spy: function spy() {
|
2877 | return this.add(sinon.spy.apply(sinon, arguments));
|
2878 | },
|
2879 |
|
2880 | stub: function stub(object, property, value) {
|
2881 | if (property) {
|
2882 | var original = object[property];
|
2883 |
|
2884 | if (typeof original != "function") {
|
2885 | if (!hasOwnProperty.call(object, property)) {
|
2886 | throw new TypeError("Cannot stub non-existent own property " + property);
|
2887 | }
|
2888 |
|
2889 | object[property] = value;
|
2890 |
|
2891 | return this.add({
|
2892 | restore: function () {
|
2893 | object[property] = original;
|
2894 | }
|
2895 | });
|
2896 | }
|
2897 | }
|
2898 | if (!property && !!object && typeof object == "object") {
|
2899 | var stubbedObj = sinon.stub.apply(sinon, arguments);
|
2900 |
|
2901 | for (var prop in stubbedObj) {
|
2902 | if (typeof stubbedObj[prop] === "function") {
|
2903 | this.add(stubbedObj[prop]);
|
2904 | }
|
2905 | }
|
2906 |
|
2907 | return stubbedObj;
|
2908 | }
|
2909 |
|
2910 | return this.add(sinon.stub.apply(sinon, arguments));
|
2911 | },
|
2912 |
|
2913 | mock: function mock() {
|
2914 | return this.add(sinon.mock.apply(sinon, arguments));
|
2915 | },
|
2916 |
|
2917 | inject: function inject(obj) {
|
2918 | var col = this;
|
2919 |
|
2920 | obj.spy = function () {
|
2921 | return col.spy.apply(col, arguments);
|
2922 | };
|
2923 |
|
2924 | obj.stub = function () {
|
2925 | return col.stub.apply(col, arguments);
|
2926 | };
|
2927 |
|
2928 | obj.mock = function () {
|
2929 | return col.mock.apply(col, arguments);
|
2930 | };
|
2931 |
|
2932 | return obj;
|
2933 | }
|
2934 | };
|
2935 |
|
2936 | if (commonJSModule) {
|
2937 | module.exports = collection;
|
2938 | } else {
|
2939 | sinon.collection = collection;
|
2940 | }
|
2941 | }(typeof sinon == "object" && sinon || null));
|
2942 |
|
2943 |
|
2944 |
|
2945 |
|
2946 |
|
2947 |
|
2948 |
|
2949 |
|
2950 |
|
2951 |
|
2952 |
|
2953 |
|
2954 |
|
2955 |
|
2956 |
|
2957 |
|
2958 |
|
2959 |
|
2960 |
|
2961 |
|
2962 |
|
2963 | if (typeof sinon == "undefined") {
|
2964 | var sinon = {};
|
2965 | }
|
2966 |
|
2967 | (function (global) {
|
2968 |
|
2969 |
|
2970 |
|
2971 | var timeoutResult = setTimeout(function() {}, 0);
|
2972 | var addTimerReturnsObject = typeof timeoutResult === 'object';
|
2973 | clearTimeout(timeoutResult);
|
2974 |
|
2975 | var id = 1;
|
2976 |
|
2977 | function addTimer(args, recurring) {
|
2978 | if (args.length === 0) {
|
2979 | throw new Error("Function requires at least 1 parameter");
|
2980 | }
|
2981 |
|
2982 | if (typeof args[0] === "undefined") {
|
2983 | throw new Error("Callback must be provided to timer calls");
|
2984 | }
|
2985 |
|
2986 | var toId = id++;
|
2987 | var delay = args[1] || 0;
|
2988 |
|
2989 | if (!this.timeouts) {
|
2990 | this.timeouts = {};
|
2991 | }
|
2992 |
|
2993 | this.timeouts[toId] = {
|
2994 | id: toId,
|
2995 | func: args[0],
|
2996 | callAt: this.now + delay,
|
2997 | invokeArgs: Array.prototype.slice.call(args, 2)
|
2998 | };
|
2999 |
|
3000 | if (recurring === true) {
|
3001 | this.timeouts[toId].interval = delay;
|
3002 | }
|
3003 |
|
3004 | if (addTimerReturnsObject) {
|
3005 | return {
|
3006 | id: toId,
|
3007 | ref: function() {},
|
3008 | unref: function() {}
|
3009 | };
|
3010 | }
|
3011 | else {
|
3012 | return toId;
|
3013 | }
|
3014 | }
|
3015 |
|
3016 | function parseTime(str) {
|
3017 | if (!str) {
|
3018 | return 0;
|
3019 | }
|
3020 |
|
3021 | var strings = str.split(":");
|
3022 | var l = strings.length, i = l;
|
3023 | var ms = 0, parsed;
|
3024 |
|
3025 | if (l > 3 || !/^(\d\d:){0,2}\d\d?$/.test(str)) {
|
3026 | throw new Error("tick only understands numbers and 'h:m:s'");
|
3027 | }
|
3028 |
|
3029 | while (i--) {
|
3030 | parsed = parseInt(strings[i], 10);
|
3031 |
|
3032 | if (parsed >= 60) {
|
3033 | throw new Error("Invalid time " + str);
|
3034 | }
|
3035 |
|
3036 | ms += parsed * Math.pow(60, (l - i - 1));
|
3037 | }
|
3038 |
|
3039 | return ms * 1000;
|
3040 | }
|
3041 |
|
3042 | function createObject(object) {
|
3043 | var newObject;
|
3044 |
|
3045 | if (Object.create) {
|
3046 | newObject = Object.create(object);
|
3047 | } else {
|
3048 | var F = function () {};
|
3049 | F.prototype = object;
|
3050 | newObject = new F();
|
3051 | }
|
3052 |
|
3053 | newObject.Date.clock = newObject;
|
3054 | return newObject;
|
3055 | }
|
3056 |
|
3057 | sinon.clock = {
|
3058 | now: 0,
|
3059 |
|
3060 | create: function create(now) {
|
3061 | var clock = createObject(this);
|
3062 |
|
3063 | if (typeof now == "number") {
|
3064 | clock.now = now;
|
3065 | }
|
3066 |
|
3067 | if (!!now && typeof now == "object") {
|
3068 | throw new TypeError("now should be milliseconds since UNIX epoch");
|
3069 | }
|
3070 |
|
3071 | return clock;
|
3072 | },
|
3073 |
|
3074 | setTimeout: function setTimeout(callback, timeout) {
|
3075 | return addTimer.call(this, arguments, false);
|
3076 | },
|
3077 |
|
3078 | clearTimeout: function clearTimeout(timerId) {
|
3079 | if (!this.timeouts) {
|
3080 | this.timeouts = [];
|
3081 | }
|
3082 |
|
3083 | if (timerId in this.timeouts) {
|
3084 | delete this.timeouts[timerId];
|
3085 | }
|
3086 | },
|
3087 |
|
3088 | setInterval: function setInterval(callback, timeout) {
|
3089 | return addTimer.call(this, arguments, true);
|
3090 | },
|
3091 |
|
3092 | clearInterval: function clearInterval(timerId) {
|
3093 | this.clearTimeout(timerId);
|
3094 | },
|
3095 |
|
3096 | setImmediate: function setImmediate(callback) {
|
3097 | var passThruArgs = Array.prototype.slice.call(arguments, 1);
|
3098 |
|
3099 | return addTimer.call(this, [callback, 0].concat(passThruArgs), false);
|
3100 | },
|
3101 |
|
3102 | clearImmediate: function clearImmediate(timerId) {
|
3103 | this.clearTimeout(timerId);
|
3104 | },
|
3105 |
|
3106 | tick: function tick(ms) {
|
3107 | ms = typeof ms == "number" ? ms : parseTime(ms);
|
3108 | var tickFrom = this.now, tickTo = this.now + ms, previous = this.now;
|
3109 | var timer = this.firstTimerInRange(tickFrom, tickTo);
|
3110 |
|
3111 | var firstException;
|
3112 | while (timer && tickFrom <= tickTo) {
|
3113 | if (this.timeouts[timer.id]) {
|
3114 | tickFrom = this.now = timer.callAt;
|
3115 | try {
|
3116 | this.callTimer(timer);
|
3117 | } catch (e) {
|
3118 | firstException = firstException || e;
|
3119 | }
|
3120 | }
|
3121 |
|
3122 | timer = this.firstTimerInRange(previous, tickTo);
|
3123 | previous = tickFrom;
|
3124 | }
|
3125 |
|
3126 | this.now = tickTo;
|
3127 |
|
3128 | if (firstException) {
|
3129 | throw firstException;
|
3130 | }
|
3131 |
|
3132 | return this.now;
|
3133 | },
|
3134 |
|
3135 | firstTimerInRange: function (from, to) {
|
3136 | var timer, smallest = null, originalTimer;
|
3137 |
|
3138 | for (var id in this.timeouts) {
|
3139 | if (this.timeouts.hasOwnProperty(id)) {
|
3140 | if (this.timeouts[id].callAt < from || this.timeouts[id].callAt > to) {
|
3141 | continue;
|
3142 | }
|
3143 |
|
3144 | if (smallest === null || this.timeouts[id].callAt < smallest) {
|
3145 | originalTimer = this.timeouts[id];
|
3146 | smallest = this.timeouts[id].callAt;
|
3147 |
|
3148 | timer = {
|
3149 | func: this.timeouts[id].func,
|
3150 | callAt: this.timeouts[id].callAt,
|
3151 | interval: this.timeouts[id].interval,
|
3152 | id: this.timeouts[id].id,
|
3153 | invokeArgs: this.timeouts[id].invokeArgs
|
3154 | };
|
3155 | }
|
3156 | }
|
3157 | }
|
3158 |
|
3159 | return timer || null;
|
3160 | },
|
3161 |
|
3162 | callTimer: function (timer) {
|
3163 | if (typeof timer.interval == "number") {
|
3164 | this.timeouts[timer.id].callAt += timer.interval;
|
3165 | } else {
|
3166 | delete this.timeouts[timer.id];
|
3167 | }
|
3168 |
|
3169 | try {
|
3170 | if (typeof timer.func == "function") {
|
3171 | timer.func.apply(null, timer.invokeArgs);
|
3172 | } else {
|
3173 | eval(timer.func);
|
3174 | }
|
3175 | } catch (e) {
|
3176 | var exception = e;
|
3177 | }
|
3178 |
|
3179 | if (!this.timeouts[timer.id]) {
|
3180 | if (exception) {
|
3181 | throw exception;
|
3182 | }
|
3183 | return;
|
3184 | }
|
3185 |
|
3186 | if (exception) {
|
3187 | throw exception;
|
3188 | }
|
3189 | },
|
3190 |
|
3191 | reset: function reset() {
|
3192 | this.timeouts = {};
|
3193 | },
|
3194 |
|
3195 | Date: (function () {
|
3196 | var NativeDate = Date;
|
3197 |
|
3198 | function ClockDate(year, month, date, hour, minute, second, ms) {
|
3199 |
|
3200 |
|
3201 | switch (arguments.length) {
|
3202 | case 0:
|
3203 | return new NativeDate(ClockDate.clock.now);
|
3204 | case 1:
|
3205 | return new NativeDate(year);
|
3206 | case 2:
|
3207 | return new NativeDate(year, month);
|
3208 | case 3:
|
3209 | return new NativeDate(year, month, date);
|
3210 | case 4:
|
3211 | return new NativeDate(year, month, date, hour);
|
3212 | case 5:
|
3213 | return new NativeDate(year, month, date, hour, minute);
|
3214 | case 6:
|
3215 | return new NativeDate(year, month, date, hour, minute, second);
|
3216 | default:
|
3217 | return new NativeDate(year, month, date, hour, minute, second, ms);
|
3218 | }
|
3219 | }
|
3220 |
|
3221 | return mirrorDateProperties(ClockDate, NativeDate);
|
3222 | }())
|
3223 | };
|
3224 |
|
3225 | function mirrorDateProperties(target, source) {
|
3226 | if (source.now) {
|
3227 | target.now = function now() {
|
3228 | return target.clock.now;
|
3229 | };
|
3230 | } else {
|
3231 | delete target.now;
|
3232 | }
|
3233 |
|
3234 | if (source.toSource) {
|
3235 | target.toSource = function toSource() {
|
3236 | return source.toSource();
|
3237 | };
|
3238 | } else {
|
3239 | delete target.toSource;
|
3240 | }
|
3241 |
|
3242 | target.toString = function toString() {
|
3243 | return source.toString();
|
3244 | };
|
3245 |
|
3246 | target.prototype = source.prototype;
|
3247 | target.parse = source.parse;
|
3248 | target.UTC = source.UTC;
|
3249 | target.prototype.toUTCString = source.prototype.toUTCString;
|
3250 |
|
3251 | for (var prop in source) {
|
3252 | if (source.hasOwnProperty(prop)) {
|
3253 | target[prop] = source[prop];
|
3254 | }
|
3255 | }
|
3256 |
|
3257 | return target;
|
3258 | }
|
3259 |
|
3260 | var methods = ["Date", "setTimeout", "setInterval",
|
3261 | "clearTimeout", "clearInterval"];
|
3262 |
|
3263 | if (typeof global.setImmediate !== "undefined") {
|
3264 | methods.push("setImmediate");
|
3265 | }
|
3266 |
|
3267 | if (typeof global.clearImmediate !== "undefined") {
|
3268 | methods.push("clearImmediate");
|
3269 | }
|
3270 |
|
3271 | function restore() {
|
3272 | var method;
|
3273 |
|
3274 | for (var i = 0, l = this.methods.length; i < l; i++) {
|
3275 | method = this.methods[i];
|
3276 |
|
3277 | if (global[method].hadOwnProperty) {
|
3278 | global[method] = this["_" + method];
|
3279 | } else {
|
3280 | try {
|
3281 | delete global[method];
|
3282 | } catch (e) {}
|
3283 | }
|
3284 | }
|
3285 |
|
3286 |
|
3287 | this.methods = [];
|
3288 | }
|
3289 |
|
3290 | function stubGlobal(method, clock) {
|
3291 | clock[method].hadOwnProperty = Object.prototype.hasOwnProperty.call(global, method);
|
3292 | clock["_" + method] = global[method];
|
3293 |
|
3294 | if (method == "Date") {
|
3295 | var date = mirrorDateProperties(clock[method], global[method]);
|
3296 | global[method] = date;
|
3297 | } else {
|
3298 | global[method] = function () {
|
3299 | return clock[method].apply(clock, arguments);
|
3300 | };
|
3301 |
|
3302 | for (var prop in clock[method]) {
|
3303 | if (clock[method].hasOwnProperty(prop)) {
|
3304 | global[method][prop] = clock[method][prop];
|
3305 | }
|
3306 | }
|
3307 | }
|
3308 |
|
3309 | global[method].clock = clock;
|
3310 | }
|
3311 |
|
3312 | sinon.useFakeTimers = function useFakeTimers(now) {
|
3313 | var clock = sinon.clock.create(now);
|
3314 | clock.restore = restore;
|
3315 | clock.methods = Array.prototype.slice.call(arguments,
|
3316 | typeof now == "number" ? 1 : 0);
|
3317 |
|
3318 | if (clock.methods.length === 0) {
|
3319 | clock.methods = methods;
|
3320 | }
|
3321 |
|
3322 | for (var i = 0, l = clock.methods.length; i < l; i++) {
|
3323 | stubGlobal(clock.methods[i], clock);
|
3324 | }
|
3325 |
|
3326 | return clock;
|
3327 | };
|
3328 | }(typeof global != "undefined" && typeof global !== "function" ? global : this));
|
3329 |
|
3330 | sinon.timers = {
|
3331 | setTimeout: setTimeout,
|
3332 | clearTimeout: clearTimeout,
|
3333 | setImmediate: (typeof setImmediate !== "undefined" ? setImmediate : undefined),
|
3334 | clearImmediate: (typeof clearImmediate !== "undefined" ? clearImmediate: undefined),
|
3335 | setInterval: setInterval,
|
3336 | clearInterval: clearInterval,
|
3337 | Date: Date
|
3338 | };
|
3339 |
|
3340 | if (typeof module !== 'undefined' && module.exports) {
|
3341 | module.exports = sinon;
|
3342 | }
|
3343 |
|
3344 |
|
3345 |
|
3346 |
|
3347 |
|
3348 |
|
3349 |
|
3350 |
|
3351 |
|
3352 |
|
3353 |
|
3354 |
|
3355 |
|
3356 |
|
3357 |
|
3358 |
|
3359 | if (typeof sinon == "undefined") {
|
3360 | this.sinon = {};
|
3361 | }
|
3362 |
|
3363 | (function () {
|
3364 | var push = [].push;
|
3365 |
|
3366 | sinon.Event = function Event(type, bubbles, cancelable, target) {
|
3367 | this.initEvent(type, bubbles, cancelable, target);
|
3368 | };
|
3369 |
|
3370 | sinon.Event.prototype = {
|
3371 | initEvent: function(type, bubbles, cancelable, target) {
|
3372 | this.type = type;
|
3373 | this.bubbles = bubbles;
|
3374 | this.cancelable = cancelable;
|
3375 | this.target = target;
|
3376 | },
|
3377 |
|
3378 | stopPropagation: function () {},
|
3379 |
|
3380 | preventDefault: function () {
|
3381 | this.defaultPrevented = true;
|
3382 | }
|
3383 | };
|
3384 |
|
3385 | sinon.ProgressEvent = function ProgressEvent(type, progressEventRaw, target) {
|
3386 | this.initEvent(type, false, false, target);
|
3387 | this.loaded = progressEventRaw.loaded || null;
|
3388 | this.total = progressEventRaw.total || null;
|
3389 | };
|
3390 |
|
3391 | sinon.ProgressEvent.prototype = new sinon.Event();
|
3392 |
|
3393 | sinon.ProgressEvent.prototype.constructor = sinon.ProgressEvent;
|
3394 |
|
3395 | sinon.CustomEvent = function CustomEvent(type, customData, target) {
|
3396 | this.initEvent(type, false, false, target);
|
3397 | this.detail = customData.detail || null;
|
3398 | };
|
3399 |
|
3400 | sinon.CustomEvent.prototype = new sinon.Event();
|
3401 |
|
3402 | sinon.CustomEvent.prototype.constructor = sinon.CustomEvent;
|
3403 |
|
3404 | sinon.EventTarget = {
|
3405 | addEventListener: function addEventListener(event, listener) {
|
3406 | this.eventListeners = this.eventListeners || {};
|
3407 | this.eventListeners[event] = this.eventListeners[event] || [];
|
3408 | push.call(this.eventListeners[event], listener);
|
3409 | },
|
3410 |
|
3411 | removeEventListener: function removeEventListener(event, listener) {
|
3412 | var listeners = this.eventListeners && this.eventListeners[event] || [];
|
3413 |
|
3414 | for (var i = 0, l = listeners.length; i < l; ++i) {
|
3415 | if (listeners[i] == listener) {
|
3416 | return listeners.splice(i, 1);
|
3417 | }
|
3418 | }
|
3419 | },
|
3420 |
|
3421 | dispatchEvent: function dispatchEvent(event) {
|
3422 | var type = event.type;
|
3423 | var listeners = this.eventListeners && this.eventListeners[type] || [];
|
3424 |
|
3425 | for (var i = 0; i < listeners.length; i++) {
|
3426 | if (typeof listeners[i] == "function") {
|
3427 | listeners[i].call(this, event);
|
3428 | } else {
|
3429 | listeners[i].handleEvent(event);
|
3430 | }
|
3431 | }
|
3432 |
|
3433 | return !!event.defaultPrevented;
|
3434 | }
|
3435 | };
|
3436 | }());
|
3437 |
|
3438 |
|
3439 |
|
3440 |
|
3441 |
|
3442 |
|
3443 |
|
3444 |
|
3445 |
|
3446 |
|
3447 |
|
3448 |
|
3449 |
|
3450 |
|
3451 |
|
3452 |
|
3453 |
|
3454 | (function(global) {
|
3455 | if (typeof sinon === "undefined") {
|
3456 | global.sinon = {};
|
3457 | }
|
3458 |
|
3459 | var supportsProgress = typeof ProgressEvent !== "undefined";
|
3460 | var supportsCustomEvent = typeof CustomEvent !== "undefined";
|
3461 | sinon.xhr = { XMLHttpRequest: global.XMLHttpRequest };
|
3462 | var xhr = sinon.xhr;
|
3463 | xhr.GlobalXMLHttpRequest = global.XMLHttpRequest;
|
3464 | xhr.GlobalActiveXObject = global.ActiveXObject;
|
3465 | xhr.supportsActiveX = typeof xhr.GlobalActiveXObject != "undefined";
|
3466 | xhr.supportsXHR = typeof xhr.GlobalXMLHttpRequest != "undefined";
|
3467 | xhr.workingXHR = xhr.supportsXHR ? xhr.GlobalXMLHttpRequest : xhr.supportsActiveX
|
3468 | ? function() { return new xhr.GlobalActiveXObject("MSXML2.XMLHTTP.3.0") } : false;
|
3469 | xhr.supportsCORS = 'withCredentials' in (new sinon.xhr.GlobalXMLHttpRequest());
|
3470 |
|
3471 |
|
3472 | var unsafeHeaders = {
|
3473 | "Accept-Charset": true,
|
3474 | "Accept-Encoding": true,
|
3475 | "Connection": true,
|
3476 | "Content-Length": true,
|
3477 | "Cookie": true,
|
3478 | "Cookie2": true,
|
3479 | "Content-Transfer-Encoding": true,
|
3480 | "Date": true,
|
3481 | "Expect": true,
|
3482 | "Host": true,
|
3483 | "Keep-Alive": true,
|
3484 | "Referer": true,
|
3485 | "TE": true,
|
3486 | "Trailer": true,
|
3487 | "Transfer-Encoding": true,
|
3488 | "Upgrade": true,
|
3489 | "User-Agent": true,
|
3490 | "Via": true
|
3491 | };
|
3492 |
|
3493 |
|
3494 | function FakeXMLHttpRequest() {
|
3495 | this.readyState = FakeXMLHttpRequest.UNSENT;
|
3496 | this.requestHeaders = {};
|
3497 | this.requestBody = null;
|
3498 | this.status = 0;
|
3499 | this.statusText = "";
|
3500 | this.upload = new UploadProgress();
|
3501 | if (sinon.xhr.supportsCORS) {
|
3502 | this.withCredentials = false;
|
3503 | }
|
3504 |
|
3505 |
|
3506 | var xhr = this;
|
3507 | var events = ["loadstart", "load", "abort", "loadend"];
|
3508 |
|
3509 | function addEventListener(eventName) {
|
3510 | xhr.addEventListener(eventName, function (event) {
|
3511 | var listener = xhr["on" + eventName];
|
3512 |
|
3513 | if (listener && typeof listener == "function") {
|
3514 | listener.call(this, event);
|
3515 | }
|
3516 | });
|
3517 | }
|
3518 |
|
3519 | for (var i = events.length - 1; i >= 0; i--) {
|
3520 | addEventListener(events[i]);
|
3521 | }
|
3522 |
|
3523 | if (typeof FakeXMLHttpRequest.onCreate == "function") {
|
3524 | FakeXMLHttpRequest.onCreate(this);
|
3525 | }
|
3526 | }
|
3527 |
|
3528 |
|
3529 |
|
3530 |
|
3531 |
|
3532 | function UploadProgress() {
|
3533 | this.eventListeners = {
|
3534 | "progress": [],
|
3535 | "load": [],
|
3536 | "abort": [],
|
3537 | "error": []
|
3538 | }
|
3539 | }
|
3540 |
|
3541 | UploadProgress.prototype.addEventListener = function(event, listener) {
|
3542 | this.eventListeners[event].push(listener);
|
3543 | };
|
3544 |
|
3545 | UploadProgress.prototype.removeEventListener = function(event, listener) {
|
3546 | var listeners = this.eventListeners[event] || [];
|
3547 |
|
3548 | for (var i = 0, l = listeners.length; i < l; ++i) {
|
3549 | if (listeners[i] == listener) {
|
3550 | return listeners.splice(i, 1);
|
3551 | }
|
3552 | }
|
3553 | };
|
3554 |
|
3555 | UploadProgress.prototype.dispatchEvent = function(event) {
|
3556 | var listeners = this.eventListeners[event.type] || [];
|
3557 |
|
3558 | for (var i = 0, listener; (listener = listeners[i]) != null; i++) {
|
3559 | listener(event);
|
3560 | }
|
3561 | };
|
3562 |
|
3563 | function verifyState(xhr) {
|
3564 | if (xhr.readyState !== FakeXMLHttpRequest.OPENED) {
|
3565 | throw new Error("INVALID_STATE_ERR");
|
3566 | }
|
3567 |
|
3568 | if (xhr.sendFlag) {
|
3569 | throw new Error("INVALID_STATE_ERR");
|
3570 | }
|
3571 | }
|
3572 |
|
3573 |
|
3574 |
|
3575 | function each(collection, callback) {
|
3576 | if (!collection) return;
|
3577 | for (var i = 0, l = collection.length; i < l; i += 1) {
|
3578 | callback(collection[i]);
|
3579 | }
|
3580 | }
|
3581 | function some(collection, callback) {
|
3582 | for (var index = 0; index < collection.length; index++) {
|
3583 | if(callback(collection[index]) === true) return true;
|
3584 | }
|
3585 | return false;
|
3586 | }
|
3587 |
|
3588 | var apply = function(obj,method,args) {
|
3589 | switch(args.length) {
|
3590 | case 0: return obj[method]();
|
3591 | case 1: return obj[method](args[0]);
|
3592 | case 2: return obj[method](args[0],args[1]);
|
3593 | case 3: return obj[method](args[0],args[1],args[2]);
|
3594 | case 4: return obj[method](args[0],args[1],args[2],args[3]);
|
3595 | case 5: return obj[method](args[0],args[1],args[2],args[3],args[4]);
|
3596 | }
|
3597 | };
|
3598 |
|
3599 | FakeXMLHttpRequest.filters = [];
|
3600 | FakeXMLHttpRequest.addFilter = function(fn) {
|
3601 | this.filters.push(fn)
|
3602 | };
|
3603 | var IE6Re = /MSIE 6/;
|
3604 | FakeXMLHttpRequest.defake = function(fakeXhr,xhrArgs) {
|
3605 | var xhr = new sinon.xhr.workingXHR();
|
3606 | each(["open","setRequestHeader","send","abort","getResponseHeader",
|
3607 | "getAllResponseHeaders","addEventListener","overrideMimeType","removeEventListener"],
|
3608 | function(method) {
|
3609 | fakeXhr[method] = function() {
|
3610 | return apply(xhr,method,arguments);
|
3611 | };
|
3612 | });
|
3613 |
|
3614 | var copyAttrs = function(args) {
|
3615 | each(args, function(attr) {
|
3616 | try {
|
3617 | fakeXhr[attr] = xhr[attr]
|
3618 | } catch(e) {
|
3619 | if(!IE6Re.test(navigator.userAgent)) throw e;
|
3620 | }
|
3621 | });
|
3622 | };
|
3623 |
|
3624 | var stateChange = function() {
|
3625 | fakeXhr.readyState = xhr.readyState;
|
3626 | if(xhr.readyState >= FakeXMLHttpRequest.HEADERS_RECEIVED) {
|
3627 | copyAttrs(["status","statusText"]);
|
3628 | }
|
3629 | if(xhr.readyState >= FakeXMLHttpRequest.LOADING) {
|
3630 | copyAttrs(["responseText"]);
|
3631 | }
|
3632 | if(xhr.readyState === FakeXMLHttpRequest.DONE) {
|
3633 | copyAttrs(["responseXML"]);
|
3634 | }
|
3635 | if(fakeXhr.onreadystatechange) fakeXhr.onreadystatechange.call(fakeXhr, { target: fakeXhr });
|
3636 | };
|
3637 | if(xhr.addEventListener) {
|
3638 | for(var event in fakeXhr.eventListeners) {
|
3639 | if(fakeXhr.eventListeners.hasOwnProperty(event)) {
|
3640 | each(fakeXhr.eventListeners[event],function(handler) {
|
3641 | xhr.addEventListener(event, handler);
|
3642 | });
|
3643 | }
|
3644 | }
|
3645 | xhr.addEventListener("readystatechange",stateChange);
|
3646 | } else {
|
3647 | xhr.onreadystatechange = stateChange;
|
3648 | }
|
3649 | apply(xhr,"open",xhrArgs);
|
3650 | };
|
3651 | FakeXMLHttpRequest.useFilters = false;
|
3652 |
|
3653 | function verifyRequestOpened(xhr) {
|
3654 | if (xhr.readyState != FakeXMLHttpRequest.OPENED) {
|
3655 | throw new Error("INVALID_STATE_ERR - " + xhr.readyState);
|
3656 | }
|
3657 | }
|
3658 |
|
3659 | function verifyRequestSent(xhr) {
|
3660 | if (xhr.readyState == FakeXMLHttpRequest.DONE) {
|
3661 | throw new Error("Request done");
|
3662 | }
|
3663 | }
|
3664 |
|
3665 | function verifyHeadersReceived(xhr) {
|
3666 | if (xhr.async && xhr.readyState != FakeXMLHttpRequest.HEADERS_RECEIVED) {
|
3667 | throw new Error("No headers received");
|
3668 | }
|
3669 | }
|
3670 |
|
3671 | function verifyResponseBodyType(body) {
|
3672 | if (typeof body != "string") {
|
3673 | var error = new Error("Attempted to respond to fake XMLHttpRequest with " +
|
3674 | body + ", which is not a string.");
|
3675 | error.name = "InvalidBodyException";
|
3676 | throw error;
|
3677 | }
|
3678 | }
|
3679 |
|
3680 | sinon.extend(FakeXMLHttpRequest.prototype, sinon.EventTarget, {
|
3681 | async: true,
|
3682 |
|
3683 | open: function open(method, url, async, username, password) {
|
3684 | this.method = method;
|
3685 | this.url = url;
|
3686 | this.async = typeof async == "boolean" ? async : true;
|
3687 | this.username = username;
|
3688 | this.password = password;
|
3689 | this.responseText = null;
|
3690 | this.responseXML = null;
|
3691 | this.requestHeaders = {};
|
3692 | this.sendFlag = false;
|
3693 | if(sinon.FakeXMLHttpRequest.useFilters === true) {
|
3694 | var xhrArgs = arguments;
|
3695 | var defake = some(FakeXMLHttpRequest.filters,function(filter) {
|
3696 | return filter.apply(this,xhrArgs)
|
3697 | });
|
3698 | if (defake) {
|
3699 | return sinon.FakeXMLHttpRequest.defake(this,arguments);
|
3700 | }
|
3701 | }
|
3702 | this.readyStateChange(FakeXMLHttpRequest.OPENED);
|
3703 | },
|
3704 |
|
3705 | readyStateChange: function readyStateChange(state) {
|
3706 | this.readyState = state;
|
3707 |
|
3708 | if (typeof this.onreadystatechange == "function") {
|
3709 | try {
|
3710 | this.onreadystatechange();
|
3711 | } catch (e) {
|
3712 | sinon.logError("Fake XHR onreadystatechange handler", e);
|
3713 | }
|
3714 | }
|
3715 |
|
3716 | this.dispatchEvent(new sinon.Event("readystatechange"));
|
3717 |
|
3718 | switch (this.readyState) {
|
3719 | case FakeXMLHttpRequest.DONE:
|
3720 | this.dispatchEvent(new sinon.Event("load", false, false, this));
|
3721 | this.dispatchEvent(new sinon.Event("loadend", false, false, this));
|
3722 | this.upload.dispatchEvent(new sinon.Event("load", false, false, this));
|
3723 | if (supportsProgress) {
|
3724 | this.upload.dispatchEvent(new sinon.ProgressEvent('progress', {loaded: 100, total: 100}));
|
3725 | }
|
3726 | break;
|
3727 | }
|
3728 | },
|
3729 |
|
3730 | setRequestHeader: function setRequestHeader(header, value) {
|
3731 | verifyState(this);
|
3732 |
|
3733 | if (unsafeHeaders[header] || /^(Sec-|Proxy-)/.test(header)) {
|
3734 | throw new Error("Refused to set unsafe header \"" + header + "\"");
|
3735 | }
|
3736 |
|
3737 | if (this.requestHeaders[header]) {
|
3738 | this.requestHeaders[header] += "," + value;
|
3739 | } else {
|
3740 | this.requestHeaders[header] = value;
|
3741 | }
|
3742 | },
|
3743 |
|
3744 |
|
3745 | setResponseHeaders: function setResponseHeaders(headers) {
|
3746 | verifyRequestOpened(this);
|
3747 | this.responseHeaders = {};
|
3748 |
|
3749 | for (var header in headers) {
|
3750 | if (headers.hasOwnProperty(header)) {
|
3751 | this.responseHeaders[header] = headers[header];
|
3752 | }
|
3753 | }
|
3754 |
|
3755 | if (this.async) {
|
3756 | this.readyStateChange(FakeXMLHttpRequest.HEADERS_RECEIVED);
|
3757 | } else {
|
3758 | this.readyState = FakeXMLHttpRequest.HEADERS_RECEIVED;
|
3759 | }
|
3760 | },
|
3761 |
|
3762 |
|
3763 | send: function send(data) {
|
3764 | verifyState(this);
|
3765 |
|
3766 | if (!/^(get|head)$/i.test(this.method)) {
|
3767 | if (this.requestHeaders["Content-Type"]) {
|
3768 | var value = this.requestHeaders["Content-Type"].split(";");
|
3769 | this.requestHeaders["Content-Type"] = value[0] + ";charset=utf-8";
|
3770 | } else {
|
3771 | this.requestHeaders["Content-Type"] = "text/plain;charset=utf-8";
|
3772 | }
|
3773 |
|
3774 | this.requestBody = data;
|
3775 | }
|
3776 |
|
3777 | this.errorFlag = false;
|
3778 | this.sendFlag = this.async;
|
3779 | this.readyStateChange(FakeXMLHttpRequest.OPENED);
|
3780 |
|
3781 | if (typeof this.onSend == "function") {
|
3782 | this.onSend(this);
|
3783 | }
|
3784 |
|
3785 | this.dispatchEvent(new sinon.Event("loadstart", false, false, this));
|
3786 | },
|
3787 |
|
3788 | abort: function abort() {
|
3789 | this.aborted = true;
|
3790 | this.responseText = null;
|
3791 | this.errorFlag = true;
|
3792 | this.requestHeaders = {};
|
3793 |
|
3794 | if (this.readyState > sinon.FakeXMLHttpRequest.UNSENT && this.sendFlag) {
|
3795 | this.readyStateChange(sinon.FakeXMLHttpRequest.DONE);
|
3796 | this.sendFlag = false;
|
3797 | }
|
3798 |
|
3799 | this.readyState = sinon.FakeXMLHttpRequest.UNSENT;
|
3800 |
|
3801 | this.dispatchEvent(new sinon.Event("abort", false, false, this));
|
3802 |
|
3803 | this.upload.dispatchEvent(new sinon.Event("abort", false, false, this));
|
3804 |
|
3805 | if (typeof this.onerror === "function") {
|
3806 | this.onerror();
|
3807 | }
|
3808 | },
|
3809 |
|
3810 | getResponseHeader: function getResponseHeader(header) {
|
3811 | if (this.readyState < FakeXMLHttpRequest.HEADERS_RECEIVED) {
|
3812 | return null;
|
3813 | }
|
3814 |
|
3815 | if (/^Set-Cookie2?$/i.test(header)) {
|
3816 | return null;
|
3817 | }
|
3818 |
|
3819 | header = header.toLowerCase();
|
3820 |
|
3821 | for (var h in this.responseHeaders) {
|
3822 | if (h.toLowerCase() == header) {
|
3823 | return this.responseHeaders[h];
|
3824 | }
|
3825 | }
|
3826 |
|
3827 | return null;
|
3828 | },
|
3829 |
|
3830 | getAllResponseHeaders: function getAllResponseHeaders() {
|
3831 | if (this.readyState < FakeXMLHttpRequest.HEADERS_RECEIVED) {
|
3832 | return "";
|
3833 | }
|
3834 |
|
3835 | var headers = "";
|
3836 |
|
3837 | for (var header in this.responseHeaders) {
|
3838 | if (this.responseHeaders.hasOwnProperty(header) &&
|
3839 | !/^Set-Cookie2?$/i.test(header)) {
|
3840 | headers += header + ": " + this.responseHeaders[header] + "\r\n";
|
3841 | }
|
3842 | }
|
3843 |
|
3844 | return headers;
|
3845 | },
|
3846 |
|
3847 | setResponseBody: function setResponseBody(body) {
|
3848 | verifyRequestSent(this);
|
3849 | verifyHeadersReceived(this);
|
3850 | verifyResponseBodyType(body);
|
3851 |
|
3852 | var chunkSize = this.chunkSize || 10;
|
3853 | var index = 0;
|
3854 | this.responseText = "";
|
3855 |
|
3856 | do {
|
3857 | if (this.async) {
|
3858 | this.readyStateChange(FakeXMLHttpRequest.LOADING);
|
3859 | }
|
3860 |
|
3861 | this.responseText += body.substring(index, index + chunkSize);
|
3862 | index += chunkSize;
|
3863 | } while (index < body.length);
|
3864 |
|
3865 | var type = this.getResponseHeader("Content-Type");
|
3866 |
|
3867 | if (this.responseText &&
|
3868 | (!type || /(text\/xml)|(application\/xml)|(\+xml)/.test(type))) {
|
3869 | try {
|
3870 | this.responseXML = FakeXMLHttpRequest.parseXML(this.responseText);
|
3871 | } catch (e) {
|
3872 |
|
3873 | }
|
3874 | }
|
3875 |
|
3876 | if (this.async) {
|
3877 | this.readyStateChange(FakeXMLHttpRequest.DONE);
|
3878 | } else {
|
3879 | this.readyState = FakeXMLHttpRequest.DONE;
|
3880 | }
|
3881 | },
|
3882 |
|
3883 | respond: function respond(status, headers, body) {
|
3884 | this.status = typeof status == "number" ? status : 200;
|
3885 | this.statusText = FakeXMLHttpRequest.statusCodes[this.status];
|
3886 | this.setResponseHeaders(headers || {});
|
3887 | this.setResponseBody(body || "");
|
3888 | },
|
3889 |
|
3890 | uploadProgress: function uploadProgress(progressEventRaw) {
|
3891 | if (supportsProgress) {
|
3892 | this.upload.dispatchEvent(new sinon.ProgressEvent("progress", progressEventRaw));
|
3893 | }
|
3894 | },
|
3895 |
|
3896 | uploadError: function uploadError(error) {
|
3897 | if (supportsCustomEvent) {
|
3898 | this.upload.dispatchEvent(new sinon.CustomEvent("error", {"detail": error}));
|
3899 | }
|
3900 | }
|
3901 | });
|
3902 |
|
3903 | sinon.extend(FakeXMLHttpRequest, {
|
3904 | UNSENT: 0,
|
3905 | OPENED: 1,
|
3906 | HEADERS_RECEIVED: 2,
|
3907 | LOADING: 3,
|
3908 | DONE: 4
|
3909 | });
|
3910 |
|
3911 |
|
3912 | FakeXMLHttpRequest.parseXML = function parseXML(text) {
|
3913 | var xmlDoc;
|
3914 |
|
3915 | if (typeof DOMParser != "undefined") {
|
3916 | var parser = new DOMParser();
|
3917 | xmlDoc = parser.parseFromString(text, "text/xml");
|
3918 | } else {
|
3919 | xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
|
3920 | xmlDoc.async = "false";
|
3921 | xmlDoc.loadXML(text);
|
3922 | }
|
3923 |
|
3924 | return xmlDoc;
|
3925 | };
|
3926 |
|
3927 | FakeXMLHttpRequest.statusCodes = {
|
3928 | 100: "Continue",
|
3929 | 101: "Switching Protocols",
|
3930 | 200: "OK",
|
3931 | 201: "Created",
|
3932 | 202: "Accepted",
|
3933 | 203: "Non-Authoritative Information",
|
3934 | 204: "No Content",
|
3935 | 205: "Reset Content",
|
3936 | 206: "Partial Content",
|
3937 | 300: "Multiple Choice",
|
3938 | 301: "Moved Permanently",
|
3939 | 302: "Found",
|
3940 | 303: "See Other",
|
3941 | 304: "Not Modified",
|
3942 | 305: "Use Proxy",
|
3943 | 307: "Temporary Redirect",
|
3944 | 400: "Bad Request",
|
3945 | 401: "Unauthorized",
|
3946 | 402: "Payment Required",
|
3947 | 403: "Forbidden",
|
3948 | 404: "Not Found",
|
3949 | 405: "Method Not Allowed",
|
3950 | 406: "Not Acceptable",
|
3951 | 407: "Proxy Authentication Required",
|
3952 | 408: "Request Timeout",
|
3953 | 409: "Conflict",
|
3954 | 410: "Gone",
|
3955 | 411: "Length Required",
|
3956 | 412: "Precondition Failed",
|
3957 | 413: "Request Entity Too Large",
|
3958 | 414: "Request-URI Too Long",
|
3959 | 415: "Unsupported Media Type",
|
3960 | 416: "Requested Range Not Satisfiable",
|
3961 | 417: "Expectation Failed",
|
3962 | 422: "Unprocessable Entity",
|
3963 | 500: "Internal Server Error",
|
3964 | 501: "Not Implemented",
|
3965 | 502: "Bad Gateway",
|
3966 | 503: "Service Unavailable",
|
3967 | 504: "Gateway Timeout",
|
3968 | 505: "HTTP Version Not Supported"
|
3969 | };
|
3970 |
|
3971 | sinon.useFakeXMLHttpRequest = function () {
|
3972 | sinon.FakeXMLHttpRequest.restore = function restore(keepOnCreate) {
|
3973 | if (xhr.supportsXHR) {
|
3974 | global.XMLHttpRequest = xhr.GlobalXMLHttpRequest;
|
3975 | }
|
3976 |
|
3977 | if (xhr.supportsActiveX) {
|
3978 | global.ActiveXObject = xhr.GlobalActiveXObject;
|
3979 | }
|
3980 |
|
3981 | delete sinon.FakeXMLHttpRequest.restore;
|
3982 |
|
3983 | if (keepOnCreate !== true) {
|
3984 | delete sinon.FakeXMLHttpRequest.onCreate;
|
3985 | }
|
3986 | };
|
3987 | if (xhr.supportsXHR) {
|
3988 | global.XMLHttpRequest = sinon.FakeXMLHttpRequest;
|
3989 | }
|
3990 |
|
3991 | if (xhr.supportsActiveX) {
|
3992 | global.ActiveXObject = function ActiveXObject(objId) {
|
3993 | if (objId == "Microsoft.XMLHTTP" || /^Msxml2\.XMLHTTP/i.test(objId)) {
|
3994 |
|
3995 | return new sinon.FakeXMLHttpRequest();
|
3996 | }
|
3997 |
|
3998 | return new xhr.GlobalActiveXObject(objId);
|
3999 | };
|
4000 | }
|
4001 |
|
4002 | return sinon.FakeXMLHttpRequest;
|
4003 | };
|
4004 |
|
4005 | sinon.FakeXMLHttpRequest = FakeXMLHttpRequest;
|
4006 |
|
4007 | })(typeof global === "object" ? global : this);
|
4008 |
|
4009 | if (typeof module !== 'undefined' && module.exports) {
|
4010 | module.exports = sinon;
|
4011 | }
|
4012 |
|
4013 |
|
4014 |
|
4015 |
|
4016 |
|
4017 |
|
4018 |
|
4019 |
|
4020 |
|
4021 |
|
4022 |
|
4023 |
|
4024 |
|
4025 |
|
4026 |
|
4027 |
|
4028 |
|
4029 |
|
4030 | if (typeof sinon == "undefined") {
|
4031 | var sinon = {};
|
4032 | }
|
4033 |
|
4034 | sinon.fakeServer = (function () {
|
4035 | var push = [].push;
|
4036 | function F() {}
|
4037 |
|
4038 | function create(proto) {
|
4039 | F.prototype = proto;
|
4040 | return new F();
|
4041 | }
|
4042 |
|
4043 | function responseArray(handler) {
|
4044 | var response = handler;
|
4045 |
|
4046 | if (Object.prototype.toString.call(handler) != "[object Array]") {
|
4047 | response = [200, {}, handler];
|
4048 | }
|
4049 |
|
4050 | if (typeof response[2] != "string") {
|
4051 | throw new TypeError("Fake server response body should be string, but was " +
|
4052 | typeof response[2]);
|
4053 | }
|
4054 |
|
4055 | return response;
|
4056 | }
|
4057 |
|
4058 | var wloc = typeof window !== "undefined" ? window.location : {};
|
4059 | var rCurrLoc = new RegExp("^" + wloc.protocol + "//" + wloc.host);
|
4060 |
|
4061 | function matchOne(response, reqMethod, reqUrl) {
|
4062 | var rmeth = response.method;
|
4063 | var matchMethod = !rmeth || rmeth.toLowerCase() == reqMethod.toLowerCase();
|
4064 | var url = response.url;
|
4065 | var matchUrl = !url || url == reqUrl || (typeof url.test == "function" && url.test(reqUrl));
|
4066 |
|
4067 | return matchMethod && matchUrl;
|
4068 | }
|
4069 |
|
4070 | function match(response, request) {
|
4071 | var requestUrl = request.url;
|
4072 |
|
4073 | if (!/^https?:\/\//.test(requestUrl) || rCurrLoc.test(requestUrl)) {
|
4074 | requestUrl = requestUrl.replace(rCurrLoc, "");
|
4075 | }
|
4076 |
|
4077 | if (matchOne(response, this.getHTTPMethod(request), requestUrl)) {
|
4078 | if (typeof response.response == "function") {
|
4079 | var ru = response.url;
|
4080 | var args = [request].concat(ru && typeof ru.exec == "function" ? ru.exec(requestUrl).slice(1) : []);
|
4081 | return response.response.apply(response, args);
|
4082 | }
|
4083 |
|
4084 | return true;
|
4085 | }
|
4086 |
|
4087 | return false;
|
4088 | }
|
4089 |
|
4090 | function log(response, request) {
|
4091 | var str;
|
4092 |
|
4093 | str = "Request:\n" + sinon.format(request) + "\n\n";
|
4094 | str += "Response:\n" + sinon.format(response) + "\n\n";
|
4095 |
|
4096 | sinon.log(str);
|
4097 | }
|
4098 |
|
4099 | return {
|
4100 | create: function () {
|
4101 | var server = create(this);
|
4102 | this.xhr = sinon.useFakeXMLHttpRequest();
|
4103 | server.requests = [];
|
4104 |
|
4105 | this.xhr.onCreate = function (xhrObj) {
|
4106 | server.addRequest(xhrObj);
|
4107 | };
|
4108 |
|
4109 | return server;
|
4110 | },
|
4111 |
|
4112 | addRequest: function addRequest(xhrObj) {
|
4113 | var server = this;
|
4114 | push.call(this.requests, xhrObj);
|
4115 |
|
4116 | xhrObj.onSend = function () {
|
4117 | server.handleRequest(this);
|
4118 |
|
4119 | if (server.autoRespond && !server.responding) {
|
4120 | setTimeout(function () {
|
4121 | server.responding = false;
|
4122 | server.respond();
|
4123 | }, server.autoRespondAfter || 10);
|
4124 |
|
4125 | server.responding = true;
|
4126 | }
|
4127 | };
|
4128 | },
|
4129 |
|
4130 | getHTTPMethod: function getHTTPMethod(request) {
|
4131 | if (this.fakeHTTPMethods && /post/i.test(request.method)) {
|
4132 | var matches = (request.requestBody || "").match(/_method=([^\b;]+)/);
|
4133 | return !!matches ? matches[1] : request.method;
|
4134 | }
|
4135 |
|
4136 | return request.method;
|
4137 | },
|
4138 |
|
4139 | handleRequest: function handleRequest(xhr) {
|
4140 | if (xhr.async) {
|
4141 | if (!this.queue) {
|
4142 | this.queue = [];
|
4143 | }
|
4144 |
|
4145 | push.call(this.queue, xhr);
|
4146 | } else {
|
4147 | this.processRequest(xhr);
|
4148 | }
|
4149 | },
|
4150 |
|
4151 | respondWith: function respondWith(method, url, body) {
|
4152 | if (arguments.length == 1 && typeof method != "function") {
|
4153 | this.response = responseArray(method);
|
4154 | return;
|
4155 | }
|
4156 |
|
4157 | if (!this.responses) { this.responses = []; }
|
4158 |
|
4159 | if (arguments.length == 1) {
|
4160 | body = method;
|
4161 | url = method = null;
|
4162 | }
|
4163 |
|
4164 | if (arguments.length == 2) {
|
4165 | body = url;
|
4166 | url = method;
|
4167 | method = null;
|
4168 | }
|
4169 |
|
4170 | push.call(this.responses, {
|
4171 | method: method,
|
4172 | url: url,
|
4173 | response: typeof body == "function" ? body : responseArray(body)
|
4174 | });
|
4175 | },
|
4176 |
|
4177 | respond: function respond() {
|
4178 | if (arguments.length > 0) this.respondWith.apply(this, arguments);
|
4179 | var queue = this.queue || [];
|
4180 | var requests = queue.splice(0);
|
4181 | var request;
|
4182 |
|
4183 | while(request = requests.shift()) {
|
4184 | this.processRequest(request);
|
4185 | }
|
4186 | },
|
4187 |
|
4188 | processRequest: function processRequest(request) {
|
4189 | try {
|
4190 | if (request.aborted) {
|
4191 | return;
|
4192 | }
|
4193 |
|
4194 | var response = this.response || [404, {}, ""];
|
4195 |
|
4196 | if (this.responses) {
|
4197 | for (var l = this.responses.length, i = l - 1; i >= 0; i--) {
|
4198 | if (match.call(this, this.responses[i], request)) {
|
4199 | response = this.responses[i].response;
|
4200 | break;
|
4201 | }
|
4202 | }
|
4203 | }
|
4204 |
|
4205 | if (request.readyState != 4) {
|
4206 | log(response, request);
|
4207 |
|
4208 | request.respond(response[0], response[1], response[2]);
|
4209 | }
|
4210 | } catch (e) {
|
4211 | sinon.logError("Fake server request processing", e);
|
4212 | }
|
4213 | },
|
4214 |
|
4215 | restore: function restore() {
|
4216 | return this.xhr.restore && this.xhr.restore.apply(this.xhr, arguments);
|
4217 | }
|
4218 | };
|
4219 | }());
|
4220 |
|
4221 | if (typeof module !== 'undefined' && module.exports) {
|
4222 | module.exports = sinon;
|
4223 | }
|
4224 |
|
4225 |
|
4226 |
|
4227 |
|
4228 |
|
4229 |
|
4230 |
|
4231 |
|
4232 |
|
4233 |
|
4234 |
|
4235 |
|
4236 |
|
4237 |
|
4238 |
|
4239 |
|
4240 |
|
4241 |
|
4242 |
|
4243 |
|
4244 |
|
4245 |
|
4246 | (function () {
|
4247 | function Server() {}
|
4248 | Server.prototype = sinon.fakeServer;
|
4249 |
|
4250 | sinon.fakeServerWithClock = new Server();
|
4251 |
|
4252 | sinon.fakeServerWithClock.addRequest = function addRequest(xhr) {
|
4253 | if (xhr.async) {
|
4254 | if (typeof setTimeout.clock == "object") {
|
4255 | this.clock = setTimeout.clock;
|
4256 | } else {
|
4257 | this.clock = sinon.useFakeTimers();
|
4258 | this.resetClock = true;
|
4259 | }
|
4260 |
|
4261 | if (!this.longestTimeout) {
|
4262 | var clockSetTimeout = this.clock.setTimeout;
|
4263 | var clockSetInterval = this.clock.setInterval;
|
4264 | var server = this;
|
4265 |
|
4266 | this.clock.setTimeout = function (fn, timeout) {
|
4267 | server.longestTimeout = Math.max(timeout, server.longestTimeout || 0);
|
4268 |
|
4269 | return clockSetTimeout.apply(this, arguments);
|
4270 | };
|
4271 |
|
4272 | this.clock.setInterval = function (fn, timeout) {
|
4273 | server.longestTimeout = Math.max(timeout, server.longestTimeout || 0);
|
4274 |
|
4275 | return clockSetInterval.apply(this, arguments);
|
4276 | };
|
4277 | }
|
4278 | }
|
4279 |
|
4280 | return sinon.fakeServer.addRequest.call(this, xhr);
|
4281 | };
|
4282 |
|
4283 | sinon.fakeServerWithClock.respond = function respond() {
|
4284 | var returnVal = sinon.fakeServer.respond.apply(this, arguments);
|
4285 |
|
4286 | if (this.clock) {
|
4287 | this.clock.tick(this.longestTimeout || 0);
|
4288 | this.longestTimeout = 0;
|
4289 |
|
4290 | if (this.resetClock) {
|
4291 | this.clock.restore();
|
4292 | this.resetClock = false;
|
4293 | }
|
4294 | }
|
4295 |
|
4296 | return returnVal;
|
4297 | };
|
4298 |
|
4299 | sinon.fakeServerWithClock.restore = function restore() {
|
4300 | if (this.clock) {
|
4301 | this.clock.restore();
|
4302 | }
|
4303 |
|
4304 | return sinon.fakeServer.restore.apply(this, arguments);
|
4305 | };
|
4306 | }());
|
4307 |
|
4308 |
|
4309 |
|
4310 |
|
4311 |
|
4312 |
|
4313 |
|
4314 |
|
4315 |
|
4316 |
|
4317 |
|
4318 |
|
4319 |
|
4320 |
|
4321 |
|
4322 |
|
4323 |
|
4324 |
|
4325 |
|
4326 | if (typeof module !== 'undefined' && module.exports) {
|
4327 | var sinon = require("../sinon");
|
4328 | sinon.extend(sinon, require("./util/fake_timers"));
|
4329 | }
|
4330 |
|
4331 | (function () {
|
4332 | var push = [].push;
|
4333 |
|
4334 | function exposeValue(sandbox, config, key, value) {
|
4335 | if (!value) {
|
4336 | return;
|
4337 | }
|
4338 |
|
4339 | if (config.injectInto && !(key in config.injectInto)) {
|
4340 | config.injectInto[key] = value;
|
4341 | sandbox.injectedKeys.push(key);
|
4342 | } else {
|
4343 | push.call(sandbox.args, value);
|
4344 | }
|
4345 | }
|
4346 |
|
4347 | function prepareSandboxFromConfig(config) {
|
4348 | var sandbox = sinon.create(sinon.sandbox);
|
4349 |
|
4350 | if (config.useFakeServer) {
|
4351 | if (typeof config.useFakeServer == "object") {
|
4352 | sandbox.serverPrototype = config.useFakeServer;
|
4353 | }
|
4354 |
|
4355 | sandbox.useFakeServer();
|
4356 | }
|
4357 |
|
4358 | if (config.useFakeTimers) {
|
4359 | if (typeof config.useFakeTimers == "object") {
|
4360 | sandbox.useFakeTimers.apply(sandbox, config.useFakeTimers);
|
4361 | } else {
|
4362 | sandbox.useFakeTimers();
|
4363 | }
|
4364 | }
|
4365 |
|
4366 | return sandbox;
|
4367 | }
|
4368 |
|
4369 | sinon.sandbox = sinon.extend(sinon.create(sinon.collection), {
|
4370 | useFakeTimers: function useFakeTimers() {
|
4371 | this.clock = sinon.useFakeTimers.apply(sinon, arguments);
|
4372 |
|
4373 | return this.add(this.clock);
|
4374 | },
|
4375 |
|
4376 | serverPrototype: sinon.fakeServer,
|
4377 |
|
4378 | useFakeServer: function useFakeServer() {
|
4379 | var proto = this.serverPrototype || sinon.fakeServer;
|
4380 |
|
4381 | if (!proto || !proto.create) {
|
4382 | return null;
|
4383 | }
|
4384 |
|
4385 | this.server = proto.create();
|
4386 | return this.add(this.server);
|
4387 | },
|
4388 |
|
4389 | inject: function (obj) {
|
4390 | sinon.collection.inject.call(this, obj);
|
4391 |
|
4392 | if (this.clock) {
|
4393 | obj.clock = this.clock;
|
4394 | }
|
4395 |
|
4396 | if (this.server) {
|
4397 | obj.server = this.server;
|
4398 | obj.requests = this.server.requests;
|
4399 | }
|
4400 |
|
4401 | return obj;
|
4402 | },
|
4403 |
|
4404 | restore: function () {
|
4405 | sinon.collection.restore.apply(this, arguments);
|
4406 | this.restoreContext();
|
4407 | },
|
4408 |
|
4409 | restoreContext: function () {
|
4410 | if (this.injectedKeys) {
|
4411 | for (var i = 0, j = this.injectedKeys.length; i < j; i++) {
|
4412 | delete this.injectInto[this.injectedKeys[i]];
|
4413 | }
|
4414 | this.injectedKeys = [];
|
4415 | }
|
4416 | },
|
4417 |
|
4418 | create: function (config) {
|
4419 | if (!config) {
|
4420 | return sinon.create(sinon.sandbox);
|
4421 | }
|
4422 |
|
4423 | var sandbox = prepareSandboxFromConfig(config);
|
4424 | sandbox.args = sandbox.args || [];
|
4425 | sandbox.injectedKeys = [];
|
4426 | sandbox.injectInto = config.injectInto;
|
4427 | var prop, value, exposed = sandbox.inject({});
|
4428 |
|
4429 | if (config.properties) {
|
4430 | for (var i = 0, l = config.properties.length; i < l; i++) {
|
4431 | prop = config.properties[i];
|
4432 | value = exposed[prop] || prop == "sandbox" && sandbox;
|
4433 | exposeValue(sandbox, config, prop, value);
|
4434 | }
|
4435 | } else {
|
4436 | exposeValue(sandbox, config, "sandbox", value);
|
4437 | }
|
4438 |
|
4439 | return sandbox;
|
4440 | }
|
4441 | });
|
4442 |
|
4443 | sinon.sandbox.useFakeXMLHttpRequest = sinon.sandbox.useFakeServer;
|
4444 |
|
4445 | if (typeof module !== 'undefined' && module.exports) {
|
4446 | module.exports = sinon.sandbox;
|
4447 | }
|
4448 | }());
|
4449 |
|
4450 |
|
4451 |
|
4452 |
|
4453 |
|
4454 |
|
4455 |
|
4456 |
|
4457 |
|
4458 |
|
4459 |
|
4460 |
|
4461 |
|
4462 |
|
4463 |
|
4464 |
|
4465 |
|
4466 |
|
4467 | (function (sinon) {
|
4468 | var commonJSModule = typeof module !== 'undefined' && module.exports;
|
4469 |
|
4470 | if (!sinon && commonJSModule) {
|
4471 | sinon = require("../sinon");
|
4472 | }
|
4473 |
|
4474 | if (!sinon) {
|
4475 | return;
|
4476 | }
|
4477 |
|
4478 | function test(callback) {
|
4479 | var type = typeof callback;
|
4480 |
|
4481 | if (type != "function") {
|
4482 | throw new TypeError("sinon.test needs to wrap a test function, got " + type);
|
4483 | }
|
4484 |
|
4485 | return function () {
|
4486 | var config = sinon.getConfig(sinon.config);
|
4487 | config.injectInto = config.injectIntoThis && this || config.injectInto;
|
4488 | var sandbox = sinon.sandbox.create(config);
|
4489 | var exception, result;
|
4490 | var args = Array.prototype.slice.call(arguments).concat(sandbox.args);
|
4491 |
|
4492 | try {
|
4493 | result = callback.apply(this, args);
|
4494 | } catch (e) {
|
4495 | exception = e;
|
4496 | }
|
4497 |
|
4498 | if (typeof exception !== "undefined") {
|
4499 | sandbox.restore();
|
4500 | throw exception;
|
4501 | }
|
4502 | else {
|
4503 | sandbox.verifyAndRestore();
|
4504 | }
|
4505 |
|
4506 | return result;
|
4507 | };
|
4508 | }
|
4509 |
|
4510 | test.config = {
|
4511 | injectIntoThis: true,
|
4512 | injectInto: null,
|
4513 | properties: ["spy", "stub", "mock", "clock", "server", "requests"],
|
4514 | useFakeTimers: true,
|
4515 | useFakeServer: true
|
4516 | };
|
4517 |
|
4518 | if (commonJSModule) {
|
4519 | module.exports = test;
|
4520 | } else {
|
4521 | sinon.test = test;
|
4522 | }
|
4523 | }(typeof sinon == "object" && sinon || null));
|
4524 |
|
4525 |
|
4526 |
|
4527 |
|
4528 |
|
4529 |
|
4530 |
|
4531 |
|
4532 |
|
4533 |
|
4534 |
|
4535 |
|
4536 |
|
4537 |
|
4538 |
|
4539 |
|
4540 | (function (sinon) {
|
4541 | var commonJSModule = typeof module !== 'undefined' && module.exports;
|
4542 |
|
4543 | if (!sinon && commonJSModule) {
|
4544 | sinon = require("../sinon");
|
4545 | }
|
4546 |
|
4547 | if (!sinon || !Object.prototype.hasOwnProperty) {
|
4548 | return;
|
4549 | }
|
4550 |
|
4551 | function createTest(property, setUp, tearDown) {
|
4552 | return function () {
|
4553 | if (setUp) {
|
4554 | setUp.apply(this, arguments);
|
4555 | }
|
4556 |
|
4557 | var exception, result;
|
4558 |
|
4559 | try {
|
4560 | result = property.apply(this, arguments);
|
4561 | } catch (e) {
|
4562 | exception = e;
|
4563 | }
|
4564 |
|
4565 | if (tearDown) {
|
4566 | tearDown.apply(this, arguments);
|
4567 | }
|
4568 |
|
4569 | if (exception) {
|
4570 | throw exception;
|
4571 | }
|
4572 |
|
4573 | return result;
|
4574 | };
|
4575 | }
|
4576 |
|
4577 | function testCase(tests, prefix) {
|
4578 |
|
4579 | if (!tests || typeof tests != "object") {
|
4580 | throw new TypeError("sinon.testCase needs an object with test functions");
|
4581 | }
|
4582 |
|
4583 |
|
4584 | prefix = prefix || "test";
|
4585 | var rPrefix = new RegExp("^" + prefix);
|
4586 | var methods = {}, testName, property, method;
|
4587 | var setUp = tests.setUp;
|
4588 | var tearDown = tests.tearDown;
|
4589 |
|
4590 | for (testName in tests) {
|
4591 | if (tests.hasOwnProperty(testName)) {
|
4592 | property = tests[testName];
|
4593 |
|
4594 | if (/^(setUp|tearDown)$/.test(testName)) {
|
4595 | continue;
|
4596 | }
|
4597 |
|
4598 | if (typeof property == "function" && rPrefix.test(testName)) {
|
4599 | method = property;
|
4600 |
|
4601 | if (setUp || tearDown) {
|
4602 | method = createTest(property, setUp, tearDown);
|
4603 | }
|
4604 |
|
4605 | methods[testName] = sinon.test(method);
|
4606 | } else {
|
4607 | methods[testName] = tests[testName];
|
4608 | }
|
4609 | }
|
4610 | }
|
4611 |
|
4612 | return methods;
|
4613 | }
|
4614 |
|
4615 | if (commonJSModule) {
|
4616 | module.exports = testCase;
|
4617 | } else {
|
4618 | sinon.testCase = testCase;
|
4619 | }
|
4620 | }(typeof sinon == "object" && sinon || null));
|
4621 |
|
4622 |
|
4623 |
|
4624 |
|
4625 |
|
4626 |
|
4627 |
|
4628 |
|
4629 |
|
4630 |
|
4631 |
|
4632 |
|
4633 |
|
4634 |
|
4635 |
|
4636 |
|
4637 | (function (sinon, global) {
|
4638 | var commonJSModule = typeof module !== "undefined" && module.exports;
|
4639 | var slice = Array.prototype.slice;
|
4640 | var assert;
|
4641 |
|
4642 | if (!sinon && commonJSModule) {
|
4643 | sinon = require("../sinon");
|
4644 | }
|
4645 |
|
4646 | if (!sinon) {
|
4647 | return;
|
4648 | }
|
4649 |
|
4650 | function verifyIsStub() {
|
4651 | var method;
|
4652 |
|
4653 | for (var i = 0, l = arguments.length; i < l; ++i) {
|
4654 | method = arguments[i];
|
4655 |
|
4656 | if (!method) {
|
4657 | assert.fail("fake is not a spy");
|
4658 | }
|
4659 |
|
4660 | if (typeof method != "function") {
|
4661 | assert.fail(method + " is not a function");
|
4662 | }
|
4663 |
|
4664 | if (typeof method.getCall != "function") {
|
4665 | assert.fail(method + " is not stubbed");
|
4666 | }
|
4667 | }
|
4668 | }
|
4669 |
|
4670 | function failAssertion(object, msg) {
|
4671 | object = object || global;
|
4672 | var failMethod = object.fail || assert.fail;
|
4673 | failMethod.call(object, msg);
|
4674 | }
|
4675 |
|
4676 | function mirrorPropAsAssertion(name, method, message) {
|
4677 | if (arguments.length == 2) {
|
4678 | message = method;
|
4679 | method = name;
|
4680 | }
|
4681 |
|
4682 | assert[name] = function (fake) {
|
4683 | verifyIsStub(fake);
|
4684 |
|
4685 | var args = slice.call(arguments, 1);
|
4686 | var failed = false;
|
4687 |
|
4688 | if (typeof method == "function") {
|
4689 | failed = !method(fake);
|
4690 | } else {
|
4691 | failed = typeof fake[method] == "function" ?
|
4692 | !fake[method].apply(fake, args) : !fake[method];
|
4693 | }
|
4694 |
|
4695 | if (failed) {
|
4696 | failAssertion(this, fake.printf.apply(fake, [message].concat(args)));
|
4697 | } else {
|
4698 | assert.pass(name);
|
4699 | }
|
4700 | };
|
4701 | }
|
4702 |
|
4703 | function exposedName(prefix, prop) {
|
4704 | return !prefix || /^fail/.test(prop) ? prop :
|
4705 | prefix + prop.slice(0, 1).toUpperCase() + prop.slice(1);
|
4706 | }
|
4707 |
|
4708 | assert = {
|
4709 | failException: "AssertError",
|
4710 |
|
4711 | fail: function fail(message) {
|
4712 | var error = new Error(message);
|
4713 | error.name = this.failException || assert.failException;
|
4714 |
|
4715 | throw error;
|
4716 | },
|
4717 |
|
4718 | pass: function pass(assertion) {},
|
4719 |
|
4720 | callOrder: function assertCallOrder() {
|
4721 | verifyIsStub.apply(null, arguments);
|
4722 | var expected = "", actual = "";
|
4723 |
|
4724 | if (!sinon.calledInOrder(arguments)) {
|
4725 | try {
|
4726 | expected = [].join.call(arguments, ", ");
|
4727 | var calls = slice.call(arguments);
|
4728 | var i = calls.length;
|
4729 | while (i) {
|
4730 | if (!calls[--i].called) {
|
4731 | calls.splice(i, 1);
|
4732 | }
|
4733 | }
|
4734 | actual = sinon.orderByFirstCall(calls).join(", ");
|
4735 | } catch (e) {
|
4736 |
|
4737 | }
|
4738 |
|
4739 | failAssertion(this, "expected " + expected + " to be " +
|
4740 | "called in order but were called as " + actual);
|
4741 | } else {
|
4742 | assert.pass("callOrder");
|
4743 | }
|
4744 | },
|
4745 |
|
4746 | callCount: function assertCallCount(method, count) {
|
4747 | verifyIsStub(method);
|
4748 |
|
4749 | if (method.callCount != count) {
|
4750 | var msg = "expected %n to be called " + sinon.timesInWords(count) +
|
4751 | " but was called %c%C";
|
4752 | failAssertion(this, method.printf(msg));
|
4753 | } else {
|
4754 | assert.pass("callCount");
|
4755 | }
|
4756 | },
|
4757 |
|
4758 | expose: function expose(target, options) {
|
4759 | if (!target) {
|
4760 | throw new TypeError("target is null or undefined");
|
4761 | }
|
4762 |
|
4763 | var o = options || {};
|
4764 | var prefix = typeof o.prefix == "undefined" && "assert" || o.prefix;
|
4765 | var includeFail = typeof o.includeFail == "undefined" || !!o.includeFail;
|
4766 |
|
4767 | for (var method in this) {
|
4768 | if (method != "export" && (includeFail || !/^(fail)/.test(method))) {
|
4769 | target[exposedName(prefix, method)] = this[method];
|
4770 | }
|
4771 | }
|
4772 |
|
4773 | return target;
|
4774 | },
|
4775 |
|
4776 | match: function match(actual, expectation) {
|
4777 | var matcher = sinon.match(expectation);
|
4778 | if (matcher.test(actual)) {
|
4779 | assert.pass("match");
|
4780 | } else {
|
4781 | var formatted = [
|
4782 | "expected value to match",
|
4783 | " expected = " + sinon.format(expectation),
|
4784 | " actual = " + sinon.format(actual)
|
4785 | ]
|
4786 | failAssertion(this, formatted.join("\n"));
|
4787 | }
|
4788 | }
|
4789 | };
|
4790 |
|
4791 | mirrorPropAsAssertion("called", "expected %n to have been called at least once but was never called");
|
4792 | mirrorPropAsAssertion("notCalled", function (spy) { return !spy.called; },
|
4793 | "expected %n to not have been called but was called %c%C");
|
4794 | mirrorPropAsAssertion("calledOnce", "expected %n to be called once but was called %c%C");
|
4795 | mirrorPropAsAssertion("calledTwice", "expected %n to be called twice but was called %c%C");
|
4796 | mirrorPropAsAssertion("calledThrice", "expected %n to be called thrice but was called %c%C");
|
4797 | mirrorPropAsAssertion("calledOn", "expected %n to be called with %1 as this but was called with %t");
|
4798 | mirrorPropAsAssertion("alwaysCalledOn", "expected %n to always be called with %1 as this but was called with %t");
|
4799 | mirrorPropAsAssertion("calledWithNew", "expected %n to be called with new");
|
4800 | mirrorPropAsAssertion("alwaysCalledWithNew", "expected %n to always be called with new");
|
4801 | mirrorPropAsAssertion("calledWith", "expected %n to be called with arguments %*%C");
|
4802 | mirrorPropAsAssertion("calledWithMatch", "expected %n to be called with match %*%C");
|
4803 | mirrorPropAsAssertion("alwaysCalledWith", "expected %n to always be called with arguments %*%C");
|
4804 | mirrorPropAsAssertion("alwaysCalledWithMatch", "expected %n to always be called with match %*%C");
|
4805 | mirrorPropAsAssertion("calledWithExactly", "expected %n to be called with exact arguments %*%C");
|
4806 | mirrorPropAsAssertion("alwaysCalledWithExactly", "expected %n to always be called with exact arguments %*%C");
|
4807 | mirrorPropAsAssertion("neverCalledWith", "expected %n to never be called with arguments %*%C");
|
4808 | mirrorPropAsAssertion("neverCalledWithMatch", "expected %n to never be called with match %*%C");
|
4809 | mirrorPropAsAssertion("threw", "%n did not throw exception%C");
|
4810 | mirrorPropAsAssertion("alwaysThrew", "%n did not always throw exception%C");
|
4811 |
|
4812 | if (commonJSModule) {
|
4813 | module.exports = assert;
|
4814 | } else {
|
4815 | sinon.assert = assert;
|
4816 | }
|
4817 | }(typeof sinon == "object" && sinon || null, typeof window != "undefined" ? window : (typeof self != "undefined") ? self : global));
|
4818 |
|
4819 | return sinon;}.call(typeof window != 'undefined' && window || {})); |
\ | No newline at end of file |