create-sandbox.spec.js 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. import {expect} from 'chai';
  2. import {Sandbox, createSandbox} from './create-sandbox.js';
  3. describe('Sandbox', function () {
  4. describe('createSandbox factory', function () {
  5. it('should return an instance of Sandbox', function () {
  6. const sandbox = createSandbox();
  7. expect(sandbox).to.be.instanceOf(Sandbox);
  8. });
  9. it('should initialize with an empty spies array', function () {
  10. const sandbox = createSandbox();
  11. expect(sandbox.spies).to.be.an('array').that.is.empty;
  12. });
  13. });
  14. describe('Sandbox instance', function () {
  15. describe('.on(target, methodNameOrImpl, customImplForMethod)', function () {
  16. it('should create a spy for a standalone function', function () {
  17. const sandbox = createSandbox();
  18. const targetFn = () => {};
  19. const fnSpy = sandbox.on(targetFn);
  20. expect(fnSpy).to.be.a('function');
  21. expect(fnSpy.callCount).to.equal(0);
  22. expect(fnSpy).to.have.property('calls');
  23. });
  24. it('should create a spy for a standalone function with a custom implementation', function () {
  25. const sandbox = createSandbox();
  26. const targetFn = () => {};
  27. const customImpl = () => 'custom result';
  28. const fnSpy = sandbox.on(targetFn, customImpl);
  29. fnSpy();
  30. expect(fnSpy.calls[0].returnValue).to.equal('custom result');
  31. });
  32. it('should create a spy for an object method and replace the original method', function () {
  33. const sandbox = createSandbox();
  34. const obj = {method: () => 'original method'};
  35. const methodSpy = sandbox.on(obj, 'method');
  36. expect(obj.method).to.equal(methodSpy);
  37. expect(methodSpy).to.be.a('function');
  38. });
  39. it('should create a spy for an object method with a custom implementation', function () {
  40. const sandbox = createSandbox();
  41. const obj = {method: () => 'original method'};
  42. const customImpl = () => 'custom method';
  43. sandbox.on(obj, 'method', customImpl);
  44. expect(obj.method()).to.equal('custom method');
  45. });
  46. it('should add the created spy to the internal spies array', function () {
  47. const sandbox = createSandbox();
  48. const targetFn1 = () => {};
  49. const targetFn2 = () => {};
  50. const spy1 = sandbox.on(targetFn1);
  51. expect(sandbox.spies).to.have.lengthOf(1);
  52. expect(sandbox.spies[0]).to.equal(spy1);
  53. const spy2 = sandbox.on(targetFn2);
  54. expect(sandbox.spies).to.have.lengthOf(2);
  55. expect(sandbox.spies[1]).to.equal(spy2);
  56. });
  57. it('should return the created spy instance', function () {
  58. const sandbox = createSandbox();
  59. const targetFn = () => {};
  60. const returnedSpy = sandbox.on(targetFn);
  61. expect(returnedSpy).to.be.a('function');
  62. expect(sandbox.spies[0]).to.equal(returnedSpy);
  63. });
  64. });
  65. describe('.restore()', function () {
  66. it('should restore original methods on objects', function () {
  67. const sandbox = createSandbox();
  68. const originalMethod = () => 'original';
  69. const obj = {method: originalMethod};
  70. sandbox.on(obj, 'method');
  71. expect(obj.method).to.not.equal(originalMethod);
  72. sandbox.restore();
  73. expect(obj.method).to.equal(originalMethod);
  74. expect(obj.method()).to.equal('original');
  75. });
  76. it('should reset call history for all spies', function () {
  77. const sandbox = createSandbox();
  78. const fn = () => {};
  79. const spy = sandbox.on(fn);
  80. spy();
  81. expect(spy.isCalled).to.be.true;
  82. expect(spy.callCount).to.equal(1);
  83. sandbox.restore();
  84. expect(spy.isCalled).to.be.false;
  85. expect(spy.callCount).to.equal(0);
  86. });
  87. it('should clear the internal spies array', function () {
  88. const sandbox = createSandbox();
  89. sandbox.on(() => {});
  90. sandbox.on({m: () => {}}, 'm');
  91. expect(sandbox.spies).to.have.lengthOf(2);
  92. sandbox.restore();
  93. expect(sandbox.spies).to.be.an('array').that.is.empty;
  94. });
  95. it('should return the Sandbox instance for chaining', function () {
  96. const sandbox = createSandbox();
  97. const returnedValue = sandbox.restore();
  98. expect(returnedValue).to.equal(sandbox);
  99. });
  100. it('should be idempotent (calling restore multiple times does not throw)', function () {
  101. const sandbox = createSandbox();
  102. const obj = {method: () => {}};
  103. sandbox.on(obj, 'method');
  104. sandbox.restore();
  105. expect(() => sandbox.restore()).to.not.throw();
  106. });
  107. it('should handle an empty spies array gracefully', function () {
  108. const sandbox = createSandbox();
  109. expect(() => sandbox.restore()).to.not.throw();
  110. expect(sandbox.spies).to.be.an('array').that.is.empty;
  111. });
  112. });
  113. });
  114. });