UNPKG

sinon

Version:

JavaScript test spies, stubs and mocks.

75 lines (62 loc) 2.07 kB
'use strict'; 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;