You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
442 lines
10 KiB
442 lines
10 KiB
4 years ago
|
'use strict'
|
||
|
|
||
|
const { test } = require('tap')
|
||
|
const { sink, once, check } = require('./helper')
|
||
|
const pino = require('../')
|
||
|
|
||
|
test('set the level by string', async ({ is }) => {
|
||
|
const expected = [{
|
||
|
level: 50,
|
||
|
msg: 'this is an error'
|
||
|
}, {
|
||
|
level: 60,
|
||
|
msg: 'this is fatal'
|
||
|
}]
|
||
|
const stream = sink()
|
||
|
const instance = pino(stream)
|
||
|
instance.level = 'error'
|
||
|
instance.info('hello world')
|
||
|
instance.error('this is an error')
|
||
|
instance.fatal('this is fatal')
|
||
|
const result = await once(stream, 'data')
|
||
|
const current = expected.shift()
|
||
|
check(is, result, current.level, current.msg)
|
||
|
})
|
||
|
|
||
|
test('the wrong level throws', async ({ throws }) => {
|
||
|
const instance = pino()
|
||
|
throws(() => {
|
||
|
instance.level = 'kaboom'
|
||
|
})
|
||
|
})
|
||
|
|
||
|
test('set the level by number', async ({ is }) => {
|
||
|
const expected = [{
|
||
|
level: 50,
|
||
|
msg: 'this is an error'
|
||
|
}, {
|
||
|
level: 60,
|
||
|
msg: 'this is fatal'
|
||
|
}]
|
||
|
const stream = sink()
|
||
|
const instance = pino(stream)
|
||
|
|
||
|
instance.level = 50
|
||
|
instance.info('hello world')
|
||
|
instance.error('this is an error')
|
||
|
instance.fatal('this is fatal')
|
||
|
const result = await once(stream, 'data')
|
||
|
const current = expected.shift()
|
||
|
check(is, result, current.level, current.msg)
|
||
|
})
|
||
|
|
||
|
test('exposes level string mappings', async ({ is }) => {
|
||
|
is(pino.levels.values.error, 50)
|
||
|
})
|
||
|
|
||
|
test('exposes level number mappings', async ({ is }) => {
|
||
|
is(pino.levels.labels[50], 'error')
|
||
|
})
|
||
|
|
||
|
test('returns level integer', async ({ is }) => {
|
||
|
const instance = pino({ level: 'error' })
|
||
|
is(instance.levelVal, 50)
|
||
|
})
|
||
|
|
||
|
test('child returns level integer', async ({ is }) => {
|
||
|
const parent = pino({ level: 'error' })
|
||
|
const child = parent.child({ foo: 'bar' })
|
||
|
is(child.levelVal, 50)
|
||
|
})
|
||
|
|
||
|
test('set the level via exported pino function', async ({ is }) => {
|
||
|
const expected = [{
|
||
|
level: 50,
|
||
|
msg: 'this is an error'
|
||
|
}, {
|
||
|
level: 60,
|
||
|
msg: 'this is fatal'
|
||
|
}]
|
||
|
const stream = sink()
|
||
|
const instance = pino({ level: 'error' }, stream)
|
||
|
|
||
|
instance.info('hello world')
|
||
|
instance.error('this is an error')
|
||
|
instance.fatal('this is fatal')
|
||
|
const result = await once(stream, 'data')
|
||
|
const current = expected.shift()
|
||
|
check(is, result, current.level, current.msg)
|
||
|
})
|
||
|
|
||
|
test('level-change event', async ({ is }) => {
|
||
|
const instance = pino()
|
||
|
function handle (lvl, val, prevLvl, prevVal) {
|
||
|
is(lvl, 'trace')
|
||
|
is(val, 10)
|
||
|
is(prevLvl, 'info')
|
||
|
is(prevVal, 30)
|
||
|
}
|
||
|
instance.on('level-change', handle)
|
||
|
instance.level = 'trace'
|
||
|
instance.removeListener('level-change', handle)
|
||
|
instance.level = 'info'
|
||
|
|
||
|
var count = 0
|
||
|
|
||
|
const l1 = () => count++
|
||
|
const l2 = () => count++
|
||
|
const l3 = () => count++
|
||
|
instance.on('level-change', l1)
|
||
|
instance.on('level-change', l2)
|
||
|
instance.on('level-change', l3)
|
||
|
|
||
|
instance.level = 'trace'
|
||
|
instance.removeListener('level-change', l3)
|
||
|
instance.level = 'fatal'
|
||
|
instance.removeListener('level-change', l1)
|
||
|
instance.level = 'debug'
|
||
|
instance.removeListener('level-change', l2)
|
||
|
instance.level = 'info'
|
||
|
|
||
|
is(count, 6)
|
||
|
})
|
||
|
|
||
|
test('enable', async ({ fail }) => {
|
||
|
const instance = pino({
|
||
|
level: 'trace',
|
||
|
enabled: false
|
||
|
}, sink((result, enc) => {
|
||
|
fail('no data should be logged')
|
||
|
}))
|
||
|
|
||
|
Object.keys(pino.levels.values).forEach((level) => {
|
||
|
instance[level]('hello world')
|
||
|
})
|
||
|
})
|
||
|
|
||
|
test('silent level', async ({ fail }) => {
|
||
|
const instance = pino({
|
||
|
level: 'silent'
|
||
|
}, sink((result, enc) => {
|
||
|
fail('no data should be logged')
|
||
|
}))
|
||
|
|
||
|
Object.keys(pino.levels.values).forEach((level) => {
|
||
|
instance[level]('hello world')
|
||
|
})
|
||
|
})
|
||
|
|
||
|
test('set silent via Infinity', async ({ fail }) => {
|
||
|
const instance = pino({
|
||
|
level: Infinity
|
||
|
}, sink((result, enc) => {
|
||
|
fail('no data should be logged')
|
||
|
}))
|
||
|
|
||
|
Object.keys(pino.levels.values).forEach((level) => {
|
||
|
instance[level]('hello world')
|
||
|
})
|
||
|
})
|
||
|
|
||
|
test('exposed levels', async ({ same }) => {
|
||
|
same(Object.keys(pino.levels.values), [
|
||
|
'trace',
|
||
|
'debug',
|
||
|
'info',
|
||
|
'warn',
|
||
|
'error',
|
||
|
'fatal'
|
||
|
])
|
||
|
})
|
||
|
|
||
|
test('exposed labels', async ({ same }) => {
|
||
|
same(Object.keys(pino.levels.labels), [
|
||
|
'10',
|
||
|
'20',
|
||
|
'30',
|
||
|
'40',
|
||
|
'50',
|
||
|
'60'
|
||
|
])
|
||
|
})
|
||
|
|
||
|
test('setting level in child', async ({ is }) => {
|
||
|
const expected = [{
|
||
|
level: 50,
|
||
|
msg: 'this is an error'
|
||
|
}, {
|
||
|
level: 60,
|
||
|
msg: 'this is fatal'
|
||
|
}]
|
||
|
const instance = pino(sink((result, enc, cb) => {
|
||
|
const current = expected.shift()
|
||
|
check(is, result, current.level, current.msg)
|
||
|
cb()
|
||
|
})).child({ level: 30 })
|
||
|
|
||
|
instance.level = 'error'
|
||
|
instance.info('hello world')
|
||
|
instance.error('this is an error')
|
||
|
instance.fatal('this is fatal')
|
||
|
})
|
||
|
|
||
|
test('setting level by assigning a number to level', async ({ is }) => {
|
||
|
const instance = pino()
|
||
|
is(instance.levelVal, 30)
|
||
|
is(instance.level, 'info')
|
||
|
instance.level = 50
|
||
|
is(instance.levelVal, 50)
|
||
|
is(instance.level, 'error')
|
||
|
})
|
||
|
|
||
|
test('setting level by number to unknown value results in a throw', async ({ throws }) => {
|
||
|
const instance = pino()
|
||
|
throws(() => { instance.level = 973 })
|
||
|
})
|
||
|
|
||
|
test('setting level by assigning a known label to level', async ({ is }) => {
|
||
|
const instance = pino()
|
||
|
is(instance.levelVal, 30)
|
||
|
is(instance.level, 'info')
|
||
|
instance.level = 'error'
|
||
|
is(instance.levelVal, 50)
|
||
|
is(instance.level, 'error')
|
||
|
})
|
||
|
|
||
|
test('levelVal is read only', async ({ throws }) => {
|
||
|
const instance = pino()
|
||
|
throws(() => { instance.levelVal = 20 })
|
||
|
})
|
||
|
|
||
|
test('produces labels when told to', async ({ is }) => {
|
||
|
const expected = [{
|
||
|
level: 'info',
|
||
|
msg: 'hello world'
|
||
|
}]
|
||
|
const instance = pino({ useLevelLabels: true }, sink((result, enc, cb) => {
|
||
|
const current = expected.shift()
|
||
|
check(is, result, current.level, current.msg)
|
||
|
cb()
|
||
|
}))
|
||
|
|
||
|
instance.info('hello world')
|
||
|
})
|
||
|
|
||
|
test('resets levels from labels to numbers', async ({ is }) => {
|
||
|
const expected = [{
|
||
|
level: 30,
|
||
|
msg: 'hello world'
|
||
|
}]
|
||
|
pino({ useLevelLabels: true })
|
||
|
const instance = pino({ useLevelLabels: false }, sink((result, enc, cb) => {
|
||
|
const current = expected.shift()
|
||
|
check(is, result, current.level, current.msg)
|
||
|
cb()
|
||
|
}))
|
||
|
|
||
|
instance.info('hello world')
|
||
|
})
|
||
|
|
||
|
test('aliases changeLevelName to levelKey', async ({ is }) => {
|
||
|
const instance = pino({ changeLevelName: 'priority' }, sink((result, enc, cb) => {
|
||
|
is(result.priority, 30)
|
||
|
cb()
|
||
|
}))
|
||
|
|
||
|
instance.info('hello world')
|
||
|
})
|
||
|
|
||
|
test('changes label naming when told to', async ({ is }) => {
|
||
|
const expected = [{
|
||
|
priority: 30,
|
||
|
msg: 'hello world'
|
||
|
}]
|
||
|
const instance = pino({ levelKey: 'priority' }, sink((result, enc, cb) => {
|
||
|
const current = expected.shift()
|
||
|
is(result.priority, current.priority)
|
||
|
is(result.msg, current.msg)
|
||
|
cb()
|
||
|
}))
|
||
|
|
||
|
instance.info('hello world')
|
||
|
})
|
||
|
|
||
|
test('children produce labels when told to', async ({ is }) => {
|
||
|
const expected = [
|
||
|
{
|
||
|
level: 'info',
|
||
|
msg: 'child 1'
|
||
|
},
|
||
|
{
|
||
|
level: 'info',
|
||
|
msg: 'child 2'
|
||
|
}
|
||
|
]
|
||
|
const instance = pino({ useLevelLabels: true }, sink((result, enc, cb) => {
|
||
|
const current = expected.shift()
|
||
|
check(is, result, current.level, current.msg)
|
||
|
cb()
|
||
|
}))
|
||
|
|
||
|
const child1 = instance.child({ name: 'child1' })
|
||
|
const child2 = child1.child({ name: 'child2' })
|
||
|
|
||
|
child1.info('child 1')
|
||
|
child2.info('child 2')
|
||
|
})
|
||
|
|
||
|
test('produces labels for custom levels', async ({ is }) => {
|
||
|
const expected = [
|
||
|
{
|
||
|
level: 'info',
|
||
|
msg: 'hello world'
|
||
|
},
|
||
|
{
|
||
|
level: 'foo',
|
||
|
msg: 'foobar'
|
||
|
}
|
||
|
]
|
||
|
const opts = {
|
||
|
useLevelLabels: true,
|
||
|
customLevels: {
|
||
|
foo: 35
|
||
|
}
|
||
|
}
|
||
|
const instance = pino(opts, sink((result, enc, cb) => {
|
||
|
const current = expected.shift()
|
||
|
check(is, result, current.level, current.msg)
|
||
|
cb()
|
||
|
}))
|
||
|
|
||
|
instance.info('hello world')
|
||
|
instance.foo('foobar')
|
||
|
})
|
||
|
|
||
|
test('setting levelKey does not affect labels when told to', async ({ is }) => {
|
||
|
const instance = pino(
|
||
|
{
|
||
|
useLevelLabels: true,
|
||
|
levelKey: 'priority'
|
||
|
},
|
||
|
sink((result, enc, cb) => {
|
||
|
is(result.priority, 'info')
|
||
|
cb()
|
||
|
})
|
||
|
)
|
||
|
|
||
|
instance.info('hello world')
|
||
|
})
|
||
|
|
||
|
test('throws when creating a default label that does not exist in logger levels', async ({ is, throws }) => {
|
||
|
const defaultLevel = 'foo'
|
||
|
throws(() => {
|
||
|
pino({
|
||
|
customLevels: {
|
||
|
bar: 5
|
||
|
},
|
||
|
level: defaultLevel
|
||
|
})
|
||
|
})
|
||
|
try {
|
||
|
pino({
|
||
|
level: defaultLevel
|
||
|
})
|
||
|
} catch ({ message }) {
|
||
|
is(message, `default level:${defaultLevel} must be included in custom levels`)
|
||
|
}
|
||
|
})
|
||
|
|
||
|
test('throws when creating a default value that does not exist in logger levels', async ({ is, throws }) => {
|
||
|
const defaultLevel = 15
|
||
|
throws(() => {
|
||
|
pino({
|
||
|
customLevels: {
|
||
|
bar: 5
|
||
|
},
|
||
|
level: defaultLevel
|
||
|
})
|
||
|
})
|
||
|
try {
|
||
|
pino({
|
||
|
level: defaultLevel
|
||
|
})
|
||
|
} catch ({ message }) {
|
||
|
is(message, `default level:${defaultLevel} must be included in custom levels`)
|
||
|
}
|
||
|
})
|
||
|
|
||
|
test('throws when creating a default value that does not exist in logger levels', async ({ is, throws }) => {
|
||
|
throws(() => {
|
||
|
pino({
|
||
|
customLevels: {
|
||
|
foo: 5
|
||
|
},
|
||
|
useOnlyCustomLevels: true
|
||
|
})
|
||
|
})
|
||
|
try {
|
||
|
pino({
|
||
|
customLevels: {
|
||
|
foo: 5
|
||
|
},
|
||
|
useOnlyCustomLevels: true
|
||
|
})
|
||
|
} catch ({ message }) {
|
||
|
is(message, 'default level:info must be included in custom levels')
|
||
|
}
|
||
|
})
|
||
|
|
||
|
test('passes when creating a default value that exists in logger levels', async ({ is, throws }) => {
|
||
|
pino({
|
||
|
level: 30
|
||
|
})
|
||
|
})
|
||
|
|
||
|
test('fatal method sync-flushes the destination if sync flushing is available', async ({ pass, doesNotThrow, plan }) => {
|
||
|
plan(2)
|
||
|
const stream = sink()
|
||
|
stream.flushSync = () => {
|
||
|
pass('destination flushed')
|
||
|
}
|
||
|
const instance = pino(stream)
|
||
|
instance.fatal('this is fatal')
|
||
|
await once(stream, 'data')
|
||
|
doesNotThrow(() => {
|
||
|
stream.flushSync = undefined
|
||
|
instance.fatal('this is fatal')
|
||
|
})
|
||
|
})
|
||
|
|
||
|
test('fatal method should call async when sync-flushing fails', ({ equal, fail, doesNotThrow, plan }) => {
|
||
|
plan(2)
|
||
|
const messages = [
|
||
|
'this is fatal 1'
|
||
|
]
|
||
|
const stream = sink((result) => equal(result.msg, messages.shift()))
|
||
|
stream.flushSync = () => { throw new Error('Error') }
|
||
|
stream.flush = () => fail('flush should be called')
|
||
|
|
||
|
const instance = pino(stream)
|
||
|
doesNotThrow(() => instance.fatal(messages[0]))
|
||
|
})
|