mirror of
https://github.com/AutoMaker-Org/automaker.git
synced 2026-01-30 22:32:04 +00:00
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>
293 lines
8.4 KiB
TypeScript
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);
|
|
});
|
|
});
|
|
});
|