1
0
Fork 0
arangodb/js/npm/node_modules/sinon/lib/sinon/mock.js

425 lines
13 KiB
JavaScript

/**
* @depend ../sinon.js
* @depend stub.js
*/
/*jslint eqeqeq: false, onevar: false, nomen: false*/
/*global module, require, sinon*/
/**
* Mock functions.
*
* @author Christian Johansen (christian@cjohansen.no)
* @license BSD
*
* Copyright (c) 2010-2013 Christian Johansen
*/
"use strict";
(function (sinon) {
var commonJSModule = typeof module == "object" && typeof require == "function";
var push = [].push;
if (!sinon && commonJSModule) {
sinon = require("../sinon");
}
if (!sinon) {
return;
}
function mock(object) {
if (!object) {
return sinon.expectation.create("Anonymous mock");
}
return mock.create(object);
}
sinon.mock = mock;
sinon.extend(mock, (function () {
function each(collection, callback) {
if (!collection) {
return;
}
for (var i = 0, l = collection.length; i < l; i += 1) {
callback(collection[i]);
}
}
return {
create: function create(object) {
if (!object) {
throw new TypeError("object is null");
}
var mockObject = sinon.extend({}, mock);
mockObject.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 = [];
}
if (!this.expectations[method]) {
this.expectations[method] = [];
var mockObject = this;
sinon.wrapMethod(this.object, method, function () {
return mockObject.invokeMethod(method, this, arguments);
});
push.call(this.proxies, method);
}
var expectation = sinon.expectation.create(method);
push.call(this.expectations[method], 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 = [], met = [];
each(this.proxies, function (proxy) {
each(expectations[proxy], function (expectation) {
if (!expectation.met()) {
push.call(messages, expectation.toString());
} else {
push.call(met, expectation.toString());
}
});
});
this.restore();
if (messages.length > 0) {
sinon.expectation.fail(messages.concat(met).join("\n"));
} else {
sinon.expectation.pass(messages.concat(met).join("\n"));
}
return true;
},
invokeMethod: function invokeMethod(method, thisValue, args) {
var expectations = this.expectations && this.expectations[method];
var length = expectations && expectations.length || 0, i;
for (i = 0; i < length; i += 1) {
if (!expectations[i].met() &&
expectations[i].allowsCall(thisValue, args)) {
return expectations[i].apply(thisValue, args);
}
}
var messages = [], available, exhausted = 0;
for (i = 0; i < length; i += 1) {
if (expectations[i].allowsCall(thisValue, args)) {
available = available || expectations[i];
} else {
exhausted += 1;
}
push.call(messages, " " + expectations[i].toString());
}
if (exhausted === 0) {
return available.apply(thisValue, args);
}
messages.unshift("Unexpected call: " + sinon.spyCall.toString.call({
proxy: method,
args: args
}));
sinon.expectation.fail(messages.join("\n"));
}
};
}()));
var times = sinon.timesInWords;
sinon.expectation = (function () {
var slice = Array.prototype.slice;
var _invoke = sinon.spy.invoke;
function callCountInWords(callCount) {
if (callCount == 0) {
return "never called";
} else {
return "called " + times(callCount);
}
}
function expectedCallCountInWords(expectation) {
var min = expectation.minCalls;
var max = expectation.maxCalls;
if (typeof min == "number" && typeof max == "number") {
var str = times(min);
if (min != max) {
str = "at least " + str + " and at most " + times(max);
}
return str;
}
if (typeof min == "number") {
return "at least " + times(min);
}
return "at most " + times(max);
}
function receivedMinCalls(expectation) {
var hasMinLimit = typeof expectation.minCalls == "number";
return !hasMinLimit || expectation.callCount >= expectation.minCalls;
}
function receivedMaxCalls(expectation) {
if (typeof expectation.maxCalls != "number") {
return false;
}
return expectation.callCount == expectation.maxCalls;
}
return {
minCalls: 1,
maxCalls: 1,
create: function create(methodName) {
var expectation = sinon.extend(sinon.stub.create(), sinon.expectation);
delete expectation.create;
expectation.method = methodName;
return expectation;
},
invoke: function invoke(func, thisValue, args) {
this.verifyCallAllowed(thisValue, args);
return _invoke.apply(this, arguments);
},
atLeast: function atLeast(num) {
if (typeof num != "number") {
throw new TypeError("'" + num + "' is not number");
}
if (!this.limitsSet) {
this.maxCalls = null;
this.limitsSet = true;
}
this.minCalls = num;
return this;
},
atMost: function atMost(num) {
if (typeof num != "number") {
throw new TypeError("'" + num + "' is not number");
}
if (!this.limitsSet) {
this.minCalls = null;
this.limitsSet = true;
}
this.maxCalls = num;
return this;
},
never: function never() {
return this.exactly(0);
},
once: function once() {
return this.exactly(1);
},
twice: function twice() {
return this.exactly(2);
},
thrice: function thrice() {
return this.exactly(3);
},
exactly: function exactly(num) {
if (typeof num != "number") {
throw new TypeError("'" + num + "' is not a number");
}
this.atLeast(num);
return this.atMost(num);
},
met: function met() {
return !this.failed && receivedMinCalls(this);
},
verifyCallAllowed: function verifyCallAllowed(thisValue, args) {
if (receivedMaxCalls(this)) {
this.failed = true;
sinon.expectation.fail(this.method + " already called " + times(this.maxCalls));
}
if ("expectedThis" in this && this.expectedThis !== thisValue) {
sinon.expectation.fail(this.method + " called with " + thisValue + " as thisValue, expected " +
this.expectedThis);
}
if (!("expectedArguments" in this)) {
return;
}
if (!args) {
sinon.expectation.fail(this.method + " received no arguments, expected " +
sinon.format(this.expectedArguments));
}
if (args.length < this.expectedArguments.length) {
sinon.expectation.fail(this.method + " received too few arguments (" + sinon.format(args) +
"), expected " + sinon.format(this.expectedArguments));
}
if (this.expectsExactArgCount &&
args.length != this.expectedArguments.length) {
sinon.expectation.fail(this.method + " received too many arguments (" + sinon.format(args) +
"), expected " + sinon.format(this.expectedArguments));
}
for (var i = 0, l = this.expectedArguments.length; i < l; i += 1) {
if (!sinon.deepEqual(this.expectedArguments[i], args[i])) {
sinon.expectation.fail(this.method + " received wrong arguments " + sinon.format(args) +
", expected " + sinon.format(this.expectedArguments));
}
}
},
allowsCall: function allowsCall(thisValue, args) {
if (this.met() && receivedMaxCalls(this)) {
return false;
}
if ("expectedThis" in this && this.expectedThis !== thisValue) {
return false;
}
if (!("expectedArguments" in this)) {
return true;
}
args = args || [];
if (args.length < this.expectedArguments.length) {
return false;
}
if (this.expectsExactArgCount &&
args.length != this.expectedArguments.length) {
return false;
}
for (var i = 0, l = this.expectedArguments.length; i < l; i += 1) {
if (!sinon.deepEqual(this.expectedArguments[i], args[i])) {
return false;
}
}
return true;
},
withArgs: function withArgs() {
this.expectedArguments = slice.call(arguments);
return this;
},
withExactArgs: function withExactArgs() {
this.withArgs.apply(this, arguments);
this.expectsExactArgCount = true;
return this;
},
on: function on(thisValue) {
this.expectedThis = thisValue;
return this;
},
toString: function () {
var args = (this.expectedArguments || []).slice();
if (!this.expectsExactArgCount) {
push.call(args, "[...]");
}
var callStr = sinon.spyCall.toString.call({
proxy: this.method || "anonymous mock expectation",
args: args
});
var message = callStr.replace(", [...", "[, ...") + " " +
expectedCallCountInWords(this);
if (this.met()) {
return "Expectation met: " + message;
}
return "Expected " + message + " (" +
callCountInWords(this.callCount) + ")";
},
verify: function verify() {
if (!this.met()) {
sinon.expectation.fail(this.toString());
} else {
sinon.expectation.pass(this.toString());
}
return true;
},
pass: function(message) {
sinon.assert.pass(message);
},
fail: function (message) {
var exception = new Error(message);
exception.name = "ExpectationError";
throw exception;
}
};
}());
if (commonJSModule) {
module.exports = mock;
} else {
sinon.mock = mock;
}
}(typeof sinon == "object" && sinon || null));