1 | 'use strict'
|
2 |
|
3 | const path = require('path')
|
4 | const spawn = require('child_process').spawn
|
5 | const test = require('tap').test
|
6 | const fs = require('fs')
|
7 | const rimraf = require('rimraf')
|
8 |
|
9 | const bin = require.resolve('../bin')
|
10 | const logLine = '{"level":30,"time":1522431328992,"msg":"hello world","pid":42,"hostname":"foo"}\n'
|
11 | const noop = () => {}
|
12 |
|
13 | test('cli', (t) => {
|
14 | const tmpDir = path.join(__dirname, '.tmp_' + Date.now())
|
15 | fs.mkdirSync(tmpDir)
|
16 |
|
17 | t.tearDown(() => rimraf(tmpDir, noop))
|
18 |
|
19 | t.test('loads and applies default config file: pino-pretty.config.js', (t) => {
|
20 | t.plan(1)
|
21 |
|
22 | const configFile = path.join(tmpDir, 'pino-pretty.config.js')
|
23 | fs.writeFileSync(configFile, 'module.exports = { translateTime: true }')
|
24 | const env = { TERM: 'dumb' }
|
25 | const child = spawn(process.argv[0], [bin], { env, cwd: tmpDir })
|
26 |
|
27 | child.on('error', t.threw)
|
28 | child.stdout.on('data', (data) => {
|
29 | t.is(data.toString(), '[2018-03-30 17:35:28.992 +0000] INFO (42 on foo): hello world\n')
|
30 | })
|
31 | child.stdin.write(logLine)
|
32 | t.tearDown(() => {
|
33 | fs.unlinkSync(configFile)
|
34 | child.kill()
|
35 | })
|
36 | })
|
37 |
|
38 | t.test('loads and applies default config file: .pino-prettyrc', (t) => {
|
39 | t.plan(1)
|
40 |
|
41 | const configFile = path.join(tmpDir, '.pino-prettyrc')
|
42 | fs.writeFileSync(configFile, JSON.stringify({ translateTime: true }, null, 4))
|
43 | const env = { TERM: 'dumb' }
|
44 | const child = spawn(process.argv[0], [bin], { env, cwd: tmpDir })
|
45 |
|
46 | child.on('error', t.threw)
|
47 | child.stdout.on('data', (data) => {
|
48 | t.is(data.toString(), '[2018-03-30 17:35:28.992 +0000] INFO (42 on foo): hello world\n')
|
49 | })
|
50 | child.stdin.write(logLine)
|
51 | t.tearDown(() => {
|
52 | fs.unlinkSync(configFile)
|
53 | child.kill()
|
54 | })
|
55 | })
|
56 |
|
57 | t.test('loads and applies default config file: .pino-prettyrc.json', (t) => {
|
58 | t.plan(1)
|
59 |
|
60 | const configFile = path.join(tmpDir, '.pino-prettyrc.json')
|
61 | fs.writeFileSync(configFile, JSON.stringify({ translateTime: true }, null, 4))
|
62 | const env = { TERM: 'dumb' }
|
63 | const child = spawn(process.argv[0], [bin], { env, cwd: tmpDir })
|
64 |
|
65 | child.on('error', t.threw)
|
66 | child.stdout.on('data', (data) => {
|
67 | t.is(data.toString(), '[2018-03-30 17:35:28.992 +0000] INFO (42 on foo): hello world\n')
|
68 | })
|
69 | child.stdin.write(logLine)
|
70 | t.tearDown(() => {
|
71 | fs.unlinkSync(configFile)
|
72 | child.kill()
|
73 | })
|
74 | })
|
75 |
|
76 | t.test('loads and applies custom config file: pino-pretty.config.test.json', (t) => {
|
77 | t.plan(1)
|
78 |
|
79 | const configFile = path.join(tmpDir, 'pino-pretty.config.test.json')
|
80 | fs.writeFileSync(configFile, JSON.stringify({ translateTime: true }, null, 4))
|
81 | const env = { TERM: 'dumb' }
|
82 | const child = spawn(process.argv[0], [bin, '--config', configFile], { env, cwd: tmpDir })
|
83 |
|
84 | child.on('error', t.threw)
|
85 | child.stdout.on('data', (data) => {
|
86 | t.is(data.toString(), '[2018-03-30 17:35:28.992 +0000] INFO (42 on foo): hello world\n')
|
87 | })
|
88 | child.stdin.write(logLine)
|
89 | t.tearDown(() => child.kill())
|
90 | })
|
91 |
|
92 | t.test('loads and applies custom config file: pino-pretty.config.test.js', (t) => {
|
93 | t.plan(1)
|
94 |
|
95 | const configFile = path.join(tmpDir, 'pino-pretty.config.test.js')
|
96 | fs.writeFileSync(configFile, 'module.exports = { translateTime: true }')
|
97 | const env = { TERM: 'dumb' }
|
98 | const child = spawn(process.argv[0], [bin, '--config', configFile], { env, cwd: tmpDir })
|
99 |
|
100 | child.on('error', t.threw)
|
101 | child.stdout.on('data', (data) => {
|
102 | t.is(data.toString(), '[2018-03-30 17:35:28.992 +0000] INFO (42 on foo): hello world\n')
|
103 | })
|
104 | child.stdin.write(logLine)
|
105 | t.tearDown(() => child.kill())
|
106 | })
|
107 |
|
108 | t.test('cli options override config options', (t) => {
|
109 | t.plan(1)
|
110 |
|
111 | const configFile = path.join(tmpDir, 'pino-pretty.config.js')
|
112 | fs.writeFileSync(configFile, `
|
113 | module.exports = {
|
114 | translateTime: true,
|
115 | messageKey: 'custom_msg'
|
116 | }
|
117 | `.trim())
|
118 |
|
119 | const env = { TERM: 'dumb' }
|
120 | const child = spawn(process.argv[0], [bin, '--messageKey', 'new_msg'], { env, cwd: tmpDir })
|
121 |
|
122 | child.on('error', t.threw)
|
123 | child.stdout.on('data', (data) => {
|
124 | t.is(data.toString(), '[2018-03-30 17:35:28.992 +0000] INFO (42 on foo): hello world\n')
|
125 | })
|
126 | child.stdin.write(logLine.replace(/"msg"/, '"new_msg"'))
|
127 | t.tearDown(() => {
|
128 | fs.unlinkSync(configFile)
|
129 | child.kill()
|
130 | })
|
131 | })
|
132 |
|
133 | t.test('cli options with defaults can be overridden by config', (t) => {
|
134 | t.plan(1)
|
135 |
|
136 | const configFile = path.join(tmpDir, 'pino-pretty.config.js')
|
137 | fs.writeFileSync(configFile, `
|
138 | module.exports = {
|
139 | errorProps: '*'
|
140 | }
|
141 | `.trim())
|
142 |
|
143 | const env = { TERM: 'dumb' }
|
144 | const child = spawn(process.argv[0], [bin], { env, cwd: tmpDir })
|
145 |
|
146 | child.on('error', t.threw)
|
147 | child.stdout.on('data', (data) => {
|
148 | t.is(data.toString(), '[1594416696006] FATAL: There was an error starting the process.\n QueryError: Error during sql query: syntax error at or near SELECTT\n at /home/me/projects/example/sql.js\n at /home/me/projects/example/index.js\nquerySql: SELECTT * FROM "test" WHERE id = $1;\nqueryArgs: 12\n')
|
149 | })
|
150 | child.stdin.write('{"level":60,"time":1594416696006,"msg":"There was an error starting the process.","type":"Error","stack":"QueryError: Error during sql query: syntax error at or near SELECTT\\n at /home/me/projects/example/sql.js\\n at /home/me/projects/example/index.js","querySql":"SELECTT * FROM \\"test\\" WHERE id = $1;","queryArgs":[12]}\n')
|
151 | t.tearDown(() => {
|
152 | fs.unlinkSync(configFile)
|
153 | child.kill()
|
154 | })
|
155 | })
|
156 |
|
157 | t.test('throws on missing config file', (t) => {
|
158 | t.plan(2)
|
159 | const args = [bin, '--config', 'pino-pretty.config.missing.json']
|
160 | const env = { TERM: 'dumb' }
|
161 | const child = spawn(process.argv[0], args, { env, cwd: tmpDir })
|
162 | child.on('close', (code) => t.is(code, 1))
|
163 | child.stderr.on('data', (data) => {
|
164 | t.contains(data.toString(), 'Error: Failed to load runtime configuration file: pino-pretty.config.missing.json\n')
|
165 | })
|
166 | t.tearDown(() => child.kill())
|
167 | })
|
168 |
|
169 | t.test('throws on invalid default config file', (t) => {
|
170 | t.plan(2)
|
171 | const configFile = path.join(tmpDir, 'pino-pretty.config.js')
|
172 | fs.writeFileSync(configFile, 'module.exports = () => {}')
|
173 | const env = { TERM: 'dumb' }
|
174 | const child = spawn(process.argv[0], [bin], { env, cwd: tmpDir })
|
175 | child.on('close', (code) => t.is(code, 1))
|
176 | child.stderr.on('data', (data) => {
|
177 | t.contains(data.toString(), 'Error: Invalid runtime configuration file: pino-pretty.config.js\n')
|
178 | })
|
179 | t.tearDown(() => child.kill())
|
180 | })
|
181 |
|
182 | t.test('throws on invalid custom config file', (t) => {
|
183 | t.plan(2)
|
184 | const configFile = path.join(tmpDir, 'pino-pretty.config.invalid.js')
|
185 | fs.writeFileSync(configFile, 'module.exports = () => {}')
|
186 | const args = [bin, '--config', path.relative(tmpDir, configFile)]
|
187 | const env = { TERM: 'dumb' }
|
188 | const child = spawn(process.argv[0], args, { env, cwd: tmpDir })
|
189 | child.on('close', (code) => t.is(code, 1))
|
190 | child.stderr.on('data', (data) => {
|
191 | t.contains(data.toString(), 'Error: Invalid runtime configuration file: pino-pretty.config.invalid.js\n')
|
192 | })
|
193 | t.tearDown(() => child.kill())
|
194 | })
|
195 |
|
196 | t.end()
|
197 | })
|