Skip to main content
Glama
logger.test.ts8.22 kB
import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest'; import { Logger } from '../../src/utils/logger.js'; describe('Logger', () => { let originalEnv: NodeJS.ProcessEnv; let consoleSpy: { log: any; error: any; warn: any; }; beforeEach(() => { // Store original environment originalEnv = { ...process.env }; // Mock console methods consoleSpy = { log: vi.spyOn(console, 'log').mockImplementation(() => {}), error: vi.spyOn(console, 'error').mockImplementation(() => {}), warn: vi.spyOn(console, 'warn').mockImplementation(() => {}), }; // Reset singleton instance (Logger as any).instance = undefined; }); afterEach(() => { // Restore environment process.env = originalEnv; // Restore console methods consoleSpy.log.mockRestore(); consoleSpy.error.mockRestore(); consoleSpy.warn.mockRestore(); // Reset singleton instance (Logger as any).instance = undefined; }); describe('getInstance', () => { it('should return singleton instance', () => { const logger1 = Logger.getInstance(); const logger2 = Logger.getInstance(); expect(logger1).toBe(logger2); }); it('should use default log level when LOG_LEVEL is not set', () => { delete process.env.LOG_LEVEL; const logger = Logger.getInstance(); expect(logger).toBeInstanceOf(Logger); }); it('should use custom log level when LOG_LEVEL is set', () => { process.env.LOG_LEVEL = 'debug'; const logger = Logger.getInstance(); expect(logger).toBeInstanceOf(Logger); }); }); describe('log levels', () => { describe('when log level is debug', () => { beforeEach(() => { process.env.LOG_LEVEL = 'debug'; (Logger as any).instance = undefined; }); it('should log debug messages', () => { const logger = Logger.getInstance(); logger.debug('Debug message', { key: 'value' }); expect(consoleSpy.error).toHaveBeenCalledWith( expect.stringContaining('[DEBUG] Debug message {"key":"value"}') ); }); it('should log info messages', () => { const logger = Logger.getInstance(); logger.info('Info message'); expect(consoleSpy.log).toHaveBeenCalledWith( expect.stringContaining('[INFO] Info message') ); }); it('should log warn messages', () => { const logger = Logger.getInstance(); logger.warn('Warn message'); expect(consoleSpy.warn).toHaveBeenCalledWith( expect.stringContaining('[WARN] Warn message') ); }); it('should log error messages', () => { const logger = Logger.getInstance(); logger.error('Error message'); expect(consoleSpy.error).toHaveBeenCalledWith( expect.stringContaining('[ERROR] Error message') ); }); }); describe('when log level is info', () => { beforeEach(() => { process.env.LOG_LEVEL = 'info'; (Logger as any).instance = undefined; }); it('should not log debug messages', () => { const logger = Logger.getInstance(); logger.debug('Debug message'); expect(consoleSpy.error).not.toHaveBeenCalled(); }); it('should log info messages', () => { const logger = Logger.getInstance(); logger.info('Info message'); expect(consoleSpy.log).toHaveBeenCalledWith( expect.stringContaining('[INFO] Info message') ); }); it('should log warn messages', () => { const logger = Logger.getInstance(); logger.warn('Warn message'); expect(consoleSpy.warn).toHaveBeenCalledWith( expect.stringContaining('[WARN] Warn message') ); }); it('should log error messages', () => { const logger = Logger.getInstance(); logger.error('Error message'); expect(consoleSpy.error).toHaveBeenCalledWith( expect.stringContaining('[ERROR] Error message') ); }); }); describe('when log level is warn', () => { beforeEach(() => { process.env.LOG_LEVEL = 'warn'; (Logger as any).instance = undefined; }); it('should not log debug messages', () => { const logger = Logger.getInstance(); logger.debug('Debug message'); expect(consoleSpy.error).not.toHaveBeenCalled(); }); it('should not log info messages', () => { const logger = Logger.getInstance(); logger.info('Info message'); expect(consoleSpy.log).not.toHaveBeenCalled(); }); it('should log warn messages', () => { const logger = Logger.getInstance(); logger.warn('Warn message'); expect(consoleSpy.warn).toHaveBeenCalledWith( expect.stringContaining('[WARN] Warn message') ); }); it('should log error messages', () => { const logger = Logger.getInstance(); logger.error('Error message'); expect(consoleSpy.error).toHaveBeenCalledWith( expect.stringContaining('[ERROR] Error message') ); }); }); describe('when log level is error', () => { beforeEach(() => { process.env.LOG_LEVEL = 'error'; (Logger as any).instance = undefined; }); it('should not log debug messages', () => { const logger = Logger.getInstance(); logger.debug('Debug message'); expect(consoleSpy.error).not.toHaveBeenCalled(); }); it('should not log info messages', () => { const logger = Logger.getInstance(); logger.info('Info message'); expect(consoleSpy.log).not.toHaveBeenCalled(); }); it('should not log warn messages', () => { const logger = Logger.getInstance(); logger.warn('Warn message'); expect(consoleSpy.warn).not.toHaveBeenCalled(); }); it('should log error messages', () => { const logger = Logger.getInstance(); logger.error('Error message'); expect(consoleSpy.error).toHaveBeenCalledWith( expect.stringContaining('[ERROR] Error message') ); }); }); }); describe('message formatting', () => { beforeEach(() => { process.env.LOG_LEVEL = 'debug'; (Logger as any).instance = undefined; }); it('should format messages with timestamp and level', () => { const logger = Logger.getInstance(); logger.info('Test message'); expect(consoleSpy.log).toHaveBeenCalledWith( expect.stringMatching(/^\[\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z\] \[INFO\] Test message$/) ); }); it('should include data when provided', () => { const logger = Logger.getInstance(); logger.info('Test message', { key1: 'value1', key2: 42 }); expect(consoleSpy.log).toHaveBeenCalledWith( expect.stringContaining('[INFO] Test message {"key1":"value1","key2":42}') ); }); it('should not include data when not provided', () => { const logger = Logger.getInstance(); logger.info('Test message'); expect(consoleSpy.log).toHaveBeenCalledWith( expect.stringMatching(/^\[\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z\] \[INFO\] Test message$/) ); }); it('should handle errors with stack traces', () => { const logger = Logger.getInstance(); const error = new Error('Test error'); logger.error('Error occurred', error); expect(consoleSpy.error).toHaveBeenCalledWith( expect.stringContaining('[ERROR] Error occurred') ); expect(consoleSpy.error).toHaveBeenCalledWith( expect.stringContaining('Error: Test error') ); }); it('should handle errors without stack traces', () => { const logger = Logger.getInstance(); const error = { message: 'Plain error object' }; logger.error('Error occurred', error); expect(consoleSpy.error).toHaveBeenCalledWith( expect.stringContaining('[ERROR] Error occurred') ); expect(consoleSpy.error).toHaveBeenCalledTimes(1); // No stack trace logged }); }); });

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/JonathanJude/openrouter-image-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server