refactor the fix based on the e2e test failure

This commit is contained in:
Cynthia Long
2026-03-17 04:43:10 +00:00
parent 2e466bd4cb
commit bd60ba9e68
5 changed files with 150 additions and 140 deletions
+147 -102
View File
@@ -6,135 +6,180 @@
/* eslint-disable no-console */
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
import { describe, it, expect, vi, afterEach } from 'vitest';
import { ConsolePatcher } from './ConsolePatcher.js';
describe('ConsolePatcher', () => {
let patcher: ConsolePatcher;
const onNewMessage = vi.fn();
beforeEach(() => {
vi.clearAllMocks();
});
afterEach(() => {
if (patcher) {
patcher.cleanup();
}
vi.restoreAllMocks();
vi.clearAllMocks();
});
it('should suppress output when suppressConsoleOutput is true and debugMode is false', () => {
const originalError = console.error;
const errorSpy = vi.spyOn(console, 'error').mockImplementation(() => {});
it('should patch and restore console methods', () => {
const beforeLog = console.log;
const beforeWarn = console.warn;
const beforeError = console.error;
const beforeDebug = console.debug;
const beforeInfo = console.info;
patcher = new ConsolePatcher({
debugMode: false,
suppressConsoleOutput: true,
stderr: true,
});
patcher = new ConsolePatcher({ onNewMessage, debugMode: false });
patcher.patch();
console.log('test log');
expect(errorSpy).not.toHaveBeenCalled();
expect(console.log).not.toBe(beforeLog);
expect(console.warn).not.toBe(beforeWarn);
expect(console.error).not.toBe(beforeError);
expect(console.debug).not.toBe(beforeDebug);
expect(console.info).not.toBe(beforeInfo);
patcher.cleanup();
errorSpy.mockRestore();
console.error = originalError;
expect(console.log).toBe(beforeLog);
expect(console.warn).toBe(beforeWarn);
expect(console.error).toBe(beforeError);
expect(console.debug).toBe(beforeDebug);
expect(console.info).toBe(beforeInfo);
});
it('should NOT suppress console.error even when suppressConsoleOutput is true', () => {
const originalError = console.error;
const errorSpy = vi.spyOn(console, 'error').mockImplementation(() => {});
describe('when stderr is false', () => {
it('should call onNewMessage for log, warn, error, and info', () => {
patcher = new ConsolePatcher({
onNewMessage,
debugMode: false,
stderr: false,
});
patcher.patch();
patcher = new ConsolePatcher({
debugMode: false,
suppressConsoleOutput: true,
stderr: true,
});
patcher.patch();
console.error('test error');
expect(errorSpy).toHaveBeenCalled();
patcher.cleanup();
errorSpy.mockRestore();
console.error = originalError;
});
it('should NOT suppress output when suppressConsoleOutput is true but debugMode is true', () => {
const originalError = console.error;
const errorSpy = vi.spyOn(console, 'error').mockImplementation(() => {});
patcher = new ConsolePatcher({
debugMode: true,
suppressConsoleOutput: true,
stderr: true,
});
patcher.patch();
console.log('test log');
// When stderr is true, log goes to originalConsoleError
expect(errorSpy).toHaveBeenCalled();
patcher.cleanup();
errorSpy.mockRestore();
console.error = originalError;
});
it('should NOT suppress output when suppressConsoleOutput is false', () => {
const originalError = console.error;
const errorSpy = vi.spyOn(console, 'error').mockImplementation(() => {});
patcher = new ConsolePatcher({
debugMode: false,
suppressConsoleOutput: false,
stderr: true,
});
patcher.patch();
console.error('test error');
expect(errorSpy).toHaveBeenCalled();
patcher.cleanup();
errorSpy.mockRestore();
console.error = originalError;
});
it('should call onNewMessage when stderr is false and not suppressed', () => {
patcher = new ConsolePatcher({
debugMode: false,
suppressConsoleOutput: false,
stderr: false,
onNewMessage,
});
patcher.patch();
console.log('test log');
expect(onNewMessage).toHaveBeenCalledWith(
expect.objectContaining({
console.log('test log');
expect(onNewMessage).toHaveBeenCalledWith({
type: 'log',
content: 'test log',
}),
);
count: 1,
});
patcher.cleanup();
console.warn('test warn');
expect(onNewMessage).toHaveBeenCalledWith({
type: 'warn',
content: 'test warn',
count: 1,
});
console.error('test error');
expect(onNewMessage).toHaveBeenCalledWith({
type: 'error',
content: 'test error',
count: 1,
});
console.info('test info');
expect(onNewMessage).toHaveBeenCalledWith({
type: 'info',
content: 'test info',
count: 1,
});
});
it('should not call onNewMessage for debug when debugMode is false', () => {
patcher = new ConsolePatcher({
onNewMessage,
debugMode: false,
stderr: false,
});
patcher.patch();
console.debug('test debug');
expect(onNewMessage).not.toHaveBeenCalled();
});
it('should call onNewMessage for debug when debugMode is true', () => {
patcher = new ConsolePatcher({
onNewMessage,
debugMode: true,
stderr: false,
});
patcher.patch();
console.debug('test debug');
expect(onNewMessage).toHaveBeenCalledWith({
type: 'debug',
content: 'test debug',
count: 1,
});
});
it('should format multiple arguments using util.format', () => {
patcher = new ConsolePatcher({
onNewMessage,
debugMode: false,
stderr: false,
});
patcher.patch();
console.log('test %s %d', 'string', 123);
expect(onNewMessage).toHaveBeenCalledWith({
type: 'log',
content: 'test string 123',
count: 1,
});
});
});
it('should NOT suppress output when suppressConsoleOutput is true but debugMode is true (explicit check)', () => {
const onNewMessage = vi.fn();
patcher = new ConsolePatcher({
debugMode: true,
suppressConsoleOutput: true,
stderr: false,
onNewMessage,
describe('when stderr is true', () => {
it('should redirect warn and error to originalConsoleError', () => {
const spyError = vi.spyOn(console, 'error').mockImplementation(() => {});
patcher = new ConsolePatcher({ debugMode: false, stderr: true });
patcher.patch();
console.warn('test warn');
expect(spyError).toHaveBeenCalledWith('test warn');
console.error('test error');
expect(spyError).toHaveBeenCalledWith('test error');
});
patcher.patch();
console.log('test log');
it('should ignore log and info when debugMode is false', () => {
const spyError = vi.spyOn(console, 'error').mockImplementation(() => {});
patcher = new ConsolePatcher({ debugMode: false, stderr: true });
patcher.patch();
expect(onNewMessage).toHaveBeenCalled();
patcher.cleanup();
console.log('test log');
console.info('test info');
expect(spyError).not.toHaveBeenCalled();
});
it('should redirect log and info to originalConsoleError when debugMode is true', () => {
const spyError = vi.spyOn(console, 'error').mockImplementation(() => {});
patcher = new ConsolePatcher({ debugMode: true, stderr: true });
patcher.patch();
console.log('test log');
expect(spyError).toHaveBeenCalledWith('test log');
console.info('test info');
expect(spyError).toHaveBeenCalledWith('test info');
});
it('should ignore debug when debugMode is false', () => {
const spyError = vi.spyOn(console, 'error').mockImplementation(() => {});
patcher = new ConsolePatcher({ debugMode: false, stderr: true });
patcher.patch();
console.debug('test debug');
expect(spyError).not.toHaveBeenCalled();
});
it('should redirect debug to originalConsoleError when debugMode is true', () => {
const spyError = vi.spyOn(console, 'error').mockImplementation(() => {});
patcher = new ConsolePatcher({ debugMode: true, stderr: true });
patcher.patch();
console.debug('test debug');
expect(spyError).toHaveBeenCalledWith('test debug');
});
});
});