Files
automaker/libs/utils/tests/logger.test.ts
SuperComboGamer 584f5a3426 Merge main into massive-terminal-upgrade
Resolves merge conflicts:
- apps/server/src/routes/terminal/common.ts: Keep randomBytes import, use @automaker/utils for createLogger
- apps/ui/eslint.config.mjs: Use main's explicit globals list with XMLHttpRequest and MediaQueryListEvent additions
- apps/ui/src/components/views/terminal-view.tsx: Keep our terminal improvements (killAllSessions, beforeunload, better error handling)
- apps/ui/src/config/terminal-themes.ts: Keep our search highlight colors for all themes
- apps/ui/src/store/app-store.ts: Keep our terminal settings persistence improvements (merge function)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-21 20:27:44 -05:00

293 lines
8.4 KiB
TypeScript

import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
import { createLogger, LogLevel, getLogLevel, setLogLevel } from '../src/logger';
describe('logger.ts', () => {
let originalConsoleError: typeof console.error;
let originalConsoleWarn: typeof console.warn;
let originalConsoleLog: typeof console.log;
let originalLogLevel: LogLevel;
beforeEach(() => {
// Save original console methods and log level
originalConsoleError = console.error;
originalConsoleWarn = console.warn;
originalConsoleLog = console.log;
originalLogLevel = getLogLevel();
// Mock console methods
console.error = vi.fn();
console.warn = vi.fn();
console.log = vi.fn();
});
afterEach(() => {
// Restore original console methods and log level
console.error = originalConsoleError;
console.warn = originalConsoleWarn;
console.log = originalConsoleLog;
setLogLevel(originalLogLevel);
});
describe('createLogger', () => {
it('should create logger with context prefix', () => {
const logger = createLogger('TestContext');
setLogLevel(LogLevel.INFO);
logger.info('test message');
expect(console.log).toHaveBeenCalledWith('[TestContext]', 'test message');
});
it('should handle multiple arguments', () => {
const logger = createLogger('Test');
setLogLevel(LogLevel.INFO);
logger.info('message', { data: 123 }, [1, 2, 3]);
expect(console.log).toHaveBeenCalledWith('[Test]', 'message', { data: 123 }, [1, 2, 3]);
});
});
describe('Log levels', () => {
it('should log error at ERROR level', () => {
const logger = createLogger('Test');
setLogLevel(LogLevel.ERROR);
logger.error('error message');
logger.warn('warn message');
logger.info('info message');
logger.debug('debug message');
expect(console.error).toHaveBeenCalledTimes(1);
expect(console.warn).not.toHaveBeenCalled();
expect(console.log).not.toHaveBeenCalled();
});
it('should log error and warn at WARN level', () => {
const logger = createLogger('Test');
setLogLevel(LogLevel.WARN);
logger.error('error message');
logger.warn('warn message');
logger.info('info message');
logger.debug('debug message');
expect(console.error).toHaveBeenCalledTimes(1);
expect(console.warn).toHaveBeenCalledTimes(1);
expect(console.log).not.toHaveBeenCalled();
});
it('should log error, warn, and info at INFO level', () => {
const logger = createLogger('Test');
setLogLevel(LogLevel.INFO);
logger.error('error message');
logger.warn('warn message');
logger.info('info message');
logger.debug('debug message');
expect(console.error).toHaveBeenCalledTimes(1);
expect(console.warn).toHaveBeenCalledTimes(1);
expect(console.log).toHaveBeenCalledTimes(1); // Only info, not debug
});
it('should log all messages at DEBUG level', () => {
const logger = createLogger('Test');
setLogLevel(LogLevel.DEBUG);
logger.error('error message');
logger.warn('warn message');
logger.info('info message');
logger.debug('debug message');
expect(console.error).toHaveBeenCalledTimes(1);
expect(console.warn).toHaveBeenCalledTimes(1);
expect(console.log).toHaveBeenCalledTimes(2); // info + debug
});
});
describe('error method', () => {
it('should use console.error', () => {
const logger = createLogger('ErrorTest');
setLogLevel(LogLevel.ERROR);
logger.error('error occurred', { code: 500 });
expect(console.error).toHaveBeenCalledWith('[ErrorTest]', 'error occurred', { code: 500 });
});
it('should not log when level is below ERROR', () => {
const logger = createLogger('Test');
setLogLevel((LogLevel.ERROR - 1) as LogLevel);
logger.error('should not appear');
expect(console.error).not.toHaveBeenCalled();
});
});
describe('warn method', () => {
it('should use console.warn', () => {
const logger = createLogger('WarnTest');
setLogLevel(LogLevel.WARN);
logger.warn('warning message');
expect(console.warn).toHaveBeenCalledWith('[WarnTest]', 'warning message');
});
it('should not log when level is below WARN', () => {
const logger = createLogger('Test');
setLogLevel(LogLevel.ERROR);
logger.warn('should not appear');
expect(console.warn).not.toHaveBeenCalled();
});
});
describe('info method', () => {
it('should use console.log', () => {
const logger = createLogger('InfoTest');
setLogLevel(LogLevel.INFO);
logger.info('info message');
expect(console.log).toHaveBeenCalledWith('[InfoTest]', 'info message');
});
it('should not log when level is below INFO', () => {
const logger = createLogger('Test');
setLogLevel(LogLevel.WARN);
logger.info('should not appear');
expect(console.log).not.toHaveBeenCalled();
});
});
describe('debug method', () => {
it('should use console.log with DEBUG prefix', () => {
const logger = createLogger('DebugTest');
setLogLevel(LogLevel.DEBUG);
logger.debug('debug details', { trace: '...' });
expect(console.log).toHaveBeenCalledWith('[DebugTest]', '[DEBUG]', 'debug details', {
trace: '...',
});
});
it('should not log when level is below DEBUG', () => {
const logger = createLogger('Test');
setLogLevel(LogLevel.INFO);
logger.debug('should not appear');
expect(console.log).not.toHaveBeenCalled();
});
});
describe('getLogLevel', () => {
it('should return current log level', () => {
setLogLevel(LogLevel.DEBUG);
expect(getLogLevel()).toBe(LogLevel.DEBUG);
setLogLevel(LogLevel.ERROR);
expect(getLogLevel()).toBe(LogLevel.ERROR);
});
});
describe('setLogLevel', () => {
it('should change log level', () => {
setLogLevel(LogLevel.WARN);
expect(getLogLevel()).toBe(LogLevel.WARN);
setLogLevel(LogLevel.DEBUG);
expect(getLogLevel()).toBe(LogLevel.DEBUG);
});
it('should affect subsequent logging', () => {
const logger = createLogger('Test');
setLogLevel(LogLevel.ERROR);
logger.info('should not log');
expect(console.log).not.toHaveBeenCalled();
setLogLevel(LogLevel.INFO);
logger.info('should log');
expect(console.log).toHaveBeenCalledWith('[Test]', 'should log');
});
});
describe('Multiple logger instances', () => {
it('should maintain separate contexts', () => {
const logger1 = createLogger('Service1');
const logger2 = createLogger('Service2');
setLogLevel(LogLevel.INFO);
logger1.info('from service 1');
logger2.info('from service 2');
expect(console.log).toHaveBeenNthCalledWith(1, '[Service1]', 'from service 1');
expect(console.log).toHaveBeenNthCalledWith(2, '[Service2]', 'from service 2');
});
it('should share log level setting', () => {
const logger1 = createLogger('Service1');
const logger2 = createLogger('Service2');
setLogLevel(LogLevel.ERROR);
logger1.info('should not log');
logger2.info('should not log');
expect(console.log).not.toHaveBeenCalled();
});
});
describe('Edge cases', () => {
it('should handle empty context string', () => {
const logger = createLogger('');
setLogLevel(LogLevel.INFO);
logger.info('message');
expect(console.log).toHaveBeenCalledWith('[]', 'message');
});
it('should handle context with special characters', () => {
const logger = createLogger('Test-Service_v2.0');
setLogLevel(LogLevel.INFO);
logger.info('message');
expect(console.log).toHaveBeenCalledWith('[Test-Service_v2.0]', 'message');
});
it('should handle no arguments to log methods', () => {
const logger = createLogger('Test');
setLogLevel(LogLevel.INFO);
logger.info();
expect(console.log).toHaveBeenCalledWith('[Test]');
});
it('should handle complex object arguments', () => {
const logger = createLogger('Test');
setLogLevel(LogLevel.INFO);
const complexObj = {
nested: { deep: { value: 123 } },
array: [1, 2, 3],
fn: () => {},
};
logger.info('complex', complexObj);
expect(console.log).toHaveBeenCalledWith('[Test]', 'complex', complexObj);
});
});
});