This commit is contained in:
Dawid Dziurla 2020-03-26 15:37:35 +01:00
parent d9becc67b6
commit 9308795b8b
No known key found for this signature in database
GPG key ID: 7B6D8368172E9B0B
964 changed files with 104265 additions and 16 deletions

702
node_modules/pino/test/basic.test.js generated vendored Normal file
View file

@ -0,0 +1,702 @@
'use strict'
const os = require('os')
const { join } = require('path')
const { readFileSync, existsSync, statSync } = require('fs')
const { test } = require('tap')
const { sink, check, once } = require('./helper')
const pino = require('../')
const { version } = require('../package.json')
const { pid } = process
const hostname = os.hostname()
const watchFileCreated = (filename) => new Promise((resolve, reject) => {
const TIMEOUT = 800
const INTERVAL = 100
const threshold = TIMEOUT / INTERVAL
let counter = 0
const interval = setInterval(() => {
// On some CI runs file is created but not filled
if (existsSync(filename) && statSync(filename).size !== 0) {
clearInterval(interval)
resolve()
} else if (counter <= threshold) {
counter++
} else {
clearInterval(interval)
reject(new Error(`${filename} was not created.`))
}
}, INTERVAL)
})
test('pino version is exposed on export', async ({ is }) => {
is(pino.version, version)
})
test('pino version is exposed on instance', async ({ is }) => {
const instance = pino()
is(instance.version, version)
})
test('child instance exposes pino version', async ({ is }) => {
const child = pino().child({ foo: 'bar' })
is(child.version, version)
})
test('bindings are exposed on every instance', async ({ same }) => {
const instance = pino()
same(instance.bindings(), {})
})
test('bindings contain the name and the child bindings', async ({ same }) => {
const instance = pino({ name: 'basicTest', level: 'info' }).child({ foo: 'bar' }).child({ a: 2 })
same(instance.bindings(), { name: 'basicTest', foo: 'bar', a: 2 })
})
test('set bindings on instance', async ({ same }) => {
const instance = pino({ name: 'basicTest', level: 'info' })
instance.setBindings({ foo: 'bar' })
same(instance.bindings(), { name: 'basicTest', foo: 'bar' })
})
test('newly set bindings overwrite old bindings', async ({ same }) => {
const instance = pino({ name: 'basicTest', level: 'info', base: { foo: 'bar' } })
instance.setBindings({ foo: 'baz' })
same(instance.bindings(), { name: 'basicTest', foo: 'baz' })
})
test('set bindings on child instance', async ({ same }) => {
const child = pino({ name: 'basicTest', level: 'info' }).child({})
child.setBindings({ foo: 'bar' })
same(child.bindings(), { name: 'basicTest', foo: 'bar' })
})
test('child should have bindings set by parent', async ({ same }) => {
const instance = pino({ name: 'basicTest', level: 'info' })
instance.setBindings({ foo: 'bar' })
const child = instance.child({})
same(child.bindings(), { name: 'basicTest', foo: 'bar' })
})
test('child should not share bindings of parent set after child creation', async ({ same }) => {
const instance = pino({ name: 'basicTest', level: 'info' })
const child = instance.child({})
instance.setBindings({ foo: 'bar' })
same(instance.bindings(), { name: 'basicTest', foo: 'bar' })
same(child.bindings(), { name: 'basicTest' })
})
function levelTest (name, level) {
test(`${name} logs as ${level}`, async ({ is }) => {
const stream = sink()
const instance = pino(stream)
instance.level = name
instance[name]('hello world')
check(is, await once(stream, 'data'), level, 'hello world')
})
test(`passing objects at level ${name}`, async ({ is, same }) => {
const stream = sink()
const instance = pino(stream)
instance.level = name
const obj = { hello: 'world' }
instance[name](obj)
const result = await once(stream, 'data')
is(new Date(result.time) <= new Date(), true, 'time is greater than Date.now()')
is(result.pid, pid)
is(result.hostname, hostname)
is(result.level, level)
is(result.hello, 'world')
is(result.v, 1)
same(Object.keys(obj), ['hello'])
})
test(`passing an object and a string at level ${name}`, async ({ is, same }) => {
const stream = sink()
const instance = pino(stream)
instance.level = name
const obj = { hello: 'world' }
instance[name](obj, 'a string')
const result = await once(stream, 'data')
is(new Date(result.time) <= new Date(), true, 'time is greater than Date.now()')
delete result.time
same(result, {
pid: pid,
hostname: hostname,
level: level,
msg: 'a string',
hello: 'world',
v: 1
})
same(Object.keys(obj), ['hello'])
})
test(`overriding object key by string at level ${name}`, async ({ is, same }) => {
const stream = sink()
const instance = pino(stream)
instance.level = name
instance[name]({ hello: 'world', msg: 'object' }, 'string')
const result = await once(stream, 'data')
is(new Date(result.time) <= new Date(), true, 'time is greater than Date.now()')
delete result.time
same(result, {
pid: pid,
hostname: hostname,
level: level,
msg: 'string',
hello: 'world',
v: 1
})
})
test(`formatting logs as ${name}`, async ({ is }) => {
const stream = sink()
const instance = pino(stream)
instance.level = name
instance[name]('hello %d', 42)
const result = await once(stream, 'data')
check(is, result, level, 'hello 42')
})
test(`formatting a symbol at level ${name}`, async ({ is }) => {
const stream = sink()
const instance = pino(stream)
instance.level = name
const sym = Symbol('foo')
instance[name]('hello', sym)
const result = await once(stream, 'data')
check(is, result, level, 'hello Symbol(foo)')
})
test(`passing error with a serializer at level ${name}`, async ({ is, same }) => {
const stream = sink()
const err = new Error('myerror')
const instance = pino({
serializers: {
err: pino.stdSerializers.err
}
}, stream)
instance.level = name
instance[name]({ err })
const result = await once(stream, 'data')
is(new Date(result.time) <= new Date(), true, 'time is greater than Date.now()')
delete result.time
same(result, {
pid: pid,
hostname: hostname,
level: level,
err: {
type: 'Error',
message: err.message,
stack: err.stack
},
v: 1
})
})
test(`child logger for level ${name}`, async ({ is, same }) => {
const stream = sink()
const instance = pino(stream)
instance.level = name
const child = instance.child({ hello: 'world' })
child[name]('hello world')
const result = await once(stream, 'data')
is(new Date(result.time) <= new Date(), true, 'time is greater than Date.now()')
delete result.time
same(result, {
pid: pid,
hostname: hostname,
level: level,
msg: 'hello world',
hello: 'world',
v: 1
})
})
}
levelTest('fatal', 60)
levelTest('error', 50)
levelTest('warn', 40)
levelTest('info', 30)
levelTest('debug', 20)
levelTest('trace', 10)
test('serializers can return undefined to strip field', async ({ is }) => {
const stream = sink()
const instance = pino({
serializers: {
test () { return undefined }
}
}, stream)
instance.info({ test: 'sensitive info' })
const result = await once(stream, 'data')
is('test' in result, false)
})
test('does not explode with a circular ref', async ({ doesNotThrow }) => {
const stream = sink()
const instance = pino(stream)
const b = {}
const a = {
hello: b
}
b.a = a // circular ref
doesNotThrow(() => instance.info(a))
})
test('set the name', async ({ is, same }) => {
const stream = sink()
const instance = pino({
name: 'hello'
}, stream)
instance.fatal('this is fatal')
const result = await once(stream, 'data')
is(new Date(result.time) <= new Date(), true, 'time is greater than Date.now()')
delete result.time
same(result, {
pid: pid,
hostname: hostname,
level: 60,
name: 'hello',
msg: 'this is fatal',
v: 1
})
})
test('set the messageKey', async ({ is, same }) => {
const stream = sink()
const message = 'hello world'
const messageKey = 'fooMessage'
const instance = pino({
messageKey
}, stream)
instance.info(message)
const result = await once(stream, 'data')
is(new Date(result.time) <= new Date(), true, 'time is greater than Date.now()')
delete result.time
same(result, {
pid: pid,
hostname: hostname,
level: 30,
fooMessage: message,
v: 1
})
})
test('set the nestedKey', async ({ is, same }) => {
const stream = sink()
const object = { hello: 'world' }
const nestedKey = 'stuff'
const instance = pino({
nestedKey
}, stream)
instance.info(object)
const result = await once(stream, 'data')
is(new Date(result.time) <= new Date(), true, 'time is greater than Date.now()')
delete result.time
same(result, {
pid: pid,
hostname: hostname,
level: 30,
stuff: object,
v: 1
})
})
test('set undefined properties', async ({ is, same }) => {
const stream = sink()
const instance = pino(stream)
instance.info({ hello: 'world', property: undefined })
const result = await once(stream, 'data')
is(new Date(result.time) <= new Date(), true, 'time is greater than Date.now()')
delete result.time
same(result, {
pid: pid,
hostname: hostname,
level: 30,
hello: 'world',
v: 1
})
})
test('prototype properties are not logged', async ({ is }) => {
const stream = sink()
const instance = pino(stream)
instance.info(Object.create({ hello: 'world' }))
const { hello } = await once(stream, 'data')
is(hello, undefined)
})
test('set the base', async ({ is, same }) => {
const stream = sink()
const instance = pino({
base: {
a: 'b'
}
}, stream)
instance.fatal('this is fatal')
const result = await once(stream, 'data')
is(new Date(result.time) <= new Date(), true, 'time is greater than Date.now()')
delete result.time
same(result, {
a: 'b',
level: 60,
msg: 'this is fatal',
v: 1
})
})
test('set the base to null', async ({ is, same }) => {
const stream = sink()
const instance = pino({
base: null
}, stream)
instance.fatal('this is fatal')
const result = await once(stream, 'data')
is(new Date(result.time) <= new Date(), true, 'time is greater than Date.now()')
delete result.time
same(result, {
level: 60,
msg: 'this is fatal',
v: 1
})
})
test('set the base to null and use a serializer', async ({ is, same }) => {
const stream = sink()
const instance = pino({
base: null,
serializers: {
[Symbol.for('pino.*')]: (input) => {
return Object.assign({}, input, { additionalMessage: 'using pino' })
}
}
}, stream)
instance.fatal('this is fatal too')
const result = await once(stream, 'data')
is(new Date(result.time) <= new Date(), true, 'time is greater than Date.now()')
delete result.time
same(result, {
level: 60,
msg: 'this is fatal too',
additionalMessage: 'using pino',
v: 1
})
})
test('throw if creating child without bindings', async ({ throws }) => {
const stream = sink()
const instance = pino(stream)
throws(() => instance.child())
})
test('correctly escapes msg strings with stray double quote at end', async ({ same }) => {
const stream = sink()
const instance = pino({
name: 'hello'
}, stream)
instance.fatal('this contains "')
const result = await once(stream, 'data')
delete result.time
same(result, {
pid: pid,
hostname: hostname,
level: 60,
name: 'hello',
msg: 'this contains "',
v: 1
})
})
test('correctly escape msg strings with unclosed double quote', async ({ same }) => {
const stream = sink()
const instance = pino({
name: 'hello'
}, stream)
instance.fatal('" this contains')
const result = await once(stream, 'data')
delete result.time
same(result, {
pid: pid,
hostname: hostname,
level: 60,
name: 'hello',
msg: '" this contains',
v: 1
})
})
// https://github.com/pinojs/pino/issues/139
test('object and format string', async ({ same }) => {
const stream = sink()
const instance = pino(stream)
instance.info({}, 'foo %s', 'bar')
const result = await once(stream, 'data')
delete result.time
same(result, {
pid: pid,
hostname: hostname,
level: 30,
msg: 'foo bar',
v: 1
})
})
test('object and format string property', async ({ same }) => {
const stream = sink()
const instance = pino(stream)
instance.info({ answer: 42 }, 'foo %s', 'bar')
const result = await once(stream, 'data')
delete result.time
same(result, {
pid: pid,
hostname: hostname,
level: 30,
msg: 'foo bar',
answer: 42,
v: 1
})
})
test('correctly strip undefined when returned from toJSON', async ({ is }) => {
const stream = sink()
const instance = pino({
test: 'this'
}, stream)
instance.fatal({ test: { toJSON () { return undefined } } })
const result = await once(stream, 'data')
is('test' in result, false)
})
test('correctly supports stderr', async ({ same }) => {
// stderr inherits from Stream, rather than Writable
const dest = {
writable: true,
write (result) {
result = JSON.parse(result)
delete result.time
same(result, {
pid: pid,
hostname: hostname,
level: 60,
msg: 'a message',
v: 1
})
}
}
const instance = pino(dest)
instance.fatal('a message')
})
test('normalize number to string', async ({ same }) => {
const stream = sink()
const instance = pino(stream)
instance.info(1)
const result = await once(stream, 'data')
delete result.time
same(result, {
pid: pid,
hostname: hostname,
level: 30,
msg: '1',
v: 1
})
})
test('normalize number to string with an object', async ({ same }) => {
const stream = sink()
const instance = pino(stream)
instance.info({ answer: 42 }, 1)
const result = await once(stream, 'data')
delete result.time
same(result, {
pid: pid,
hostname: hostname,
level: 30,
msg: '1',
answer: 42,
v: 1
})
})
test('handles objects with null prototype', async ({ same }) => {
const stream = sink()
const instance = pino(stream)
const o = Object.create(null)
o.test = 'test'
instance.info(o)
const result = await once(stream, 'data')
delete result.time
same(result, {
pid: pid,
hostname: hostname,
level: 30,
test: 'test',
v: 1
})
})
test('pino.destination', async ({ same }) => {
const tmp = join(
os.tmpdir(),
'_' + Math.random().toString(36).substr(2, 9)
)
const instance = pino(pino.destination(tmp))
instance.info('hello')
await watchFileCreated(tmp)
const result = JSON.parse(readFileSync(tmp).toString())
delete result.time
same(result, {
pid: pid,
hostname: hostname,
level: 30,
msg: 'hello',
v: 1
})
})
test('auto pino.destination with a string', async ({ same }) => {
const tmp = join(
os.tmpdir(),
'_' + Math.random().toString(36).substr(2, 9)
)
const instance = pino(tmp)
instance.info('hello')
await watchFileCreated(tmp)
const result = JSON.parse(readFileSync(tmp).toString())
delete result.time
same(result, {
pid: pid,
hostname: hostname,
level: 30,
msg: 'hello',
v: 1
})
})
test('auto pino.destination with a string as second argument', async ({ same }) => {
const tmp = join(
os.tmpdir(),
'_' + Math.random().toString(36).substr(2, 9)
)
const instance = pino(null, tmp)
instance.info('hello')
await watchFileCreated(tmp)
const result = JSON.parse(readFileSync(tmp).toString())
delete result.time
same(result, {
pid: pid,
hostname: hostname,
level: 30,
msg: 'hello',
v: 1
})
})
test('does not override opts with a string as second argument', async ({ same }) => {
const tmp = join(
os.tmpdir(),
'_' + Math.random().toString(36).substr(2, 9)
)
const instance = pino({
timestamp: () => ',"time":"none"'
}, tmp)
instance.info('hello')
await watchFileCreated(tmp)
const result = JSON.parse(readFileSync(tmp).toString())
same(result, {
pid: pid,
hostname: hostname,
level: 30,
time: 'none',
msg: 'hello',
v: 1
})
})
// https://github.com/pinojs/pino/issues/222
test('children with same names render in correct order', async ({ is }) => {
const stream = sink()
const root = pino(stream)
root.child({ a: 1 }).child({ a: 2 }).info({ a: 3 })
const { a } = await once(stream, 'data')
is(a, 3, 'last logged object takes precedence')
})
// https://github.com/pinojs/pino/pull/251 - use this.stringify
test('use `fast-safe-stringify` to avoid circular dependencies', async ({ deepEqual }) => {
const stream = sink()
const root = pino(stream)
// circular depth
const obj = {}
obj.a = obj
root.info(obj)
const { a } = await once(stream, 'data')
deepEqual(a, { a: '[Circular]' })
})
test('fast-safe-stringify must be used when interpolating', async (t) => {
const stream = sink()
const instance = pino(stream)
const o = { a: { b: {} } }
o.a.b.c = o.a.b
instance.info('test', o)
const { msg } = await once(stream, 'data')
t.is(msg, 'test {"a":{"b":{"c":"[Circular]"}}}')
})
test('throws when setting useOnlyCustomLevels without customLevels', async ({ is, throws }) => {
throws(() => {
pino({
useOnlyCustomLevels: true
})
})
try {
pino({
useOnlyCustomLevels: true
})
} catch ({ message }) {
is(message, 'customLevels is required if useOnlyCustomLevels is set true')
}
})
test('correctly log Infinity', async (t) => {
const stream = sink()
const instance = pino(stream)
const o = { num: Infinity }
instance.info(o)
const { num } = await once(stream, 'data')
t.is(num, null)
})
test('correctly log -Infinity', async (t) => {
const stream = sink()
const instance = pino(stream)
const o = { num: -Infinity }
instance.info(o)
const { num } = await once(stream, 'data')
t.is(num, null)
})
test('correctly log NaN', async (t) => {
const stream = sink()
const instance = pino(stream)
const o = { num: NaN }
instance.info(o)
const { num } = await once(stream, 'data')
t.is(num, null)
})

42
node_modules/pino/test/broken-pipe.test.js generated vendored Normal file
View file

