sinon
Version:
JavaScript test spies, stubs and mocks.
75 lines (62 loc) • 2.07 kB
JavaScript
;
var commons = require('@sinonjs/commons');
var getPropertyDescriptor = require('./get-property-descriptor.js');
var walk = require('./walk.js');
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
var commons__default = /*#__PURE__*/_interopDefault(commons);
const { functionName } = commons__default.default;
/**
* @callback ObjectMutator
* @param {object} object
* @param {string} property
* @returns {void}
*/
/**
* @callback ObjectFilter
* @param {object} object
* @param {string} property
* @returns {boolean}
*/
/**
* A utility that allows traversing an object, applying mutating functions on the properties
*
* @param {ObjectMutator} mutator called on each property
* @param {object} object the object we are walking over
* @param {ObjectFilter} filter a predicate (boolean function) that will decide whether or not to apply the mutator to the current property
* @returns {void} nothing
*/
const walkObject = function (mutator, object, filter) {
let called = false;
const name = functionName(mutator);
if (!object) {
throw new Error(
`Trying to ${name} object but received ${String(object)}`,
);
}
walk(object, function (prop, propOwner) {
// we don't want to stub things like toString(), valueOf(), etc. so we only stub if the object
// is not Object.prototype
if (
propOwner !== Object.prototype &&
prop !== "constructor" &&
typeof getPropertyDescriptor(propOwner, prop).value === "function"
) {
if (filter) {
if (filter(object, prop)) {
called = true;
mutator(object, prop);
}
} else {
called = true;
mutator(object, prop);
}
}
});
if (!called) {
throw new Error(
`Found no methods on object to which we could apply mutations`,
);
}
return object;
};
module.exports = walkObject;