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

188 lines
5.8 KiB
TypeScript

/**
* Logger Integration Tests
*
* Tests the core functionality of the simplified @stock-bot/logger package.
*/
import { afterEach, beforeEach, describe, expect, it } from 'bun:test';
import { getLogger, Logger, shutdownLoggers } from '../src';
import { loggerTestHelpers } from './setup';
describe('Logger Integration Tests', () => {
let logger: Logger;
let testLoggerInstance: ReturnType<typeof loggerTestHelpers.createTestLogger>;
beforeEach(() => {
testLoggerInstance = loggerTestHelpers.createTestLogger('integration-test');
logger = testLoggerInstance.logger;
});
afterEach(async () => {
testLoggerInstance.clearCapturedLogs();
// Clear any global logger cache
await shutdownLoggers();
});
describe('Core Logger Functionality', () => {
it('should log messages at different levels', () => {
// Test multiple log levels
logger.debug('Debug message');
logger.info('Info message');
logger.warn('Warning message');
logger.error('Error message');
// Get captured logs
const logs = testLoggerInstance.getCapturedLogs();
// Verify logs were captured
expect(logs.length).toBe(4);
expect(logs[0].level).toBe('debug');
expect(logs[0].msg).toBe('Debug message');
expect(logs[1].level).toBe('info');
expect(logs[1].msg).toBe('Info message');
expect(logs[2].level).toBe('warn');
expect(logs[2].msg).toBe('Warning message');
expect(logs[3].level).toBe('error');
expect(logs[3].msg).toBe('Error message');
});
it('should log objects as structured logs', () => {
// Log an object
logger.info('User logged in', { userId: '123', action: 'login' });
// Get captured logs
const logs = testLoggerInstance.getCapturedLogs();
// Verify structured log
expect(logs.length).toBe(1);
expect(logs[0].userId).toBe('123');
expect(logs[0].action).toBe('login');
expect(logs[0].msg).toBe('User logged in');
});
it('should handle error objects in error logs', () => {
const testError = new Error('Test error message');
// Log error with error object
logger.error('Something went wrong', { error: testError });
// Get captured logs
const logs = testLoggerInstance.getCapturedLogs();
// Verify error was logged
expect(logs.length).toBe(1);
expect(logs[0].level).toBe('error');
expect(logs[0].msg).toBe('Something went wrong');
});
it('should create child loggers with additional context', () => {
// Create a child logger with additional context
const childLogger = logger.child({
transactionId: 'tx-789',
operation: 'payment',
});
// Log with child logger
childLogger.info('Child logger test');
// Get captured logs
const logs = testLoggerInstance.getCapturedLogs();
// Verify child logger logged something
expect(logs.length).toBe(1);
expect(logs[0].msg).toBe('Child logger test');
});
});
describe('Factory Functions', () => {
it('should export factory functions', () => {
// Verify that the factory functions are exported and callable
expect(typeof getLogger).toBe('function');
});
it('should create different logger instances', () => {
const logger1Instance = loggerTestHelpers.createTestLogger('service-1');
const logger2Instance = loggerTestHelpers.createTestLogger('service-2');
logger1Instance.logger.info('Message from service 1');
logger2Instance.logger.info('Message from service 2');
const logs1 = logger1Instance.getCapturedLogs();
expect(logs1.length).toBe(1);
expect(logs1[0].service).toBe('service-1');
const logs2 = logger2Instance.getCapturedLogs();
expect(logs2.length).toBe(1);
expect(logs2[0].service).toBe('service-2');
});
});
describe('Error Handling', () => {
it('should normalize Error objects', () => {
const error = new Error('Test error');
error.stack = 'Error stack trace';
logger.error('Error occurred', error);
const logs = testLoggerInstance.getCapturedLogs();
expect(logs.length).toBe(1);
expect(logs[0].level).toBe('error');
expect(logs[0].msg).toBe('Error occurred');
});
it('should handle error-like objects', () => {
const errorLike = {
name: 'CustomError',
message: 'Custom error message',
code: 'ERR_CUSTOM',
};
logger.error('Custom error occurred', { error: errorLike });
const logs = testLoggerInstance.getCapturedLogs();
expect(logs.length).toBe(1);
expect(logs[0].level).toBe('error');
expect(logs[0].msg).toBe('Custom error occurred');
});
it('should handle primitive error values', () => {
logger.error('String error occurred', { error: 'Simple string error' });
const logs = testLoggerInstance.getCapturedLogs();
expect(logs.length).toBe(1);
expect(logs[0].level).toBe('error');
expect(logs[0].msg).toBe('String error occurred');
});
});
describe('Metadata Handling', () => {
it('should include metadata in logs', () => {
const metadata = {
requestId: 'req-123',
userId: 'user-456',
operation: 'data-fetch',
};
logger.info('Operation completed', metadata);
const logs = testLoggerInstance.getCapturedLogs();
expect(logs.length).toBe(1);
expect(logs[0].requestId).toBe('req-123');
expect(logs[0].userId).toBe('user-456');
expect(logs[0].operation).toBe('data-fetch');
});
it('should handle object messages', () => {
const objectMessage = {
event: 'user_action',
action: 'login',
timestamp: Date.now(),
};
logger.info(objectMessage);
const logs = testLoggerInstance.getCapturedLogs();
expect(logs.length).toBe(1);
expect(logs[0].level).toBe('info');
});
});
});