@brainbits/node-logger
Version:
Logger for node projects
216 lines (212 loc) • 7.61 kB
JavaScript
;
var _fs = _interopRequireDefault(require("fs"));
var _config = _interopRequireDefault(require("./config"));
var _nodeNodeLoggerFormatterTest = _interopRequireDefault(require("/some/root/testpackage/node_modules/@brainbits/node-node-logger-formatter-test"));
var _nodeNodeLoggerSentryPlugin = _interopRequireDefault(require("/some/root/testpackage/node_modules/@brainbits/node-node-logger-sentry-plugin"));
var _package = _interopRequireDefault(require("/some/root/testpackage/package.json"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/* eslint-disable import/no-absolute-path, import/no-unresolved */
// eslint-disable-next-line import/extensions
// eslint-disable-next-line import/extensions
jest.mock('fs');
jest.mock('/some/root/testpackage/node_modules/@brainbits/node-node-logger-formatter-test', () => ({
default: jest.fn()
}), {
virtual: true
});
jest.mock('/some/root/testpackage/node_modules/@brainbits/node-node-logger-sentry-plugin', () => ({
default: jest.fn()
}), {
virtual: true
});
jest.mock('/some/root/testpackage/package.json', () => ({
name: 'testpackage',
nodeLogger: {
channel: 'test-channel',
levels: ['error', 'info', 'debug'],
outputs: {
error: 'stdout'
},
formatter: '@brainbits/node-node-logger-formatter-test'
}
}), {
virtual: true
});
describe('loadConfiguration', () => {
beforeEach(() => {
_fs.default.existsSync.mockReturnValue(false);
jest.spyOn(process, 'cwd').mockReturnValue('/some/root/testpackage');
});
describe('validation', () => {
it('throws an error if formatter is missing', () => {
const expectedError = new Error('Invalid formatter: No formatter found in configuration');
expect(() => (0, _config.default)()).toThrow(expectedError);
});
it('throws an error if levels are null', () => {
const expectedError = new Error('Invalid levels: No levels were configured');
expect(() => (0, _config.default)({
formatter: jest.fn(),
levels: null
})).toThrow(expectedError);
});
it('throws an error if levels are an empty array', () => {
const expectedError = new Error('Invalid levels: No levels were configured');
expect(() => (0, _config.default)({
formatter: jest.fn(),
levels: []
})).toThrow(expectedError);
});
it('throws an error if no maxLevel is configured', () => {
const expectedError = new Error('Invalid maxLevel: null');
expect(() => (0, _config.default)({
formatter: jest.fn(),
maxLevel: null
})).toThrow(expectedError);
});
it('throws an error if maxLevel is no valid level', () => {
const expectedError = new Error('Invalid maxLevel: foobar');
expect(() => (0, _config.default)({
formatter: jest.fn(),
maxLevel: 'foobar'
})).toThrow(expectedError);
});
it('throws an error if no timerLevel is configured', () => {
const expectedError = new Error('Invalid timerLevel: null');
expect(() => (0, _config.default)({
formatter: jest.fn(),
timerLevel: null
})).toThrow(expectedError);
});
it('throws an error if timerLevel is no valid level', () => {
const expectedError = new Error('Invalid timerLevel: foobar');
expect(() => (0, _config.default)({
formatter: jest.fn(),
timerLevel: 'foobar'
})).toThrow(expectedError);
});
it('throws an error if no outputs were configured', () => {
const expectedError = new Error('Invalid outputs: Outputs can only be configured for existing log levels');
expect(() => (0, _config.default)({
formatter: jest.fn(),
outputs: null
})).toThrow(expectedError);
});
it('throws an error if output was configured for invalid level', () => {
const expectedError = new Error('Invalid outputs: Outputs can only be configured for existing log levels');
expect(() => (0, _config.default)({
formatter: jest.fn(),
outputs: {
foobar: 'stdout'
}
})).toThrow(expectedError);
});
it('throws an error if output is anything but stdout or stderr', () => {
const expectedError = new Error('Invalid outputs: Output must be stdout or stderr');
expect(() => (0, _config.default)({
formatter: jest.fn(),
outputs: {
error: 'stdin'
}
})).toThrow(expectedError);
});
});
it('resolves to default configuration', () => {
const config = (0, _config.default)({
formatter: jest.fn()
});
expect(config).toMatchObject({
channel: 'unknown',
levels: ['emergency', 'alert', 'critical', 'error', 'warning', 'notice', 'info', 'debug'],
maxLevel: 'info',
outputs: {
emergency: 'stderr',
warning: 'stdout'
},
timerLevel: 'debug',
plugins: []
});
});
describe('with package.json', () => {
beforeEach(() => {
_fs.default.existsSync.mockReturnValue(true);
_fs.default.statSync.mockReturnValue({
isFile: jest.fn().mockReturnValue(true)
});
});
it('merges configuration with defaults', () => {
const config = (0, _config.default)();
expect(config).toMatchObject({
channel: _package.default.nodeLogger.channel,
levels: _package.default.nodeLogger.levels,
maxLevel: 'info',
outputs: {
error: 'stdout'
},
timerLevel: 'debug',
plugins: [],
formatter: _nodeNodeLoggerFormatterTest.default.default
});
});
it('uses package name as channel if none was set explicitly', () => {
delete _package.default.nodeLogger.channel;
const config = (0, _config.default)();
expect(config).toMatchObject({
channel: _package.default.name
});
});
it('prioritizes manual configuration over package.json', () => {
const config = (0, _config.default)({
channel: 'foobar'
});
expect(config).toMatchObject({
channel: 'foobar'
});
});
});
describe('with plugins', () => {
beforeEach(() => {
_fs.default.existsSync.mockReturnValue(true);
});
it('instantiates plugins', () => {
const config = (0, _config.default)({
formatter: jest.fn(),
plugins: ['@brainbits/node-node-logger-sentry-plugin']
});
expect(config.plugins).toHaveLength(1);
expect(config.plugins[0]).toBeInstanceOf(_nodeNodeLoggerSentryPlugin.default.default);
});
});
describe('environment variables', () => {
it('are parsed correctly', () => {
process.env.MY_TEST = 'foobar';
const config = (0, _config.default)({
formatter: jest.fn(),
channel: 'env(MY_TEST)'
});
delete process.env.MY_TEST;
expect(config.channel).toEqual('foobar');
});
it('use default value if given', () => {
const config = (0, _config.default)({
formatter: jest.fn(),
channel: 'env(MY_TEST, baz)'
});
expect(config.channel).toEqual('baz');
});
it('throws error on missing variable', () => {
delete process.env.MY_TEST;
expect(() => (0, _config.default)({
formatter: jest.fn(),
channel: 'env(MY_TEST)'
})).toThrow(/MY_TEST/);
});
it('allow empty strings as valid values', () => {
process.env.MY_TEST = '';
const config = (0, _config.default)({
formatter: jest.fn(),
channel: 'env(MY_TEST)'
});
expect(config.channel).toEqual('');
});
});
});