UNPKG

sinon

Version:

JavaScript test spies, stubs and mocks.

70 lines (56 loc) 2.27 kB
'use strict'; var commons = require('@sinonjs/commons'); function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; } var commons__default = /*#__PURE__*/_interopDefault(commons); const { prototypes } = commons__default.default; const forEach = prototypes.array.forEach; /** * @callback WalkIterator * @param {unknown} value * @param {string} key * @param {object} object * @returns {void} */ function walkInternal(obj, iterator, context, originalObj, seen) { let prop; const proto = Object.getPrototypeOf(obj); if (typeof Object.getOwnPropertyNames !== "function") { // We explicitly want to enumerate through all of the prototype's properties // in this case, therefore we deliberately leave out an own property check. /* eslint-disable-next-line guard-for-in */ for (prop in obj) { iterator.call(context, obj[prop], prop, obj); } return; } forEach(Object.getOwnPropertyNames(obj), function (k) { if (seen[k] !== true) { seen[k] = true; const target = typeof Object.getOwnPropertyDescriptor(obj, k).get === "function" ? originalObj : obj; iterator.call(context, k, target); } }); if (proto) { walkInternal(proto, iterator, context, originalObj, seen); } } /** * Walks the prototype chain of an object and iterates over every own property * name encountered. The iterator is called in the same fashion that Array.prototype.forEach * works, where it is passed the value, key, and own object as the 1st, 2nd, and 3rd positional * argument, respectively. In cases where Object.getOwnPropertyNames is not available, walk will * default to using a simple for..in loop. * * @param {object} obj - The object to walk the prototype chain for. * @param {WalkIterator} iterator - The function to be called on each pass of the walk. * @param {object} [context] - (Optional) When given, the iterator will be called with this object as the receiver. * @returns {void} nothing */ const walk = function (obj, iterator, context) { return walkInternal(obj, iterator, context, obj, {}); }; module.exports = walk;