2024-01-01 21:11:32 +00:00
|
|
|
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
2024-04-29 02:57:30 +00:00
|
|
|
import { assert, assertEquals, assertMatch } from "@std/assert";
|
2024-02-27 21:57:25 +00:00
|
|
|
import { Logger, type LogRecord } from "./logger.ts";
|
|
|
|
import { type LevelName, LogLevels } from "./levels.ts";
|
2024-01-14 21:14:48 +00:00
|
|
|
import { BaseHandler } from "./base_handler.ts";
|
2019-01-27 15:21:00 +00:00
|
|
|
|
|
|
|
class TestHandler extends BaseHandler {
|
2024-06-21 04:13:08 +00:00
|
|
|
messages: string[] = [];
|
|
|
|
records: LogRecord[] = [];
|
2019-01-27 15:21:00 +00:00
|
|
|
|
2022-08-24 01:21:57 +00:00
|
|
|
override handle(record: LogRecord) {
|
2020-04-09 11:45:24 +00:00
|
|
|
this.records.push(record);
|
2019-01-27 15:21:00 +00:00
|
|
|
super.handle(record);
|
|
|
|
}
|
|
|
|
|
2024-06-21 04:13:08 +00:00
|
|
|
override log(str: string) {
|
2019-01-27 15:21:00 +00:00
|
|
|
this.messages.push(str);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-18 10:50:18 +00:00
|
|
|
Deno.test({
|
2024-02-27 20:06:29 +00:00
|
|
|
name: "Logger handles formatter option",
|
2020-06-18 10:50:18 +00:00
|
|
|
fn() {
|
|
|
|
const handlerNoName = new TestHandler("DEBUG");
|
|
|
|
const handlerWithLoggerName = new TestHandler("DEBUG", {
|
2024-01-25 08:03:19 +00:00
|
|
|
formatter: ({ loggerName, levelName, msg }) =>
|
|
|
|
`[${loggerName}] ${levelName} ${msg}`,
|
2020-06-18 10:50:18 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
const logger = new Logger("config", "DEBUG", {
|
|
|
|
handlers: [handlerNoName, handlerWithLoggerName],
|
|
|
|
});
|
|
|
|
logger.debug("hello");
|
|
|
|
assertEquals(handlerNoName.messages[0], "DEBUG hello");
|
|
|
|
assertEquals(handlerWithLoggerName.messages[0], "[config] DEBUG hello");
|
|
|
|
},
|
|
|
|
});
|
|
|
|
|
2024-02-27 20:06:29 +00:00
|
|
|
Deno.test("Logger handles handlers option", () => {
|
2019-01-27 15:21:00 +00:00
|
|
|
const handler = new TestHandler("DEBUG");
|
2020-06-18 10:50:18 +00:00
|
|
|
let logger = new Logger("default", "DEBUG");
|
2019-01-27 15:21:00 +00:00
|
|
|
|
2020-04-25 09:13:26 +00:00
|
|
|
assertEquals(logger.level, LogLevels.DEBUG);
|
2019-03-07 00:42:24 +00:00
|
|
|
assertEquals(logger.levelName, "DEBUG");
|
|
|
|
assertEquals(logger.handlers, []);
|
2019-01-27 15:21:00 +00:00
|
|
|
|
2020-06-18 10:50:18 +00:00
|
|
|
logger = new Logger("default", "DEBUG", { handlers: [handler] });
|
2019-01-27 15:21:00 +00:00
|
|
|
|
2019-03-07 00:42:24 +00:00
|
|
|
assertEquals(logger.handlers, [handler]);
|
2019-01-27 15:21:00 +00:00
|
|
|
});
|
|
|
|
|
2024-02-27 20:06:29 +00:00
|
|
|
Deno.test("Logger handles custom handler", () => {
|
2019-01-27 15:21:00 +00:00
|
|
|
const handler = new TestHandler("DEBUG");
|
2020-06-18 10:50:18 +00:00
|
|
|
const logger = new Logger("default", "DEBUG", { handlers: [handler] });
|
2019-01-27 15:21:00 +00:00
|
|
|
|
2020-06-12 13:27:41 +00:00
|
|
|
const inlineData: string = logger.debug("foo", 1, 2);
|
2019-01-27 15:21:00 +00:00
|
|
|
|
2024-03-14 03:40:50 +00:00
|
|
|
const record = handler.records[0]!;
|
2019-05-30 12:59:30 +00:00
|
|
|
assertEquals(record.msg, "foo");
|
|
|
|
assertEquals(record.args, [1, 2]);
|
2020-04-25 09:13:26 +00:00
|
|
|
assertEquals(record.level, LogLevels.DEBUG);
|
2019-05-30 12:59:30 +00:00
|
|
|
assertEquals(record.levelName, "DEBUG");
|
2019-01-27 15:21:00 +00:00
|
|
|
|
2019-03-07 00:42:24 +00:00
|
|
|
assertEquals(handler.messages, ["DEBUG foo"]);
|
2020-06-12 13:27:41 +00:00
|
|
|
assertEquals(inlineData!, "foo");
|
2019-01-27 15:21:00 +00:00
|
|
|
});
|
|
|
|
|
2024-02-27 20:06:29 +00:00
|
|
|
Deno.test("Logger handles log functions", () => {
|
2020-04-25 09:13:26 +00:00
|
|
|
const doLog = (level: LevelName): TestHandler => {
|
2019-05-30 12:59:30 +00:00
|
|
|
const handler = new TestHandler(level);
|
2020-06-18 10:50:18 +00:00
|
|
|
const logger = new Logger("default", level, { handlers: [handler] });
|
2020-06-12 13:27:41 +00:00
|
|
|
const debugData = logger.debug("foo");
|
|
|
|
const infoData = logger.info("bar");
|
2024-01-11 01:36:15 +00:00
|
|
|
const warnData = logger.warn("baz");
|
2020-06-12 13:27:41 +00:00
|
|
|
const errorData = logger.error("boo");
|
|
|
|
const criticalData = logger.critical("doo");
|
|
|
|
assertEquals(debugData, "foo");
|
|
|
|
assertEquals(infoData, "bar");
|
2024-01-11 01:36:15 +00:00
|
|
|
assertEquals(warnData, "baz");
|
2020-06-12 13:27:41 +00:00
|
|
|
assertEquals(errorData, "boo");
|
|
|
|
assertEquals(criticalData, "doo");
|
2019-05-30 12:59:30 +00:00
|
|
|
return handler;
|
2019-01-27 15:21:00 +00:00
|
|
|
};
|
|
|
|
|
2019-05-30 12:59:30 +00:00
|
|
|
let handler: TestHandler;
|
|
|
|
handler = doLog("DEBUG");
|
2019-01-27 15:21:00 +00:00
|
|
|
|
2019-03-07 00:42:24 +00:00
|
|
|
assertEquals(handler.messages, [
|
2019-01-27 15:21:00 +00:00
|
|
|
"DEBUG foo",
|
|
|
|
"INFO bar",
|
2024-02-02 05:57:14 +00:00
|
|
|
"WARN baz",
|
2019-01-27 15:21:00 +00:00
|
|
|
"ERROR boo",
|
2020-03-28 17:03:49 +00:00
|
|
|
"CRITICAL doo",
|
2019-01-27 15:21:00 +00:00
|
|
|
]);
|
|
|
|
|
2019-05-30 12:59:30 +00:00
|
|
|
handler = doLog("INFO");
|
2019-01-27 15:21:00 +00:00
|
|
|
|
2019-03-07 00:42:24 +00:00
|
|
|
assertEquals(handler.messages, [
|
2019-01-27 15:21:00 +00:00
|
|
|
"INFO bar",
|
2024-02-02 05:57:14 +00:00
|
|
|
"WARN baz",
|
2019-01-27 15:21:00 +00:00
|
|
|
"ERROR boo",
|
2020-03-28 17:03:49 +00:00
|
|
|
"CRITICAL doo",
|
2019-01-27 15:21:00 +00:00
|
|
|
]);
|
|
|
|
|
2024-02-02 05:57:14 +00:00
|
|
|
handler = doLog("WARN");
|
2019-01-27 15:21:00 +00:00
|
|
|
|
2024-02-02 05:57:14 +00:00
|
|
|
assertEquals(handler.messages, ["WARN baz", "ERROR boo", "CRITICAL doo"]);
|
2019-01-27 15:21:00 +00:00
|
|
|
|
2019-05-30 12:59:30 +00:00
|
|
|
handler = doLog("ERROR");
|
2019-01-27 15:21:00 +00:00
|
|
|
|
2019-03-07 00:42:24 +00:00
|
|
|
assertEquals(handler.messages, ["ERROR boo", "CRITICAL doo"]);
|
2019-01-27 15:21:00 +00:00
|
|
|
|
2019-05-30 12:59:30 +00:00
|
|
|
handler = doLog("CRITICAL");
|
2019-01-27 15:21:00 +00:00
|
|
|
|
2019-03-07 00:42:24 +00:00
|
|
|
assertEquals(handler.messages, ["CRITICAL doo"]);
|
2019-01-27 15:21:00 +00:00
|
|
|
});
|
2020-06-12 13:27:41 +00:00
|
|
|
|
2020-06-12 19:23:38 +00:00
|
|
|
Deno.test(
|
2024-02-27 20:06:29 +00:00
|
|
|
"Logger handles function argument without resolution",
|
|
|
|
() => {
|
2020-06-12 19:23:38 +00:00
|
|
|
const handler = new TestHandler("ERROR");
|
2020-06-18 10:50:18 +00:00
|
|
|
const logger = new Logger("default", "ERROR", { handlers: [handler] });
|
2020-06-12 19:23:38 +00:00
|
|
|
let called = false;
|
|
|
|
|
|
|
|
const expensiveFunction = (): string => {
|
|
|
|
called = true;
|
|
|
|
return "expensive function result";
|
|
|
|
};
|
|
|
|
|
|
|
|
const inlineData: string | undefined = logger.debug(
|
|
|
|
expensiveFunction,
|
|
|
|
1,
|
2020-07-14 19:24:17 +00:00
|
|
|
2,
|
2020-06-12 19:23:38 +00:00
|
|
|
);
|
|
|
|
assert(!called);
|
|
|
|
assertEquals(inlineData, undefined);
|
2020-07-14 19:24:17 +00:00
|
|
|
},
|
2020-06-12 19:23:38 +00:00
|
|
|
);
|
2020-06-12 13:27:41 +00:00
|
|
|
|
2024-02-27 20:06:29 +00:00
|
|
|
Deno.test("Logger handles function argument with resolution", () => {
|
2020-06-12 13:27:41 +00:00
|
|
|
const handler = new TestHandler("ERROR");
|
2020-06-18 10:50:18 +00:00
|
|
|
const logger = new Logger("default", "ERROR", { handlers: [handler] });
|
2020-06-12 13:27:41 +00:00
|
|
|
const expensiveFunction = (x: number): string => {
|
|
|
|
return "expensive function result " + x;
|
|
|
|
};
|
|
|
|
|
|
|
|
const firstInlineData = logger.error(() => expensiveFunction(5));
|
|
|
|
const secondInlineData = logger.error(() => expensiveFunction(12), 1, "abc");
|
|
|
|
assertEquals(firstInlineData, "expensive function result 5");
|
|
|
|
assertEquals(secondInlineData, "expensive function result 12");
|
|
|
|
});
|
|
|
|
|
2020-06-12 19:23:38 +00:00
|
|
|
Deno.test(
|
2024-02-27 20:06:29 +00:00
|
|
|
"Logger handles log function return types",
|
|
|
|
() => {
|
2020-06-12 19:23:38 +00:00
|
|
|
const handler = new TestHandler("DEBUG");
|
2020-06-18 10:50:18 +00:00
|
|
|
const logger = new Logger("default", "DEBUG", { handlers: [handler] });
|
2020-06-12 19:23:38 +00:00
|
|
|
const sym = Symbol();
|
|
|
|
const syma = Symbol("a");
|
|
|
|
const fn = (): string => {
|
|
|
|
return "abc";
|
|
|
|
};
|
|
|
|
|
|
|
|
// string
|
|
|
|
const data1: string = logger.debug("abc");
|
|
|
|
assertEquals(data1, "abc");
|
|
|
|
const data2: string = logger.debug("def", 1);
|
|
|
|
assertEquals(data2, "def");
|
|
|
|
assertEquals(handler.messages[0], "DEBUG abc");
|
|
|
|
assertEquals(handler.messages[1], "DEBUG def");
|
|
|
|
|
|
|
|
// null
|
|
|
|
const data3: null = logger.info(null);
|
|
|
|
assertEquals(data3, null);
|
|
|
|
const data4: null = logger.info(null, 1);
|
|
|
|
assertEquals(data4, null);
|
|
|
|
assertEquals(handler.messages[2], "INFO null");
|
|
|
|
assertEquals(handler.messages[3], "INFO null");
|
|
|
|
|
|
|
|
// number
|
2024-01-11 01:36:15 +00:00
|
|
|
const data5: number = logger.warn(3);
|
2020-06-12 19:23:38 +00:00
|
|
|
assertEquals(data5, 3);
|
2024-01-11 01:36:15 +00:00
|
|
|
const data6: number = logger.warn(3, 1);
|
2020-06-12 19:23:38 +00:00
|
|
|
assertEquals(data6, 3);
|
2024-02-02 05:57:14 +00:00
|
|
|
assertEquals(handler.messages[4], "WARN 3");
|
|
|
|
assertEquals(handler.messages[5], "WARN 3");
|
2020-06-12 19:23:38 +00:00
|
|
|
|
|
|
|
// bigint
|
|
|
|
const data7: bigint = logger.error(5n);
|
|
|
|
assertEquals(data7, 5n);
|
|
|
|
const data8: bigint = logger.error(5n, 1);
|
|
|
|
assertEquals(data8, 5n);
|
|
|
|
assertEquals(handler.messages[6], "ERROR 5");
|
|
|
|
assertEquals(handler.messages[7], "ERROR 5");
|
|
|
|
|
|
|
|
// boolean
|
|
|
|
const data9: boolean = logger.critical(true);
|
|
|
|
assertEquals(data9, true);
|
|
|
|
const data10: boolean = logger.critical(false, 1);
|
|
|
|
assertEquals(data10, false);
|
|
|
|
assertEquals(handler.messages[8], "CRITICAL true");
|
|
|
|
assertEquals(handler.messages[9], "CRITICAL false");
|
|
|
|
|
|
|
|
// undefined
|
|
|
|
const data11: undefined = logger.debug(undefined);
|
|
|
|
assertEquals(data11, undefined);
|
|
|
|
const data12: undefined = logger.debug(undefined, 1);
|
|
|
|
assertEquals(data12, undefined);
|
|
|
|
assertEquals(handler.messages[10], "DEBUG undefined");
|
|
|
|
assertEquals(handler.messages[11], "DEBUG undefined");
|
|
|
|
|
|
|
|
// symbol
|
|
|
|
const data13: symbol = logger.info(sym);
|
|
|
|
assertEquals(data13, sym);
|
|
|
|
const data14: symbol = logger.info(syma, 1);
|
|
|
|
assertEquals(data14, syma);
|
|
|
|
assertEquals(handler.messages[12], "INFO Symbol()");
|
|
|
|
assertEquals(handler.messages[13], "INFO Symbol(a)");
|
|
|
|
|
|
|
|
// function
|
2024-01-11 01:36:15 +00:00
|
|
|
const data15: string | undefined = logger.warn(fn);
|
2020-06-12 19:23:38 +00:00
|
|
|
assertEquals(data15, "abc");
|
2024-01-11 01:36:15 +00:00
|
|
|
const data16: string | undefined = logger.warn(fn, 1);
|
2020-06-12 19:23:38 +00:00
|
|
|
assertEquals(data16, "abc");
|
2024-02-02 05:57:14 +00:00
|
|
|
assertEquals(handler.messages[14], "WARN abc");
|
|
|
|
assertEquals(handler.messages[15], "WARN abc");
|
2020-06-12 19:23:38 +00:00
|
|
|
|
|
|
|
// object
|
|
|
|
const data17: { payload: string; other: number } = logger.error({
|
|
|
|
payload: "data",
|
|
|
|
other: 123,
|
|
|
|
});
|
|
|
|
assertEquals(data17, {
|
|
|
|
payload: "data",
|
|
|
|
other: 123,
|
|
|
|
});
|
|
|
|
const data18: { payload: string; other: number } = logger.error(
|
|
|
|
{ payload: "data", other: 123 },
|
2020-07-14 19:24:17 +00:00
|
|
|
1,
|
2020-06-12 19:23:38 +00:00
|
|
|
);
|
|
|
|
assertEquals(data18, {
|
|
|
|
payload: "data",
|
|
|
|
other: 123,
|
|
|
|
});
|
2023-08-21 04:26:58 +00:00
|
|
|
const data19: { payload: string; other: bigint } = logger.error({
|
|
|
|
payload: "data",
|
|
|
|
other: 123n,
|
|
|
|
});
|
|
|
|
assertEquals(data19, {
|
|
|
|
payload: "data",
|
|
|
|
other: 123n,
|
|
|
|
});
|
|
|
|
const data20: { payload: string; other: bigint } = logger.error(
|
|
|
|
{ payload: "data", other: 123n },
|
|
|
|
1,
|
|
|
|
);
|
|
|
|
assertEquals(data20, {
|
|
|
|
payload: "data",
|
|
|
|
other: 123n,
|
|
|
|
});
|
2020-06-12 19:23:38 +00:00
|
|
|
assertEquals(handler.messages[16], 'ERROR {"payload":"data","other":123}');
|
|
|
|
assertEquals(handler.messages[17], 'ERROR {"payload":"data","other":123}');
|
2023-08-21 04:26:58 +00:00
|
|
|
assertEquals(handler.messages[18], 'ERROR {"payload":"data","other":123}');
|
|
|
|
assertEquals(handler.messages[19], 'ERROR {"payload":"data","other":123}');
|
2020-11-19 11:58:53 +00:00
|
|
|
|
|
|
|
// error
|
|
|
|
const error = new RangeError("Uh-oh!");
|
2023-08-21 04:26:58 +00:00
|
|
|
const data21: RangeError = logger.error(error);
|
|
|
|
assertEquals(data21, error);
|
2024-03-14 03:40:50 +00:00
|
|
|
const messages21 = handler.messages[20]!.split("\n");
|
|
|
|
assertEquals(messages21[0]!, `ERROR ${error.name}: ${error.message}`);
|
|
|
|
assertMatch(messages21[1]!, /^\s+at file:.*\d+:\d+$/);
|
2020-07-14 19:24:17 +00:00
|
|
|
},
|
2020-06-12 19:23:38 +00:00
|
|
|
);
|