@ -0,0 +1,42 @@
'use strict'
const t = require('tap')
const { join } = require('path')
const { fork } = require('child_process')
const { once } = require('./helper')
const pino = require('..')
function test (file) {
file = join('fixtures', 'broken-pipe', file)
t.test(file, { parallel: true }, async ({ is }) => {
const child = fork(join(__dirname, file), { silent: true })
child.stdout.destroy()
child.stderr.pipe(process.stdout)
const res = await once(child, 'close')
is(res, 0) // process exits successfully
})
}
t.jobs = 42
test('basic.js')
test('destination.js')
test('extreme.js')
t.test('let error pass through', ({ is, plan }) => {
plan(3)
const stream = pino.destination()
// side effect of the pino constructor is that it will set an
// event handler for error
pino(stream)
process.nextTick(() => stream.emit('error', new Error('kaboom')))
process.nextTick(() => stream.emit('error', new Error('kaboom')))
stream.on('error', (err) => {
is(err.message, 'kaboom')
})
})

218
node_modules/pino/test/browser-levels.test.js generated vendored Normal file
View file

@ -0,0 +1,218 @@
'use strict'
const test = require('tape')
const pino = require('../browser')
test('set the level by string', ({ end, same, is }) => {
const expected = [
{
level: 50,
msg: 'this is an error'
},
{
level: 60,
msg: 'this is fatal'
}
]
const instance = pino({
browser: {
write (actual) {
checkLogObjects(is, same, actual, expected.shift())
}
}
})
instance.level = 'error'
instance.info('hello world')
instance.error('this is an error')
instance.fatal('this is fatal')
end()
})
test('set the level by string. init with silent', ({ end, same, is }) => {
const expected = [
{
level: 50,
msg: 'this is an error'
},
{
level: 60,
msg: 'this is fatal'
}
]
const instance = pino({
level: 'silent',
browser: {
write (actual) {
checkLogObjects(is, same, actual, expected.shift())
}
}
})
instance.level = 'error'
instance.info('hello world')
instance.error('this is an error')
instance.fatal('this is fatal')
end()
})
test('set the level by string. init with silent and transmit', ({ end, same, is }) => {
const expected = [
{
level: 50,
msg: 'this is an error'
},
{
level: 60,
msg: 'this is fatal'
}
]
const instance = pino({
level: 'silent',
browser: {
write (actual) {
checkLogObjects(is, same, actual, expected.shift())
}
},
transmit: {
send () {}
}
})
instance.level = 'error'
instance.info('hello world')
instance.error('this is an error')
instance.fatal('this is fatal')
end()
})
test('set the level via constructor', ({ end, same, is }) => {
const expected = [
{
level: 50,
msg: 'this is an error'
},
{
level: 60,
msg: 'this is fatal'
}
]
const instance = pino({
level: 'error',
browser: {
write (actual) {
checkLogObjects(is, same, actual, expected.shift())
}
}
})
instance.info('hello world')
instance.error('this is an error')
instance.fatal('this is fatal')
end()
})
test('the wrong level throws', ({ end, throws }) => {
const instance = pino()
throws(() => {
instance.level = 'kaboom'
})
end()
})
test('the wrong level by number throws', ({ end, throws }) => {
const instance = pino()
throws(() => {
instance.levelVal = 55
})
end()
})
test('exposes level string mappings', ({ end, is }) => {
is(pino.levels.values.error, 50)
end()
})
test('exposes level number mappings', ({ end, is }) => {
is(pino.levels.labels[50], 'error')
end()
})
test('returns level integer', ({ end, is }) => {
const instance = pino({ level: 'error' })
is(instance.levelVal, 50)
end()
})
test('silent level via constructor', ({ end, fail }) => {
const instance = pino({
level: 'silent',
browser: {
write () {
fail('no data should be logged')
}
}
})
Object.keys(pino.levels.values).forEach((level) => {
instance[level]('hello world')
})
end()
})
test('silent level by string', ({ end, fail }) => {
const instance = pino({
browser: {
write () {
fail('no data should be logged')
}
}
})
instance.level = 'silent'
Object.keys(pino.levels.values).forEach((level) => {
instance[level]('hello world')
})
end()
})
test('exposed levels', ({ end, same }) => {
same(Object.keys(pino.levels.values), [
'fatal',
'error',
'warn',
'info',
'debug',
'trace'
])
end()
})
test('exposed labels', ({ end, same }) => {
same(Object.keys(pino.levels.labels), [
'10',
'20',
'30',
'40',
'50',
'60'
])
end()
})
function checkLogObjects (is, same, actual, expected) {
is(actual.time <= Date.now(), true, 'time is greater than Date.now()')
const actualCopy = Object.assign({}, actual)
const expectedCopy = Object.assign({}, expected)
delete actualCopy.time
delete expectedCopy.time
same(actualCopy, expectedCopy)
}

327
node_modules/pino/test/browser-serializers.test.js generated vendored Normal file
View file

@ -0,0 +1,327 @@
'use strict'
// eslint-disable-next-line
if (typeof $1 !== 'undefined') $1 = arguments.callee.caller.arguments[0]
const test = require('tape')
const fresh = require('import-fresh')
const pino = require('../browser')
const parentSerializers = {
test: () => 'parent'
}
const childSerializers = {
test: () => 'child'
}
test('serializers override values', ({ end, is }) => {
const parent = pino({
serializers: parentSerializers,
browser: {
serialize: true,
write (o) {
is(o.test, 'parent')
end()
}
}
})
parent.fatal({ test: 'test' })
})
test('without the serialize option, serializers do not override values', ({ end, is }) => {
const parent = pino({
serializers: parentSerializers,
browser: {
write (o) {
is(o.test, 'test')
end()
}
}
})
parent.fatal({ test: 'test' })
})
if (process.title !== 'browser') {
test('if serialize option is true, standard error serializer is auto enabled', ({ end, same }) => {
const err = Error('test')
err.code = 'test'
err.type = 'Error' // get that cov
const expect = pino.stdSerializers.err(err)
const consoleError = console.error
console.error = function (err) {
same(err, expect)
}
const logger = fresh('../browser')({
browser: { serialize: true }
})
console.error = consoleError
logger.fatal(err)
end()
})
test('if serialize option is array, standard error serializer is auto enabled', ({ end, same }) => {
const err = Error('test')
err.code = 'test'
const expect = pino.stdSerializers.err(err)
const consoleError = console.error
console.error = function (err) {
same(err, expect)
}
const logger = fresh('../browser', require)({
browser: { serialize: [] }
})
console.error = consoleError
logger.fatal(err)
end()
})
test('if serialize option is array containing !stdSerializers.err, standard error serializer is disabled', ({ end, is }) => {
const err = Error('test')
err.code = 'test'
const expect = err
const consoleError = console.error
console.error = function (err) {
is(err, expect)
}
const logger = fresh('../browser', require)({
browser: { serialize: ['!stdSerializers.err'] }
})
console.error = consoleError
logger.fatal(err)
end()
})
test('in browser, serializers apply to all objects', ({ end, is }) => {
const consoleError = console.error
console.error = function (test, test2, test3, test4, test5) {
is(test.key, 'serialized')
is(test2.key2, 'serialized2')
is(test5.key3, 'serialized3')
}
const logger = fresh('../browser', require)({
serializers: {
key: () => 'serialized',
key2: () => 'serialized2',
key3: () => 'serialized3'
},
browser: { serialize: true }
})
console.error = consoleError
logger.fatal({ key: 'test' }, { key2: 'test' }, 'str should skip', [{ foo: 'array should skip' }], { key3: 'test' })
end()
})
test('serialize can be an array of selected serializers', ({ end, is }) => {
const consoleError = console.error
console.error = function (test, test2, test3, test4, test5) {
is(test.key, 'test')
is(test2.key2, 'serialized2')
is(test5.key3, 'test')
}
const logger = fresh('../browser', require)({
serializers: {
key: () => 'serialized',
key2: () => 'serialized2',
key3: () => 'serialized3'
},
browser: { serialize: ['key2'] }
})
console.error = consoleError
logger.fatal({ key: 'test' }, { key2: 'test' }, 'str should skip', [{ foo: 'array should skip' }], { key3: 'test' })
end()
})
test('serialize filter applies to child loggers', ({ end, is }) => {
const consoleError = console.error
console.error = function (binding, test, test2, test3, test4, test5) {
is(test.key, 'test')
is(test2.key2, 'serialized2')
is(test5.key3, 'test')
}
const logger = fresh('../browser', require)({
browser: { serialize: ['key2'] }
})
console.error = consoleError
logger.child({
aBinding: 'test',
serializers: {
key: () => 'serialized',
key2: () => 'serialized2',
key3: () => 'serialized3'
}
}).fatal({ key: 'test' }, { key2: 'test' }, 'str should skip', [{ foo: 'array should skip' }], { key3: 'test' })
end()
})
test('parent serializers apply to child bindings', ({ end, is }) => {
const consoleError = console.error
console.error = function (binding) {
is(binding.key, 'serialized')
}
const logger = fresh('../browser', require)({
serializers: {
key: () => 'serialized'
},
browser: { serialize: true }
})
console.error = consoleError
logger.child({ key: 'test' }).fatal({ test: 'test' })
end()
})
test('child serializers apply to child bindings', ({ end, is }) => {
const consoleError = console.error
console.error = function (binding) {
is(binding.key, 'serialized')
}
const logger = fresh('../browser', require)({
browser: { serialize: true }
})
console.error = consoleError
logger.child({
key: 'test',
serializers: {
key: () => 'serialized'
}
}).fatal({ test: 'test' })
end()
})
}
test('child does not overwrite parent serializers', ({ end, is }) => {
var c = 0
const parent = pino({
serializers: parentSerializers,
browser: {
serialize: true,
write (o) {
c++
if (c === 1) is(o.test, 'parent')
if (c === 2) {
is(o.test, 'child')
end()
}
}
}
})
const child = parent.child({ serializers: childSerializers })
parent.fatal({ test: 'test' })
child.fatal({ test: 'test' })
})
test('children inherit parent serializers', ({ end, is }) => {
const parent = pino({
serializers: parentSerializers,
browser: {
serialize: true,
write (o) {
is(o.test, 'parent')
}
}
})
const child = parent.child({ a: 'property' })
child.fatal({ test: 'test' })
end()
})
test('children serializers get called', ({ end, is }) => {
const parent = pino({
test: 'this',
browser: {
serialize: true,
write (o) {
is(o.test, 'child')
}
}
})
const child = parent.child({ a: 'property', serializers: childSerializers })
child.fatal({ test: 'test' })
end()
})
test('children serializers get called when inherited from parent', ({ end, is }) => {
const parent = pino({
test: 'this',
serializers: parentSerializers,
browser: {
serialize: true,
write: (o) => {
is(o.test, 'pass')
}
}
})
const child = parent.child({ serializers: { test: () => 'pass' } })
child.fatal({ test: 'fail' })
end()
})
test('non overriden serializers are available in the children', ({ end, is }) => {
const pSerializers = {
onlyParent: () => 'parent',
shared: () => 'parent'
}
const cSerializers = {
shared: () => 'child',
onlyChild: () => 'child'
}
var c = 0
const parent = pino({
serializers: pSerializers,
browser: {
serialize: true,
write (o) {
c++
if (c === 1) is(o.shared, 'child')
if (c === 2) is(o.onlyParent, 'parent')
if (c === 3) is(o.onlyChild, 'child')
if (c === 4) is(o.onlyChild, 'test')
}
}
})
const child = parent.child({ serializers: cSerializers })
child.fatal({ shared: 'test' })
child.fatal({ onlyParent: 'test' })
child.fatal({ onlyChild: 'test' })
parent.fatal({ onlyChild: 'test' })
end()
})

349
node_modules/pino/test/browser-transmit.test.js generated vendored Normal file
View file

@ -0,0 +1,349 @@
'use strict'
const test = require('tape')
const pino = require('../browser')
function noop () {}
test('throws if transmit object does not have send function', ({ end, throws }) => {
throws(() => {
pino({ browser: { transmit: {} } })
})
throws(() => {
pino({ browser: { transmit: { send: 'not a func' } } })
})
end()
})
test('calls send function after write', ({ end, is }) => {
var c = 0
const logger = pino({
browser: {
write: () => {
c++
},
transmit: {
send () { is(c, 1) }
}
}
})
logger.fatal({ test: 'test' })
end()
})
test('passes send function the logged level', ({ end, is }) => {
const logger = pino({
browser: {
write () {},
transmit: {
send (level) {
is(level, 'fatal')
}
}
}
})
logger.fatal({ test: 'test' })
end()
})
test('passes send function message strings in logEvent object when asObject is not set', ({ end, same, is }) => {
const logger = pino({
browser: {
write: noop,
transmit: {
send (level, { messages }) {
is(messages[0], 'test')
is(messages[1], 'another test')
}
}
}
})
logger.fatal('test', 'another test')
end()
})
test('passes send function message objects in logEvent object when asObject is not set', ({ end, same, is }) => {
const logger = pino({
browser: {
write: noop,
transmit: {
send (level, { messages }) {
same(messages[0], { test: 'test' })
is(messages[1], 'another test')
}
}
}
})
logger.fatal({ test: 'test' }, 'another test')
end()
})
test('passes send function message strings in logEvent object when asObject is set', ({ end, same, is }) => {
const logger = pino({
browser: {
asObject: true,
write: noop,
transmit: {
send (level, { messages }) {
is(messages[0], 'test')
is(messages[1], 'another test')
}
}
}
})
logger.fatal('test', 'another test')
end()
})
test('passes send function message objects in logEvent object when asObject is set', ({ end, same, is }) => {
const logger = pino({
browser: {
asObject: true,
write: noop,
transmit: {
send (level, { messages }) {
same(messages[0], { test: 'test' })
is(messages[1], 'another test')
}
}
}
})
logger.fatal({ test: 'test' }, 'another test')
end()
})
test('supplies a timestamp (ts) in logEvent object which is exactly the same as the `time` property in asObject mode', ({ end, is }) => {
var expected
const logger = pino({
browser: {
asObject: true, // implict because `write`, but just to be explicit
write (o) {
expected = o.time
},
transmit: {
send (level, logEvent) {
is(logEvent.ts, expected)
}
}
}
})
logger.fatal('test')
end()
})
test('passes send function child bindings via logEvent object', ({ end, same, is }) => {
const logger = pino({
browser: {
write: noop,
transmit: {
send (level, logEvent) {
const messages = logEvent.messages
const bindings = logEvent.bindings
same(bindings[0], { first: 'binding' })
same(bindings[1], { second: 'binding2' })
same(messages[0], { test: 'test' })
is(messages[1], 'another test')
}
}
}
})
logger
.child({ first: 'binding' })
.child({ second: 'binding2' })
.fatal({ test: 'test' }, 'another test')
end()
})
test('passes send function level:{label, value} via logEvent object', ({ end, is }) => {
const logger = pino({
browser: {
write: noop,
transmit: {
send (level, logEvent) {
const label = logEvent.level.label
const value = logEvent.level.value
is(label, 'fatal')
is(value, 60)
}
}
}
})
logger.fatal({ test: 'test' }, 'another test')
end()
})
test('calls send function according to transmit.level', ({ end, is }) => {
var c = 0
const logger = pino({
browser: {
write: noop,
transmit: {
level: 'error',
send (level) {
c++
if (c === 1) is(level, 'error')
if (c === 2) is(level, 'fatal')
}
}
}
})
logger.warn('ignored')
logger.error('test')
logger.fatal('test')
end()
})
test('transmit.level defaults to logger level', ({ end, is }) => {
var c = 0
const logger = pino({
level: 'error',
browser: {
write: noop,
transmit: {
send (level) {
c++
if (c === 1) is(level, 'error')
if (c === 2) is(level, 'fatal')
}
}
}
})
logger.warn('ignored')
logger.error('test')
logger.fatal('test')
end()
})
test('transmit.level is effective even if lower than logger level', ({ end, is }) => {
var c = 0
const logger = pino({
level: 'error',
browser: {
write: noop,
transmit: {
level: 'info',
send (level) {
c++
if (c === 1) is(level, 'warn')
if (c === 2) is(level, 'error')
if (c === 3) is(level, 'fatal')
}
}
}
})
logger.warn('ignored')
logger.error('test')
logger.fatal('test')
end()
})
test('applies all serializers to messages and bindings (serialize:false - default)', ({ end, same, is }) => {
const logger = pino({
serializers: {
first: () => 'first',
second: () => 'second',
test: () => 'serialize it'
},
browser: {
write: noop,
transmit: {
send (level, logEvent) {
const messages = logEvent.messages
const bindings = logEvent.bindings
same(bindings[0], { first: 'first' })
same(bindings[1], { second: 'second' })
same(messages[0], { test: 'serialize it' })
is(messages[1].type, 'Error')
}
}
}
})
logger
.child({ first: 'binding' })
.child({ second: 'binding2' })
.fatal({ test: 'test' }, Error())
end()
})
test('applies all serializers to messages and bindings (serialize:true)', ({ end, same, is }) => {
const logger = pino({
serializers: {
first: () => 'first',
second: () => 'second',
test: () => 'serialize it'
},
browser: {
serialize: true,
write: noop,
transmit: {
send (level, logEvent) {
const messages = logEvent.messages
const bindings = logEvent.bindings
same(bindings[0], { first: 'first' })
same(bindings[1], { second: 'second' })
same(messages[0], { test: 'serialize it' })
is(messages[1].type, 'Error')
}
}
}
})
logger
.child({ first: 'binding' })
.child({ second: 'binding2' })
.fatal({ test: 'test' }, Error())
end()
})
test('extracts correct bindings and raw messages over multiple transmits', ({ end, same, is }) => {
var messages = null
var bindings = null
const logger = pino({
browser: {
write: noop,
transmit: {
send (level, logEvent) {
messages = logEvent.messages
bindings = logEvent.bindings
}
}
}
})
const child = logger.child({ child: true })
const grandchild = child.child({ grandchild: true })
logger.fatal({ test: 'parent:test1' })
logger.fatal({ test: 'parent:test2' })
same([], bindings)
same([{ test: 'parent:test2' }], messages)
child.fatal({ test: 'child:test1' })
child.fatal({ test: 'child:test2' })
same([{ child: true }], bindings)
same([{ test: 'child:test2' }], messages)
grandchild.fatal({ test: 'grandchild:test1' })
grandchild.fatal({ test: 'grandchild:test2' })
same([{ child: true }, { grandchild: true }], bindings)
same([{ test: 'grandchild:test2' }], messages)
end()
})

