diff --git a/dist/utils.js b/dist/utils.js index 99a362e..10bf276 100644 --- a/dist/utils.js +++ b/dist/utils.js @@ -1,7 +1,136 @@ -const os = require('os'); +"use strict"; +const os = require("os"); +const path = require("path"); +const chalk_1 = require("chalk"); +// 堆栈报错格式: https://github.com/v8/v8/wiki/Stack%20Trace%20API +const stackReg = /at\s+(.*)\s+\((.*):(\d*):(\d*)\)/i; +const stackReg2 = /at\s+()(.*):(\d*):(\d*)/i; +/** + * 自动为数字补0 + * @param num + */ +function padZero(num) { + if (num < 10) { + return '0' + num; + } + else { + return num + ''; + } +} +/** + * 增强型Date对象 + */ +function getPowerDate() { + const date = new Date(); + date.now = () => date.getTime() + ''; + date.format = () => { + const year = padZero(date.getFullYear()), month = padZero(date.getMonth() + 1), day = padZero(date.getDate()), hour = padZero(date.getHours()), minute = padZero(date.getMinutes()), second = padZero(date.getSeconds()); + return `${year}/${month}/${day} ${hour}:${minute}:${second}`; + }; + return date; +} +/** + * 日志类 + */ +class Logger { + constructor() { + this._colors = { + info: chalk_1.default.blue, + success: chalk_1.default.green, + warn: chalk_1.default.yellow, + error: chalk_1.default.red + }; + } + /** + * 捕获日志的时间、触发函数、触发文件等详细信息 + * + * @param message 日志信息 + * @param level 日志级别 + */ + _capture(message, level) { + const error = new Error(); + const stackList = error.stack.split('\n').slice(3); + const sp = stackReg.exec(stackList[0]) || stackReg2.exec(stackList[0]); + if (!sp) { + return; + } + return { + time: getPowerDate().format(), + method: sp[1], + path: sp[2], + line: sp[3], + pos: sp[4], + file: path.basename(sp[2]), + stack: error.stack, + message, + level + }; + } + /** + * 将详细日志信息输出到控制台 + * + * @param info 详细日志信息 + */ + _console(info) { + if (!info) { + return; + } + const colorLevel = this._colors[info.level](`[${info.level}]`); + return `${colorLevel} ${info.time} ${info.file}:${info.line} (${info.method}) ${info.message}`; + } + /** + * log级别日志(正常输出) + * + * @param message 日志信息 + */ + log(message) { + return console.log(`[log] ${message}`); + } + /** + * info级别日志 + * + * @param message 日志信息 + */ + info(message) { + const logInfo = this._capture(message, 'info'); + const consoleInfo = this._console(logInfo); + console.log(consoleInfo); + } + /** + * success级别日志 + * + * @param message 日志信息 + */ + success(message) { + const logInfo = this._capture(message, 'success'); + const consoleInfo = this._console(logInfo); + console.log(consoleInfo); + } + /** + * warning级别日志 + * + * @param message 日志信息 + */ + warn(message) { + const logInfo = this._capture(message, 'warn'); + const consoleInfo = this._console(logInfo); + console.log(consoleInfo); + } + /** + * error级别日志 + * + * @param message 日志信息 + */ + error(message) { + const logInfo = this._capture(message, 'error'); + const consoleInfo = this._console(logInfo); + console.log(consoleInfo); + } +} module.exports = { get cpuNum() { - let len = os.cpus().length; + const len = os.cpus().length; return Math.max(len, 4); - } + }, + logger: new Logger() }; diff --git a/package-lock.json b/package-lock.json index e844bae..10fe53a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "@vemo/cli", - "version": "0.0.29", + "version": "0.0.30", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -626,9 +626,9 @@ "dev": true }, "@types/qs": { - "version": "6.5.3", - "resolved": "https://registry.npm.taobao.org/@types/qs/download/@types/qs-6.5.3.tgz", - "integrity": "sha1-HDtxsJHq6vWSRTgAa39wYDzmPTg=", + "version": "6.5.2", + "resolved": "http://r.tnpm.oa.com/@types/qs/download/@types/qs-6.5.2.tgz", + "integrity": "sha1-fzRwYmVQVmYoRbpLt53L/cOCzWE=", "dev": true }, "@types/range-parser": { @@ -757,15 +757,6 @@ "resolved": "https://registry.npmjs.org/after/-/after-0.8.2.tgz", "integrity": "sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8=" }, - "agent-base": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.2.1.tgz", - "integrity": "sha512-JVwXMr9nHYTUXsBFKUqhJwvlcYU/blreOEUkhNR2eXZIvwd+c+o5V4MgDPKWnMS/56awN3TRzIP+KoPn+roQtg==", - "dev": true, - "requires": { - "es6-promisify": "^5.0.0" - } - }, "ajv": { "version": "6.10.0", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.0.tgz", @@ -1280,8 +1271,8 @@ }, "chalk": { "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "resolved": "http://r.tnpm.oa.com/chalk/download/chalk-2.4.2.tgz", + "integrity": "sha1-zUJUFnelQzPPVBpJEIwUMrRMlCQ=", "requires": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -1484,18 +1475,6 @@ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" }, - "concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - } - }, "condense-newlines": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/condense-newlines/-/condense-newlines-0.2.1.tgz", @@ -1979,21 +1958,6 @@ "is-symbol": "^1.0.2" } }, - "es6-promise": { - "version": "4.2.6", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.6.tgz", - "integrity": "sha512-aRVgGdnmW2OiySVPUC9e6m+plolMAJKjZnQlCwNSuK5yQ0JN61DZSO1X1Ufd1foqWRAlig0rhduTCHe7sVtK5Q==", - "dev": true - }, - "es6-promisify": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", - "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", - "dev": true, - "requires": { - "es6-promise": "^4.0.3" - } - }, "escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", @@ -2363,29 +2327,6 @@ } } }, - "extract-zip": { - "version": "1.6.7", - "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.6.7.tgz", - "integrity": "sha1-qEC0uK9kAyZMjbV/Txp0Mz74H+k=", - "dev": true, - "requires": { - "concat-stream": "1.6.2", - "debug": "2.6.9", - "mkdirp": "0.5.1", - "yauzl": "2.4.1" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - } - } - }, "extsprintf": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", @@ -2416,15 +2357,6 @@ "bser": "^2.0.0" } }, - "fd-slicer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.0.1.tgz", - "integrity": "sha1-i1vL2ewyfFBBv5qwI/1nUPEXfmU=", - "dev": true, - "requires": { - "pend": "~1.2.0" - } - }, "figures": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", @@ -2603,8 +2535,7 @@ "version": "2.1.1", "resolved": false, "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true, - "optional": true + "dev": true }, "aproba": { "version": "1.2.0", @@ -2628,15 +2559,13 @@ "version": "1.0.0", "resolved": false, "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true, - "optional": true + "dev": true }, "brace-expansion": { "version": "1.1.11", "resolved": false, "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, - "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -2653,22 +2582,19 @@ "version": "1.1.0", "resolved": false, "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", - "dev": true, - "optional": true + "dev": true }, "concat-map": { "version": "0.0.1", "resolved": false, "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true, - "optional": true + "dev": true }, "console-control-strings": { "version": "1.1.0", "resolved": false, "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", - "dev": true, - "optional": true + "dev": true }, "core-util-is": { "version": "1.0.2", @@ -2799,8 +2725,7 @@ "version": "2.0.3", "resolved": false, "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true, - "optional": true + "dev": true }, "ini": { "version": "1.3.5", @@ -2814,7 +2739,6 @@ "resolved": false, "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", "dev": true, - "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -2831,7 +2755,6 @@ "resolved": false, "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", "dev": true, - "optional": true, "requires": { "brace-expansion": "^1.1.7" } @@ -2840,15 +2763,13 @@ "version": "0.0.8", "resolved": false, "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true, - "optional": true + "dev": true }, "minipass": { "version": "2.3.5", "resolved": false, "integrity": "sha512-Gi1W4k059gyRbyVUZQ4mEqLm0YIUiGYfvxhF6SIlk3ui1WVxMTGfGdQ2SInh3PDrRTVvPKgULkpJtT4RH10+VA==", "dev": true, - "optional": true, "requires": { "safe-buffer": "^5.1.2", "yallist": "^3.0.0" @@ -2869,7 +2790,6 @@ "resolved": false, "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", "dev": true, - "optional": true, "requires": { "minimist": "0.0.8" } @@ -2958,8 +2878,7 @@ "version": "1.0.1", "resolved": false, "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", - "dev": true, - "optional": true + "dev": true }, "object-assign": { "version": "4.1.1", @@ -2973,7 +2892,6 @@ "resolved": false, "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", "dev": true, - "optional": true, "requires": { "wrappy": "1" } @@ -3069,8 +2987,7 @@ "version": "5.1.2", "resolved": false, "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true, - "optional": true + "dev": true }, "safer-buffer": { "version": "2.1.2", @@ -3112,7 +3029,6 @@ "resolved": false, "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", "dev": true, - "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -3134,7 +3050,6 @@ "resolved": false, "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, - "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -3183,15 +3098,13 @@ "version": "1.0.2", "resolved": false, "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true, - "optional": true + "dev": true }, "yallist": { "version": "3.0.3", "resolved": false, "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==", - "dev": true, - "optional": true + "dev": true } } }, @@ -3443,16 +3356,6 @@ "sshpk": "^1.7.0" } }, - "https-proxy-agent": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.1.tgz", - "integrity": "sha512-HPCTS1LW51bcyMYbxUIOO4HEOlQ1/1qRaFWcyxvwaqUS9TY88aoEuHUY33kuAh1YhVVaDQhLZsnPd+XNARWZlQ==", - "dev": true, - "requires": { - "agent-base": "^4.1.0", - "debug": "^3.1.0" - } - }, "iconv-lite": { "version": "0.4.23", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz", @@ -5061,12 +4964,6 @@ } } }, - "mime": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.2.tgz", - "integrity": "sha512-zJBfZDkwRu+j3Pdd2aHsR5GfH2jIWhmL1ZzBoc+X+3JEti2hbArWcyJ+1laC1D2/U/W1a/+Cegj0/OnEU2ybjg==", - "dev": true - }, "mime-db": { "version": "1.38.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.38.0.tgz", @@ -5654,12 +5551,6 @@ "pinkie-promise": "^2.0.0" } }, - "pend": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", - "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=", - "dev": true - }, "performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", @@ -5779,12 +5670,6 @@ "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz", "integrity": "sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk=" }, - "proxy-from-env": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.0.0.tgz", - "integrity": "sha1-M8UDmPcOp+uW0h97gXYwpVeRx+4=", - "dev": true - }, "pseudomap": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", @@ -5810,39 +5695,6 @@ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" }, - "puppeteer": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-1.15.0.tgz", - "integrity": "sha512-D2y5kwA9SsYkNUmcBzu9WZ4V1SGHiQTmgvDZSx6sRYFsgV25IebL4V6FaHjF6MbwLK9C6f3G3pmck9qmwM8H3w==", - "dev": true, - "requires": { - "debug": "^4.1.0", - "extract-zip": "^1.6.6", - "https-proxy-agent": "^2.2.1", - "mime": "^2.0.3", - "progress": "^2.0.1", - "proxy-from-env": "^1.0.0", - "rimraf": "^2.6.1", - "ws": "^6.1.0" - }, - "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", - "dev": true - } - } - }, "qs": { "version": "6.6.0", "resolved": "https://registry.npmjs.org/qs/-/qs-6.6.0.tgz", @@ -7075,12 +6927,6 @@ "mime-types": "~2.1.18" } }, - "typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", - "dev": true - }, "typescript": { "version": "3.4.5", "resolved": "https://registry.npm.taobao.org/typescript/download/typescript-3.4.5.tgz", @@ -7548,15 +7394,6 @@ "decamelize": "^1.2.0" } }, - "yauzl": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.4.1.tgz", - "integrity": "sha1-lSj0QtqxsihOWLQ3m7GU4i4MQAU=", - "dev": true, - "requires": { - "fd-slicer": "~1.0.1" - } - }, "yeast": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/yeast/-/yeast-0.1.2.tgz", diff --git a/package.json b/package.json index 4e74afb..e3ce48c 100755 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@vemo/cli", - "version": "0.0.30", + "version": "0.0.31", "description": "", "bin": { "vemo": "dist/bin/bin.js" @@ -45,6 +45,7 @@ "@types/koa-joi-router": "^5.2.2", "@types/koa-static": "^4.0.1", "@types/node": "^12.0.0", + "@types/qs": "^6.5.2", "@types/socket.io": "^2.1.2", "coveralls": "^3.0.3", "eslint": "^5.16.0", diff --git a/src/utils.ts b/src/utils.ts index ca88915..5d1346f 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,8 +1,181 @@ -const os = require('os') +import * as os from 'os' +import * as path from 'path' +import { default as chalk } from 'chalk' -module.exports = { - get cpuNum():number { - let len = os.cpus().length - return Math.max(len, 4) +// 堆栈报错格式: https://github.com/v8/v8/wiki/Stack%20Trace%20API +const stackReg = /at\s+(.*)\s+\((.*):(\d*):(\d*)\)/i +const stackReg2 = /at\s+()(.*):(\d*):(\d*)/i + +interface LogInfo { + time: string, + method: string, + path: string, + line: string, + pos: string, + file: string, + level: string, + message: string, + stack?: string +} + +interface PowerDate extends Date { + now?: () => string, + format?: () => string +} + +/** + * 自动为数字补0 + * @param num + */ +function padZero(num: number): string { + if (num < 10) { + return '0' + num + } else { + return num + '' + } +} + +/** + * 增强型Date对象 + */ +function getPowerDate(): PowerDate { + const date: PowerDate = new Date() + + date.now = () => date.getTime() + '' + + date.format = () => { + const year = padZero(date.getFullYear()), + month = padZero(date.getMonth() + 1), + day = padZero(date.getDate()), + hour = padZero(date.getHours()), + minute = padZero(date.getMinutes()), + second = padZero(date.getSeconds()) + + return `${year}/${month}/${day} ${hour}:${minute}:${second}` + } + + return date +} + +/** + * 日志类 + */ +class Logger { + + /** + * 颜色函数映射 + */ + private _colors: any; + + public constructor () { + this._colors = { + info: chalk.blue, + success: chalk.green, + warn: chalk.yellow, + error: chalk.red + } + } + + /** + * 捕获日志的时间、触发函数、触发文件等详细信息 + * + * @param message 日志信息 + * @param level 日志级别 + */ + private _capture (message: string, level: string): void | LogInfo { + const error = new Error() + const stackList = error.stack.split('\n').slice(3) + const sp = stackReg.exec(stackList[0]) || stackReg2.exec(stackList[0]) + + if (!sp) { + return + } + + return { + time: getPowerDate().format(), + method: sp[1], + path: sp[2], + line: sp[3], + pos: sp[4], + file: path.basename(sp[2]), + stack: error.stack, + message, + level + } } + + /** + * 将详细日志信息输出到控制台 + * + * @param info 详细日志信息 + */ + private _console (info: void | LogInfo): string { + if (!info) { + return + } + + const colorLevel = this._colors[info.level](`[${info.level}]`) + return `${colorLevel} ${info.time} ${info.file}:${info.line} (${info.method}) ${info.message}` + } + + /** + * log级别日志(正常输出) + * + * @param message 日志信息 + */ + public log (message: string) { + return console.log(`[log] ${message}`) + } + + /** + * info级别日志 + * + * @param message 日志信息 + */ + public info (message: string) { + const logInfo = this._capture(message, 'info') + const consoleInfo = this._console(logInfo) + console.log(consoleInfo) + } + + /** + * success级别日志 + * + * @param message 日志信息 + */ + public success (message: string) { + const logInfo = this._capture(message, 'success') + const consoleInfo = this._console(logInfo) + console.log(consoleInfo) + } + + /** + * warning级别日志 + * + * @param message 日志信息 + */ + public warn (message: string) { + const logInfo = this._capture(message, 'warn') + const consoleInfo = this._console(logInfo) + console.log(consoleInfo) + } + + /** + * error级别日志 + * + * @param message 日志信息 + */ + public error (message: string) { + const logInfo = this._capture(message, 'error') + const consoleInfo = this._console(logInfo) + console.log(consoleInfo) + } +} + +export = { + get cpuNum (): number { + const len = os.cpus().length + return Math.max(len, 4) + }, + logger: new Logger() } \ No newline at end of file diff --git a/test/utils.test.js b/test/utils.test.js index df9bafd..05e1477 100644 --- a/test/utils.test.js +++ b/test/utils.test.js @@ -4,4 +4,12 @@ describe('utils.js', () => { test('cpuNum getter', () => { expect(utils.cpuNum).toBeGreaterThanOrEqual(4) }) + + test('logger', () => { + const { logger } = utils + const levels = ['log', 'info', 'success', 'warn', 'error'] + levels.forEach((level) => logger[level]('just a test')) + const valid = levels.reduce((pre, current) => pre && typeof logger[current] === 'function', true) + expect(valid).toBeTruthy() + }) }) \ No newline at end of file