diff --git a/__tests__/unit/core-logger/__stubs__/logger.ts b/__tests__/unit/core-logger/__stubs__/logger.ts index f50083c056..2c6eeb5dd3 100644 --- a/__tests__/unit/core-logger/__stubs__/logger.ts +++ b/__tests__/unit/core-logger/__stubs__/logger.ts @@ -1,31 +1,39 @@ import { AbstractLogger } from "../../../../packages/core-logger/src"; export class Logger extends AbstractLogger { + protected logger = { + error: jest.fn(), + warn: jest.fn(), + info: jest.fn(), + debug: jest.fn(), + verbose: jest.fn(), + }; + public make(): any { - return this; - } + if (this.options.stubLogger) { + this.logger = this.options.stubLogger; + } - public error(message: string): void { - // + return this; } - public warn(message: string): void { - // + public error(message: string): boolean { + return this.log("error", message); } - public info(message: string): void { - // + public warn(message: string): boolean { + return this.log("warn", message); } - public debug(message: string): void { - // + public info(message: string): boolean { + return this.log("info", message); } - public verbose(message: string): void { - // + public debug(message: string): boolean { + return this.log("debug", message); } - public suppressConsoleOutput(suppress: boolean): void { - // + public verbose(message: string): boolean { + return this.log("verbose", message); } } diff --git a/__tests__/unit/core-logger/logger.test.ts b/__tests__/unit/core-logger/logger.test.ts new file mode 100644 index 0000000000..929924bf9c --- /dev/null +++ b/__tests__/unit/core-logger/logger.test.ts @@ -0,0 +1,63 @@ +import "jest-extended"; +import { Logger } from "./__stubs__/logger"; + +const dummyMessage = "Hello World"; + +const stubLogger = { + error: jest.fn(), + warn: jest.fn(), + info: jest.fn(), + debug: jest.fn(), + verbose: jest.fn(), +}; + +let logger; +beforeEach(() => { + logger = new Logger({ stubLogger }).make(); +}); + +describe("Logger", () => { + describe.each(Object.keys(stubLogger))(".%s(message)", level => { + it("should log a message", () => { + const spy = jest.spyOn(logger, "log"); + + expect(logger[level](dummyMessage)).toBeTrue(); + expect(spy).toHaveBeenCalledWith(level, dummyMessage); + expect(stubLogger[level]).toHaveBeenCalledWith(dummyMessage); + + spy.mockRestore(); + }); + + it("should not log a message if suppressing console output", () => { + const spy = jest.spyOn(logger, "log"); + + logger.suppressConsoleOutput(); + + expect(logger[level](dummyMessage)).toBeFalse(); + expect(spy).toHaveBeenCalledWith(level, dummyMessage); + expect(stubLogger[level]).not.toHaveBeenCalledWith(); + + spy.mockRestore(); + }); + + it("should not log a message if it is empty", () => { + expect(logger[level]("")).toBeFalse(); + expect(logger[level]({})).toBeFalse(); + expect(logger[level]([])).toBeFalse(); + expect(logger[level](null)).toBeFalse(); + expect(logger[level](undefined)).toBeFalse(); + }); + + it("should modify and log a message if it is an object", () => { + logger[level]({ hello: "world" }); + + expect(stubLogger[level]).toHaveBeenCalledWith("{ hello: 'world' }"); + }); + + it("should modify and log a message if it is an array", () => { + logger[level](["hello"]); + + expect(stubLogger[level]).toHaveBeenCalledWith("[ 'hello' ]"); + }); + }); +}); diff --git a/__tests__/unit/core-logger/manager.test.ts b/__tests__/unit/core-logger/manager.test.ts index 5806f0cf0e..d411c95a5d 100644 --- a/__tests__/unit/core-logger/manager.test.ts +++ b/__tests__/unit/core-logger/manager.test.ts @@ -1,15 +1,24 @@ import "jest-extended"; import { AbstractLogger, LoggerManager } from "../../../packages/core-logger/src"; +import { LoggerFactory } from "../../../packages/core-logger/src/factory"; import { Logger } from "./__stubs__/logger"; const manager = new LoggerManager(); -describe("Config Manager", () => { - describe("driver", () => { - it("should return the driver", async () => { - await manager.createDriver(new Logger({})); +describe("Manager", () => { + it("should return the driver", async () => { + await manager.createDriver(new Logger({})); - expect(manager.driver()).toBeInstanceOf(AbstractLogger); - }); + expect(manager.driver()).toBeInstanceOf(AbstractLogger); + }); + + it("should return all drivers", async () => { + await manager.createDriver(new Logger({})); + + expect(manager.getDrivers()).toBeInstanceOf(Map); + }); + + it("should return the factory", async () => { + expect(manager.getFactory()).toBeInstanceOf(LoggerFactory); }); }); diff --git a/packages/core-interfaces/src/core-logger/logger.ts b/packages/core-interfaces/src/core-logger/logger.ts index 82ef3fa549..675db16a08 100644 --- a/packages/core-interfaces/src/core-logger/logger.ts +++ b/packages/core-interfaces/src/core-logger/logger.ts @@ -1,49 +1,13 @@ export interface ILogger { - /** - * Make the logger instance. - * @return {Object} - */ make(): ILogger; + getLogger(): T; - /** - * Log an error message. - * @param {*} message - * @return {void} - */ - error(message: any): void; + log(level: string, message: any): boolean; + error(message: any): boolean; + warn(message: any): boolean; + info(message: any): boolean; + debug(message: any): boolean; + verbose(message: any): boolean; - /** - * Log a warning message. - * @param {*} message - * @return {void} - */ - warn(message: any): void; - - /** - * Log an info message. - * @param {*} message - * @return {void} - */ - info(message: any): void; - - /** - * Log a debug message. - * @param {*} message - * @return {void} - */ - debug(message: any): void; - - /** - * Log a verbose message. - * @param {*} message - * @return {void} - */ - verbose(message: any): void; - - /** - * Suppress console output. - * @param {Boolean} - * @return {void} - */ - suppressConsoleOutput(suppress: boolean): void; + suppressConsoleOutput(suppress?: boolean): void; } diff --git a/packages/core-logger-winston/src/driver.ts b/packages/core-logger-winston/src/driver.ts index 0d93866649..e448066d27 100644 --- a/packages/core-logger-winston/src/driver.ts +++ b/packages/core-logger-winston/src/driver.ts @@ -15,7 +15,7 @@ export class WinstonLogger extends AbstractLogger { return this; } - public suppressConsoleOutput(suppress: boolean): void { + public suppressConsoleOutput(suppress: boolean = true): void { const consoleTransport = this.logger.transports.find( (transport: ITransportStream) => transport.name === "console", ); diff --git a/packages/core-logger/src/logger.ts b/packages/core-logger/src/logger.ts index 5c0914fb73..52d285686e 100644 --- a/packages/core-logger/src/logger.ts +++ b/packages/core-logger/src/logger.ts @@ -5,7 +5,6 @@ import { inspect } from "util"; export abstract class AbstractLogger implements Logger.ILogger { protected logger: any; protected silentConsole: boolean = false; - protected readonly defaultLevels: Record = { error: "error", warn: "warn", @@ -14,31 +13,53 @@ export abstract class AbstractLogger implements Logger.ILogger { verbose: "verbose", }; - constructor(protected readonly options: any) {} + constructor(protected readonly options: Record) {} public abstract make(): Logger.ILogger; - public error(message: any): void { - this.createLog(this.getLevel("error"), message); + public getLogger(): T { + return this.logger; + } + + public log(level: string, message: any): boolean { + if (this.silentConsole) { + return false; + } + + if (isEmpty(message)) { + return false; + } + + if (typeof message !== "string") { + message = inspect(message, { depth: 1 }); + } + + this.logger[level](message); + + return true; } - public warn(message: any): void { - this.createLog(this.getLevel("warn"), message); + public error(message: any): boolean { + return this.log(this.getLevel("error"), message); } - public info(message: any): void { - this.createLog(this.getLevel("info"), message); + public warn(message: any): boolean { + return this.log(this.getLevel("warn"), message); } - public debug(message: any): void { - this.createLog(this.getLevel("debug"), message); + public info(message: any): boolean { + return this.log(this.getLevel("info"), message); } - public verbose(message: any): void { - this.createLog(this.getLevel("verbose"), message); + public debug(message: any): boolean { + return this.log(this.getLevel("debug"), message); } - public suppressConsoleOutput(suppress: boolean): void { + public verbose(message: any): boolean { + return this.log(this.getLevel("verbose"), message); + } + + public suppressConsoleOutput(suppress: boolean = true): void { this.silentConsole = suppress; } @@ -49,20 +70,4 @@ export abstract class AbstractLogger implements Logger.ILogger { protected getLevels(): Record { return this.defaultLevels; } - - private createLog(method: string, message: any): void { - if (this.silentConsole) { - return; - } - - if (isEmpty(message)) { - return; - } - - if (typeof message !== "string") { - message = inspect(message, { depth: 1 }); - } - - this.logger[method](message); - } }