553
node_modules/pino/test/browser.test.js generated vendored Normal file
View file

@ -0,0 +1,553 @@
'use strict'
const test = require('tape')
const fresh = require('import-fresh')
const pinoStdSerializers = require('pino-std-serializers')
const pino = require('../browser')
levelTest('fatal')
levelTest('error')
levelTest('warn')
levelTest('info')
levelTest('debug')
levelTest('trace')
test('silent level', ({ end, fail, pass }) => {
const instance = pino({
level: 'silent',
browser: { write: fail }
})
instance.info('test')
const child = instance.child({ test: 'test' })
child.info('msg-test')
// use setTimeout because setImmediate isn't supported in most browsers
setTimeout(() => {
pass()
end()
}, 0)
})
test('enabled false', ({ end, fail, pass }) => {
const instance = pino({
enabled: false,
browser: { write: fail }
})
instance.info('test')
const child = instance.child({ test: 'test' })
child.info('msg-test')
// use setTimeout because setImmediate isn't supported in most browsers
setTimeout(() => {
pass()
end()
}, 0)
})
test('throw if creating child without bindings', ({ end, throws }) => {
const instance = pino()
throws(() => instance.child())
end()
})
test('stubs write, flush and ee methods on instance', ({ end, ok, is }) => {
const instance = pino()
ok(isFunc(instance.setMaxListeners))
ok(isFunc(instance.getMaxListeners))
ok(isFunc(instance.emit))
ok(isFunc(instance.addListener))
ok(isFunc(instance.on))
ok(isFunc(instance.prependListener))
ok(isFunc(instance.once))
ok(isFunc(instance.prependOnceListener))
ok(isFunc(instance.removeListener))
ok(isFunc(instance.removeAllListeners))
ok(isFunc(instance.listeners))
ok(isFunc(instance.listenerCount))
ok(isFunc(instance.eventNames))
ok(isFunc(instance.write))
ok(isFunc(instance.flush))
is(instance.on(), undefined)
end()
})
test('exposes levels object', ({ end, same }) => {
same(pino.levels, {
values: {
fatal: 60,
error: 50,
warn: 40,
info: 30,
debug: 20,
trace: 10
},
labels: {
10: 'trace',
20: 'debug',
30: 'info',
40: 'warn',
50: 'error',
60: 'fatal'
}
})
end()
})
test('exposes LOG_VERSION', ({ end, is }) => {
is(pino.LOG_VERSION, 1)
end()
})
test('exposes faux stdSerializers', ({ end, ok, same }) => {
ok(pino.stdSerializers)
// make sure faux stdSerializers match pino-std-serializers
for (const serializer in pinoStdSerializers) {
ok(pino.stdSerializers[serializer], `pino.stdSerializers.${serializer}`)
}
// confirm faux methods return empty objects
same(pino.stdSerializers.req(), {})
same(pino.stdSerializers.mapHttpRequest(), {})
same(pino.stdSerializers.mapHttpResponse(), {})
same(pino.stdSerializers.res(), {})
// confirm wrapping function is a passthrough
const noChange = { foo: 'bar', fuz: 42 }
same(pino.stdSerializers.wrapRequestSerializer(noChange), noChange)
same(pino.stdSerializers.wrapResponseSerializer(noChange), noChange)
end()
})
test('exposes err stdSerializer', ({ end, ok }) => {
ok(pino.stdSerializers.err)
ok(pino.stdSerializers.err(Error()))
end()
})
consoleMethodTest('error')
consoleMethodTest('fatal', 'error')
consoleMethodTest('warn')
consoleMethodTest('info')
consoleMethodTest('debug')
consoleMethodTest('trace')
absentConsoleMethodTest('error', 'log')
absentConsoleMethodTest('warn', 'error')
absentConsoleMethodTest('info', 'log')
absentConsoleMethodTest('debug', 'log')
absentConsoleMethodTest('trace', 'log')
// do not run this with airtap
if (process.title !== 'browser') {
test('in absence of console, log methods become noops', ({ end, ok }) => {
var console = global.console
delete global.console
const instance = fresh('../browser')()
global.console = console
ok(fnName(instance.log).match(/noop/))
ok(fnName(instance.fatal).match(/noop/))
ok(fnName(instance.error).match(/noop/))
ok(fnName(instance.warn).match(/noop/))
ok(fnName(instance.info).match(/noop/))
ok(fnName(instance.debug).match(/noop/))
ok(fnName(instance.trace).match(/noop/))
end()
})
}
test('opts.browser.asObject logs pino-like object to console', ({ end, ok, is }) => {
var info = console.info
console.info = function (o) {
is(o.level, 30)
is(o.msg, 'test')
ok(o.time)
console.info = info
}
const instance = require('../browser')({
browser: {
asObject: true
}
})
instance.info('test')
end()
})
test('opts.browser.write func log single string', ({ end, ok, is }) => {
const instance = pino({
browser: {
write: function (o) {
is(o.level, 30)
is(o.msg, 'test')
ok(o.time)
}
}
})
instance.info('test')
end()
})
test('opts.browser.write func string joining', ({ end, ok, is }) => {
const instance = pino({
browser: {
write: function (o) {
is(o.level, 30)
is(o.msg, 'test test2 test3')
ok(o.time)
}
}
})
instance.info('test', 'test2', 'test3')
end()
})
test('opts.browser.write func string joining when asObject is true', ({ end, ok, is }) => {
const instance = pino({
browser: {
asObject: true,
write: function (o) {
is(o.level, 30)
is(o.msg, 'test test2 test3')
ok(o.time)
}
}
})
instance.info('test', 'test2', 'test3')
end()
})
test('opts.browser.write func string joining when asObject is true', ({ end, ok, is }) => {
const instance = pino({
browser: {
asObject: true,
write: function (o) {
is(o.level, 30)
is(o.msg, 'test test2 test3')
ok(o.time)
}
}
})
instance.info('test', 'test2', 'test3')
end()
})
test('opts.browser.write func string object joining', ({ end, ok, is }) => {
const instance = pino({
browser: {
write: function (o) {
is(o.level, 30)
is(o.msg, 'test {"test":"test2"} {"test":"test3"}')
ok(o.time)
}
}
})
instance.info('test', { test: 'test2' }, { test: 'test3' })
end()
})
test('opts.browser.write func string object joining when asObject is true', ({ end, ok, is }) => {
const instance = pino({
browser: {
asObject: true,
write: function (o) {
is(o.level, 30)
is(o.msg, 'test {"test":"test2"} {"test":"test3"}')
ok(o.time)
}
}
})
instance.info('test', { test: 'test2' }, { test: 'test3' })
end()
})
test('opts.browser.write func string interpolation', ({ end, ok, is }) => {
const instance = pino({
browser: {
write: function (o) {
is(o.level, 30)
is(o.msg, 'test2 test ({"test":"test3"})')
ok(o.time)
}
}
})
instance.info('%s test (%j)', 'test2', { test: 'test3' })
end()
})
test('opts.browser.write func number', ({ end, ok, is }) => {
const instance = pino({
browser: {
write: function (o) {
is(o.level, 30)
is(o.msg, 1)
ok(o.time)
}
}
})
instance.info(1)
end()
})
test('opts.browser.write func log single object', ({ end, ok, is }) => {
const instance = pino({
browser: {
write: function (o) {
is(o.level, 30)
is(o.test, 'test')
ok(o.time)
}
}
})
instance.info({ test: 'test' })
end()
})
test('opts.browser.write obj writes to methods corresponding to level', ({ end, ok, is }) => {
const instance = pino({
browser: {
write: {
error: function (o) {
is(o.level, 50)
is(o.test, 'test')
ok(o.time)
}
}
}
})
instance.error({ test: 'test' })
end()
})
test('opts.browser.asObject/write supports child loggers', ({ end, ok, is }) => {
const instance = pino({
browser: {
write (o) {
is(o.level, 30)
is(o.test, 'test')
is(o.msg, 'msg-test')
ok(o.time)
}
}
})
const child = instance.child({ test: 'test' })
child.info('msg-test')
end()
})
test('opts.browser.asObject/write supports child child loggers', ({ end, ok, is }) => {
const instance = pino({
browser: {
write (o) {
is(o.level, 30)
is(o.test, 'test')
is(o.foo, 'bar')
is(o.msg, 'msg-test')
ok(o.time)
}
}
})
const child = instance.child({ test: 'test' }).child({ foo: 'bar' })
child.info('msg-test')
end()
})
test('opts.browser.asObject/write supports child child child loggers', ({ end, ok, is }) => {
const instance = pino({
browser: {
write (o) {
is(o.level, 30)
is(o.test, 'test')
is(o.foo, 'bar')
is(o.baz, 'bop')
is(o.msg, 'msg-test')
ok(o.time)
}
}
})
const child = instance.child({ test: 'test' }).child({ foo: 'bar' }).child({ baz: 'bop' })
child.info('msg-test')
end()
})
test('opts.browser.asObject defensively mitigates naughty numbers', ({ end, pass }) => {
const instance = pino({
browser: { asObject: true, write: () => {} }
})
const child = instance.child({ test: 'test' })
child._childLevel = -10
child.info('test')
pass() // if we reached here, there was no infinite loop, so, .. pass.
end()
})
test('opts.browser.write obj falls back to console where a method is not supplied', ({ end, ok, is }) => {
var info = console.info
console.info = (o) => {
is(o.level, 30)
is(o.msg, 'test')
ok(o.time)
console.info = info
}
const instance = require('../browser')({
browser: {
write: {
error (o) {
is(o.level, 50)
is(o.test, 'test')
ok(o.time)
}
}
}
})
instance.error({ test: 'test' })
instance.info('test')
end()
})
function levelTest (name) {
test(name + ' logs', ({ end, is }) => {
var msg = 'hello world'
sink(name, (args) => {
is(args[0], msg)
end()
})
pino({ level: name })[name](msg)
})
test('passing objects at level ' + name, ({ end, is }) => {
var msg = { hello: 'world' }
sink(name, (args) => {
is(args[0], msg)
end()
})
pino({ level: name })[name](msg)
})
test('passing an object and a string at level ' + name, ({ end, is }) => {
var a = { hello: 'world' }
var b = 'a string'
sink(name, (args) => {
is(args[0], a)
is(args[1], b)
end()
})
pino({ level: name })[name](a, b)
})
test('formatting logs as ' + name, ({ end, is }) => {
sink(name, (args) => {
is(args[0], 'hello %d')
is(args[1], 42)
end()
})
pino({ level: name })[name]('hello %d', 42)
})
test('passing error at level ' + name, ({ end, is }) => {
var err = new Error('myerror')
sink(name, (args) => {
is(args[0], err)
end()
})
pino({ level: name })[name](err)
})
test('passing error with a serializer at level ' + name, ({ end, is }) => {
// in browser - should have no effect (should not crash)
var err = new Error('myerror')
sink(name, (args) => {
is(args[0].err, err)
end()
})
const instance = pino({
level: name,
serializers: {
err: pino.stdSerializers.err
}
})
instance[name]({ err: err })
})
test('child logger for level ' + name, ({ end, is }) => {
var msg = 'hello world'
var parent = { hello: 'world' }
sink(name, (args) => {
is(args[0], parent)
is(args[1], msg)
end()
})
const instance = pino({ level: name })
const child = instance.child(parent)
child[name](msg)
})
test('child-child logger for level ' + name, ({ end, is }) => {
var msg = 'hello world'
var grandParent = { hello: 'world' }
var parent = { hello: 'you' }
sink(name, (args) => {
is(args[0], grandParent)
is(args[1], parent)
is(args[2], msg)
end()
})
const instance = pino({ level: name })
const child = instance.child(grandParent).child(parent)
child[name](msg)
})
}
function consoleMethodTest (level, method) {
if (!method) method = level
test('pino().' + level + ' uses console.' + method, ({ end, is }) => {
sink(method, (args) => {
is(args[0], 'test')
end()
})
const instance = require('../browser')({ level: level })
instance[level]('test')
})
}
function absentConsoleMethodTest (method, fallback) {
test('in absence of console.' + method + ', console.' + fallback + ' is used', ({ end, is }) => {
var fn = console[method]
console[method] = undefined
sink(fallback, function (args) {
is(args[0], 'test')
end()
console[method] = fn
})
const instance = require('../browser')({ level: method })
instance[method]('test')
})
}
function isFunc (fn) { return typeof fn === 'function' }
function fnName (fn) {
var rx = /^\s*function\s*([^(]*)/i
var match = rx.exec(fn)
return match && match[1]
}
function sink (method, fn) {
if (method === 'fatal') method = 'error'
var orig = console[method]
console[method] = function () {
console[method] = orig
fn(Array.prototype.slice.call(arguments))
}
}

32
node_modules/pino/test/crlf.test.js generated vendored Normal file
View file

@ -0,0 +1,32 @@
'use strict'
const { test } = require('tap')
const writer = require('flush-write-stream')
const pino = require('../')
function capture () {
const ws = writer((chunk, enc, cb) => {
ws.data += chunk.toString()
cb()
})
ws.data = ''
return ws
}
test('pino uses LF by default', async ({ ok }) => {
const stream = capture()
const logger = pino(stream)
logger.info('foo')
logger.error('bar')
ok(/foo[^\r\n]+\n[^\r\n]+bar[^\r\n]+\n/.test(stream.data))
})
test('pino can log CRLF', async ({ ok }) => {
const stream = capture()
const logger = pino({
crlf: true
}, stream)
logger.info('foo')
logger.error('bar')
ok(/foo[^\n]+\r\n[^\n]+bar[^\n]+\r\n/.test(stream.data))
})

308
node_modules/pino/test/custom-levels.test.js generated vendored Normal file
View file

@ -0,0 +1,308 @@
'use strict'
/* eslint no-prototype-builtins: 0 */
const { test } = require('tap')
const { sink, once } = require('./helper')
const pino = require('../')
test('adds additional levels', async ({ is }) => {
const stream = sink()
const logger = pino({
customLevels: {
foo: 35,
bar: 45
}
}, stream)
logger.foo('test')
const { level } = await once(stream, 'data')
is(level, 35)
})
test('custom levels does not override default levels', async ({ is }) => {
const stream = sink()
const logger = pino({
customLevels: {
foo: 35
}
}, stream)
logger.info('test')
const { level } = await once(stream, 'data')
is(level, 30)
})
test('default levels can be redefined using custom levels', async ({ is }) => {
const stream = sink()
const logger = pino({
customLevels: {
info: 35,
debug: 45
},
useOnlyCustomLevels: true
}, stream)
is(logger.hasOwnProperty('info'), true)
logger.info('test')
const { level } = await once(stream, 'data')
is(level, 35)
})
test('custom levels overrides default level label if use useOnlyCustomLevels', async ({ is }) => {
const stream = sink()
const logger = pino({
customLevels: {
foo: 35
},
useOnlyCustomLevels: true,
level: 'foo'
}, stream)
is(logger.hasOwnProperty('info'), false)
})
test('custom levels overrides default level value if use useOnlyCustomLevels', async ({ is }) => {
const stream = sink()
const logger = pino({
customLevels: {
foo: 35
},
useOnlyCustomLevels: true,
level: 35
}, stream)
is(logger.hasOwnProperty('info'), false)
})
test('custom levels are inherited by children', async ({ is }) => {
const stream = sink()
const logger = pino({
customLevels: {
foo: 35
}
}, stream)
logger.child({ childMsg: 'ok' }).foo('test')
const { msg, childMsg, level } = await once(stream, 'data')
is(level, 35)
is(childMsg, 'ok')
is(msg, 'test')
})
test('custom levels can be specified on child bindings', async ({ is }) => {
const stream = sink()
const logger = pino(stream).child({
customLevels: {
foo: 35
},
childMsg: 'ok'
})
logger.foo('test')
const { msg, childMsg, level } = await once(stream, 'data')
is(level, 35)
is(childMsg, 'ok')
is(msg, 'test')
})
test('customLevels property child bindings does not get logged', async ({ is }) => {
const stream = sink()
const logger = pino(stream).child({
customLevels: {
foo: 35
},
childMsg: 'ok'
})
logger.foo('test')
const { customLevels } = await once(stream, 'data')
is(customLevels, undefined)
})
test('throws when specifying pre-existing parent labels via child bindings', async ({ is, throws }) => {
const stream = sink()
throws(() => pino({
customLevels: {
foo: 35
}
}, stream).child({
customLevels: {
foo: 45
}
})
)
try {
pino({
customLevels: {
foo: 35
}
}, stream).child({
customLevels: {
foo: 45
}
})
} catch ({ message }) {
is(message, 'levels cannot be overridden')
}
})
test('throws when specifying pre-existing parent values via child bindings', async ({ is, throws }) => {
const stream = sink()
throws(() => pino({
customLevels: {
foo: 35
}
}, stream).child({
customLevels: {
bar: 35
}
})
)
try {
pino({
customLevels: {
foo: 35
}
}, stream).child({
customLevels: {
bar: 35
}
})
} catch ({ message }) {
is(message, 'pre-existing level values cannot be used for new levels')
}
})
test('throws when specifying core values via child bindings', async ({ is, throws }) => {
const stream = sink()
throws(() => pino(stream).child({
customLevels: {
foo: 30
}
})
)
try {
pino(stream).child({
customLevels: {
foo: 30
}
})
} catch ({ message }) {
is(message, 'pre-existing level values cannot be used for new levels')
}
})
test('throws when useOnlyCustomLevels is set true without customLevels', async ({ is, throws }) => {
const stream = sink()
throws(() => pino({
useOnlyCustomLevels: true
}, stream)
)
try {
pino({
useOnlyCustomLevels: true
}, stream)
} catch ({ message }) {
is(message, 'customLevels is required if useOnlyCustomLevels is set true')
}
})
test('custom level on one instance does not affect other instances', async ({ is }) => {
pino({
customLevels: {
foo: 37
}
})
is(typeof pino().foo, 'undefined')
})
test('setting level below or at custom level will successfully log', async ({ is }) => {
const stream = sink()
const instance = pino({ customLevels: { foo: 35 } }, stream)
instance.level = 'foo'
instance.info('nope')
instance.foo('bar')
const { msg } = await once(stream, 'data')
is(msg, 'bar')
})
test('custom level below level threshold will not log', async ({ is }) => {
const stream = sink()
const instance = pino({ customLevels: { foo: 15 } }, stream)
instance.level = 'info'
instance.info('bar')
instance.foo('nope')
const { msg } = await once(stream, 'data')
is(msg, 'bar')
})
test('does not share custom level state across siblings', async ({ doesNotThrow }) => {
const stream = sink()
const logger = pino(stream)
logger.child({
customLevels: { foo: 35 }
})
doesNotThrow(() => {
logger.child({
customLevels: { foo: 35 }
})
})
})
test('custom level does not affect levelKey', async ({ is }) => {
const stream = sink()
const logger = pino({
customLevels: {
foo: 35,
bar: 45
},
levelKey: 'priority'
}, stream)
logger.foo('test')
const { priority } = await once(stream, 'data')
is(priority, 35)
})
test('custom levels accesible in prettifier function', async ({ plan, same }) => {
plan(1)
const logger = pino({
prettyPrint: true,
prettifier: function prettifierFactory () {
const instance = this
return function () {
same(instance.levels, {
labels: {
10: 'trace',
20: 'debug',
30: 'info',
35: 'foo',
40: 'warn',
45: 'bar',
50: 'error',
60: 'fatal'
},
values: {
trace: 10,
debug: 20,
info: 30,
warn: 40,
error: 50,
fatal: 60,
foo: 35,
bar: 45
}
})
}
},
customLevels: {
foo: 35,
bar: 45
},
changeLevelName: 'priority'
})
logger.foo('test')
})

179
node_modules/pino/test/error.test.js generated vendored Normal file
View file

@ -0,0 +1,179 @@
'use strict'
/* eslint no-prototype-builtins: 0 */
const os = require('os')
const { test } = require('tap')
const { sink, once } = require('./helper')
const pino = require('../')
const { pid } = process
const hostname = os.hostname()
const level = 50
const name = 'error'
test('err is serialized with additional properties set on the Error object', async ({ ok, same }) => {
const stream = sink()
const err = Object.assign(new Error('myerror'), { foo: 'bar' })
const instance = pino(stream)
instance.level = name
instance[name](err)
const result = await once(stream, 'data')
ok(new Date(result.time) <= new Date(), 'time is greater than Date.now()')
delete result.time
same(result, {
pid: pid,
hostname: hostname,
level: level,
type: 'Error',
msg: err.message,
stack: err.stack,
foo: err.foo,
v: 1
})
})
test('type should be retained, even if type is a property', async ({ ok, same }) => {
const stream = sink()
const err = Object.assign(new Error('myerror'), { type: 'bar' })
const instance = pino(stream)
instance.level = name
instance[name](err)
const result = await once(stream, 'data')
ok(new Date(result.time) <= new Date(), 'time is greater than Date.now()')
delete result.time
same(result, {
pid: pid,
hostname: hostname,
level: level,
type: 'bar',
msg: err.message,
stack: err.stack,
v: 1
})
})
test('type, message and stack should be first level properties', async ({ ok, same }) => {
const stream = sink()
const err = Object.assign(new Error('foo'), { foo: 'bar' })
const instance = pino(stream)
instance.level = name
instance[name](err)
const result = await once(stream, 'data')
ok(new Date(result.time) <= new Date(), 'time is greater than Date.now()')
delete result.time
same(result, {
pid: pid,
hostname: hostname,
level: level,
type: 'Error',
msg: err.message,
stack: err.stack,
foo: err.foo,
v: 1
})
})
test('err serializer', async ({ ok, same }) => {
const stream = sink()
const err = Object.assign(new Error('myerror'), { foo: 'bar' })
const instance = pino({
serializers: {
err: pino.stdSerializers.err
}
}, stream)
instance.level = name
instance[name]({ err })
const result = await once(stream, 'data')
ok(new Date(result.time) <= new Date(), 'time is greater than Date.now()')
delete result.time
same(result, {
pid: pid,
hostname: hostname,
level: level,
err: {
type: 'Error',
message: err.message,
stack: err.stack,
foo: err.foo
},
v: 1
})
})
test('an error with statusCode property is not confused for a http response', async ({ ok, same }) => {
const stream = sink()
const err = Object.assign(new Error('StatusCodeErr'), { statusCode: 500 })
const instance = pino(stream)
instance.level = name
instance[name](err)
const result = await once(stream, 'data')
ok(new Date(result.time) <= new Date(), 'time is greater than Date.now()')
delete result.time
same(result, {
pid: pid,
hostname: hostname,
level: level,
type: 'Error',
msg: err.message,
stack: err.stack,
statusCode: err.statusCode,
v: 1
})
})
test('stack is omitted if it is not set on err', t => {
t.plan(2)
var err = new Error('myerror')
delete err.stack
var instance = pino(sink(function (chunk, enc, cb) {
t.ok(new Date(chunk.time) <= new Date(), 'time is greater than Date.now()')
delete chunk.time
t.equal(chunk.hasOwnProperty('stack'), false)
cb()
}))
instance.level = name
instance[name](err)
})
test('stack is rendered as any other property if it\'s not a string', t => {
t.plan(3)
var err = new Error('myerror')
err.stack = null
var instance = pino(sink(function (chunk, enc, cb) {
t.ok(new Date(chunk.time) <= new Date(), 'time is greater than Date.now()')
delete chunk.time
t.equal(chunk.hasOwnProperty('stack'), true)
t.equal(chunk.stack, null)
cb()
}))
instance.level = name
instance[name](err)
})
test('correctly ignores toString on errors', async ({ same }) => {
const err = new Error('myerror')
err.toString = () => undefined
const stream = sink()
const instance = pino({
test: 'this'
}, stream)
instance.fatal(err)
const result = await once(stream, 'data')
delete result.time
same(result, {
pid: pid,
hostname: hostname,
level: 60,
type: 'Error',
msg: err.message,
stack: err.stack,
v: 1
})
})

93
node_modules/pino/test/escaping.test.js generated vendored Normal file
View file

@ -0,0 +1,93 @@
'use strict'
const os = require('os')
const { test } = require('tap')
const { sink, once } = require('./helper')
const pino = require('../')
const { pid } = process
const hostname = os.hostname()
function testEscape (ch, key) {
test('correctly escape ' + ch, async ({ same }) => {
const stream = sink()
const instance = pino({
name: 'hello'
}, stream)
instance.fatal('this contains ' + key)
const result = await once(stream, 'data')
delete result.time
same(result, {
pid: pid,
hostname: hostname,
level: 60,
name: 'hello',
msg: 'this contains ' + key,
v: 1
})
})
}
testEscape('\\n', '\n')
testEscape('\\/', '/')
testEscape('\\\\', '\\')
testEscape('\\r', '\r')
testEscape('\\t', '\t')
testEscape('\\b', '\b')
const toEscape = [
'\u0000', // NUL Null character
'\u0001', // SOH Start of Heading
'\u0002', // STX Start of Text
'\u0003', // ETX End-of-text character
'\u0004', // EOT End-of-transmission character
'\u0005', // ENQ Enquiry character
'\u0006', // ACK Acknowledge character
'\u0007', // BEL Bell character
'\u0008', // BS Backspace
'\u0009', // HT Horizontal tab
'\u000A', // LF Line feed
'\u000B', // VT Vertical tab
'\u000C', // FF Form feed
'\u000D', // CR Carriage return
'\u000E', // SO Shift Out
'\u000F', // SI Shift In
'\u0010', // DLE Data Link Escape
'\u0011', // DC1 Device Control 1
'\u0012', // DC2 Device Control 2
'\u0013', // DC3 Device Control 3
'\u0014', // DC4 Device Control 4
'\u0015', // NAK Negative-acknowledge character
'\u0016', // SYN Synchronous Idle
'\u0017', // ETB End of Transmission Block
'\u0018', // CAN Cancel character
'\u0019', // EM End of Medium
'\u001A', // SUB Substitute character
'\u001B', // ESC Escape character
'\u001C', // FS File Separator
'\u001D', // GS Group Separator
'\u001E', // RS Record Separator
'\u001F' // US Unit Separator
]
toEscape.forEach((key) => {
testEscape(JSON.stringify(key), key)
})
test('correctly escape `hello \\u001F world \\n \\u0022`', async ({ same }) => {
const stream = sink()
const instance = pino({
name: 'hello'
}, stream)
instance.fatal('hello \u001F world \n \u0022')
const result = await once(stream, 'data')
delete result.time
same(result, {
pid: pid,
hostname: hostname,
level: 60,
name: 'hello',
msg: 'hello \u001F world \n \u0022',
v: 1
})
})

53
node_modules/pino/test/exit.test.js generated vendored Normal file
View file

@ -0,0 +1,53 @@
'use strict'
const { test } = require('tap')
const { join } = require('path')
const execa = require('execa')
const writer = require('flush-write-stream')
const { once } = require('./helper')
// https://github.com/pinojs/pino/issues/542
test('pino.destination log everything when calling process.exit(0)', async ({ isNot }) => {
var actual = ''
const child = execa(process.argv[0], [join(__dirname, 'fixtures', 'destination-exit.js')])
child.stdout.pipe(writer((s, enc, cb) => {
actual += s
cb()
}))
await once(child, 'close')
isNot(actual.match(/hello/), null)
isNot(actual.match(/world/), null)
})
test('pino.extreme does not log everything when calling process.exit(0)', async ({ is }) => {
var actual = ''
const child = execa(process.argv[0], [join(__dirname, 'fixtures', 'extreme-exit.js')])
child.stdout.pipe(writer((s, enc, cb) => {
actual += s
cb()
}))
await once(child, 'close')
is(actual.match(/hello/), null)
is(actual.match(/world/), null)
})
test('pino.extreme logs everything when calling flushSync', async ({ isNot }) => {
var actual = ''
const child = execa(process.argv[0], [join(__dirname, 'fixtures', 'extreme-flush-exit.js')])
child.stdout.pipe(writer((s, enc, cb) => {
actual += s
cb()
}))
await once(child, 'close')
isNot(actual.match(/hello/), null)
isNot(actual.match(/world/), null)
})

125
node_modules/pino/test/extreme.test.js generated vendored Normal file
View file

@ -0,0 +1,125 @@
'use strict'
const os = require('os')
const { createWriteStream } = require('fs')
const { join } = require('path')
const { test } = require('tap')
const { fork } = require('child_process')
const writer = require('flush-write-stream')
const { once, getPathToNull } = require('./helper')
test('extreme mode', async ({ is, teardown }) => {
const now = Date.now
const hostname = os.hostname
const proc = process
global.process = {
__proto__: process,
pid: 123456
}
Date.now = () => 1459875739796
os.hostname = () => 'abcdefghijklmnopqr'
delete require.cache[require.resolve('../')]
const pino = require('../')
var expected = ''
var actual = ''
const normal = pino(writer((s, enc, cb) => {
expected += s
cb()
}))
const dest = createWriteStream(getPathToNull())
dest.write = (s) => {
actual += s
}
const extreme = pino(dest)
var i = 44
while (i--) {
normal.info('h')
extreme.info('h')
}
var expected2 = expected.split('\n')[0]
var actual2 = ''
const child = fork(join(__dirname, '/fixtures/extreme.js'), { silent: true })
child.stdout.pipe(writer((s, enc, cb) => {
actual2 += s
cb()
}))
await once(child, 'close')
is(actual, expected)
is(actual2.trim(), expected2)
teardown(() => {
os.hostname = hostname
Date.now = now
global.process = proc
})
})
test('extreme mode with child', async ({ is, teardown }) => {
const now = Date.now
const hostname = os.hostname
const proc = process
global.process = {
__proto__: process,
pid: 123456
}
Date.now = function () {
return 1459875739796
}
os.hostname = function () {
return 'abcdefghijklmnopqr'
}
delete require.cache[require.resolve('../')]
const pino = require('../')
var expected = ''
var actual = ''
const normal = pino(writer((s, enc, cb) => {
expected += s
cb()
})).child({ hello: 'world' })
const dest = createWriteStream(getPathToNull())
dest.write = function (s) { actual += s }
const extreme = pino(dest).child({ hello: 'world' })
var i = 500
while (i--) {
normal.info('h')
extreme.info('h')
}
extreme.flush()
var expected2 = expected.split('\n')[0]
var actual2 = ''
const child = fork(join(__dirname, '/fixtures/extreme-child.js'), { silent: true })
child.stdout.pipe(writer((s, enc, cb) => {
actual2 += s
cb()
}))
await once(child, 'close')
is(actual, expected)
is(actual2.trim(), expected2)
teardown(() => {
os.hostname = hostname
Date.now = now
global.process = proc
})
})
test('throw an error if extreme is passed', async ({ throws }) => {
const pino = require('..')
throws(() => {
pino({ extreme: true })
})
})
test('flush does nothing without extreme mode', async () => {
var instance = require('..')()
instance.flush()
})

182
node_modules/pino/test/final.test.js generated vendored Normal file
View file

@ -0,0 +1,182 @@
'use strict'
const pino = require('..')
const fs = require('fs')
const { test } = require('tap')
const { sleep, getPathToNull } = require('./helper')
test('replaces onTerminated option', async ({ throws }) => {
throws(() => {
pino({
onTerminated: () => {}
})
}, Error('The onTerminated option has been removed, use pino.final instead'))
})
test('throws if not supplied a logger instance', async ({ throws }) => {
throws(() => {
pino.final()
}, Error('expected a pino logger instance'))
})
test('throws if the supplied handler is not a function', async ({ throws }) => {
throws(() => {
pino.final(pino(), 'dummy')
}, Error('if supplied, the handler parameter should be a function'))
})
test('throws if not supplied logger with pino.extreme instance', async ({ throws, doesNotThrow }) => {
throws(() => {
pino.final(pino(fs.createWriteStream(getPathToNull())), () => {})
}, Error('final requires a stream that has a flushSync method, such as pino.destination and pino.extreme'))
doesNotThrow(() => {
pino.final(pino(pino.extreme()), () => {})
})
doesNotThrow(() => {
pino.final(pino(pino.extreme()), () => {})
})
})
test('returns an exit listener function', async ({ is }) => {
is(typeof pino.final(pino(pino.extreme()), () => {}), 'function')
})
test('listener function immediately sync flushes when fired', async ({ pass, fail }) => {
const dest = pino.extreme(getPathToNull())
var passed = false
dest.flushSync = () => {
passed = true
pass('flushSync called')
}
pino.final(pino(dest), () => {})()
await sleep(10)
if (passed === false) fail('flushSync not called')
})
test('listener function immediately sync flushes when fired (pino.destination)', async ({ pass, fail }) => {
const dest = pino.destination(getPathToNull())
var passed = false
dest.flushSync = () => {
passed = true
pass('flushSync called')
}
pino.final(pino(dest), () => {})()
await sleep(10)
if (passed === false) fail('flushSync not called')
})
test('swallows the non-ready error', async ({ doesNotThrow }) => {
const dest = pino.extreme(getPathToNull())
doesNotThrow(() => {
pino.final(pino(dest), () => {})()
})
})
test('listener function triggers handler function parameter', async ({ pass, fail }) => {
const dest = pino.extreme(getPathToNull())
var passed = false
pino.final(pino(dest), () => {
passed = true
pass('handler function triggered')
})()
await sleep(10)
if (passed === false) fail('handler function not triggered')
})
test('passes any error to the handler', async ({ is }) => {
const dest = pino.extreme(getPathToNull())
pino.final(pino(dest), (err) => {
is(err.message, 'test')
})(Error('test'))
})
test('passes a specialized final logger instance', async ({ is, isNot, error }) => {
const dest = pino.extreme(getPathToNull())
const logger = pino(dest)
pino.final(logger, (err, finalLogger) => {
error(err)
is(typeof finalLogger.trace, 'function')
is(typeof finalLogger.debug, 'function')
is(typeof finalLogger.info, 'function')
is(typeof finalLogger.warn, 'function')
is(typeof finalLogger.error, 'function')
is(typeof finalLogger.fatal, 'function')
isNot(finalLogger.trace, logger.trace)
isNot(finalLogger.debug, logger.debug)
isNot(finalLogger.info, logger.info)
isNot(finalLogger.warn, logger.warn)
isNot(finalLogger.error, logger.error)
isNot(finalLogger.fatal, logger.fatal)
is(finalLogger.child, logger.child)
is(finalLogger.levels, logger.levels)
})()
})
test('returns a specialized final logger instance if no handler is passed', async ({ is, isNot }) => {
const dest = pino.extreme(getPathToNull())
const logger = pino(dest)
const finalLogger = pino.final(logger)
is(typeof finalLogger.trace, 'function')
is(typeof finalLogger.debug, 'function')
is(typeof finalLogger.info, 'function')
is(typeof finalLogger.warn, 'function')
is(typeof finalLogger.error, 'function')
is(typeof finalLogger.fatal, 'function')
isNot(finalLogger.trace, logger.trace)
isNot(finalLogger.debug, logger.debug)
isNot(finalLogger.info, logger.info)
isNot(finalLogger.warn, logger.warn)
isNot(finalLogger.error, logger.error)
isNot(finalLogger.fatal, logger.fatal)
is(finalLogger.child, logger.child)
is(finalLogger.levels, logger.levels)
})
test('final logger instances synchronously flush after a log method call', async ({ pass, fail, error }) => {
const dest = pino.extreme(getPathToNull())
const logger = pino(dest)
var passed = false
var count = 0
dest.flushSync = () => {
count++
if (count === 2) {
passed = true
pass('flushSync called')
}
}
pino.final(logger, (err, finalLogger) => {
error(err)
finalLogger.info('hello')
})()
await sleep(10)
if (passed === false) fail('flushSync not called')
})
test('also instruments custom log methods', async ({ pass, fail, error }) => {
const dest = pino.extreme(getPathToNull())
const logger = pino({
customLevels: {
foo: 35
}
}, dest)
var passed = false
var count = 0
dest.flushSync = () => {
count++
if (count === 2) {
passed = true
pass('flushSync called')
}
}
pino.final(logger, (err, finalLogger) => {
error(err)
finalLogger.foo('hello')
})()
await sleep(10)
if (passed === false) fail('flushSync not called')
})

9
node_modules/pino/test/fixtures/broken-pipe/basic.js generated vendored Normal file
View file

@ -0,0 +1,9 @@
'use strict'
global.process = { __proto__: process, pid: 123456 }
Date.now = function () { return 1459875739796 }
require('os').hostname = function () { return 'abcdefghijklmnopqr' }
const pino = require('../../..')()
pino.info('hello world')

View file

@ -0,0 +1,10 @@
'use strict'
global.process = { __proto__: process, pid: 123456 }
Date.now = function () { return 1459875739796 }
require('os').hostname = function () { return 'abcdefghijklmnopqr' }
const pino = require('../../..')
const logger = pino(pino.destination())
logger.info('hello world')

12
node_modules/pino/test/fixtures/broken-pipe/extreme.js generated vendored Normal file
View file

@ -0,0 +1,12 @@
'use strict'
global.process = { __proto__: process, pid: 123456 }
Date.now = function () { return 1459875739796 }
require('os').hostname = function () { return 'abcdefghijklmnopqr' }
const pino = require('../../..')
const logger = pino(pino.extreme())
for (let i = 0; i < 1000; i++) {
logger.info('hello world')
}

8
node_modules/pino/test/fixtures/destination-exit.js generated vendored Normal file
View file

@ -0,0 +1,8 @@
global.process = { __proto__: process, pid: 123456 }
Date.now = function () { return 1459875739796 }
require('os').hostname = function () { return 'abcdefghijklmnopqr' }
var pino = require(require.resolve('./../../'))
var logger = pino({}, pino.destination(1))
logger.info('hello')
logger.info('world')
process.exit(0)

6
node_modules/pino/test/fixtures/extreme-child.js generated vendored Normal file
View file

@ -0,0 +1,6 @@
global.process = { __proto__: process, pid: 123456 }
Date.now = function () { return 1459875739796 }
require('os').hostname = function () { return 'abcdefghijklmnopqr' }
var pino = require(require.resolve('./../../'))
var extreme = pino(pino.extreme()).child({ hello: 'world' })
pino.final(extreme, (_, logger) => logger.info('h'))()

9
node_modules/pino/test/fixtures/extreme-exit.js generated vendored Normal file
View file

@ -0,0 +1,9 @@
global.process = { __proto__: process, pid: 123456 }
Date.now = function () { return 1459875739796 }
require('os').hostname = function () { return 'abcdefghijklmnopqr' }
var pino = require(require.resolve('./../../'))
var dest = pino.extreme(1)
var logger = pino({}, dest)
logger.info('hello')
logger.info('world')
process.exit(0)

10
node_modules/pino/test/fixtures/extreme-flush-exit.js generated vendored Normal file
View file

@ -0,0 +1,10 @@
global.process = { __proto__: process, pid: 123456 }
Date.now = function () { return 1459875739796 }
require('os').hostname = function () { return 'abcdefghijklmnopqr' }
var pino = require(require.resolve('./../../'))
var dest = pino.extreme(1)
var logger = pino({}, dest)
logger.info('hello')
logger.info('world')
dest.flushSync()
process.exit(0)

6
node_modules/pino/test/fixtures/extreme.js generated vendored Normal file
View file

@ -0,0 +1,6 @@
global.process = { __proto__: process, pid: 123456 }
Date.now = function () { return 1459875739796 }
require('os').hostname = function () { return 'abcdefghijklmnopqr' }
var pino = require(require.resolve('./../../'))
var extreme = pino(pino.extreme())
pino.final(extreme, (_, logger) => logger.info('h'))()

6
node_modules/pino/test/fixtures/pretty/basic.js generated vendored Normal file
View file

@ -0,0 +1,6 @@
global.process = { __proto__: process, pid: 123456 }
Date.now = function () { return 1459875739796 }
require('os').hostname = function () { return 'abcdefghijklmnopqr' }
var pino = require(require.resolve('./../../../'))
var log = pino({ prettyPrint: true })
log.info('h')

8
node_modules/pino/test/fixtures/pretty/child.js generated vendored Normal file
View file

@ -0,0 +1,8 @@
global.process = { __proto__: process, pid: 123456 }
Date.now = function () { return 1459875739796 }
require('os').hostname = function () { return 'abcdefghijklmnopqr' }
var pino = require(require.resolve('./../../../'))
var log = pino({ prettyPrint: true }).child({ a: 1 })
log.info('h')
log.child({ b: 2 }).info('h3')
setTimeout(() => log.info('h2'), 200)

View file

@ -0,0 +1,9 @@
global.process = { __proto__: process, pid: 123456 }
Date.now = function () { return 1459875739796 }
require('os').hostname = function () { return 'abcdefghijklmnopqr' }
var pino = require(require.resolve('./../../../'))
var log = pino({
timestamp: () => ',"custom-time-label":"test"',
prettyPrint: true
})
log.info('h')

View file

@ -0,0 +1,9 @@
global.process = { __proto__: process, pid: 123456 }
Date.now = function () { return 1459875739796 }
require('os').hostname = function () { return 'abcdefghijklmnopqr' }
var pino = require(require.resolve('./../../../'))
var log = pino({
timestamp: () => ',"time":"test"',
prettyPrint: true
})
log.info('h')

10
node_modules/pino/test/fixtures/pretty/dateformat.js generated vendored Normal file
View file

@ -0,0 +1,10 @@
global.process = { __proto__: process, pid: 123456 }
Date.now = function () { return 1459875739796 }
require('os').hostname = function () { return 'abcdefghijklmnopqr' }
var pino = require(require.resolve('./../../../'))
var log = pino({
prettyPrint: {
translateTime: true
}
})
log.info('h')

View file

@ -0,0 +1,9 @@
global.process = { __proto__: process, pid: 123456 }
Date.now = function () { return 1459875739796 }
require('os').hostname = function () { return 'abcdefghijklmnopqr' }
var pino = require(require.resolve('./../../../'))
var log = pino({
prettyPrint: { errorProps: 'code,errno' }
})
var err = Object.assign(new Error('kaboom'), { code: 'ENOENT', errno: 1 })
log.error(err)

7
node_modules/pino/test/fixtures/pretty/error.js generated vendored Normal file
View file

@ -0,0 +1,7 @@
global.process = { __proto__: process, pid: 123456 }
Date.now = function () { return 1459875739796 }
require('os').hostname = function () { return 'abcdefghijklmnopqr' }
var pino = require(require.resolve('./../../../'))
var log = pino({ prettyPrint: true })
log.error(new Error('kaboom'))
log.error(new Error('kaboom'), 'with', 'a', 'message')

View file

@ -0,0 +1,8 @@
global.process = { __proto__: process, pid: 123456 }
Date.now = function () { return 1459875739796 }
require('os').hostname = function () { return 'abcdefghijklmnopqr' }
var pino = require(require.resolve('./../../../'))
var log = pino({ prettyPrint: true })
process.once('beforeExit', pino.final(log, (_, logger) => {
logger.info('beforeExit')
}))

View file

@ -0,0 +1,7 @@
global.process = { __proto__: process, pid: 123456 }
Date.now = function () { return 1459875739796 }
require('os').hostname = function () { return 'abcdefghijklmnopqr' }
var pino = require(require.resolve('./../../../'))
var log = pino({ prettyPrint: true })
log.info('h')
pino.final(log).info('after')

9
node_modules/pino/test/fixtures/pretty/final.js generated vendored Normal file
View file

@ -0,0 +1,9 @@
global.process = { __proto__: process, pid: 123456 }
Date.now = function () { return 1459875739796 }
require('os').hostname = function () { return 'abcdefghijklmnopqr' }
var pino = require(require.resolve('./../../../'))
var log = pino({ prettyPrint: true })
log.info('h')
process.once('beforeExit', pino.final(log, (_, logger) => {
logger.info('beforeExit')
}))

View file

@ -0,0 +1,6 @@
global.process = { __proto__: process, pid: 123456 }
Date.now = function () { return 1459875739796 }
require('os').hostname = function () { return 'abcdefghijklmnopqr' }
var pino = require(require.resolve('./../../../'))
var log = pino({ prettyPrint: { levelFirst: true } })
log.info('h')

9
node_modules/pino/test/fixtures/pretty/no-time.js generated vendored Normal file
View file

@ -0,0 +1,9 @@
global.process = { __proto__: process, pid: 123456 }
Date.now = function () { return 1459875739796 }
require('os').hostname = function () { return 'abcdefghijklmnopqr' }
var pino = require(require.resolve('./../../../'))
var log = pino({
timestamp: false,
prettyPrint: true
})
log.info('h')

View file

@ -0,0 +1,6 @@
global.process = { __proto__: process, pid: 123456 }
Date.now = function () { return 1459875739796 }
require('os').hostname = function () { return 'abcdefghijklmnopqr' }
var pino = require(require.resolve('./../../../'))
var log = pino({ prettyPrint: true })
log.info({ msg: 'hello' })

View file

@ -0,0 +1,6 @@
global.process = { __proto__: process, pid: 123456 }
Date.now = function () { return 1459875739796 }
require('os').hostname = function () { return 'abcdefghijklmnopqr' }
var pino = require(require.resolve('./../../../'))
var log = pino({ prettyPrint: { levelFirst: true }, prettifier: require('pino-pretty') })
log.info('h')

9
node_modules/pino/test/fixtures/pretty/redact.js generated vendored Normal file
View file

@ -0,0 +1,9 @@
global.process = { __proto__: process, pid: 123456 }
Date.now = function () { return 1459875739796 }
require('os').hostname = function () { return 'abcdefghijklmnopqr' }
var pino = require(require.resolve('./../../../'))
var log = pino({
prettyPrint: true,
redact: ['foo.an']
})
log.info({ foo: { an: 'object' } }, 'h')

17
node_modules/pino/test/fixtures/pretty/serializers.js generated vendored Normal file
View file

@ -0,0 +1,17 @@
global.process = { __proto__: process, pid: 123456 }
Date.now = function () { return 1459875739796 }
require('os').hostname = function () { return 'abcdefghijklmnopqr' }
var pino = require(require.resolve('./../../../'))
var log = pino({
prettyPrint: true,
serializers: {
foo (obj) {
if (obj.an !== 'object') {
throw new Error('kaboom')
}
return 'bar'
}
}
})
log.info({ foo: { an: 'object' } }, 'h')

View file

@ -0,0 +1,13 @@
global.process = { __proto__: process, pid: 123456 }
Date.now = function () { return 1459875739796 }
require('os').hostname = function () { return 'abcdefghijklmnopqr' }
var pino = require(require.resolve('./../../../'))
var log = pino({
prettyPrint: true,
prettifier: function () {
return function () {
return undefined
}
}
})
log.info('h')

View file

@ -0,0 +1,11 @@
global.process = { __proto__: process, pid: 123456 }
const write = process.stdout.write.bind(process.stdout)
process.stdout.write = function (chunk) {
write('hack ' + chunk)
}
Date.now = function () { return 1459875739796 }
require('os').hostname = function () { return 'abcdefghijklmnopqr' }
var pino = require(require.resolve('../../'))()
pino.info('me')

55
node_modules/pino/test/helper.js generated vendored Normal file
View file

@ -0,0 +1,55 @@
'use strict'
const os = require('os')
const writer = require('flush-write-stream')
const split = require('split2')
const pid = process.pid
const hostname = os.hostname()
const v = 1
const isWin = process.platform === 'win32'
function getPathToNull () {
return isWin ? '\\\\.\\NUL' : '/dev/null'
}
function once (emitter, name) {
return new Promise((resolve, reject) => {
if (name !== 'error') emitter.once('error', reject)
emitter.once(name, (...args) => {
emitter.removeListener('error', reject)
resolve(...args)
})
})
}
function sink (func) {
const result = split((data) => {
try {
return JSON.parse(data)
} catch (err) {
console.log(err)
console.log(data)
}
})
if (func) result.pipe(writer.obj(func))
return result
}
function check (is, chunk, level, msg) {
is(new Date(chunk.time) <= new Date(), true, 'time is greater than Date.now()')
delete chunk.time
is(chunk.pid, pid)
is(chunk.hostname, hostname)
is(chunk.level, level)
is(chunk.msg, msg)
is(chunk.v, v)
}
function sleep (ms) {
return new Promise((resolve) => {
setTimeout(resolve, ms)
})
}
module.exports = { getPathToNull, sink, check, once, sleep }

247
node_modules/pino/test/http.test.js generated vendored Normal file
View file

@ -0,0 +1,247 @@
'use strict'
const http = require('http')
const os = require('os')
const semver = require('semver')
const { test } = require('tap')
const { sink, once } = require('./helper')
const pino = require('../')
const { pid } = process
const hostname = os.hostname()
test('http request support', async ({ ok, same, error, teardown }) => {
var originalReq
const instance = pino(sink((chunk, enc) => {
ok(new Date(chunk.time) <= new Date(), 'time is greater than Date.now()')
delete chunk.time
same(chunk, {
pid: pid,
hostname: hostname,
level: 30,
msg: 'my request',
v: 1,
req: {
method: originalReq.method,
url: originalReq.url,
headers: originalReq.headers,
remoteAddress: originalReq.connection.remoteAddress,
remotePort: originalReq.connection.remotePort
}
})
}))
const server = http.createServer((req, res) => {
originalReq = req
instance.info(req, 'my request')
res.end('hello')
})
server.unref()
server.listen()
const err = await once(server, 'listening')
error(err)
const res = await once(http.get('http://localhost:' + server.address().port), 'response')
res.resume()
server.close()
})
test('http request support via serializer', async ({ ok, same, error, teardown }) => {
var originalReq
const instance = pino({
serializers: {
req: pino.stdSerializers.req
}
}, sink((chunk, enc) => {
ok(new Date(chunk.time) <= new Date(), 'time is greater than Date.now()')
delete chunk.time
same(chunk, {
pid: pid,
hostname: hostname,
level: 30,
msg: 'my request',
v: 1,
req: {
method: originalReq.method,
url: originalReq.url,
headers: originalReq.headers,
remoteAddress: originalReq.connection.remoteAddress,
remotePort: originalReq.connection.remotePort
}
})
}))
const server = http.createServer(function (req, res) {
originalReq = req
instance.info({ req: req }, 'my request')
res.end('hello')
})
server.unref()
server.listen()
const err = await once(server, 'listening')
error(err)
const res = await once(http.get('http://localhost:' + server.address().port), 'response')
res.resume()
server.close()
})
test('http request support via serializer without request connection', async ({ ok, same, error, teardown }) => {
var originalReq
const instance = pino({
serializers: {
req: pino.stdSerializers.req
}
}, sink((chunk, enc) => {
ok(new Date(chunk.time) <= new Date(), 'time is greater than Date.now()')
delete chunk.time
const expected = {
pid: pid,
hostname: hostname,
level: 30,
msg: 'my request',
v: 1,
req: {
method: originalReq.method,
url: originalReq.url,
headers: originalReq.headers
}
}
if (semver.gte(process.version, '13.0.0')) {
expected.req.remoteAddress = originalReq.connection.remoteAddress
expected.req.remotePort = originalReq.connection.remotePort
}
same(chunk, expected)
}))
const server = http.createServer(function (req, res) {
originalReq = req
delete req.connection
instance.info({ req: req }, 'my request')
res.end('hello')
})
server.unref()
server.listen()
const err = await once(server, 'listening')
error(err)
const res = await once(http.get('http://localhost:' + server.address().port), 'response')
res.resume()
server.close()
})
test('http response support', async ({ ok, same, error, teardown }) => {
var originalRes
const instance = pino(sink((chunk, enc) => {
ok(new Date(chunk.time) <= new Date(), 'time is greater than Date.now()')
delete chunk.time
same(chunk, {
pid: pid,
hostname: hostname,
level: 30,
msg: 'my response',
v: 1,
res: {
statusCode: originalRes.statusCode,
headers: originalRes._headers
}
})
}))
const server = http.createServer(function (req, res) {
originalRes = res
res.end('hello')
instance.info(res, 'my response')
})
server.unref()
server.listen()
const err = await once(server, 'listening')
error(err)
const res = await once(http.get('http://localhost:' + server.address().port), 'response')
res.resume()
server.close()
})
test('http response support via a serializer', async ({ ok, same, error, teardown }) => {
const instance = pino({
serializers: {
res: pino.stdSerializers.res
}
}, sink((chunk, enc) => {
ok(new Date(chunk.time) <= new Date(), 'time is greater than Date.now()')
delete chunk.time
same(chunk, {
pid: pid,
hostname: hostname,
level: 30,
msg: 'my response',
v: 1,
res: {
statusCode: 200,
headers: {
'x-single': 'y',
'x-multi': [1, 2]
}
}
})
}))
const server = http.createServer(function (req, res) {
res.setHeader('x-single', 'y')
res.setHeader('x-multi', [1, 2])
res.end('hello')
instance.info({ res: res }, 'my response')
})
server.unref()
server.listen()
const err = await once(server, 'listening')
error(err)
const res = await once(http.get('http://localhost:' + server.address().port), 'response')
res.resume()
server.close()
})
test('http request support via serializer in a child', async ({ ok, same, error, teardown }) => {
var originalReq
const instance = pino({
serializers: {
req: pino.stdSerializers.req
}
}, sink((chunk, enc) => {
ok(new Date(chunk.time) <= new Date(), 'time is greater than Date.now()')
delete chunk.time
same(chunk, {
pid: pid,
hostname: hostname,
level: 30,
msg: 'my request',
v: 1,
req: {
method: originalReq.method,
url: originalReq.url,
headers: originalReq.headers,
remoteAddress: originalReq.connection.remoteAddress,
remotePort: originalReq.connection.remotePort
}
})
}))
const server = http.createServer(function (req, res) {
originalReq = req
const child = instance.child({ req: req })
child.info('my request')
res.end('hello')
})
server.unref()
server.listen()
const err = await once(server, 'listening')
error(err)
const res = await once(http.get('http://localhost:' + server.address().port), 'response')
res.resume()
server.close()
})

43
node_modules/pino/test/is-level-enabled.test.js generated vendored Normal file
View file

@ -0,0 +1,43 @@
'use strict'
const { test } = require('tap')
const pino = require('../')
test('can check if current level enabled', async ({ is }) => {
const log = pino({ level: 'debug' })
is(true, log.isLevelEnabled('debug'))
})
test('can check if level enabled after level set', async ({ is }) => {
const log = pino()
is(false, log.isLevelEnabled('debug'))
log.level = 'debug'
is(true, log.isLevelEnabled('debug'))
})
test('can check if higher level enabled', async ({ is }) => {
const log = pino({ level: 'debug' })
is(true, log.isLevelEnabled('error'))
})
test('can check if lower level is disabled', async ({ is }) => {
const log = pino({ level: 'error' })
is(false, log.isLevelEnabled('trace'))
})
test('can check if child has current level enabled', async ({ is }) => {
const log = pino().child({ level: 'debug' })
is(true, log.isLevelEnabled('debug'))
is(true, log.isLevelEnabled('error'))
is(false, log.isLevelEnabled('trace'))
})
test('can check if custom level is enabled', async ({ is }) => {
const log = pino({
customLevels: { foo: 35 },
level: 'debug'
})
is(true, log.isLevelEnabled('foo'))
is(true, log.isLevelEnabled('error'))
is(false, log.isLevelEnabled('trace'))
})

441
node_modules/pino/test/levels.test.js generated vendored Normal file
View file

@ -0,0 +1,441 @@
'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]))
})

