@node-dlc/logger
Version:
142 lines (121 loc) • 4.44 kB
text/typescript
import { expect } from 'chai';
import sinon from 'sinon';
import { LogLevel } from '../../lib/log-level';
import { Logger } from '../../lib/logger';
import { ITransport } from '../../lib/transport';
describe('Logger', () => {
let transport: ITransport;
let sut: Logger;
beforeEach(() => {
transport = { write: sinon.stub() };
sut = new Logger();
sut.transports.push(transport);
});
it('should default log level of Info', () => {
expect(sut.level).to.equal(LogLevel.Info);
});
it('should ignore messages below setting', () => {
const logger = sut.sub('area');
expect((transport.write as sinon.SinonSpy).callCount).to.equal(0);
logger.debug('testing');
expect((transport.write as sinon.SinonSpy).callCount).to.equal(0);
});
describe('create logger with instance', () => {
it('should create logger with instance', () => {
const logger = sut.sub('area', 'instance');
expect(logger.area).to.equal('area');
expect(logger.instance).to.equal('instance');
});
it('should write a message to the transport', () => {
const logger = sut.sub('area', 'instance');
logger.info('testing');
expect((transport.write as sinon.SinonSpy).args[0][0]).to.match(
/\d\d\d\d-\d\d-\d\dT\d\d:\d\d:\d\d\.\d\d\dZ \[INF\] area instance: testing/,
);
});
});
describe('nested sub logger', () => {
it('should point to root', () => {
sut.level = LogLevel.Debug;
const level2 = sut.sub('level2'); // eslint-disable-line @typescript-eslint/no-unused-vars
const level3 = sut.sub('level3');
level3.debug('test');
expect((transport.write as sinon.SinonSpy).args[0][0]).contain('test');
});
});
describe('create logger without instance', () => {
it('should create logger without an instance', () => {
const logger = sut.sub('area');
expect(logger.area).to.equal('area');
expect(logger.instance).to.be.undefined;
});
it('should write a message to the transport', () => {
const logger = sut.sub('area');
logger.info('testing');
expect((transport.write as sinon.SinonSpy).args[0][0]).to.match(
/\d\d\d\d-\d\d-\d\dT\d\d:\d\d:\d\d\.\d\d\dZ \[INF\] area: testing/,
);
});
});
const fixtures = [
{ fn: 'trace', level: LogLevel.Trace },
{ fn: 'debug', level: LogLevel.Debug },
{ fn: 'info', level: LogLevel.Info },
{ fn: 'warn', level: LogLevel.Warn },
{ fn: 'error', level: LogLevel.Error },
];
for (const { fn, level } of fixtures) {
describe('.' + fn, () => {
beforeEach(() => {
sut = new Logger('area', 'instance');
sut.level = LogLevel.Trace;
sut.transports.push(transport);
});
it('should have message with level ' + level, () => {
sut[fn]('testing');
expect((transport.write as sinon.SinonSpy).args[0][0]).to.match(
new RegExp('[' + level + ']'),
);
});
it('should have message with area', () => {
sut[fn]('testing');
expect((transport.write as sinon.SinonSpy).args[0][0]).to.match(
/ area/,
);
});
it('should have message with instance', () => {
sut[fn]('testing');
expect((transport.write as sinon.SinonSpy).args[0][0]).to.match(
/ instance/,
);
});
it('should have message with actual message', () => {
sut[fn]('testing');
expect((transport.write as sinon.SinonSpy).args[0][0]).to.match(
/ testing$/,
);
});
it('should call write with single variable message', () => {
sut[fn](5);
expect((transport.write as sinon.SinonSpy).args[0][0]).to.match(/5$/);
});
it('should call write with sprintf message', () => {
sut[fn]('testing %s, %d, %j', 'hello', 5, { foo: 'bar' });
expect((transport.write as sinon.SinonSpy).args[0][0]).to.contain(
'testing hello, 5, {"foo":"bar"}',
);
});
it('should call write with variadic message', () => {
sut[fn]('testing', 1, 2, 3, 4, '5');
expect((transport.write as sinon.SinonSpy).args[0][0]).to.contain(
'testing 1 2 3 4 5',
);
});
it('should work unbounded', () => {
const debug = sut[fn];
debug('testing');
expect((transport.write as sinon.SinonSpy).called).to.be.true;
});
});
}
});