Skip to content

Commit 7e6fa8a

Browse files
test: add logger factory coverage
1 parent aaabcc2 commit 7e6fa8a

1 file changed

Lines changed: 102 additions & 0 deletions

File tree

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
import { expect } from 'chai'
2+
import Sinon from 'sinon'
3+
4+
import { createLogger } from '../../../src/factories/logger-factory'
5+
import { logger as baseLogger } from '../../../src/logger'
6+
7+
type StubPinoLogger = {
8+
level: string
9+
debug: Sinon.SinonStub
10+
info: Sinon.SinonStub
11+
warn: Sinon.SinonStub
12+
error: Sinon.SinonStub
13+
fatal: Sinon.SinonStub
14+
child: Sinon.SinonStub
15+
}
16+
17+
const createStubPinoLogger = (sandbox: Sinon.SinonSandbox): StubPinoLogger => ({
18+
level: 'info',
19+
debug: sandbox.stub(),
20+
info: sandbox.stub(),
21+
warn: sandbox.stub(),
22+
error: sandbox.stub(),
23+
fatal: sandbox.stub(),
24+
child: sandbox.stub(),
25+
})
26+
27+
describe('createLogger', () => {
28+
let sandbox: Sinon.SinonSandbox
29+
let rootInstance: StubPinoLogger
30+
let childInstance: StubPinoLogger
31+
32+
beforeEach(() => {
33+
sandbox = Sinon.createSandbox()
34+
35+
rootInstance = createStubPinoLogger(sandbox)
36+
childInstance = createStubPinoLogger(sandbox)
37+
38+
sandbox.stub(baseLogger, 'child').returns(rootInstance as any)
39+
rootInstance.child.callsFake(() => childInstance as any)
40+
childInstance.child.callsFake(() => childInstance as any)
41+
})
42+
43+
afterEach(() => {
44+
sandbox.restore()
45+
})
46+
47+
it('enables debug level when requested', () => {
48+
createLogger('payments', { enabled: true })
49+
50+
expect(rootInstance.level).to.equal('debug')
51+
})
52+
53+
it('logs formatted string messages', () => {
54+
const logger = createLogger('payments')
55+
56+
logger.info('invoice %s created', 'abc123')
57+
58+
Sinon.assert.calledOnceWithExactly(rootInstance.info, 'invoice abc123 created')
59+
})
60+
61+
it('logs Error instances under err key', () => {
62+
const logger = createLogger('payments')
63+
const error = new Error('boom')
64+
65+
logger.error(error)
66+
67+
Sinon.assert.calledOnceWithExactly(rootInstance.error, { err: error })
68+
})
69+
70+
it('logs mixed non-string messages safely', () => {
71+
const logger = createLogger('payments')
72+
73+
logger.warn({ id: 42 }, 'extra')
74+
75+
Sinon.assert.calledOnce(rootInstance.warn)
76+
expect(rootInstance.warn.firstCall.args[0]).to.contain('id: 42')
77+
})
78+
79+
it('forwards plain objects when no extra args are provided', () => {
80+
const logger = createLogger('payments')
81+
const payload = { status: 'ok' }
82+
83+
logger.fatal(payload)
84+
85+
Sinon.assert.calledOnceWithExactly(rootInstance.fatal, payload)
86+
})
87+
88+
it('supports child and extended loggers', () => {
89+
const logger = createLogger('payments')
90+
91+
const childLogger = logger.child({ requestId: 'req-1' })
92+
childLogger.info('child logger message')
93+
94+
const extendedLogger = logger.extend('settlements')
95+
extendedLogger.debug('extended logger message')
96+
97+
Sinon.assert.calledWith(rootInstance.child, { requestId: 'req-1' })
98+
Sinon.assert.calledWith(rootInstance.child, Sinon.match.has('scope', Sinon.match.string))
99+
Sinon.assert.calledWithExactly(childInstance.info, 'child logger message')
100+
Sinon.assert.calledWithExactly(childInstance.debug, 'extended logger message')
101+
})
102+
})

0 commit comments

Comments
 (0)