110
node_modules/pino/test/metadata.test.js generated vendored Normal file
View file

@ -0,0 +1,110 @@
'use strict'
const os = require('os')
const { test } = require('tap')
const pino = require('../')
const { pid } = process
const hostname = os.hostname()
test('metadata works', async ({ ok, same, is }) => {
const now = Date.now()
const instance = pino({}, {
[Symbol.for('pino.metadata')]: true,
write (chunk) {
is(instance, this.lastLogger)
is(30, this.lastLevel)
is('a msg', this.lastMsg)
ok(Number(this.lastTime) >= now)
same(this.lastObj, { hello: 'world', msg: 'a msg' })
const result = JSON.parse(chunk)
ok(new Date(result.time) <= new Date(), 'time is greater than Date.now()')
delete result.time
same(result, {
pid: pid,
hostname: hostname,
level: 30,
hello: 'world',
msg: 'a msg',
v: 1
})
}
})
instance.info({ hello: 'world' }, 'a msg')
})
test('child loggers works', async ({ ok, same, is }) => {
const instance = pino({}, {
[Symbol.for('pino.metadata')]: true,
write (chunk) {
is(child, this.lastLogger)
is(30, this.lastLevel)
is('a msg', this.lastMsg)
same(this.lastObj, { from: 'child', msg: 'a msg' })
const result = JSON.parse(chunk)
ok(new Date(result.time) <= new Date(), 'time is greater than Date.now()')
delete result.time
same(result, {
pid: pid,
hostname: hostname,
level: 30,
hello: 'world',
from: 'child',
msg: 'a msg',
v: 1
})
}
})
const child = instance.child({ hello: 'world' })
child.info({ from: 'child' }, 'a msg')
})
test('without object', async ({ ok, same, is }) => {
const instance = pino({}, {
[Symbol.for('pino.metadata')]: true,
write (chunk) {
is(instance, this.lastLogger)
is(30, this.lastLevel)
is('a msg', this.lastMsg)
same({ msg: 'a msg' }, this.lastObj)
const result = JSON.parse(chunk)
ok(new Date(result.time) <= new Date(), 'time is greater than Date.now()')
delete result.time
same(result, {
pid: pid,
hostname: hostname,
level: 30,
msg: 'a msg',
v: 1
})
}
})
instance.info('a msg')
})
test('without msg', async ({ ok, same, is }) => {
const instance = pino({}, {
[Symbol.for('pino.metadata')]: true,
write (chunk) {
is(instance, this.lastLogger)
is(30, this.lastLevel)
is(undefined, this.lastMsg)
same({ hello: 'world' }, this.lastObj)
const result = JSON.parse(chunk)
ok(new Date(result.time) <= new Date(), 'time is greater than Date.now()')
delete result.time
same(result, {
pid: pid,
hostname: hostname,
level: 30,
hello: 'world',
v: 1
})
}
})
instance.info({ hello: 'world' })
})

