Spaces:
Running
Running
File size: 3,971 Bytes
d0ded63 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 | import { logger, createAsyncMetricsTracker } from './logger';
describe('Logger', () => {
const mockConsoleLog = jest.spyOn(console, 'log').mockImplementation();
const mockConsoleError = jest.spyOn(console, 'error').mockImplementation();
const mockConsoleWarn = jest.spyOn(console, 'warn').mockImplementation();
beforeEach(() => {
mockConsoleLog.mockClear();
mockConsoleError.mockClear();
mockConsoleWarn.mockClear();
});
afterAll(() => {
mockConsoleLog.mockRestore();
mockConsoleError.mockRestore();
mockConsoleWarn.mockRestore();
});
describe('log methods', () => {
it('should log error messages to console.error', () => {
logger.error('test-component', 'test error message');
expect(mockConsoleError).toHaveBeenCalledWith(
'[test-component] test error message',
);
});
it('should log warning messages to console.warn', () => {
logger.warn('test-component', 'test warning');
expect(mockConsoleWarn).toHaveBeenCalledWith(
'[test-component] test warning',
);
});
it('should include metadata in logs', () => {
const metadata = { userId: '123', action: 'create' };
logger.error('auth', 'unauthorized access', undefined, metadata);
expect(mockConsoleError).toHaveBeenCalledWith(
'[auth] unauthorized access',
{ userId: '123', action: 'create' },
);
});
it('should log error with Error object and extract message/stack', () => {
const error = new Error('test error');
logger.error('api', 'request failed', error);
expect(mockConsoleError).toHaveBeenCalled();
const callArgs = mockConsoleError.mock.calls[0];
expect(callArgs[0]).toContain('[api]');
expect(callArgs[1]).toHaveProperty('errorMessage', 'test error');
expect(callArgs[1]).toHaveProperty('errorStack');
});
});
describe('measureAsync', () => {
it('should measure async operation duration and return result', async () => {
const result = await logger.measureAsync('test', 'operation', async () => {
return 'success';
});
expect(result).toBe('success');
});
it('should measure async operation duration and log failure', async () => {
const testError = new Error('async failure');
await expect(
logger.measureAsync('test', 'operation', async () => {
throw testError;
}),
).rejects.toThrow('async failure');
expect(mockConsoleError).toHaveBeenCalled();
const callArgs = mockConsoleError.mock.calls[0];
expect(callArgs[0]).toContain('[test]');
expect(callArgs[0]).toContain('operation failed');
});
});
describe('measureSync', () => {
it('should measure sync operation duration and return result', () => {
const result = logger.measureSync('test', 'operation', () => {
return 'success';
});
expect(result).toBe('success');
});
it('should measure sync operation duration and log failure', () => {
expect(() => {
logger.measureSync('test', 'operation', () => {
throw new Error('sync failure');
});
}).toThrow('sync failure');
expect(mockConsoleError).toHaveBeenCalled();
});
});
describe('createAsyncMetricsTracker', () => {
it('should track successful async operation', () => {
const tracker = createAsyncMetricsTracker('api', 'fetch');
tracker.success({ statusCode: 200 });
// Logger call succeeds without console verification
});
it('should track failed async operation', () => {
const tracker = createAsyncMetricsTracker('api', 'fetch');
const error = new Error('network error');
tracker.error(error, { attempt: 1 });
expect(mockConsoleError).toHaveBeenCalled();
const callArgs = mockConsoleError.mock.calls[0];
expect(callArgs[0]).toContain('[api]');
expect(callArgs[0]).toContain('fetch failed');
});
});
});
|