forked from toddbluhm/sinon-bluebird
-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
117 lines (98 loc) · 3.53 KB
/
index.js
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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
var sinon = require('sinon'),
BPromise = require('bluebird');
// Create resolves function
function resolves(value) {
return this.returns(BPromise.resolve(value));
}
// Attach resolves function to sinon
sinon.stub.resolves = sinon.behavior.resolves = resolves;
// Create a Bluebird Promise wrapper class to avoid unnecessary
// "possibly unhandled exception" warnings
function RejectBPromise(value) {
this.value = value;
}
// Go through all Bluebird and wrap each method on the new RejectBPromise class
Object.keys(BPromise.prototype).map(function (key) {
RejectBPromise.prototype[key] = function () {
var prom = new BPromise.reject(this.value);
return prom[key].apply(prom, arguments);
};
});
// Create the rejects function
function rejects(value) {
this.rejectBPromise = true;
return this.returns(new RejectBPromise(value));
}
// Attach rejects function to sinon
sinon.stub.rejects = sinon.behavior.rejects = rejects;
//Special getCall method that checks for existence of promises in return value and args.
//If found, then unwraps them using their value in place of the promise
sinon.spy.getPromiseCall = function (i) {
if (i < 0 || i >= this.callCount) {
return null;
}
//Check for and unwrap args values that are promises
var argVals = this.args[i];
for (var prop in argVals) {
if (argVals[prop] &&
typeof argVals[prop].isFulfilled === 'function') {
if (argVals[prop].isFulfilled()) {
argVals[prop] = argVals[prop].value();
}
else if (argVals[prop].isRejected()) {
argVals[prop] = argVals[prop].reason();
}
}
}
//Check for and unwrap the return value if it's a promise
var returnVal = this.returnValues[i];
if (returnVal && typeof returnVal.isFulfilled === 'function') {
if (returnVal.isFulfilled()) {
returnVal = returnVal.value();
}
else if (returnVal.isRejected()) {
returnVal = returnVal.reason();
}
else {
throw new Error('Promise not resolved yet');
}
}
return sinon.spyCall(this, this.thisValues[i], argVals,
returnVal, this.exceptions[i],
this.callIds[i]);
};
//Almost identical to internal method except it calls a special getCall method
sinon.spy.delegateToCallsPromise = function (method, matchAny, actual, notCalled) {
this[method] = function () {
if (!this.called) {
if (notCalled) {
return notCalled.apply(this, arguments);
}
return false;
}
var currentCall;
var matches = 0;
for (var i = 0, l = this.callCount; i < l; i += 1) {
currentCall = this.getPromiseCall(i); //Call the special promise getCall method
if (currentCall[actual || method].apply(currentCall, arguments)) {
matches += 1;
if (matchAny) {
return true;
}
}
}
return matches === this.callCount;
};
};
//return methods
sinon.spy.delegateToCallsPromise("returnedPromise", true, "returned");
sinon.spy.delegateToCallsPromise("alwaysReturnedPromise", false, "returned");
//param methods
sinon.spy.delegateToCallsPromise("calledWithPromise", true, "calledWith");
sinon.spy.delegateToCallsPromise("calledWithMatchPromise", true, "calledWithMatch");
sinon.spy.delegateToCallsPromise("alwaysCalledWithPromise", false, "calledWith");
sinon.spy.delegateToCallsPromise("alwaysCalledWithMatchPromise", false, "calledWithMatch");
sinon.spy.delegateToCallsPromise("calledWithExactlyPromise", true, "calledWithExactly");
sinon.spy.delegateToCallsPromise("alwaysCalledWithExactlyPromise", false, "calledWithExactly");
// Export Sinon
module.exports = exports = sinon;