debuggable.spec.js 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. import {expect} from 'chai';
  2. import {createSpy} from '@e22m4u/js-spy';
  3. import {Debuggable} from './debuggable.js';
  4. import {stripAnsi} from './utils/index.js';
  5. import {escapeRegexp} from './utils/index.js';
  6. describe('Debuggable', function () {
  7. let consoleLogSpy;
  8. let originalDebugEnv;
  9. let originalDebuggerNamespaceEnv;
  10. beforeEach(function () {
  11. // шпионим за console.log перед каждым тестом
  12. consoleLogSpy = createSpy(console, 'log');
  13. // сохраняем исходные переменные окружения
  14. originalDebugEnv = process.env.DEBUG;
  15. originalDebuggerNamespaceEnv = process.env.DEBUGGER_NAMESPACE;
  16. // сбрасываем переменные перед тестом
  17. delete process.env.DEBUG;
  18. delete process.env.DEBUGGER_NAMESPACE;
  19. });
  20. afterEach(function () {
  21. // восстанавливаем console.log
  22. consoleLogSpy.restore();
  23. // восстанавливаем переменные окружения
  24. if (originalDebugEnv === undefined) {
  25. delete process.env.DEBUG;
  26. } else {
  27. process.env.DEBUG = originalDebugEnv;
  28. }
  29. if (originalDebuggerNamespaceEnv === undefined) {
  30. delete process.env.DEBUGGER_NAMESPACE;
  31. } else {
  32. process.env.DEBUGGER_NAMESPACE = originalDebuggerNamespaceEnv;
  33. }
  34. });
  35. it('has the debug method', function () {
  36. const res = new Debuggable();
  37. expect(typeof res.debug).to.be.eq('function');
  38. });
  39. describe('constructor', function () {
  40. it('should output the specific message when instantiated', function () {
  41. process.env.DEBUG = '*';
  42. new Debuggable();
  43. expect(consoleLogSpy.callCount).to.equal(1);
  44. const msg = escapeRegexp(Debuggable.INSTANTIATION_MESSAGE);
  45. expect(stripAnsi(consoleLogSpy.getCall(0).args[0])).to.match(
  46. new RegExp(`^debuggable:constructor:[a-f0-9]{4} ${msg}$`),
  47. );
  48. });
  49. it('should use DEBUGGER_NAMESPACE environment variable', function () {
  50. process.env.DEBUGGER_NAMESPACE = 'myApp';
  51. process.env.DEBUG = '*';
  52. new Debuggable();
  53. expect(consoleLogSpy.callCount).to.equal(1);
  54. const msg = escapeRegexp(Debuggable.INSTANTIATION_MESSAGE);
  55. expect(stripAnsi(consoleLogSpy.getCall(0).args[0])).to.match(
  56. new RegExp(`^myApp:debuggable:constructor:[a-f0-9]{4} ${msg}$`),
  57. );
  58. });
  59. it('uses extended class name as namespace', function () {
  60. process.env.DEBUG = '*';
  61. class MyService extends Debuggable {}
  62. new MyService();
  63. expect(consoleLogSpy.callCount).to.equal(1);
  64. const msg = escapeRegexp(Debuggable.INSTANTIATION_MESSAGE);
  65. expect(stripAnsi(consoleLogSpy.getCall(0).args[0])).to.match(
  66. new RegExp(`^myService:constructor:[a-f0-9]{4} ${msg}$`),
  67. );
  68. });
  69. describe('"namespace" option', function () {
  70. it('should use "namespace" option as the first namespace segment', function () {
  71. process.env.DEBUG = '*';
  72. new Debuggable({namespace: 'myApp'});
  73. expect(consoleLogSpy.callCount).to.equal(1);
  74. const msg = escapeRegexp(Debuggable.INSTANTIATION_MESSAGE);
  75. expect(stripAnsi(consoleLogSpy.getCall(0).args[0])).to.match(
  76. new RegExp(`^myApp:debuggable:constructor:[a-f0-9]{4} ${msg}$`),
  77. );
  78. });
  79. });
  80. describe('"noEnvironmentNamespace" option', function () {
  81. it('should use DEBUGGER_NAMESPACE when the option "noEnvironmentNamespace" is false', function () {
  82. process.env.DEBUGGER_NAMESPACE = 'myApp';
  83. process.env.DEBUG = '*';
  84. new Debuggable({noEnvironmentNamespace: false});
  85. expect(consoleLogSpy.callCount).to.equal(1);
  86. const msg = escapeRegexp(Debuggable.INSTANTIATION_MESSAGE);
  87. expect(stripAnsi(consoleLogSpy.getCall(0).args[0])).to.match(
  88. new RegExp(`^myApp:debuggable:constructor:[a-f0-9]{4} ${msg}$`),
  89. );
  90. });
  91. it('should skip DEBUGGER_NAMESPACE when the option "noEnvironmentNamespace" is true', function () {
  92. process.env.DEBUGGER_NAMESPACE = 'myApp';
  93. process.env.DEBUG = '*';
  94. new Debuggable({noEnvironmentNamespace: true});
  95. expect(consoleLogSpy.callCount).to.equal(1);
  96. const msg = escapeRegexp(Debuggable.INSTANTIATION_MESSAGE);
  97. expect(stripAnsi(consoleLogSpy.getCall(0).args[0])).to.match(
  98. new RegExp(`^debuggable:constructor:[a-f0-9]{4} ${msg}$`),
  99. );
  100. });
  101. });
  102. describe('"noInstantiationMessage" option', function () {
  103. it('should hide instantiation message', function () {
  104. process.env.DEBUG = '*';
  105. new Debuggable({noInstantiationMessage: true});
  106. expect(consoleLogSpy.callCount).to.equal(0);
  107. });
  108. });
  109. });
  110. describe('getDebuggerFor', function () {
  111. it('returns a new debugger with method name segment and hash', function () {
  112. process.env.DEBUG = '*';
  113. class MyService extends Debuggable {
  114. myMethod() {
  115. const debug = this.getDebuggerFor(this.myMethod);
  116. debug('Message');
  117. }
  118. }
  119. const myService = new MyService();
  120. myService.myMethod();
  121. expect(consoleLogSpy.callCount).to.equal(2);
  122. expect(stripAnsi(consoleLogSpy.getCall(1).args[0])).to.match(
  123. new RegExp(`^myService:myMethod:[a-f0-9]{4} Message$`),
  124. );
  125. });
  126. });
  127. });