light-sentry-sdk/tests/logger.test.ts

201 lines
6.8 KiB
TypeScript

import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
import {
setDebug,
isDebugEnabled,
logDebug,
logError,
} from '../src/utils/logger';
describe('logger', () => {
beforeEach(() => {
setDebug(false);
});
afterEach(() => {
vi.restoreAllMocks();
});
describe('setDebug', () => {
it('should enable debug mode', () => {
expect(isDebugEnabled()).toBe(false);
setDebug(true);
expect(isDebugEnabled()).toBe(true);
});
it('should disable debug mode', () => {
setDebug(true);
expect(isDebugEnabled()).toBe(true);
setDebug(false);
expect(isDebugEnabled()).toBe(false);
});
});
describe('isDebugEnabled', () => {
it('should return current debug state', () => {
expect(isDebugEnabled()).toBe(false);
setDebug(true);
expect(isDebugEnabled()).toBe(true);
});
});
describe('logDebug', () => {
it('should not log when debug is disabled', () => {
const consoleSpy = vi.spyOn(console, 'log').mockImplementation(() => {});
logDebug('Test', 'This should not appear');
expect(consoleSpy).not.toHaveBeenCalled();
});
it('should log message when debug is enabled', () => {
setDebug(true);
const consoleSpy = vi.spyOn(console, 'log').mockImplementation(() => {});
logDebug('Test', 'This should appear');
expect(consoleSpy).toHaveBeenCalled();
});
it('should log message with data when debug is enabled', () => {
setDebug(true);
const consoleSpy = vi.spyOn(console, 'log').mockImplementation(() => {});
logDebug('Test', 'Message with data', { key: 'value', num: 123 });
expect(consoleSpy).toHaveBeenCalled();
const loggedMessage = consoleSpy.mock.calls[0].join(' ');
expect(loggedMessage).toContain('[LightSDK][Test]');
expect(loggedMessage).toContain('Message with data');
});
it('should include timestamp in log message', () => {
setDebug(true);
const consoleSpy = vi.spyOn(console, 'log').mockImplementation(() => {});
logDebug('Module', 'Test message');
expect(consoleSpy).toHaveBeenCalled();
const loggedMessage = consoleSpy.mock.calls[0][0];
expect(loggedMessage).toMatch(/^\[LightSDK\]\[Module\]/);
});
it('should handle message without data', () => {
setDebug(true);
const consoleSpy = vi.spyOn(console, 'log').mockImplementation(() => {});
logDebug('Module', 'Simple message');
expect(consoleSpy).toHaveBeenCalled();
});
it('should handle undefined data', () => {
setDebug(true);
const consoleSpy = vi.spyOn(console, 'log').mockImplementation(() => {});
logDebug('Module', 'Message', undefined);
expect(consoleSpy).toHaveBeenCalled();
});
it('should handle null data', () => {
setDebug(true);
const consoleSpy = vi.spyOn(console, 'log').mockImplementation(() => {});
logDebug('Module', 'Message', null);
expect(consoleSpy).toHaveBeenCalled();
});
it('should handle complex data objects', () => {
setDebug(true);
const consoleSpy = vi.spyOn(console, 'log').mockImplementation(() => {});
const complexData = {
nested: { deeply: { value: 123 } },
array: [1, 2, 3],
bool: true,
null: null,
};
logDebug('Module', 'Complex data', complexData);
expect(consoleSpy).toHaveBeenCalled();
});
});
describe('logError', () => {
it('should always log errors even when debug is disabled', () => {
setDebug(false);
const consoleSpy = vi.spyOn(console, 'warn').mockImplementation(() => {});
logError('Test', 'This should always appear');
expect(consoleSpy).toHaveBeenCalled();
consoleSpy.mockRestore();
});
it('should log error message when debug is enabled', () => {
setDebug(true);
const consoleSpy = vi.spyOn(console, 'warn').mockImplementation(() => {});
logError('Test', 'This error should appear');
expect(consoleSpy).toHaveBeenCalled();
consoleSpy.mockRestore();
});
it('should include ERROR tag in log message', () => {
const consoleSpy = vi.spyOn(console, 'warn').mockImplementation(() => {});
logError('Module', 'Error message');
expect(consoleSpy).toHaveBeenCalled();
const loggedMessage = consoleSpy.mock.calls[0][0];
expect(loggedMessage).toContain('[LightSDK][Module][ERROR]');
consoleSpy.mockRestore();
});
it('should log error with error data', () => {
const consoleSpy = vi.spyOn(console, 'warn').mockImplementation(() => {});
const error = new Error('Test error');
logError('Module', 'Error occurred', error);
expect(consoleSpy).toHaveBeenCalled();
consoleSpy.mockRestore();
});
it('should handle plain object error', () => {
const consoleSpy = vi.spyOn(console, 'warn').mockImplementation(() => {});
const errorObj = { status: 404, message: 'Not found' };
logError('Module', 'Request failed', errorObj);
expect(consoleSpy).toHaveBeenCalled();
consoleSpy.mockRestore();
});
it('should handle error message without data', () => {
const consoleSpy = vi.spyOn(console, 'warn').mockImplementation(() => {});
logError('Module', 'Simple error');
expect(consoleSpy).toHaveBeenCalled();
consoleSpy.mockRestore();
});
it('should handle string error', () => {
const consoleSpy = vi.spyOn(console, 'warn').mockImplementation(() => {});
logError('Module', 'String error', 'error details');
expect(consoleSpy).toHaveBeenCalled();
consoleSpy.mockRestore();
});
it('should handle undefined error', () => {
const consoleSpy = vi.spyOn(console, 'warn').mockImplementation(() => {});
logError('Module', 'Error without details', undefined);
expect(consoleSpy).toHaveBeenCalled();
consoleSpy.mockRestore();
});
});
describe('debug toggle behavior', () => {
it('should toggle debug logs between enabled and disabled', () => {
const consoleLogSpy = vi.spyOn(console, 'log').mockImplementation(() => {});
const consoleWarnSpy = vi.spyOn(console, 'warn').mockImplementation(() => {});
setDebug(true);
logDebug('Test', 'Debug on');
expect(consoleLogSpy).toHaveBeenCalled();
setDebug(false);
logDebug('Test', 'Debug off');
expect(consoleLogSpy).toHaveBeenCalledTimes(1);
// logError should always work regardless of debug flag
setDebug(true);
logError('Test', 'Error on');
const errorCallCountWhenOn = consoleWarnSpy.mock.calls.length;
expect(errorCallCountWhenOn).toBeGreaterThan(0);
setDebug(false);
logError('Test', 'Error off');
expect(consoleWarnSpy).toHaveBeenCalledTimes(errorCallCountWhenOn + 1);
consoleLogSpy.mockRestore();
consoleWarnSpy.mockRestore();
});
});
});