156 lines
3.7 KiB
TypeScript
156 lines
3.7 KiB
TypeScript
import { describe, test, expect, vi, beforeEach, afterEach } from 'vitest';
|
|
import { serializeError, serializeObject, logError, logObject } from '$lib/server/utils/logger';
|
|
|
|
describe('logger utilities', () => {
|
|
describe('serializeError', () => {
|
|
test('handles Error objects', () => {
|
|
const error = new Error('Test error message');
|
|
const result = serializeError(error);
|
|
|
|
expect(result).toContain('Test error message');
|
|
expect(result).toContain('"name": "Error"');
|
|
expect(result).toContain('"message"');
|
|
});
|
|
|
|
test('handles plain objects', () => {
|
|
const obj = { code: 404, message: 'Not found' };
|
|
const result = serializeError(obj);
|
|
|
|
expect(result).toContain('"code": 404');
|
|
expect(result).toContain('"message": "Not found"');
|
|
});
|
|
|
|
test('includes stack trace for Error objects', () => {
|
|
const error = new Error('Stack test');
|
|
const result = serializeError(error);
|
|
|
|
expect(result).toContain('"stack"');
|
|
});
|
|
|
|
test('handles Error with custom properties', () => {
|
|
const error = new Error('Custom error') as any;
|
|
error.statusCode = 500;
|
|
error.details = { info: 'extra data' };
|
|
const result = serializeError(error);
|
|
|
|
expect(result).toContain('"statusCode": 500');
|
|
expect(result).toContain('extra data');
|
|
});
|
|
});
|
|
|
|
describe('serializeObject', () => {
|
|
test('handles circular references', () => {
|
|
const obj: any = { a: 1, b: 2 };
|
|
obj.self = obj;
|
|
|
|
const result = serializeObject(obj);
|
|
expect(result).toContain('[Circular]');
|
|
expect(result).toContain('"a": 1');
|
|
});
|
|
|
|
test('handles deeply nested objects', () => {
|
|
const obj = {
|
|
level1: {
|
|
level2: {
|
|
level3: {
|
|
value: 'deep'
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
const result = serializeObject(obj);
|
|
expect(result).toContain('"value": "deep"');
|
|
});
|
|
|
|
test('handles arrays', () => {
|
|
const obj = { items: [1, 2, 3] };
|
|
const result = serializeObject(obj);
|
|
|
|
expect(result).toContain('"items"');
|
|
expect(result).toContain('[');
|
|
});
|
|
|
|
test('handles null and undefined', () => {
|
|
const obj = { a: null, b: undefined };
|
|
const result = serializeObject(obj);
|
|
|
|
expect(result).toContain('"a": null');
|
|
});
|
|
});
|
|
|
|
describe('logError', () => {
|
|
let consoleErrorSpy: any;
|
|
|
|
beforeEach(() => {
|
|
consoleErrorSpy = vi.spyOn(console, 'error').mockImplementation(() => {});
|
|
});
|
|
|
|
afterEach(() => {
|
|
consoleErrorSpy.mockRestore();
|
|
});
|
|
|
|
test('outputs to console.error', () => {
|
|
const error = new Error('Test');
|
|
|
|
logError('[Test]', error);
|
|
|
|
expect(consoleErrorSpy).toHaveBeenCalledWith('[Test]', 'Test');
|
|
});
|
|
|
|
test('logs stack trace for Error objects', () => {
|
|
const error = new Error('Stack error');
|
|
|
|
logError('[Test]', error);
|
|
|
|
expect(consoleErrorSpy).toHaveBeenCalledWith(
|
|
expect.stringMatching(/Stack/),
|
|
expect.any(String)
|
|
);
|
|
});
|
|
|
|
test('handles non-Error objects', () => {
|
|
const obj = { code: 500, message: 'Server error' };
|
|
|
|
logError('[Test]', obj);
|
|
|
|
expect(consoleErrorSpy).toHaveBeenCalledWith(
|
|
'[Test]',
|
|
expect.stringContaining('"code": 500')
|
|
);
|
|
});
|
|
});
|
|
|
|
describe('logObject', () => {
|
|
let consoleLogSpy: any;
|
|
|
|
beforeEach(() => {
|
|
consoleLogSpy = vi.spyOn(console, 'log').mockImplementation(() => {});
|
|
});
|
|
|
|
afterEach(() => {
|
|
consoleLogSpy.mockRestore();
|
|
});
|
|
|
|
test('outputs to console.log', () => {
|
|
const obj = { key: 'value' };
|
|
|
|
logObject('[Test]', obj);
|
|
|
|
expect(consoleLogSpy).toHaveBeenCalledWith(
|
|
'[Test]',
|
|
expect.stringContaining('"key": "value"')
|
|
);
|
|
});
|
|
|
|
test('handles circular references', () => {
|
|
const obj: any = { a: 1 };
|
|
obj.self = obj;
|
|
|
|
logObject('[Test]', obj);
|
|
|
|
expect(consoleLogSpy).toHaveBeenCalledWith('[Test]', expect.stringContaining('[Circular]'));
|
|
});
|
|
});
|
|
});
|