log: add tests (#136)

This commit is contained in:
James Garbutt 2019-01-27 15:21:00 +00:00 committed by Ryan Dahl
parent b792fe8c72
commit 4b054d69ad
5 changed files with 289 additions and 64 deletions

95
log/handlers_test.ts Normal file
View File

@ -0,0 +1,95 @@
import { assertEqual, test } from "../testing/mod.ts";
import { LogRecord, Logger } from "./logger.ts";
import { LogLevel, getLevelName, getLevelByName } from "./levels.ts";
import { BaseHandler } from "./handlers.ts";
class TestHandler extends BaseHandler {
public messages: string[] = [];
public log(str: string): void {
this.messages.push(str);
}
}
test(function simpleHandler() {
const cases = new Map<number, string[]>([
[LogLevel.DEBUG, [
"DEBUG debug-test",
"INFO info-test",
"WARNING warning-test",
"ERROR error-test",
"CRITICAL critical-test"
]],
[LogLevel.INFO, [
"INFO info-test",
"WARNING warning-test",
"ERROR error-test",
"CRITICAL critical-test"
]],
[LogLevel.WARNING, [
"WARNING warning-test",
"ERROR error-test",
"CRITICAL critical-test"
]],
[LogLevel.ERROR, [
"ERROR error-test",
"CRITICAL critical-test"
]],
[LogLevel.CRITICAL, [
"CRITICAL critical-test"
]]
]);
for (const [testCase, messages] of cases.entries()) {
const testLevel = getLevelName(testCase);
const handler = new TestHandler(testLevel);
for (const levelName in LogLevel) {
const level = getLevelByName(levelName);
handler.handle({
msg: `${levelName.toLowerCase()}-test`,
args: [],
datetime: new Date(),
level: level,
levelName: levelName
});
}
assertEqual(handler.level, testCase);
assertEqual(handler.levelName, testLevel);
assertEqual(handler.messages, messages);
}
});
test(function testFormatterAsString() {
const handler = new TestHandler("DEBUG", {
formatter: "test {levelName} {msg}"
});
handler.handle({
msg: "Hello, world!",
args: [],
datetime: new Date(),
level: LogLevel.DEBUG,
levelName: "DEBUG"
});
assertEqual(handler.messages, ["test DEBUG Hello, world!"]);
});
test(function testFormatterAsFunction() {
const handler = new TestHandler("DEBUG", {
formatter: logRecord =>
`fn formmatter ${logRecord.levelName} ${logRecord.msg}`
});
handler.handle({
msg: "Hello, world!",
args: [],
datetime: new Date(),
level: LogLevel.ERROR,
levelName: "ERROR"
});
assertEqual(handler.messages, ["fn formmatter ERROR Hello, world!"]);
});

104
log/logger_test.ts Normal file
View File

@ -0,0 +1,104 @@
import { assertEqual, test } from "../testing/mod.ts";
import { LogRecord, Logger } from "./logger.ts";
import { LogLevel } from "./levels.ts";
import { BaseHandler } from "./handlers.ts";
class TestHandler extends BaseHandler {
public messages: string[] = [];
public records: LogRecord[] = [];
handle(record: LogRecord): void {
this.records.push({...record, datetime: null });
super.handle(record);
}
public log(str: string): void {
this.messages.push(str);
}
}
test(function simpleLogger() {
const handler = new TestHandler("DEBUG");
let logger = new Logger("DEBUG");
assertEqual(logger.level, LogLevel.DEBUG);
assertEqual(logger.levelName, "DEBUG");
assertEqual(logger.handlers, []);
logger = new Logger("DEBUG", [handler]);
assertEqual(logger.handlers, [handler]);
});
test(function customHandler() {
const handler = new TestHandler("DEBUG");
const logger = new Logger("DEBUG", [handler]);
logger.debug("foo", 1, 2);
assertEqual(handler.records, [
{
msg: "foo",
args: [1, 2],
datetime: null,
level: LogLevel.DEBUG,
levelName: "DEBUG"
}
]);
assertEqual(handler.messages, ["DEBUG foo"]);
});
test(function logFunctions() {
let handler: TestHandler;
const doLog = (level: string) => {
handler = new TestHandler(level);
let logger = new Logger(level, [handler]);
logger.debug("foo");
logger.info("bar");
logger.warning("baz");
logger.error("boo");
logger.critical("doo");
};
doLog("DEBUG");
assertEqual(handler.messages, [
"DEBUG foo",
"INFO bar",
"WARNING baz",
"ERROR boo",
"CRITICAL doo"
]);
doLog("INFO");
assertEqual(handler.messages, [
"INFO bar",
"WARNING baz",
"ERROR boo",
"CRITICAL doo"
]);
doLog("WARNING");
assertEqual(handler.messages, [
"WARNING baz",
"ERROR boo",
"CRITICAL doo"
]);
doLog("ERROR");
assertEqual(handler.messages, [
"ERROR boo",
"CRITICAL doo"
]);
doLog("CRITICAL");
assertEqual(handler.messages, [
"CRITICAL doo"
]);
});

View File

@ -21,24 +21,20 @@ export interface LogConfig {
}
const DEFAULT_LEVEL = "INFO";
const DEFAULT_NAME = "";
const DEFAULT_CONFIG: LogConfig = {
handlers: {},
handlers: {
"default": new ConsoleHandler(DEFAULT_LEVEL)
},
loggers: {
"": {
level: "INFO",
handlers: [""]
"default": {
level: DEFAULT_LEVEL,
handlers: ["default"]
}
}
};
const defaultHandler = new ConsoleHandler("INFO");
const defaultLogger = new Logger("INFO", [defaultHandler]);
const state = {
defaultHandler,
defaultLogger,
handlers: new Map(),
loggers: new Map(),
config: DEFAULT_CONFIG
@ -52,19 +48,19 @@ export const handlers = {
};
export const debug = (msg: string, ...args: any[]) =>
defaultLogger.debug(msg, ...args);
getLogger('default').debug(msg, ...args);
export const info = (msg: string, ...args: any[]) =>
defaultLogger.info(msg, ...args);
getLogger('default').info(msg, ...args);
export const warning = (msg: string, ...args: any[]) =>
defaultLogger.warning(msg, ...args);
getLogger('default').warning(msg, ...args);
export const error = (msg: string, ...args: any[]) =>
defaultLogger.error(msg, ...args);
getLogger('default').error(msg, ...args);
export const critical = (msg: string, ...args: any[]) =>
defaultLogger.critical(msg, ...args);
getLogger('default').critical(msg, ...args);
export function getLogger(name?: string) {
if (!name) {
return defaultLogger;
return state.loggers.get('default');
}
if (!state.loggers.has(name)) {
@ -81,7 +77,10 @@ export function getHandler(name: string) {
}
export async function setup(config: LogConfig) {
state.config = config;
state.config = {
handlers: {...DEFAULT_CONFIG.handlers, ...config.handlers},
loggers: {...DEFAULT_CONFIG.loggers, ...config.loggers}
};
// tear down existing handlers
state.handlers.forEach(handler => {

View File

@ -1,7 +1,8 @@
import { remove, open, readAll } from "deno";
import { assertEqual, test } from "../testing/mod.ts";
import * as log from "./mod.ts";
import { FileHandler } from "./handlers.ts";
import { BaseHandler } from "./handlers.ts";
import { LogRecord } from "./logger.ts";
import { LogLevel } from "./levels.ts";
// constructor(levelName: string, options: HandlerOptions = {}) {
// this.level = getLevelByName(levelName);
@ -11,85 +12,109 @@ import { FileHandler } from "./handlers.ts";
// }
class TestHandler extends log.handlers.BaseHandler {
testOutput = "";
public messages: string[] = [];
log(msg: string) {
this.testOutput += `${msg}\n`;
this.messages.push(msg);
}
}
test(function testDefaultlogMethods() {
log.debug("Foobar");
log.info("Foobar");
log.warning("Foobar");
log.error("Foobar");
log.critical("Foobar");
test(async function defaultHandlers() {
const loggers = {
DEBUG: log.debug,
INFO: log.info,
WARNING: log.warning,
ERROR: log.error,
CRITICAL: log.critical
};
const logger = log.getLogger("");
console.log(logger);
for (const levelName in LogLevel) {
if (levelName === "NOTSET") {
continue;
}
const level = LogLevel[levelName];
const logger = loggers[levelName];
const handler = new TestHandler(level);
await log.setup({
handlers: {
default: handler
},
loggers: {
default: {
level: levelName,
handlers: ["default"]
}
}
});
logger("foo");
logger("bar", 1, 2);
assertEqual(handler.messages, [
`${levelName} foo`,
`${levelName} bar`
]);
}
});
test(async function testDefaultFormatter() {
test(async function getLogger() {
const handler = new TestHandler("DEBUG");
await log.setup({
handlers: {
test: new TestHandler("DEBUG")
default: handler
},
loggers: {
test: {
default: {
level: "DEBUG",
handlers: ["test"]
handlers: ["default"]
}
}
});
const logger = log.getLogger("test");
const handler = log.getHandler("test");
logger.debug("Hello, world!");
assertEqual(handler.testOutput, "DEBUG Hello, world!\n");
const logger = log.getLogger();
assertEqual(logger.levelName, "DEBUG");
assertEqual(logger.handlers, [
handler
]);
});
test(async function testFormatterAsString() {
test(async function getLoggerWithName() {
const fooHandler = new TestHandler("DEBUG");
await log.setup({
handlers: {
test: new TestHandler("DEBUG", {
formatter: "test {levelName} {msg}"
})
foo: fooHandler
},
loggers: {
test: {
level: "DEBUG",
handlers: ["test"]
bar: {
level: "INFO",
handlers: ["foo"]
}
}
});
const logger = log.getLogger("test");
const handler = log.getHandler("test");
logger.debug("Hello, world!");
assertEqual(handler.testOutput, "test DEBUG Hello, world!\n");
const logger = log.getLogger("bar");
assertEqual(logger.levelName, "INFO");
assertEqual(logger.handlers, [
fooHandler
]);
});
test(async function testFormatterAsFunction() {
test(async function getLoggerUnknown() {
await log.setup({
handlers: {
test: new TestHandler("DEBUG", {
formatter: logRecord =>
`fn formmatter ${logRecord.levelName} ${logRecord.msg}`
})
},
loggers: {
test: {
level: "DEBUG",
handlers: ["test"]
}
}
});
const logger = log.getLogger("test");
const handler = log.getHandler("test");
logger.error("Hello, world!");
assertEqual(handler.testOutput, "fn formmatter ERROR Hello, world!\n");
const logger = log.getLogger("nonexistent");
assertEqual(logger.levelName, "NOTSET");
assertEqual(logger.handlers, []);
});

View File

@ -18,6 +18,8 @@ import "io/util_test.ts";
import "http/http_test.ts";
import "http/file_server_test.ts";
import "log/test.ts";
import "log/handlers_test.ts";
import "log/logger_test.ts";
import "media_types/test.ts";
import "testing/test.ts";
import "textproto/test.ts";