UNPKG

@rollercoaster-dev/rd-logger

Version:

A neurodivergent-friendly logger for Rollercoaster.dev projects

111 lines (110 loc) 4.98 kB
/// <reference types="jest" /> import { Logger } from '../logger.service'; import chalk from 'chalk'; import path from 'path'; // import fs from 'fs'; // Not used yet // Mock chalk to disable color codes in tests for easier string matching jest.mock('chalk', () => { const chalkMock = { gray: (msg) => msg, whiteBright: (msg) => msg, blue: (msg) => msg, green: (msg) => msg, yellow: (msg) => msg, red: (msg) => msg, magenta: (msg) => msg, dim: (msg) => msg, cyan: (msg) => msg, }; return Object.assign({ __esModule: true, default: chalkMock }, chalkMock); }); // Mock fs for file logging tests (optional for now) // jest.mock('fs'); const MOCK_LOG_FILE = path.join(__dirname, 'test.log'); describe('Logger Service', () => { let logger; let consoleSpy; beforeEach(() => { // Reset mocks and disable file logging by default for console tests jest.clearAllMocks(); // We mocked chalk, so setting level might not be necessary, but doesn't hurt chalk.level = 0; logger = new Logger({ logToFile: false }); // Use correct property 'logToFile' // Spy on console.log to capture output consoleSpy = jest.spyOn(console, 'log').mockImplementation(() => { }); // Suppress actual console output }); afterEach(() => { consoleSpy.mockRestore(); }); it('should initialize with default config values if no options provided', () => { const defaultLogger = new Logger(); // Access internal config for testing - adjust if Logger exposes config differently // @ts-expect-error Accessing private property for testing const config = defaultLogger.config; // Check a few key defaults expect(config.level).toBe('info'); expect(config.prettyPrint).toBe(true); expect(config.colorize).toBe(true); expect(config.logToFile).toBe(false); }); it('should initialize with merged custom config', () => { const customLogger = new Logger({ level: 'warn', // Use string literal // timestampFormat: 'YYYY-MM-DD', // Property does not exist prettyPrint: false, logToFile: true, // Use correct property logFilePath: MOCK_LOG_FILE, }); // @ts-expect-error Accessing private property for testing const config = customLogger.config; expect(config.level).toBe('warn'); // expect(config.timestampFormat).toBe('YYYY-MM-DD'); // Property does not exist expect(config.prettyPrint).toBe(false); expect(config.logToFile).toBe(true); expect(config.logFilePath).toBe(MOCK_LOG_FILE); }); it('should log an info message to console', () => { logger.info('Test info message'); expect(consoleSpy).toHaveBeenCalledTimes(1); const logOutput = consoleSpy.mock.calls[0][0]; expect(logOutput).toContain('INFO'); expect(logOutput).toContain('Test info message'); // Check for human-readable timestamp format (e.g., "Jun 7, 19:01:33.484") expect(logOutput).toMatch(/[A-Z][a-z]{2} \d{1,2}, \d{2}:\d{2}:\d{2}\.\d{3}/); }); it('should log a warn message to console', () => { logger.warn('Test warning message'); expect(consoleSpy).toHaveBeenCalledTimes(1); const logOutput = consoleSpy.mock.calls[0][0]; expect(logOutput).toContain('WARN'); expect(logOutput).toContain('Test warning message'); }); it('should log an error message to console', () => { logger.error('Test error message'); expect(consoleSpy).toHaveBeenCalledTimes(1); const logOutput = consoleSpy.mock.calls[0][0]; expect(logOutput).toContain('ERROR'); expect(logOutput).toContain('Test error message'); }); it('should include context object in log message', () => { const context = { userId: 123, data: 'sample' }; logger.info('Message with context', context); expect(consoleSpy).toHaveBeenCalledTimes(1); const logOutput = consoleSpy.mock.calls[0][0]; expect(logOutput).toContain('Message with context'); // Check for bullet list style context output expect(logOutput).toMatch(/• userId:\s*123/); expect(logOutput).toMatch(/• data:\s*sample/); }); it('should stringify context with circular references safely', () => { const context = { name: 'circular' }; context.self = context; logger.info('Circular context test', context); expect(consoleSpy).toHaveBeenCalledTimes(1); const logOutput = consoleSpy.mock.calls[0][0]; expect(logOutput).toContain('Circular context test'); expect(logOutput).toContain('"self": "[Circular]"'); expect(logOutput).not.toContain('crashed'); // Ensure it didn't throw }); // Add more tests: log levels filtering, error formatting, file logging etc. });