From 056e6d59424c60150e58a71fe93b73c84811f5c5 Mon Sep 17 00:00:00 2001 From: Wouter Date: Fri, 26 Oct 2018 16:34:34 +0200 Subject: [PATCH] WIP on #23 Implement logger change and test --- src/vue-logger/interfaces/logger.ts | 6 +- src/vue-logger/vue-logger.ts | 254 ++++++++++++++++++---------- tests/changelevel.test.ts | 35 ++++ 3 files changed, 202 insertions(+), 93 deletions(-) create mode 100644 tests/changelevel.test.ts diff --git a/src/vue-logger/interfaces/logger.ts b/src/vue-logger/interfaces/logger.ts index f5bce7d..2b83e37 100644 --- a/src/vue-logger/interfaces/logger.ts +++ b/src/vue-logger/interfaces/logger.ts @@ -1,7 +1,7 @@ -import {ILoggerOptions} from "./logger-options"; +import { ILoggerOptions } from "./logger-options"; export interface ILogger { - install(Vue: any, options: ILoggerOptions); + install(Vue: any, options: ILoggerOptions); - isValidOptions(options: ILoggerOptions, logLevels: string[]): boolean; + isValidOptions(options: ILoggerOptions, logLevels: string[]): boolean; } diff --git a/src/vue-logger/vue-logger.ts b/src/vue-logger/vue-logger.ts index bd2cde3..0e98998 100644 --- a/src/vue-logger/vue-logger.ts +++ b/src/vue-logger/vue-logger.ts @@ -1,107 +1,181 @@ -import {LogLevels} from "./enum/log-levels"; -import {ILogger} from "./interfaces/logger"; -import {ILoggerOptions} from "./interfaces/logger-options"; +import { LogLevels } from "./enum/log-levels"; +import { ILogger } from "./interfaces/logger"; +import { ILoggerOptions } from "./interfaces/logger-options"; class VueLogger implements ILogger { + private errorMessage: string = + "Provided options for vuejs-logger are not valid."; + private logLevels: string[] = Object.keys(LogLevels).map((l) => + l.toLowerCase(), + ); + private options: ILoggerOptions = this.getDefaultOptions(); + private vueInstance: any; - private errorMessage: string = "Provided options for vuejs-logger are not valid."; - private logLevels: string[] = Object.keys(LogLevels).map((l) => l.toLowerCase()); + public install(Vue: any, options: ILoggerOptions) { + this.options = Object.assign(this.options, options); - public install(Vue: any, options: ILoggerOptions) { - options = Object.assign(this.getDefaultOptions(), options); - - if (this.isValidOptions(options, this.logLevels)) { - Vue.$log = this.initLoggerInstance(options, this.logLevels); - Vue.prototype.$log = Vue.$log; - } else { - throw new Error(this.errorMessage); - } + if (this.isValidOptions(options, this.logLevels)) { + this.vueInstance = Vue; + Vue.$log = this.initLoggerInstance(options, this.logLevels); + Vue.prototype.$log = Vue.$log; + } else { + throw new Error(this.errorMessage); } + } + + /** + * Create a new logger with nother logLevel. + * Exposed on the $log object to set the loglevel. + * Implicitly enables the logger. + * + * @param aLogLevel the new loglevel + */ + private changeLogLevel(aLogLevel: string) { + this.logLevels.forEach((logLevel) => { + if ( + this.logLevels.indexOf(logLevel) >= this.logLevels.indexOf(aLogLevel) + ) { + this.vueInstance.$log[logLevel] = this.createLoggerObject( + this.options, + logLevel, + ); + } else { + this.vueInstance.$log[logLevel] = () => undefined; + } + }); + } - public isValidOptions(options: ILoggerOptions, logLevels: string[]): boolean { - if (!(options.logLevel && typeof options.logLevel === "string" && logLevels.indexOf(options.logLevel) > -1)) { - return false; - } - if (options.stringifyArguments && typeof options.stringifyArguments !== "boolean") { - return false; - } - if (options.showLogLevel && typeof options.showLogLevel !== "boolean") { - return false; - } - if (options.showConsoleColors && typeof options.showConsoleColors !== "boolean") { - return false; - } - if (options.separator && (typeof options.separator !== "string" || (typeof options.separator === "string" && options.separator.length > 3))) { - return false; - } - if (typeof options.isEnabled !== "boolean") { - return false; - } - return !(options.showMethodName && typeof options.showMethodName !== "boolean"); + public isValidOptions(options: ILoggerOptions, logLevels: string[]): boolean { + if ( + !( + options.logLevel && + typeof options.logLevel === "string" && + logLevels.indexOf(options.logLevel) > -1 + ) + ) { + return false; + } + if ( + options.stringifyArguments && + typeof options.stringifyArguments !== "boolean" + ) { + return false; + } + if (options.showLogLevel && typeof options.showLogLevel !== "boolean") { + return false; + } + if ( + options.showConsoleColors && + typeof options.showConsoleColors !== "boolean" + ) { + return false; + } + if ( + options.separator && + (typeof options.separator !== "string" || + (typeof options.separator === "string" && options.separator.length > 3)) + ) { + return false; + } + if (typeof options.isEnabled !== "boolean") { + return false; } + return !( + options.showMethodName && typeof options.showMethodName !== "boolean" + ); + } - private getMethodName(): string { - let error = {} as any; + private getMethodName(): string { + let error = {} as any; - try { - throw new Error(""); - } catch (e) { - error = e; - } - // IE9 does not have .stack property - if (error.stack === undefined) { - return ""; - } - let stackTrace = error.stack.split("\n")[3]; - if (/ /.test(stackTrace)) { - stackTrace = stackTrace.trim().split(" ")[1]; - } - if (stackTrace && stackTrace.indexOf(".") > -1) { - stackTrace = stackTrace.split(".")[1]; - } - return stackTrace; + try { + throw new Error(""); + } catch (e) { + error = e; } - - private initLoggerInstance(options: ILoggerOptions, logLevels: string[]) { - const logger = {}; - logLevels.forEach((logLevel) => { - if (logLevels.indexOf(logLevel) >= logLevels.indexOf(options.logLevel) && options.isEnabled) { - logger[logLevel] = (...args) => { - const methodName = this.getMethodName(); - const methodNamePrefix = options.showMethodName ? methodName + ` ${options.separator} ` : ""; - const logLevelPrefix = options.showLogLevel ? logLevel + ` ${options.separator} ` : ""; - const formattedArguments = options.stringifyArguments ? args.map((a) => JSON.stringify(a)) : args; - const logMessage = `${logLevelPrefix} ${methodNamePrefix}`; - this.printLogMessage(logLevel, logMessage, options.showConsoleColors, formattedArguments); - return `${logMessage} ${formattedArguments.toString()}`; - }; - } else { - logger[logLevel] = () => undefined; - } - }, - ); - return logger; + // IE9 does not have .stack property + if (error.stack === undefined) { + return ""; } - - private printLogMessage(logLevel: string, logMessage: string, showConsoleColors: boolean, formattedArguments: any) { - if (showConsoleColors && (logLevel === "warn" || logLevel === "error" || logLevel === "fatal")) { - console[logLevel === "fatal" ? "error" : logLevel](logMessage, ...formattedArguments); - } else { - console.log(logMessage, ...formattedArguments); - } + let stackTrace = error.stack.split("\n")[3]; + if (/ /.test(stackTrace)) { + stackTrace = stackTrace.trim().split(" ")[1]; + } + if (stackTrace && stackTrace.indexOf(".") > -1) { + stackTrace = stackTrace.split(".")[1]; } + return stackTrace; + } - private getDefaultOptions(): ILoggerOptions { - return { - isEnabled: true, - logLevel: LogLevels.DEBUG, - separator: "|", - showConsoleColors: false, - showLogLevel: false, - showMethodName: false, - stringifyArguments: false, - }; + private initLoggerInstance(options: ILoggerOptions, logLevels: string[]) { + const logger = {}; + logLevels.forEach((logLevel) => { + if ( + logLevels.indexOf(logLevel) >= logLevels.indexOf(options.logLevel) && + options.isEnabled + ) { + logger[logLevel] = this.createLoggerObject(options, logLevel); + } else { + logger[logLevel] = () => undefined; + } + }); + logger['changeLogLevel'] = this.changeLogLevel.bind(this); + return logger; + } + + private createLoggerObject(options: ILoggerOptions, logLevel: string) { + return (...args) => { + const methodName = this.getMethodName(); + const methodNamePrefix = options.showMethodName + ? methodName + ` ${options.separator} ` + : ""; + const logLevelPrefix = options.showLogLevel + ? logLevel + ` ${options.separator} ` + : ""; + const formattedArguments = options.stringifyArguments + ? args.map((a) => JSON.stringify(a)) + : args; + const logMessage = `${logLevelPrefix} ${methodNamePrefix}`; + this.printLogMessage( + logLevel, + logMessage, + options.showConsoleColors, + formattedArguments, + ); + return `${logMessage} ${formattedArguments.toString()}`; + }; + } + + private printLogMessage( + logLevel: string, + logMessage: string, + showConsoleColors: boolean, + formattedArguments: any, + ) { + if ( + showConsoleColors && + (logLevel === "warn" || logLevel === "error" || logLevel === "fatal") + ) { + console[logLevel === "fatal" ? "error" : logLevel]( + logMessage, + ...formattedArguments, + ); + } else { + console.log(logMessage, ...formattedArguments); } + } + + private getDefaultOptions(): ILoggerOptions { + return { + isEnabled: true, + logLevel: LogLevels.DEBUG, + separator: "|", + showConsoleColors: false, + showLogLevel: false, + showMethodName: false, + stringifyArguments: false, + }; + } } export default new VueLogger(); diff --git a/tests/changelevel.test.ts b/tests/changelevel.test.ts new file mode 100644 index 0000000..5c3a657 --- /dev/null +++ b/tests/changelevel.test.ts @@ -0,0 +1,35 @@ +import { notStrictEqual, strictEqual } from "assert"; +import chai from "chai"; +import Vue from "vue/dist/vue.min"; +import VueLogger from "../src"; +import { LogLevels } from "../src/vue-logger/enum/log-levels"; +import { ILoggerOptions } from "../src/vue-logger/interfaces/logger-options"; +const expect = chai.expect; + +describe("changeLoglevel()", () => { + + test("changeLogLevel('info') should set the loglevel to info after initialisation.", () => { + const options: ILoggerOptions = { + isEnabled: true, + logLevel: LogLevels.ERROR, + separator: "|", + stringifyArguments: false, + showConsoleColors: true, + showLogLevel: false, + showMethodName: false, + }; + Vue.use(VueLogger, options); + expect(Vue.$log).to.be.a("object"); + strictEqual(Vue.$log.debug("debug"), undefined); + strictEqual(Vue.$log.info("info"), undefined); + strictEqual(Vue.$log.warn("warn"), undefined); + expect(Vue.$log.error("error")).to.exist; + expect(Vue.$log.fatal("fatal")).to.exist; + Vue.$log.changeLogLevel('info'); + strictEqual(Vue.$log.debug("debug"), undefined); + expect(Vue.$log.error("info")).to.exist; + expect(Vue.$log.error("warn")).to.exist; + expect(Vue.$log.error("error")).to.exist; + expect(Vue.$log.error("fatal")).to.exist; + }); +});