stock-bot/libs/core/logger/test/logger.test.ts
2025-06-25 09:20:53 -04:00

114 lines
No EOL
3.7 KiB
TypeScript

import { beforeEach, describe, expect, it } from 'bun:test';
import { Logger, getLogger, setLoggerConfig, shutdownLoggers } from '../src/logger';
describe('Logger', () => {
beforeEach(async () => {
// Reset logger state
await shutdownLoggers();
});
it('should create a logger instance', () => {
const logger = getLogger('test');
expect(logger).toBeDefined();
expect(logger).toBeInstanceOf(Logger);
});
it('should use same pino instance for same name', async () => {
await shutdownLoggers(); // Reset first
const logger1 = getLogger('test');
const logger2 = getLogger('test');
// While Logger instances are different, they should share the same pino instance
expect(logger1).not.toBe(logger2); // Different Logger instances
// But they have the same service name
expect((logger1 as any).serviceName).toBe((logger2 as any).serviceName);
});
it('should create different instances for different names', () => {
const logger1 = getLogger('test1');
const logger2 = getLogger('test2');
expect(logger1).not.toBe(logger2);
});
it('should have logging methods', () => {
const logger = getLogger('test');
expect(typeof logger.info).toBe('function');
expect(typeof logger.error).toBe('function');
expect(typeof logger.warn).toBe('function');
expect(typeof logger.debug).toBe('function');
expect(typeof logger.trace).toBe('function');
});
it('should create child logger', () => {
const logger = getLogger('parent');
const child = logger.child('child');
expect(child).toBeDefined();
expect(child).toBeInstanceOf(Logger);
});
it('should accept metadata in log methods', () => {
const logger = getLogger('test');
// These should not throw
logger.info('Test message');
logger.info('Test message', { key: 'value' });
logger.error('Error message', { error: new Error('test') });
logger.warn('Warning', { count: 5 });
logger.debug('Debug info', { data: [1, 2, 3] });
logger.trace('Trace details', { nested: { value: true } });
});
it('should format log messages', () => {
const logger = getLogger('test');
// Just verify the logger can log without errors
// The actual format is handled by pino-pretty which outputs to stdout
expect(() => {
logger.info('Test message');
logger.warn('Warning message');
logger.error('Error message');
}).not.toThrow();
});
it('should set logger config', () => {
setLoggerConfig({
logLevel: 'debug',
});
const logger = getLogger('test');
expect(logger).toBeDefined();
});
it('should handle shutdown', async () => {
await shutdownLoggers(); // Reset first
const logger1 = getLogger('test1');
const _logger2 = getLogger('test2'); // not used, just to ensure multiple loggers can be created
// Store references
const logger1Ref = logger1;
await shutdownLoggers();
// Should create new instances after shutdown
const logger3 = getLogger('test1');
expect(logger3).not.toBe(logger1Ref);
});
it('should handle log levels', async () => {
await shutdownLoggers(); // Reset first
setLoggerConfig({ logLevel: 'warn' });
const logger = getLogger('test');
// Just verify that log methods exist and don't throw
// The actual level filtering is handled by pino
expect(() => {
logger.trace('Trace'); // Should not log
logger.debug('Debug'); // Should not log
logger.info('Info'); // Should not log
logger.warn('Warn'); // Should log
logger.error('Error'); // Should log
}).not.toThrow();
// Clean up
await shutdownLoggers();
});
});