Skip to content

Commit

Permalink
refactor: Simplify color handling + improve tests
Browse files Browse the repository at this point in the history
  • Loading branch information
ahochsteger committed Dec 16, 2020
1 parent ebcf277 commit 17310d6
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 53 deletions.
29 changes: 13 additions & 16 deletions lib/logger.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ addColors({
})

// Custom logging format:
const customFormat = (config, useColors) =>
const customFormat = config =>
combine(
errors({ stack: true }),
timestamp({ format: 'YYYY-MM-DD HH:mm:ss.SSS' }),
Expand All @@ -35,15 +35,10 @@ const customFormat = (config, useColors) =>
return info
})(),
label({ label: config.module.toUpperCase() }),
colorize({ level: useColors }),
colorize({ level: true }),
printf(info => {
info.timestamp = useColors
? colorizer.colorize('time', info.timestamp)
: info.timestamp
info.label = useColors
? colorizer.colorize('module', info.label || '-')
: info.label

info.timestamp = colorizer.colorize('time', info.timestamp)
info.label = colorizer.colorize('module', info.label || '-')
return `${info.timestamp} ${info.level} ${info.label}: ${info.message}`
})
)
Expand All @@ -52,15 +47,15 @@ const customFormat = (config, useColors) =>
const customTransports = config => {
const transportsList = [
new transports.Console({
format: customFormat(config, true),
format: customFormat(config),
level: config.level,
stderrLevels: ['error']
})
]
if (config.logToFile) {
transportsList.push(
new transports.File({
format: customFormat(config, false),
format: combine(customFormat(config), format.uncolorize()),
filename: config.filename,
level: config.level
})
Expand All @@ -83,19 +78,21 @@ const setupLogger = (container, module, config) => {
return logger
}

const logContainer = new winston.Container()

// Setup a logger for a certain module:
winston.loggers.module = module => {
return setupLogger(winston.loggers, module)
logContainer.loggers.module = module => {
return setupLogger(logContainer, module)
}

// Setup loggers for all modules
winston.loggers.setupAll = config => {
for (const [key, logger] of winston.loggers.loggers) {
logContainer.loggers.setupAll = config => {
for (const [key, logger] of logContainer.loggers) {
// Make sure, only winston loggers created from this logger module are modified:
if (key.startsWith(loggerPrefix)) {
logger.setup(config)
}
}
}

module.exports = winston.loggers
module.exports = logContainer.loggers
87 changes: 50 additions & 37 deletions test/lib/logger.test.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,60 @@
const { assert } = require('chai')
const winston = require('winston')
const reqlib = require('app-root-path').require
const rewire = require('rewire')

describe('#logger', () => {
let logContainer
const logContainer = reqlib('lib/logger.js')
const logContainerRewired = rewire('../../lib/logger.js')

function checkConfigDefaults (mod, cfg) {
const defaultLogFile = logContainerRewired.__get__('defaultLogFile')
cfg.module.should.equal(mod)
cfg.enabled.should.equal(true)
cfg.level.should.equal('info')
cfg.logToFile.should.equal(false)
cfg.filename.should.equal(defaultLogFile)
}

describe('logger.js', () => {
const sanitizedConfig = logContainerRewired.__get__('sanitizedConfig')
const customTransports = logContainerRewired.__get__('customTransports')
let logger1
let logger2

before(() => {
logContainer = reqlib('lib/logger.js')
it('should have a module function', () =>
assert.isFunction(logContainer.module))
it('should have a configAllLoggers function', () =>
assert.isFunction(logContainer.setupAll))

describe('sanitizedConfig()', () => {
it('should set undefined config object to defaults', () => {
const cfg = sanitizedConfig('-', undefined)
checkConfigDefaults('-', cfg)
})
it('should set empty config object to defaults', () => {
const cfg = sanitizedConfig('-', {})
checkConfigDefaults('-', cfg)
})
})

describe('customFormat()', () => {
it('should uppercase the label', () => {
// TODO: Why does it fail with 'TypeError: colors[Colorizer.allColors[lookup]] is not a function'?
// const customFormat = logContainerRewired.__get__('customFormat')
// const fmt = customFormat(sanitizedConfig('foo', {}))
// fmt.transform({ module: 'foo', level: 'info', message: 'msg' })
// .label.should.be.equal('FOO')
})
})

it('has a module function', () => assert.isFunction(logContainer.module))
it('has a configAllLoggers function', () =>
assert.isFunction(logContainer.setupAll))
describe('customTransports()', () => {
it('should have one transport by default', () => {
const transports = customTransports(sanitizedConfig('-', {}))
transports.length.should.equal(1)
})
})

describe('#module', () => {
describe('module()', () => {
before(() => {
logger1 = logContainer.module('foo')
})
Expand All @@ -25,15 +64,11 @@ describe('#logger', () => {
logger1.silent.should.be.false)
it('should have the default log level', () =>
logger1.level.should.equal('info'))
it('should have a custom format', () =>
logger1.format
.transform({ level: 'info', message: 'msg' })
.label.should.be.equal('FOO'))
it('should have one transport only', () =>
logger1.transports.length.should.be.equal(1))
})

describe('#cfg (init)', () => {
describe('setup() (init)', () => {
before(() => {
logger1 = logContainer.module('bar')
logger2 = logger1.setup({
Expand All @@ -49,13 +84,9 @@ describe('#logger', () => {
it('should change the log level', () => logger1.level.should.equal('warn'))
it('should have 2 transports', () =>
logger1.transports.length.should.be.equal(2))
it('should have a custom format', () =>
logger1.format
.transform({ level: 'info', message: 'msg' })
.label.should.be.equal('BAR'))
})

describe('#setup (reconfig)', () => {
describe('setup() (reconfigure)', () => {
before(() => {
logger1 = logContainer
.module('mod')
Expand All @@ -65,23 +96,17 @@ describe('#logger', () => {
// Test pre-conditions:
logger1.module.should.equal('mod')
logger1.level.should.equal('warn')
logger1.format
.transform({ level: 'info', message: 'msg' })
.label.should.be.equal('MOD')
logger1.transports.length.should.be.equal(1)
// Change logger configuration:
logger1.setup({ enabled: false, level: 'error', logToFile: true })
// Test post-conditions:
logger1.module.should.equal('mod')
logger1.level.should.equal('error')
logger1.format
.transform({ level: 'info', message: 'msg' })
.label.should.be.equal('MOD')
logger1.transports.length.should.be.equal(2)
})
})

describe('#configAll', () => {
describe('setupAll()', () => {
it('should change the logger config of all zwavejs2mqtt modules', () => {
logger1 = logContainer
.module('mod1')
Expand All @@ -92,15 +117,9 @@ describe('#logger', () => {
// Test pre-conditions:
logger1.module.should.equal('mod1')
logger1.level.should.equal('warn')
logger1.format
.transform({ level: 'info', message: 'msg' })
.label.should.be.equal('MOD1')
logger1.transports.length.should.be.equal(1)
logger2.module.should.equal('mod2')
logger2.level.should.equal('warn')
logger2.format
.transform({ level: 'info', message: 'msg' })
.label.should.be.equal('MOD2')
logger2.transports.length.should.be.equal(1)
// Change logger configuration:
logContainer.setupAll({
Expand All @@ -111,15 +130,9 @@ describe('#logger', () => {
// Test post-conditions:
logger1.module.should.equal('mod1')
logger1.level.should.equal('error')
logger1.format
.transform({ level: 'info', message: 'msg' })
.label.should.be.equal('MOD1')
logger1.transports.length.should.be.equal(2)
logger2.module.should.equal('mod2')
logger2.level.should.equal('error')
logger2.format
.transform({ level: 'info', message: 'msg' })
.label.should.be.equal('MOD2')
logger2.transports.length.should.be.equal(2)
})
it('should not change the logger config of non-zwavejs2mqtt loggers', () => {
Expand Down

0 comments on commit 17310d6

Please sign in to comment.