106
node_modules/pino/test/mixin.test.js generated vendored Normal file
View file

@ -0,0 +1,106 @@
'use strict'
const os = require('os')
const { test } = require('tap')
const { sink, once } = require('./helper')
const pino = require('../')
const { pid } = process
const hostname = os.hostname()
const level = 50
const name = 'error'
test('mixin object is included', async ({ ok, same }) => {
let n = 0
const stream = sink()
const instance = pino({
mixin () {
return { hello: ++n }
}
}, stream)
instance.level = name
instance[name]('test')
const result = await once(stream, 'data')
ok(new Date(result.time) <= new Date(), 'time is greater than Date.now()')
delete result.time
same(result, {
pid,
hostname,
level,
msg: 'test',
hello: 1,
v: 1
})
})
test('mixin object is new every time', async ({ plan, ok, same }) => {
plan(6)
let n = 0
const stream = sink()
const instance = pino({
mixin () {
return { hello: n }
}
}, stream)
instance.level = name
while (++n < 4) {
const msg = `test #${n}`
stream.pause()
instance[name](msg)
stream.resume()
const result = await once(stream, 'data')
ok(new Date(result.time) <= new Date(), 'time is greater than Date.now()')
delete result.time
same(result, {
pid,
hostname,
level,
msg,
hello: n,
v: 1
})
}
})
test('mixin object is not called if below log level', async ({ ok }) => {
const stream = sink()
const instance = pino({
mixin () {
ok(false, 'should not call mixin function')
}
}, stream)
instance.level = 'error'
instance.info('test')
})
test('mixin object + logged object', async ({ ok, same }) => {
const stream = sink()
const instance = pino({
mixin () {
return { foo: 1, bar: 2 }
}
}, stream)
instance.level = name
instance[name]({ bar: 3, baz: 4 })
const result = await once(stream, 'data')
ok(new Date(result.time) <= new Date(), 'time is greater than Date.now()')
delete result.time
same(result, {
pid,
hostname,
level,
foo: 1,
bar: 3,
baz: 4,
v: 1
})
})
test('mixin not a function', async ({ throws }) => {
const stream = sink()
throws(function () {
pino({ mixin: 'not a function' }, stream)
})
})

