doipjs/node_modules/sinon/lib/sinon/mock.js
Yarmo Mackenbach e996bc8023 Initial commit
2020-10-23 22:35:53 +02:00

200 lines
5.7 KiB
JavaScript

"use strict";
var arrayProto = require("@sinonjs/commons").prototypes.array;
var mockExpectation = require("./mock-expectation");
var proxyCallToString = require("./proxy-call").toString;
var extend = require("./util/core/extend");
var deepEqual = require("@sinonjs/samsam").deepEqual;
var wrapMethod = require("./util/core/wrap-method");
var usePromiseLibrary = require("./util/core/use-promise-library");
var concat = arrayProto.concat;
var filter = arrayProto.filter;
var forEach = arrayProto.forEach;
var every = arrayProto.every;
var join = arrayProto.join;
var push = arrayProto.push;
var slice = arrayProto.slice;
var unshift = arrayProto.unshift;
function mock(object) {
if (!object || typeof object === "string") {
return mockExpectation.create(object ? object : "Anonymous mock");
}
return mock.create(object);
}
function each(collection, callback) {
var col = collection || [];
forEach(col, callback);
}
function arrayEquals(arr1, arr2, compareLength) {
if (compareLength && arr1.length !== arr2.length) {
return false;
}
return every(arr1, function(element, i) {
return deepEqual(arr2[i], element);
});
}
extend(mock, {
create: function create(object) {
if (!object) {
throw new TypeError("object is null");
}
var mockObject = extend.nonEnum({}, mock, { object: object });
delete mockObject.create;
return mockObject;
},
expects: function expects(method) {
if (!method) {
throw new TypeError("method is falsy");
}
if (!this.expectations) {
this.expectations = {};
this.proxies = [];
this.failures = [];
}
if (!this.expectations[method]) {
this.expectations[method] = [];
var mockObject = this;
wrapMethod(this.object, method, function() {
return mockObject.invokeMethod(method, this, arguments);
});
push(this.proxies, method);
}
var expectation = mockExpectation.create(method);
expectation.wrappedMethod = this.object[method].wrappedMethod;
push(this.expectations[method], expectation);
usePromiseLibrary(this.promiseLibrary, expectation);
return expectation;
},
restore: function restore() {
var object = this.object;
each(this.proxies, function(proxy) {
if (typeof object[proxy].restore === "function") {
object[proxy].restore();
}
});
},
verify: function verify() {
var expectations = this.expectations || {};
var messages = this.failures ? slice(this.failures) : [];
var met = [];
each(this.proxies, function(proxy) {
each(expectations[proxy], function(expectation) {
if (!expectation.met()) {
push(messages, String(expectation));
} else {
push(met, String(expectation));
}
});
});
this.restore();
if (messages.length > 0) {
mockExpectation.fail(join(concat(messages, met), "\n"));
} else if (met.length > 0) {
mockExpectation.pass(join(concat(messages, met), "\n"));
}
return true;
},
usingPromise: function usingPromise(promiseLibrary) {
this.promiseLibrary = promiseLibrary;
return this;
},
invokeMethod: function invokeMethod(method, thisValue, args) {
/* if we cannot find any matching files we will explicitly call mockExpection#fail with error messages */
/* eslint consistent-return: "off" */
var expectations = this.expectations && this.expectations[method] ? this.expectations[method] : [];
var currentArgs = args || [];
var available;
var expectationsWithMatchingArgs = filter(expectations, function(expectation) {
var expectedArgs = expectation.expectedArguments || [];
return arrayEquals(expectedArgs, currentArgs, expectation.expectsExactArgCount);
});
var expectationsToApply = filter(expectationsWithMatchingArgs, function(expectation) {
return !expectation.met() && expectation.allowsCall(thisValue, args);
});
if (expectationsToApply.length > 0) {
return expectationsToApply[0].apply(thisValue, args);
}
var messages = [];
var exhausted = 0;
forEach(expectationsWithMatchingArgs, function(expectation) {
if (expectation.allowsCall(thisValue, args)) {
available = available || expectation;
} else {
exhausted += 1;
}
});
if (available && exhausted === 0) {
return available.apply(thisValue, args);
}
forEach(expectations, function(expectation) {
push(messages, " " + String(expectation));
});
unshift(
messages,
"Unexpected call: " +
proxyCallToString.call({
proxy: method,
args: args
})
);
var err = new Error();
if (!err.stack) {
// PhantomJS does not serialize the stack trace until the error has been thrown
try {
throw err;
} catch (e) {
/* empty */
}
}
push(
this.failures,
"Unexpected call: " +
proxyCallToString.call({
proxy: method,
args: args,
stack: err.stack
})
);
mockExpectation.fail(join(messages, "\n"));
}
});
module.exports = mock;