Files
automaker/libs/utils/tests/logger.test.ts
Kacper 30f4315c17 test: Add comprehensive tests for platform and utils packages
Added extensive test coverage for previously untested files:

Platform package (94.69% coverage, +47 tests):
- paths.test.ts: 22 tests for path construction and directory creation
- security.test.ts: 25 tests for path validation and security

Utils package (94.3% coverage, +109 tests):
- logger.test.ts: 23 tests for logging with levels
- fs-utils.test.ts: 20 tests for safe file operations
- conversation-utils.test.ts: 24 tests for message formatting
- image-handler.test.ts: 25 tests for image processing
- prompt-builder.test.ts: 17 tests for prompt construction

Coverage improvements:
- Platform: 63.71% → 94.69% stmts, 40% → 97.14% funcs
- Utils: 19.51% → 94.3% stmts, 18.51% → 100% funcs

Updated thresholds to enforce high quality:
- Platform: 90% lines/stmts, 95% funcs, 75% branches
- Utils: 90% lines/stmts, 95% funcs, 85% branches

Total new tests: 156 (platform: 47, utils: 109)
All tests passing with new coverage thresholds.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-20 23:35:31 +01:00

324 lines
8.6 KiB
TypeScript

import { describe, it, expect, beforeEach, afterEach, vi } from "vitest";
import {
createLogger,
LogLevel,
getLogLevel,
setLogLevel,
} from "../src/logger";
describe("logger.ts", () => {
let originalConsoleError: typeof console.error;
let originalConsoleWarn: typeof console.warn;
let originalConsoleLog: typeof console.log;
let originalLogLevel: LogLevel;
beforeEach(() => {
// Save original console methods and log level
originalConsoleError = console.error;
originalConsoleWarn = console.warn;
originalConsoleLog = console.log;
originalLogLevel = getLogLevel();
// Mock console methods
console.error = vi.fn();
console.warn = vi.fn();
console.log = vi.fn();
});
afterEach(() => {
// Restore original console methods and log level
console.error = originalConsoleError;
console.warn = originalConsoleWarn;
console.log = originalConsoleLog;
setLogLevel(originalLogLevel);
});
describe("createLogger", () => {
it("should create logger with context prefix", () => {
const logger = createLogger("TestContext");
setLogLevel(LogLevel.INFO);
logger.info("test message");
expect(console.log).toHaveBeenCalledWith(
"[TestContext]",
"test message"
);
});
it("should handle multiple arguments", () => {
const logger = createLogger("Test");
setLogLevel(LogLevel.INFO);
logger.info("message", { data: 123 }, [1, 2, 3]);
expect(console.log).toHaveBeenCalledWith(
"[Test]",
"message",
{ data: 123 },
[1, 2, 3]
);
});
});
describe("Log levels", () => {
it("should log error at ERROR level", () => {
const logger = createLogger("Test");
setLogLevel(LogLevel.ERROR);
logger.error("error message");
logger.warn("warn message");
logger.info("info message");
logger.debug("debug message");
expect(console.error).toHaveBeenCalledTimes(1);
expect(console.warn).not.toHaveBeenCalled();
expect(console.log).not.toHaveBeenCalled();
});
it("should log error and warn at WARN level", () => {
const logger = createLogger("Test");
setLogLevel(LogLevel.WARN);
logger.error("error message");
logger.warn("warn message");
logger.info("info message");
logger.debug("debug message");
expect(console.error).toHaveBeenCalledTimes(1);
expect(console.warn).toHaveBeenCalledTimes(1);
expect(console.log).not.toHaveBeenCalled();
});
it("should log error, warn, and info at INFO level", () => {
const logger = createLogger("Test");
setLogLevel(LogLevel.INFO);
logger.error("error message");
logger.warn("warn message");
logger.info("info message");
logger.debug("debug message");
expect(console.error).toHaveBeenCalledTimes(1);
expect(console.warn).toHaveBeenCalledTimes(1);
expect(console.log).toHaveBeenCalledTimes(1); // Only info, not debug
});
it("should log all messages at DEBUG level", () => {
const logger = createLogger("Test");
setLogLevel(LogLevel.DEBUG);
logger.error("error message");
logger.warn("warn message");
logger.info("info message");
logger.debug("debug message");
expect(console.error).toHaveBeenCalledTimes(1);
expect(console.warn).toHaveBeenCalledTimes(1);
expect(console.log).toHaveBeenCalledTimes(2); // info + debug
});
});
describe("error method", () => {
it("should use console.error", () => {
const logger = createLogger("ErrorTest");
setLogLevel(LogLevel.ERROR);
logger.error("error occurred", { code: 500 });
expect(console.error).toHaveBeenCalledWith(
"[ErrorTest]",
"error occurred",
{ code: 500 }
);
});
it("should not log when level is below ERROR", () => {
const logger = createLogger("Test");
setLogLevel(LogLevel.ERROR - 1 as LogLevel);
logger.error("should not appear");
expect(console.error).not.toHaveBeenCalled();
});
});
describe("warn method", () => {
it("should use console.warn", () => {
const logger = createLogger("WarnTest");
setLogLevel(LogLevel.WARN);
logger.warn("warning message");
expect(console.warn).toHaveBeenCalledWith("[WarnTest]", "warning message");
});
it("should not log when level is below WARN", () => {
const logger = createLogger("Test");
setLogLevel(LogLevel.ERROR);
logger.warn("should not appear");
expect(console.warn).not.toHaveBeenCalled();
});
});
describe("info method", () => {
it("should use console.log", () => {
const logger = createLogger("InfoTest");
setLogLevel(LogLevel.INFO);
logger.info("info message");
expect(console.log).toHaveBeenCalledWith("[InfoTest]", "info message");
});
it("should not log when level is below INFO", () => {
const logger = createLogger("Test");
setLogLevel(LogLevel.WARN);
logger.info("should not appear");
expect(console.log).not.toHaveBeenCalled();
});
});
describe("debug method", () => {
it("should use console.log with DEBUG prefix", () => {
const logger = createLogger("DebugTest");
setLogLevel(LogLevel.DEBUG);
logger.debug("debug details", { trace: "..." });
expect(console.log).toHaveBeenCalledWith(
"[DebugTest]",
"[DEBUG]",
"debug details",
{ trace: "..." }
);
});
it("should not log when level is below DEBUG", () => {
const logger = createLogger("Test");
setLogLevel(LogLevel.INFO);
logger.debug("should not appear");
expect(console.log).not.toHaveBeenCalled();
});
});
describe("getLogLevel", () => {
it("should return current log level", () => {
setLogLevel(LogLevel.DEBUG);
expect(getLogLevel()).toBe(LogLevel.DEBUG);
setLogLevel(LogLevel.ERROR);
expect(getLogLevel()).toBe(LogLevel.ERROR);
});
});
describe("setLogLevel", () => {
it("should change log level", () => {
setLogLevel(LogLevel.WARN);
expect(getLogLevel()).toBe(LogLevel.WARN);
setLogLevel(LogLevel.DEBUG);
expect(getLogLevel()).toBe(LogLevel.DEBUG);
});
it("should affect subsequent logging", () => {
const logger = createLogger("Test");
setLogLevel(LogLevel.ERROR);
logger.info("should not log");
expect(console.log).not.toHaveBeenCalled();
setLogLevel(LogLevel.INFO);
logger.info("should log");
expect(console.log).toHaveBeenCalledWith("[Test]", "should log");
});
});
describe("Multiple logger instances", () => {
it("should maintain separate contexts", () => {
const logger1 = createLogger("Service1");
const logger2 = createLogger("Service2");
setLogLevel(LogLevel.INFO);
logger1.info("from service 1");
logger2.info("from service 2");
expect(console.log).toHaveBeenNthCalledWith(
1,
"[Service1]",
"from service 1"
);
expect(console.log).toHaveBeenNthCalledWith(
2,
"[Service2]",
"from service 2"
);
});
it("should share log level setting", () => {
const logger1 = createLogger("Service1");
const logger2 = createLogger("Service2");
setLogLevel(LogLevel.ERROR);
logger1.info("should not log");
logger2.info("should not log");
expect(console.log).not.toHaveBeenCalled();
});
});
describe("Edge cases", () => {
it("should handle empty context string", () => {
const logger = createLogger("");
setLogLevel(LogLevel.INFO);
logger.info("message");
expect(console.log).toHaveBeenCalledWith("[]", "message");
});
it("should handle context with special characters", () => {
const logger = createLogger("Test-Service_v2.0");
setLogLevel(LogLevel.INFO);
logger.info("message");
expect(console.log).toHaveBeenCalledWith(
"[Test-Service_v2.0]",
"message"
);
});
it("should handle no arguments to log methods", () => {
const logger = createLogger("Test");
setLogLevel(LogLevel.INFO);
logger.info();
expect(console.log).toHaveBeenCalledWith("[Test]");
});
it("should handle complex object arguments", () => {
const logger = createLogger("Test");
setLogLevel(LogLevel.INFO);
const complexObj = {
nested: { deep: { value: 123 } },
array: [1, 2, 3],
fn: () => {},
};
logger.info("complex", complexObj);
expect(console.log).toHaveBeenCalledWith("[Test]", "complex", complexObj);
});
});
});