stock-bot/libs/logger/test/basic.test.ts

169 lines
5.4 KiB
TypeScript

/**
* Basic Logger Tests
*
* Tests for the core logger functionality and utilities.
*/
import { describe, it, expect, beforeEach, afterEach } from 'bun:test';
import { Logger, getLogger, shutdownLoggers } from '../src';
import { loggerTestHelpers } from './setup';
describe('Basic Logger Tests', () => {
let logger: Logger;
let testLoggerInstance: ReturnType<typeof loggerTestHelpers.createTestLogger>;
beforeEach(() => {
testLoggerInstance = loggerTestHelpers.createTestLogger('utils-test');
logger = testLoggerInstance.logger;
});
afterEach(async () => {
testLoggerInstance.clearCapturedLogs();
// Clear any global logger cache
await shutdownLoggers();
});
describe('Logger Factory Functions', () => {
it('should create logger with getLogger', () => {
expect(typeof getLogger).toBe('function');
// Test that getLogger doesn't throw
expect(() => {
const anotherTestLoggerInstance = loggerTestHelpers.createTestLogger('factory-test');
anotherTestLoggerInstance.logger.info('Factory test');
}).not.toThrow();
});
});
describe('Logger Methods', () => {
it('should have all required logging methods', () => {
expect(typeof logger.debug).toBe('function');
expect(typeof logger.info).toBe('function');
expect(typeof logger.warn).toBe('function');
expect(typeof logger.error).toBe('function');
expect(typeof logger.child).toBe('function');
});
it('should log with different message types', () => {
// String message
logger.info('String message');
// Object message
logger.info({ event: 'object_message', data: 'test' });
const logs = testLoggerInstance.getCapturedLogs();
expect(logs.length).toBe(2);
expect(logs[0].msg).toBe('String message');
expect(logs[1].level).toBe('info');
});
it('should handle metadata correctly', () => {
const metadata = {
userId: 'user123',
sessionId: 'session456',
requestId: 'req789'
};
logger.info('Request processed', metadata);
const logs = testLoggerInstance.getCapturedLogs();
expect(logs.length).toBe(1);
expect(logs[0].userId).toBe('user123');
expect(logs[0].sessionId).toBe('session456');
expect(logs[0].requestId).toBe('req789');
});
});
describe('Child Logger Functionality', () => {
it('should create child loggers with additional context', () => {
const childLogger = logger.child({
module: 'payment',
version: '1.0.0'
});
childLogger.info('Payment processed');
const logs = testLoggerInstance.getCapturedLogs();
expect(logs.length).toBe(1);
expect(logs[0].msg).toBe('Payment processed');
});
it('should inherit service name in child loggers', () => {
const childLogger = logger.child({ operation: 'test' });
childLogger.info('Child operation');
const logs = testLoggerInstance.getCapturedLogs();
expect(logs.length).toBe(1);
expect(logs[0].service).toBe('utils-test');
});
});
describe('Error Normalization', () => {
it('should handle Error objects', () => {
const error = new Error('Test error');
error.stack = 'Error stack trace';
logger.error('Error test', error);
const logs = testLoggerInstance.getCapturedLogs();
expect(logs.length).toBe(1);
expect(logs[0].level).toBe('error');
});
it('should handle error-like objects', () => {
const errorLike = {
name: 'ValidationError',
message: 'Invalid input',
code: 'VALIDATION_FAILED'
};
logger.error('Validation failed', { error: errorLike });
const logs = testLoggerInstance.getCapturedLogs();
expect(logs.length).toBe(1);
expect(logs[0].level).toBe('error');
});
it('should handle primitive error values', () => {
logger.error('Simple error', { error: 'Error string' });
const logs = testLoggerInstance.getCapturedLogs();
expect(logs.length).toBe(1);
expect(logs[0].level).toBe('error');
});
});
describe('Service Context', () => {
it('should include service name in all logs', () => {
logger.debug('Debug message');
logger.info('Info message');
logger.warn('Warn message');
logger.error('Error message');
const logs = testLoggerInstance.getCapturedLogs();
expect(logs.length).toBe(4);
logs.forEach(log => {
expect(log.service).toBe('utils-test');
});
});
it('should support different service names', () => {
const logger1Instance = loggerTestHelpers.createTestLogger('service-one');
const logger2Instance = loggerTestHelpers.createTestLogger('service-two');
logger1Instance.logger.info('Message from service one');
logger2Instance.logger.info('Message from service two');
// Since each logger instance has its own capture, we check them separately
// or combine them if that's the desired test logic.
// For this test, it seems we want to ensure they are separate.
const logs1 = logger1Instance.getCapturedLogs();
expect(logs1.length).toBe(1);
expect(logs1[0].service).toBe('service-one');
const logs2 = logger2Instance.getCapturedLogs();
expect(logs2.length).toBe(1);
expect(logs2[0].service).toBe('service-two');
});
});
});