312
node_modules/pino/test/pretty.test.js generated vendored Normal file
View file

@ -0,0 +1,312 @@
'use strict'
const { Writable } = require('stream')
const { test } = require('tap')
const { join } = require('path')
const execa = require('execa')
const writer = require('flush-write-stream')
const { once } = require('./helper')
const pino = require('../')
const tap = require('tap')
const isWin = process.platform === 'win32'
if (isWin) {
tap.comment('Skipping pretty printing tests on Windows as colour codes are different and tests fail')
process.exit(0)
}
test('can be enabled via exported pino function', async ({ isNot }) => {
var actual = ''
const child = execa(process.argv[0], [join(__dirname, 'fixtures', 'pretty', 'basic.js')])
child.stdout.pipe(writer((s, enc, cb) => {
actual += s
cb()
}))
await once(child, 'close')
isNot(actual.match(/\(123456 on abcdefghijklmnopqr\): h/), null)
})
test('can be enabled via exported pino function with pretty configuration', async ({ isNot }) => {
var actual = ''
const child = execa(process.argv[0], [join(__dirname, 'fixtures', 'pretty', 'level-first.js')])
child.stdout.pipe(writer((s, enc, cb) => {
actual += s
cb()
}))
await once(child, 'close')
isNot(actual.match(/^INFO.*h/), null)
})
test('can be enabled via exported pino function with prettifier', async ({ isNot }) => {
var actual = ''
const child = execa(process.argv[0], [join(__dirname, 'fixtures', 'pretty', 'pretty-factory.js')])
child.stdout.pipe(writer((s, enc, cb) => {
actual += s
cb()
}))
await once(child, 'close')
isNot(actual.match(/^INFO.*h/), null)
})
test('does not throw error when enabled with stream specified', async ({ doesNotThrow }) => {
doesNotThrow(() => pino({ prettyPrint: true }, process.stdout))
})
test('throws when prettyPrint is true but pino-pretty module is not installed', async ({ throws, is }) => {
// pino pretty *is* installed, and probably also cached, so rather than
// messing with the filesystem the simplest way to generate a not found
// error is to simulate it:
const prettyFactory = require('pino-pretty')
require.cache[require.resolve('pino-pretty')].exports = () => {
throw Error('Cannot find module \'pino-pretty\'')
}
throws(() => pino({ prettyPrint: true }))
try { pino({ prettyPrint: true }) } catch ({ message }) {
is(message, 'Missing `pino-pretty` module: `pino-pretty` must be installed separately')
}
require.cache[require.resolve('pino-pretty')].exports = prettyFactory
})
test('can send pretty print to custom stream', async ({ is }) => {
const dest = new Writable({
objectMode: true,
write (formatted, enc) {
is(/^INFO.*foo\n$/.test(formatted), true)
}
})
const log = pino({
prettifier: require('pino-pretty'),
prettyPrint: {
levelFirst: true,
colorize: false
}
}, dest)
log.info('foo')
})
test('ignores `undefined` from prettifier', async ({ is }) => {
var actual = ''
const child = execa(process.argv[0], [join(__dirname, 'fixtures', 'pretty', 'skipped-output.js')])
child.stdout.pipe(writer((s, enc) => {
actual += s
}))
await once(child, 'close')
is(actual, '')
})
test('parses and outputs chindings', async ({ is, isNot }) => {
var actual = ''
const child = execa(process.argv[0], [join(__dirname, 'fixtures', 'pretty', 'child.js')])
child.stdout.pipe(writer((s, enc, cb) => {
actual += s
cb()
}))
await once(child, 'close')
isNot(actual.match(/\(123456 on abcdefghijklmnopqr\): h/), null)
isNot(actual.match(/\(123456 on abcdefghijklmnopqr\): h2/), null)
isNot(actual.match(/a: 1/), null)
isNot(actual.match(/b: 2/), null)
is(actual.match(/a: 1/g).length, 3)
})
test('applies serializers', async ({ is, isNot }) => {
var actual = ''
const child = execa(process.argv[0], [join(__dirname, 'fixtures', 'pretty', 'serializers.js')])
child.stdout.pipe(writer((s, enc, cb) => {
actual += s
cb()
}))
await once(child, 'close')
isNot(actual.match(/\(123456 on abcdefghijklmnopqr\): h/), null)
isNot(actual.match(/foo: "bar"/), null)
})
test('applies redaction rules', async ({ is, isNot }) => {
var actual = ''
const child = execa(process.argv[0], [join(__dirname, 'fixtures', 'pretty', 'redact.js')])
child.stdout.pipe(writer((s, enc, cb) => {
actual += s
cb()
}))
await once(child, 'close')
isNot(actual.match(/\(123456 on abcdefghijklmnopqr\): h/), null)
isNot(actual.match(/\[Redacted\]/), null)
is(actual.match(/object/), null)
})
test('dateformat', async ({ isNot }) => {
var actual = ''
const child = execa(process.argv[0], [join(__dirname, 'fixtures', 'pretty', 'dateformat.js')])
child.stdout.pipe(writer((s, enc, cb) => {
actual += s
cb()
}))
await once(child, 'close')
isNot(actual.match(/\(123456 on abcdefghijklmnopqr\): h/), null)
})
test('without timestamp', async ({ isNot }) => {
var actual = ''
const child = execa(process.argv[0], [join(__dirname, 'fixtures', 'pretty', 'no-time.js')])
child.stdout.pipe(writer((s, enc, cb) => {
actual += s
cb()
}))
await once(child, 'close')
isNot(actual.slice(2), '[]')
})
test('with custom timestamp', async ({ is }) => {
var actual = ''
const child = execa(process.argv[0], [join(__dirname, 'fixtures', 'pretty', 'custom-time.js')])
child.stdout.pipe(writer((s, enc, cb) => {
actual += s
cb()
}))
await once(child, 'close')
is(actual.slice(0, 8), '["test"]')
})
test('with custom timestamp label', async ({ is }) => {
var actual = ''
const child = execa(process.argv[0], [join(__dirname, 'fixtures', 'pretty', 'custom-time-label.js')])
child.stdout.pipe(writer((s, enc, cb) => {
actual += s
cb()
}))
await once(child, 'close')
is(actual.slice(0, 8), '["test"]')
})
test('errors', async ({ isNot }) => {
var actual = ''
const child = execa(process.argv[0], [join(__dirname, 'fixtures', 'pretty', 'error.js')])
child.stdout.pipe(writer((s, enc, cb) => {
actual += s
cb()
}))
await once(child, 'close')
isNot(actual.match(/\(123456 on abcdefghijklmnopqr\): kaboom/), null)
isNot(actual.match(/\(123456 on abcdefghijklmnopqr\): with a message/), null)
isNot(actual.match(/.*error\.js.*/), null)
})
test('errors with props', async ({ isNot }) => {
var actual = ''
const child = execa(process.argv[0], [join(__dirname, 'fixtures', 'pretty', 'error-props.js')])
child.stdout.pipe(writer((s, enc, cb) => {
actual += s
cb()
}))
await once(child, 'close')
isNot(actual.match(/\(123456 on abcdefghijklmnopqr\): kaboom/), null)
isNot(actual.match(/code: ENOENT/), null)
isNot(actual.match(/errno: 1/), null)
isNot(actual.match(/.*error-props\.js.*/), null)
})
test('final works with pretty', async ({ isNot }) => {
var actual = ''
const child = execa(process.argv[0], [join(__dirname, 'fixtures', 'pretty', 'final.js')])
child.stdout.pipe(writer((s, enc, cb) => {
actual += s
cb()
}))
await once(child, 'close')
isNot(actual.match(/WARN\s+\(123456 on abcdefghijklmnopqr\): pino.final with prettyPrint does not support flushing/), null)
isNot(actual.match(/INFO\s+\(123456 on abcdefghijklmnopqr\): beforeExit/), null)
})
test('final works when returning a logger', async ({ isNot }) => {
var actual = ''
const child = execa(process.argv[0], [join(__dirname, 'fixtures', 'pretty', 'final-return.js')])
child.stdout.pipe(writer((s, enc, cb) => {
actual += s
cb()
}))
await once(child, 'close')
isNot(actual.match(/WARN\s+\(123456 on abcdefghijklmnopqr\): pino.final with prettyPrint does not support flushing/), null)
isNot(actual.match(/INFO\s+\(123456 on abcdefghijklmnopqr\): after/), null)
})
test('final works without prior logging', async ({ isNot }) => {
var actual = ''
const child = execa(process.argv[0], [join(__dirname, 'fixtures', 'pretty', 'final-no-log-before.js')])
child.stdout.pipe(writer((s, enc, cb) => {
actual += s
cb()
}))
await once(child, 'close')
isNot(actual.match(/WARN\s+: pino.final with prettyPrint does not support flushing/), null)
isNot(actual.match(/INFO\s+\(123456 on abcdefghijklmnopqr\): beforeExit/), null)
})
test('works as expected with an object with the msg prop', async ({ isNot }) => {
var actual = ''
const child = execa(process.argv[0], [join(__dirname, 'fixtures', 'pretty', 'obj-msg-prop.js')])
child.stdout.pipe(writer((s, enc, cb) => {
actual += s
cb()
}))
await once(child, 'close')
isNot(actual.match(/\(123456 on abcdefghijklmnopqr\): hello/), null)
})
test('should not lose stream metadata for streams with `needsMetadataGsym` flag', async ({ isNot }) => {
const dest = new Writable({
objectMode: true,
write () {
isNot(typeof this.lastLevel === 'undefined', true)
isNot(typeof this.lastMsg === 'undefined', true)
isNot(typeof this.lastObj === 'undefined', true)
isNot(typeof this.lastTime === 'undefined', true)
isNot(typeof this.lastLogger === 'undefined', true)
}
})
dest[pino.symbols.needsMetadataGsym] = true
const log = pino({
prettyPrint: true
}, dest)
log.info('foo')
})
test('should not add stream metadata for streams without `needsMetadataGsym` flag', async ({ is }) => {
const dest = new Writable({
objectMode: true,
write () {
is(typeof this.lastLevel === 'undefined', true)
is(typeof this.lastMsg === 'undefined', true)
is(typeof this.lastObj === 'undefined', true)
is(typeof this.lastTime === 'undefined', true)
is(typeof this.lastLogger === 'undefined', true)
}
})
const log = pino({
prettyPrint: true
}, dest)
log.info('foo')
})

