Files
insta-recipe/src/tests/logger.spec.ts
Giancarmine Salucci 67ab3c02d7 chore(RECIPE-0004): complete iteration 1 — fix TypeScript Timer type errors
- Fixed NodeJS.Timer → NodeJS.Timeout in scheduler.ts line 13
- Fixed NodeJS.Timer[] → NodeJS.Timeout[] in fixtures.ts line 151
- Resolves TypeScript compile errors from iteration 0 review
- All 260 tests passing, build succeeds with no errors
2026-02-17 03:08:21 +01:00

159 lines
4.2 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]')
);
});
});
});