index.js 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. 'use strict';
  2. // Keep track of mocks
  3. var mocks = [];
  4. var cache = new Map();
  5. /**
  6. * Mocks a method of an object.
  7. *
  8. * @param {Object} obj
  9. * @param {string} key
  10. * @param {!Function} method
  11. */
  12. var method = module.exports = (obj, key, method) => {
  13. method = method === undefined ? () => {} : method;
  14. var hasOwnProperty = obj.hasOwnProperty(key);
  15. mocks.push({
  16. obj,
  17. key,
  18. descriptor: Object.getOwnPropertyDescriptor(obj, key),
  19. // Make sure the key exists on object not the prototype
  20. hasOwnProperty,
  21. });
  22. // Delete the origin key, redefine it below
  23. if (hasOwnProperty) {
  24. delete obj[key];
  25. }
  26. // Set a flag that checks if it is mocked
  27. var flag = cache.get(obj);
  28. if (!flag) {
  29. flag = new Set();
  30. cache.set(obj, flag);
  31. }
  32. flag.add(key);
  33. Object.defineProperty(obj, key, {
  34. writable: true,
  35. configurable: true,
  36. enumerable: true,
  37. value: method
  38. });
  39. };
  40. /**
  41. * Restore all mocks
  42. */
  43. method.restore = () => {
  44. for (var i = mocks.length - 1; i >= 0; i--) {
  45. var m = mocks[i];
  46. if (!m.hasOwnProperty) {
  47. // Delete the mock key, use key on the prototype
  48. delete m.obj[m.key];
  49. } else {
  50. // Redefine the origin key instead of the mock key
  51. Object.defineProperty(m.obj, m.key, m.descriptor);
  52. }
  53. }
  54. mocks = [];
  55. cache.clear();
  56. };
  57. method.isMocked = function isMocked(obj, key) {
  58. var flag = cache.get(obj);
  59. return flag ? flag.has(key) : false;
  60. };