713
node_modules/pino/test/redact.test.js generated vendored Normal file
View file

@ -0,0 +1,713 @@
'use strict'
const { test } = require('tap')
const { sink, once } = require('./helper')
const pino = require('../')
test('redact option throws if not array', async ({ throws }) => {
throws(() => {
pino({ redact: 'req.headers.cookie' })
})
})
test('redact option throws if array does not only contain strings', async ({ throws }) => {
throws(() => {
pino({ redact: ['req.headers.cookie', {}] })
})
})
test('redact option throws if array contains an invalid path', async ({ throws }) => {
throws(() => {
pino({ redact: ['req,headers.cookie'] })
})
})
test('redact.paths option throws if not array', async ({ throws }) => {
throws(() => {
pino({ redact: { paths: 'req.headers.cookie' } })
})
})
test('redact.paths option throws if array does not only contain strings', async ({ throws }) => {
throws(() => {
pino({ redact: { paths: ['req.headers.cookie', {}] } })
})
})
test('redact.paths option throws if array contains an invalid path', async ({ throws }) => {
throws(() => {
pino({ redact: { paths: ['req,headers.cookie'] } })
})
})
test('redact option top level key', async ({ is }) => {
const stream = sink()
const instance = pino({ redact: ['key'] }, stream)
instance.info({
key: { redact: 'me' }
})
const { key } = await once(stream, 'data')
is(key, '[Redacted]')
})
test('redact option top level key next level key', async ({ is }) => {
const stream = sink()
const instance = pino({ redact: ['key', 'key.foo'] }, stream)
instance.info({
key: { redact: 'me' }
})
const { key } = await once(stream, 'data')
is(key, '[Redacted]')
})
test('redact option next level key then top level key', async ({ is }) => {
const stream = sink()
const instance = pino({ redact: ['key.foo', 'key'] }, stream)
instance.info({
key: { redact: 'me' }
})
const { key } = await once(stream, 'data')
is(key, '[Redacted]')
})
test('redact option object', async ({ is }) => {
const stream = sink()
const instance = pino({ redact: ['req.headers.cookie'] }, stream)
instance.info({
req: {
id: 7915,
method: 'GET',
url: '/',
headers: {
host: 'localhost:3000',
connection: 'keep-alive',
cookie: 'SESSID=298zf09hf012fh2; csrftoken=u32t4o3tb3gg43; _gat=1;'
},
remoteAddress: '::ffff:127.0.0.1',
remotePort: 58022
}
})
const { req } = await once(stream, 'data')
is(req.headers.cookie, '[Redacted]')
})
test('redact option child object', async ({ is }) => {
const stream = sink()
const instance = pino({ redact: ['req.headers.cookie'] }, stream)
instance.child({
req: {
id: 7915,
method: 'GET',
url: '/',
headers: {
host: 'localhost:3000',
connection: 'keep-alive',
cookie: 'SESSID=298zf09hf012fh2; csrftoken=u32t4o3tb3gg43; _gat=1;'
},
remoteAddress: '::ffff:127.0.0.1',
remotePort: 58022
}
}).info('message completed')
const { req } = await once(stream, 'data')
is(req.headers.cookie, '[Redacted]')
})
test('redact option interpolated object', async ({ is }) => {
const stream = sink()
const instance = pino({ redact: ['req.headers.cookie'] }, stream)
instance.info('test', {
req: {
id: 7915,
method: 'GET',
url: '/',
headers: {
host: 'localhost:3000',
connection: 'keep-alive',
cookie: 'SESSID=298zf09hf012fh2; csrftoken=u32t4o3tb3gg43; _gat=1;'
},
remoteAddress: '::ffff:127.0.0.1',
remotePort: 58022
}
})
const { msg } = await once(stream, 'data')
is(JSON.parse(msg.replace(/test /, '')).req.headers.cookie, '[Redacted]')
})
test('redact.paths option object', async ({ is }) => {
const stream = sink()
const instance = pino({ redact: { paths: ['req.headers.cookie'] } }, stream)
instance.info({
req: {
id: 7915,
method: 'GET',
url: '/',
headers: {
host: 'localhost:3000',
connection: 'keep-alive',
cookie: 'SESSID=298zf09hf012fh2; csrftoken=u32t4o3tb3gg43; _gat=1;'
},
remoteAddress: '::ffff:127.0.0.1',
remotePort: 58022
}
})
const { req } = await once(stream, 'data')
is(req.headers.cookie, '[Redacted]')
})
test('redact.paths option child object', async ({ is }) => {
const stream = sink()
const instance = pino({ redact: { paths: ['req.headers.cookie'] } }, stream)
instance.child({
req: {
id: 7915,
method: 'GET',
url: '/',
headers: {
host: 'localhost:3000',
connection: 'keep-alive',
cookie: 'SESSID=298zf09hf012fh2; csrftoken=u32t4o3tb3gg43; _gat=1;'
},
remoteAddress: '::ffff:127.0.0.1',
remotePort: 58022
}
}).info('message completed')
const { req } = await once(stream, 'data')
is(req.headers.cookie, '[Redacted]')
})
test('redact.paths option interpolated object', async ({ is }) => {
const stream = sink()
const instance = pino({ redact: { paths: ['req.headers.cookie'] } }, stream)
instance.info('test', {
req: {
id: 7915,
method: 'GET',
url: '/',
headers: {
host: 'localhost:3000',
connection: 'keep-alive',
cookie: 'SESSID=298zf09hf012fh2; csrftoken=u32t4o3tb3gg43; _gat=1;'
},
remoteAddress: '::ffff:127.0.0.1',
remotePort: 58022
}
})
const { msg } = await once(stream, 'data')
is(JSON.parse(msg.replace(/test /, '')).req.headers.cookie, '[Redacted]')
})
test('redact.censor option sets the redact value', async ({ is }) => {
const stream = sink()
const instance = pino({ redact: { paths: ['req.headers.cookie'], censor: 'test' } }, stream)
instance.info({
req: {
id: 7915,
method: 'GET',
url: '/',
headers: {
host: 'localhost:3000',
connection: 'keep-alive',
cookie: 'SESSID=298zf09hf012fh2; csrftoken=u32t4o3tb3gg43; _gat=1;'
},
remoteAddress: '::ffff:127.0.0.1',
remotePort: 58022
}
})
const { req } = await once(stream, 'data')
is(req.headers.cookie, 'test')
})
test('redact.remove option removes both key and value', async ({ is }) => {
const stream = sink()
const instance = pino({ redact: { paths: ['req.headers.cookie'], remove: true } }, stream)
instance.info({
req: {
id: 7915,
method: 'GET',
url: '/',
headers: {
host: 'localhost:3000',
connection: 'keep-alive',
cookie: 'SESSID=298zf09hf012fh2; csrftoken=u32t4o3tb3gg43; _gat=1;'
},
remoteAddress: '::ffff:127.0.0.1',
remotePort: 58022
}
})
const { req } = await once(stream, 'data')
is('cookie' in req.headers, false)
})
test('redact.remove top level key - object value', async ({ is }) => {
const stream = sink()
const instance = pino({ redact: { paths: ['key'], remove: true } }, stream)
instance.info({
key: { redact: 'me' }
})
const o = await once(stream, 'data')
is('key' in o, false)
})
test('redact.remove top level key - number value', async ({ is }) => {
const stream = sink()
const instance = pino({ redact: { paths: ['key'], remove: true } }, stream)
instance.info({
key: 1
})
const o = await once(stream, 'data')
is('key' in o, false)
})
test('redact.remove top level key - boolean value', async ({ is }) => {
const stream = sink()
const instance = pino({ redact: { paths: ['key'], remove: true } }, stream)
instance.info({
key: false
})
const o = await once(stream, 'data')
is('key' in o, false)
})
test('redact.remove top level key in child logger', async ({ is }) => {
const stream = sink()
const opts = { redact: { paths: ['key'], remove: true } }
const instance = pino(opts, stream).child({ key: { redact: 'me' } })
instance.info('test')
const o = await once(stream, 'data')
is('key' in o, false)
})
test('redact.paths preserves original object values after the log write', async ({ is }) => {
const stream = sink()
const instance = pino({ redact: ['req.headers.cookie'] }, stream)
const obj = {
req: {
id: 7915,
method: 'GET',
url: '/',
headers: {
host: 'localhost:3000',
connection: 'keep-alive',
cookie: 'SESSID=298zf09hf012fh2; csrftoken=u32t4o3tb3gg43; _gat=1;'
},
remoteAddress: '::ffff:127.0.0.1',
remotePort: 58022
}
}
instance.info(obj)
const o = await once(stream, 'data')
is(o.req.headers.cookie, '[Redacted]')
is(obj.req.headers.cookie, 'SESSID=298zf09hf012fh2; csrftoken=u32t4o3tb3gg43; _gat=1;')
})
test('redact.paths preserves original object values after the log write', async ({ is }) => {
const stream = sink()
const instance = pino({ redact: { paths: ['req.headers.cookie'] } }, stream)
const obj = {
req: {
id: 7915,
method: 'GET',
url: '/',
headers: {
host: 'localhost:3000',
connection: 'keep-alive',
cookie: 'SESSID=298zf09hf012fh2; csrftoken=u32t4o3tb3gg43; _gat=1;'
},
remoteAddress: '::ffff:127.0.0.1',
remotePort: 58022
}
}
instance.info(obj)
const o = await once(stream, 'data')
is(o.req.headers.cookie, '[Redacted]')
is(obj.req.headers.cookie, 'SESSID=298zf09hf012fh2; csrftoken=u32t4o3tb3gg43; _gat=1;')
})
test('redact.censor preserves original object values after the log write', async ({ is }) => {
const stream = sink()
const instance = pino({ redact: { paths: ['req.headers.cookie'], censor: 'test' } }, stream)
const obj = {
req: {
id: 7915,
method: 'GET',
url: '/',
headers: {
host: 'localhost:3000',
connection: 'keep-alive',
cookie: 'SESSID=298zf09hf012fh2; csrftoken=u32t4o3tb3gg43; _gat=1;'
},
remoteAddress: '::ffff:127.0.0.1',
remotePort: 58022
}
}
instance.info(obj)
const o = await once(stream, 'data')
is(o.req.headers.cookie, 'test')
is(obj.req.headers.cookie, 'SESSID=298zf09hf012fh2; csrftoken=u32t4o3tb3gg43; _gat=1;')
})
test('redact.remove preserves original object values after the log write', async ({ is }) => {
const stream = sink()
const instance = pino({ redact: { paths: ['req.headers.cookie'], remove: true } }, stream)
const obj = {
req: {
id: 7915,
method: 'GET',
url: '/',
headers: {
host: 'localhost:3000',
connection: 'keep-alive',
cookie: 'SESSID=298zf09hf012fh2; csrftoken=u32t4o3tb3gg43; _gat=1;'
},
remoteAddress: '::ffff:127.0.0.1',
remotePort: 58022
}
}
instance.info(obj)
const o = await once(stream, 'data')
is('cookie' in o.req.headers, false)
is('cookie' in obj.req.headers, true)
})
test('redact supports last position wildcard paths', async ({ is }) => {
const stream = sink()
const instance = pino({ redact: ['req.headers.*'] }, stream)
instance.info({
req: {
id: 7915,
method: 'GET',
url: '/',
headers: {
host: 'localhost:3000',
connection: 'keep-alive',
cookie: 'SESSID=298zf09hf012fh2; csrftoken=u32t4o3tb3gg43; _gat=1;'
},
remoteAddress: '::ffff:127.0.0.1',
remotePort: 58022
}
})
const { req } = await once(stream, 'data')
is(req.headers.cookie, '[Redacted]')
is(req.headers.host, '[Redacted]')
is(req.headers.connection, '[Redacted]')
})
test('redact supports first position wildcard paths', async ({ is }) => {
const stream = sink()
const instance = pino({ redact: ['*.headers'] }, stream)
instance.info({
req: {
id: 7915,
method: 'GET',
url: '/',
headers: {
host: 'localhost:3000',
connection: 'keep-alive',
cookie: 'SESSID=298zf09hf012fh2; csrftoken=u32t4o3tb3gg43; _gat=1;'
},
remoteAddress: '::ffff:127.0.0.1',
remotePort: 58022
}
})
const { req } = await once(stream, 'data')
is(req.headers, '[Redacted]')
})
test('redact supports first position wildcards before other paths', async ({ is }) => {
const stream = sink()
const instance = pino({ redact: ['*.headers.cookie', 'req.id'] }, stream)
instance.info({
req: {
id: 7915,
method: 'GET',
url: '/',
headers: {
host: 'localhost:3000',
connection: 'keep-alive',
cookie: 'SESSID=298zf09hf012fh2; csrftoken=u32t4o3tb3gg43; _gat=1;'
},
remoteAddress: '::ffff:127.0.0.1',
remotePort: 58022
}
})
const { req } = await once(stream, 'data')
is(req.headers.cookie, '[Redacted]')
is(req.id, '[Redacted]')
})
test('redact supports first position wildcards after other paths', async ({ is }) => {
const stream = sink()
const instance = pino({ redact: ['req.id', '*.headers.cookie'] }, stream)
instance.info({
req: {
id: 7915,
method: 'GET',
url: '/',
headers: {
host: 'localhost:3000',
connection: 'keep-alive',
cookie: 'SESSID=298zf09hf012fh2; csrftoken=u32t4o3tb3gg43; _gat=1;'
},
remoteAddress: '::ffff:127.0.0.1',
remotePort: 58022
}
})
const { req } = await once(stream, 'data')
is(req.headers.cookie, '[Redacted]')
is(req.id, '[Redacted]')
})
test('redact supports first position wildcards after top level keys', async ({ is }) => {
const stream = sink()
const instance = pino({ redact: ['key', '*.headers.cookie'] }, stream)
instance.info({
req: {
id: 7915,
method: 'GET',
url: '/',
headers: {
host: 'localhost:3000',
connection: 'keep-alive',
cookie: 'SESSID=298zf09hf012fh2; csrftoken=u32t4o3tb3gg43; _gat=1;'
},
remoteAddress: '::ffff:127.0.0.1',
remotePort: 58022
}
})
const { req } = await once(stream, 'data')
is(req.headers.cookie, '[Redacted]')
})
test('redact supports top level wildcard', async ({ is }) => {
const stream = sink()
const instance = pino({ redact: ['*'] }, stream)
instance.info({
req: {
id: 7915,
method: 'GET',
url: '/',
headers: {
host: 'localhost:3000',
connection: 'keep-alive',
cookie: 'SESSID=298zf09hf012fh2; csrftoken=u32t4o3tb3gg43; _gat=1;'
},
remoteAddress: '::ffff:127.0.0.1',
remotePort: 58022
}
})
const { req } = await once(stream, 'data')
is(req, '[Redacted]')
})
test('redact supports top level wildcard with a censor function', async ({ is }) => {
const stream = sink()
const instance = pino({
redact: {
paths: ['*'],
censor: () => '[Redacted]'
}
}, stream)
instance.info({
req: {
id: 7915,
method: 'GET',
url: '/',
headers: {
host: 'localhost:3000',
connection: 'keep-alive',
cookie: 'SESSID=298zf09hf012fh2; csrftoken=u32t4o3tb3gg43; _gat=1;'
},
remoteAddress: '::ffff:127.0.0.1',
remotePort: 58022
}
})
const { req } = await once(stream, 'data')
is(req, '[Redacted]')
})
test('redact supports top level wildcard and leading wildcard', async ({ is }) => {
const stream = sink()
const instance = pino({ redact: ['*', '*.req'] }, stream)
instance.info({
req: {
id: 7915,
method: 'GET',
url: '/',
headers: {
host: 'localhost:3000',
connection: 'keep-alive',
cookie: 'SESSID=298zf09hf012fh2; csrftoken=u32t4o3tb3gg43; _gat=1;'
},
remoteAddress: '::ffff:127.0.0.1',
remotePort: 58022
}
})
const { req } = await once(stream, 'data')
is(req, '[Redacted]')
})
test('redact supports intermediate wildcard paths', async ({ is }) => {
const stream = sink()
const instance = pino({ redact: ['req.*.cookie'] }, stream)
instance.info({
req: {
id: 7915,
method: 'GET',
url: '/',
headers: {
host: 'localhost:3000',
connection: 'keep-alive',
cookie: 'SESSID=298zf09hf012fh2; csrftoken=u32t4o3tb3gg43; _gat=1;'
},
remoteAddress: '::ffff:127.0.0.1',
remotePort: 58022
}
})
const { req } = await once(stream, 'data')
is(req.headers.cookie, '[Redacted]')
})
test('redacts numbers at the top level', async ({ is }) => {
const stream = sink()
const instance = pino({ redact: ['id'] }, stream)
const obj = {
id: 7915
}
instance.info(obj)
const o = await once(stream, 'data')
is(o.id, '[Redacted]')
})
test('redacts booleans at the top level', async ({ is }) => {
const stream = sink()
const instance = pino({ redact: ['maybe'] }, stream)
const obj = {
maybe: true
}
instance.info(obj)
const o = await once(stream, 'data')
is(o.maybe, '[Redacted]')
})
test('redacts strings at the top level', async ({ is }) => {
const stream = sink()
const instance = pino({ redact: ['s'] }, stream)
const obj = {
s: 's'
}
instance.info(obj)
const o = await once(stream, 'data')
is(o.s, '[Redacted]')
})
test('does not redact primitives if not objects', async ({ is }) => {
const stream = sink()
const instance = pino({ redact: ['a.b'] }, stream)
const obj = {
a: 42
}
instance.info(obj)
const o = await once(stream, 'data')
is(o.a, 42)
})
test('redacts null at the top level', async ({ is }) => {
const stream = sink()
const instance = pino({ redact: ['n'] }, stream)
const obj = {
n: null
}
instance.info(obj)
const o = await once(stream, 'data')
is(o.n, '[Redacted]')
})
test('supports bracket notation', async ({ is }) => {
const stream = sink()
const instance = pino({ redact: ['a["b.b"]'] }, stream)
const obj = {
a: { 'b.b': 'c' }
}
instance.info(obj)
const o = await once(stream, 'data')
is(o.a['b.b'], '[Redacted]')
})
test('supports bracket notation with further nesting', async ({ is }) => {
const stream = sink()
const instance = pino({ redact: ['a["b.b"].c'] }, stream)
const obj = {
a: { 'b.b': { c: 'd' } }
}
instance.info(obj)
const o = await once(stream, 'data')
is(o.a['b.b'].c, '[Redacted]')
})
test('supports bracket notation with empty string as path segment', async ({ is }) => {
const stream = sink()
const instance = pino({ redact: ['a[""].c'] }, stream)
const obj = {
a: { '': { c: 'd' } }
}
instance.info(obj)
const o = await once(stream, 'data')
is(o.a[''].c, '[Redacted]')
})
test('supports leading bracket notation (single quote)', async ({ is }) => {
const stream = sink()
const instance = pino({ redact: ['[\'a.a\'].b'] }, stream)
const obj = {
'a.a': { b: 'c' }
}
instance.info(obj)
const o = await once(stream, 'data')
is(o['a.a'].b, '[Redacted]')
})
test('supports leading bracket notation (double quote)', async ({ is }) => {
const stream = sink()
const instance = pino({ redact: ['["a.a"].b'] }, stream)
const obj = {
'a.a': { b: 'c' }
}
instance.info(obj)
const o = await once(stream, 'data')
is(o['a.a'].b, '[Redacted]')
})
test('supports leading bracket notation (backtick quote)', async ({ is }) => {
const stream = sink()
const instance = pino({ redact: ['[`a.a`].b'] }, stream)
const obj = {
'a.a': { b: 'c' }
}
instance.info(obj)
const o = await once(stream, 'data')
is(o['a.a'].b, '[Redacted]')
})
test('supports leading bracket notation (single-segment path)', async ({ is }) => {
const stream = sink()
const instance = pino({ redact: ['[`a.a`]'] }, stream)
const obj = {
'a.a': { b: 'c' }
}
instance.info(obj)
const o = await once(stream, 'data')
is(o['a.a'], '[Redacted]')
})
test('supports leading bracket notation (single-segment path, wilcard)', async ({ is }) => {
const stream = sink()
const instance = pino({ redact: ['[*]'] }, stream)
const obj = {
'a.a': { b: 'c' }
}
instance.info(obj)
const o = await once(stream, 'data')
is(o['a.a'], '[Redacted]')
})

