Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
119 changes: 119 additions & 0 deletions lib/logger.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
// deno-lint-ignore-file no-import-prefix

import { assertEquals } from "jsr:@std/assert@^1.0.0";
import { getOcvLogger, initLogger } from "./logger.ts";

Deno.test("getOcvLogger throws before initLogger is called", () => {
assertEquals(
typeof getOcvLogger,
"function",
"getOcvLogger should be an exported function",
);

// getOcvLogger() uses rootLogger which is null before init
// It throws an Error with a specific message
try {
getOcvLogger();
assertEquals(true, false, "Expected getOcvLogger() to throw");
} catch (e) {
assertEquals(
e instanceof Error,
true,
"Expected an Error to be thrown",
);
assertEquals(
(e as Error).message,
"Logger not initialized. Call initLogger() first.",
);
}
});

Deno.test({
name: "suppresses LogTape meta logger info message",
async fn() {
const tempDir = await Deno.makeTempDir({ prefix: "ocv-test-" });

// Capture stdout by replacing Deno.stdout's writable stream.
// LogTape's getConsoleSink() writes to Deno.stdout.writable.
const captured: Uint8Array[] = [];
const originalStdout = Deno.stdout;

const capturingWritable = new WritableStream<Uint8Array>({
write(chunk) {
captured.push(chunk);
},
});

Object.defineProperty(Deno, "stdout", {
value: { writable: capturingWritable },
configurable: true,
writable: true,
});

try {
await initLogger(tempDir);

// Decode all captured chunks into a single string
const output = captured.map((c) => new TextDecoder().decode(c)).join("");
const lower = output.toLowerCase();

assertEquals(
lower.includes("meta"),
false,
"Expected no meta logger info message in stdout — category ['logtape', 'meta'] set to lowestLevel 'warning' with no sinks",
);
} finally {
// Restore original stdout
Object.defineProperty(Deno, "stdout", {
value: originalStdout,
configurable: true,
writable: true,
});

// Clean up temp directory
try {
await Deno.remove(tempDir, { recursive: true });
} catch {
// Ignore cleanup errors — leaked temp dirs are acceptable in test failure
}
}
},
});

Deno.test("getOcvLogger returns a Logger after initLogger", async () => {
const tempDir = await Deno.makeTempDir({ prefix: "ocv-test-" });

try {
await initLogger(tempDir);
const logger = getOcvLogger();

// Logger should have the standard LogTape methods
assertEquals(typeof logger, "object", "Logger should be an object");
assertEquals(
typeof logger.info,
"function",
"Logger.info should be a function",
);
assertEquals(
typeof logger.warn,
"function",
"Logger.warn should be a function",
);
assertEquals(
typeof logger.error,
"function",
"Logger.error should be a function",
);
assertEquals(
typeof logger.debug,
"function",
"Logger.debug should be a function",
);
} finally {
try {
await Deno.remove(tempDir, { recursive: true });
} catch {
// Ignore cleanup errors
}
}
});
1 change: 1 addition & 0 deletions lib/logger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ export async function initLogger(logDir?: string): Promise<Logger> {
}),
},
loggers: [
{ category: ["logtape", "meta"], lowestLevel: "warning", sinks: [] },
{ category: ["ocv"], lowestLevel: "info", sinks: ["console", "file"] },
{
category: ["ocv", "mcp"],
Expand Down
2 changes: 1 addition & 1 deletion version.ts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export const VERSION = '1.6.0';
export const VERSION = "1.6.0";