245
node_modules/pino/test/serializers.test.js generated vendored Normal file
View file

@ -0,0 +1,245 @@
'use strict'
const { test } = require('tap')
const { sink, once } = require('./helper')
const pino = require('../')
const parentSerializers = {
test: () => 'parent'
}
const childSerializers = {
test: () => 'child'
}
test('default err namespace error serializer', async ({ is }) => {
const stream = sink()
const parent = pino(stream)
parent.info({ err: ReferenceError('test') })
const o = await once(stream, 'data')
is(typeof o.err, 'object')
is(o.err.type, 'ReferenceError')
is(o.err.message, 'test')
is(typeof o.err.stack, 'string')
})
test('custom serializer overrides default err namespace error serializer', async ({ is }) => {
const stream = sink()
const parent = pino({
serializers: {
err: (e) => ({
t: e.constructor.name,
m: e.message,
s: e.stack
})
}
}, stream)
parent.info({ err: ReferenceError('test') })
const o = await once(stream, 'data')
is(typeof o.err, 'object')
is(o.err.t, 'ReferenceError')
is(o.err.m, 'test')
is(typeof o.err.s, 'string')
})
test('null overrides default err namespace error serializer', async ({ is }) => {
const stream = sink()
const parent = pino({ serializers: { err: null } }, stream)
parent.info({ err: ReferenceError('test') })
const o = await once(stream, 'data')
is(typeof o.err, 'object')
is(typeof o.err.type, 'undefined')
is(typeof o.err.message, 'undefined')
is(typeof o.err.stack, 'undefined')
})
test('undefined overrides default err namespace error serializer', async ({ is }) => {
const stream = sink()
const parent = pino({ serializers: { err: undefined } }, stream)
parent.info({ err: ReferenceError('test') })
const o = await once(stream, 'data')
is(typeof o.err, 'object')
is(typeof o.err.type, 'undefined')
is(typeof o.err.message, 'undefined')
is(typeof o.err.stack, 'undefined')
})
test('serializers override values', async ({ is }) => {
const stream = sink()
const parent = pino({ serializers: parentSerializers }, stream)
parent.child({ serializers: childSerializers })
parent.fatal({ test: 'test' })
const o = await once(stream, 'data')
is(o.test, 'parent')
})
test('child does not overwrite parent serializers', async ({ is }) => {
const stream = sink()
const parent = pino({ serializers: parentSerializers }, stream)
const child = parent.child({ serializers: childSerializers })
parent.fatal({ test: 'test' })
const o = once(stream, 'data')
is((await o).test, 'parent')
const o2 = once(stream, 'data')
child.fatal({ test: 'test' })
is((await o2).test, 'child')
})
test('Symbol.for(\'pino.serializers\')', async ({ is, isNot }) => {
const stream = sink()
const parent = pino({ serializers: parentSerializers }, stream)
const child = parent.child({ a: 'property' })
is(parent[Symbol.for('pino.serializers')], parentSerializers)
is(child[Symbol.for('pino.serializers')], parentSerializers)
const child2 = parent.child({
serializers: {
a
}
})
function a () {
return 'hello'
}
isNot(child2[Symbol.for('pino.serializers')], parentSerializers)
is(child2[Symbol.for('pino.serializers')].a, a)
is(child2[Symbol.for('pino.serializers')].test, parentSerializers.test)
})
test('children inherit parent serializers', async ({ is }) => {
const stream = sink()
const parent = pino({ serializers: parentSerializers }, stream)
const child = parent.child({ a: 'property' })
child.fatal({ test: 'test' })
const o = await once(stream, 'data')
is(o.test, 'parent')
})
test('children inherit parent Symbol serializers', async ({ is, isNot }) => {
const stream = sink()
const symbolSerializers = {
[Symbol.for('pino.*')]: parentSerializers.test
}
const parent = pino({ serializers: symbolSerializers }, stream)
is(parent[Symbol.for('pino.serializers')], symbolSerializers)
const child = parent.child({
serializers: {
[Symbol.for('a')]: a,
a
}
})
function a () {
return 'hello'
}
isNot(child[Symbol.for('pino.serializers')], symbolSerializers)
is(child[Symbol.for('pino.serializers')].a, a)
is(child[Symbol.for('pino.serializers')][Symbol.for('a')], a)
is(child[Symbol.for('pino.serializers')][Symbol.for('pino.*')], parentSerializers.test)
})
test('children serializers get called', async ({ is }) => {
const stream = sink()
const parent = pino({
test: 'this'
}, stream)
const child = parent.child({ a: 'property', serializers: childSerializers })
child.fatal({ test: 'test' })
const o = await once(stream, 'data')
is(o.test, 'child')
})
test('children serializers get called when inherited from parent', async ({ is }) => {
const stream = sink()
const parent = pino({
test: 'this',
serializers: parentSerializers
}, stream)
const child = parent.child({ serializers: { test: function () { return 'pass' } } })
child.fatal({ test: 'fail' })
const o = await once(stream, 'data')
is(o.test, 'pass')
})
test('non-overridden serializers are available in the children', async ({ is }) => {
const stream = sink()
const pSerializers = {
onlyParent: function () { return 'parent' },
shared: function () { return 'parent' }
}
const cSerializers = {
shared: function () { return 'child' },
onlyChild: function () { return 'child' }
}
const parent = pino({ serializers: pSerializers }, stream)
const child = parent.child({ serializers: cSerializers })
const o = once(stream, 'data')
child.fatal({ shared: 'test' })
is((await o).shared, 'child')
const o2 = once(stream, 'data')
child.fatal({ onlyParent: 'test' })
is((await o2).onlyParent, 'parent')
const o3 = once(stream, 'data')
child.fatal({ onlyChild: 'test' })
is((await o3).onlyChild, 'child')
const o4 = once(stream, 'data')
parent.fatal({ onlyChild: 'test' })
is((await o4).onlyChild, 'test')
})
test('Symbol.for(\'pino.*\') serializer', async ({ notSame, is, isNot }) => {
const stream = sink()
const globalSerializer = {
[Symbol.for('pino.*')]: function (obj) {
if (obj.lionel === 'richie') {
return { hello: 'is', it: 'me', you: 'are', looking: 'for' }
}
return { lionel: 'richie' }
}
}
const logger = pino({ serializers: globalSerializer }, stream)
const o = once(stream, 'data')
logger.info({ hello: 'is', it: 'me', you: 'are', looking: 'for' })
is((await o).lionel, 'richie')
isNot((await o).hello, 'is')
isNot((await o).it, 'me')
isNot((await o).you, 'are')
isNot((await o).looking, 'for')
const o2 = once(stream, 'data')
logger.info({ lionel: 'richie' })
is((await o2).lionel, 'richie')
is((await o2).hello, 'is')
is((await o2).it, 'me')
is((await o2).you, 'are')
is((await o2).looking, 'for')
const o3 = once(stream, 'data')
logger.info('message')
is((await o3).lionel, 'richie')
is('pid' in (await o3), false)
is('hostname' in (await o3), false)
notSame(await o3, ['pid', 'hostname'])
})

19
node_modules/pino/test/stdout-protection.test.js generated vendored Normal file
View file

@ -0,0 +1,19 @@
'use strict'
const { test } = require('tap')
const { join } = require('path')
const { fork } = require('child_process')
const { once } = require('./helper')
const writer = require('flush-write-stream')
test('do not use SonicBoom is someone tampered with process.stdout.write', async ({ isNot }) => {
var actual = ''
const child = fork(join(__dirname, 'fixtures', 'stdout-hack-protection.js'), { silent: true })
child.stdout.pipe(writer((s, enc, cb) => {
actual += s
cb()
}))
await once(child, 'close')
isNot(actual.match(/^hack/), null)
})

121
node_modules/pino/test/timestamp.test.js generated vendored Normal file
View file

@ -0,0 +1,121 @@
'use strict'
/* eslint no-prototype-builtins: 0 */
const { test } = require('tap')
const { sink, once } = require('./helper')
const pino = require('../')
test('pino exposes standard time functions', async ({ ok }) => {
ok(pino.stdTimeFunctions)
ok(pino.stdTimeFunctions.epochTime)
ok(pino.stdTimeFunctions.unixTime)
ok(pino.stdTimeFunctions.nullTime)
ok(pino.stdTimeFunctions.isoTime)
})
test('pino accepts external time functions', async ({ is }) => {
const opts = {
timestamp: () => ',"time":"none"'
}
const stream = sink()
const instance = pino(opts, stream)
instance.info('foobar')
const result = await once(stream, 'data')
is(result.hasOwnProperty('time'), true)
is(result.time, 'none')
})
test('pino accepts external time functions with custom label', async ({ is }) => {
const opts = {
timestamp: () => ',"custom-time-label":"none"'
}
const stream = sink()
const instance = pino(opts, stream)
instance.info('foobar')
const result = await once(stream, 'data')
is(result.hasOwnProperty('custom-time-label'), true)
is(result['custom-time-label'], 'none')
})
test('inserts timestamp by default', async ({ ok, is }) => {
const stream = sink()
const instance = pino(stream)
instance.info('foobar')
const result = await once(stream, 'data')
is(result.hasOwnProperty('time'), true)
ok(new Date(result.time) <= new Date(), 'time is greater than timestamp')
is(result.msg, 'foobar')
})
test('omits timestamp when timestamp option is false', async ({ is }) => {
const stream = sink()
const instance = pino({ timestamp: false }, stream)
instance.info('foobar')
const result = await once(stream, 'data')
is(result.hasOwnProperty('time'), false)
is(result.msg, 'foobar')
})
test('inserts timestamp when timestamp option is true', async ({ ok, is }) => {
const stream = sink()
const instance = pino({ timestamp: true }, stream)
instance.info('foobar')
const result = await once(stream, 'data')
is(result.hasOwnProperty('time'), true)
ok(new Date(result.time) <= new Date(), 'time is greater than timestamp')
is(result.msg, 'foobar')
})
test('child inserts timestamp by default', async ({ ok, is }) => {
const stream = sink()
const logger = pino(stream)
const instance = logger.child({ component: 'child' })
instance.info('foobar')
const result = await once(stream, 'data')
is(result.hasOwnProperty('time'), true)
ok(new Date(result.time) <= new Date(), 'time is greater than timestamp')
is(result.msg, 'foobar')
})
test('child omits timestamp with option', async ({ is }) => {
const stream = sink()
const logger = pino({ timestamp: false }, stream)
const instance = logger.child({ component: 'child' })
instance.info('foobar')
const result = await once(stream, 'data')
is(result.hasOwnProperty('time'), false)
is(result.msg, 'foobar')
})
test('pino.stdTimeFunctions.unixTime returns seconds based timestamps', async ({ is }) => {
const opts = {
timestamp: pino.stdTimeFunctions.unixTime
}
const stream = sink()
const instance = pino(opts, stream)
const now = Date.now
Date.now = () => 1531069919686
instance.info('foobar')
const result = await once(stream, 'data')
is(result.hasOwnProperty('time'), true)
is(result.time, 1531069920)
Date.now = now
})
test('pino.stdTimeFunctions.isoTime returns ISO 8601 timestamps', async ({ is }) => {
const opts = {
timestamp: pino.stdTimeFunctions.isoTime
}
const stream = sink()
const instance = pino(opts, stream)
const ms = 1531069919686
const now = Date.now
Date.now = () => ms
const iso = new Date(ms).toISOString()
instance.info('foobar')
const result = await once(stream, 'data')
is(result.hasOwnProperty('time'), true)
is(result.time, iso)
Date.now = now
})