273 lines
9 KiB
JavaScript
273 lines
9 KiB
JavaScript
|
// Licensed to the Software Freedom Conservancy (SFC) under one
|
||
|
// or more contributor license agreements. See the NOTICE file
|
||
|
// distributed with this work for additional information
|
||
|
// regarding copyright ownership. The SFC licenses this file
|
||
|
// to you under the Apache License, Version 2.0 (the
|
||
|
// "License"); you may not use this file except in compliance
|
||
|
// with the License. You may obtain a copy of the License at
|
||
|
//
|
||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||
|
//
|
||
|
// Unless required by applicable law or agreed to in writing,
|
||
|
// software distributed under the License is distributed on an
|
||
|
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||
|
// KIND, either express or implied. See the License for the
|
||
|
// specific language governing permissions and limitations
|
||
|
// under the License.
|
||
|
|
||
|
'use strict';
|
||
|
|
||
|
const assert = require('assert');
|
||
|
const sinon = require('sinon');
|
||
|
const logging = require('../../lib/logging');
|
||
|
|
||
|
describe('logging', function() {
|
||
|
let mgr, root, clock;
|
||
|
|
||
|
beforeEach(function setUp() {
|
||
|
mgr = new logging.LogManager;
|
||
|
root = mgr.getLogger('');
|
||
|
|
||
|
clock = sinon.useFakeTimers();
|
||
|
});
|
||
|
|
||
|
afterEach(function tearDown() {
|
||
|
clock.restore();
|
||
|
});
|
||
|
|
||
|
describe('LogManager', function() {
|
||
|
describe('getLogger()', function() {
|
||
|
it('handles falsey input', function() {
|
||
|
assert.strictEqual(root, mgr.getLogger());
|
||
|
assert.strictEqual(root, mgr.getLogger(''));
|
||
|
assert.strictEqual(root, mgr.getLogger(null));
|
||
|
assert.strictEqual(root, mgr.getLogger(0));
|
||
|
});
|
||
|
|
||
|
it('creates parent loggers', function() {
|
||
|
let logger = mgr.getLogger('foo.bar.baz');
|
||
|
assert.strictEqual(logger.parent_, mgr.getLogger('foo.bar'));
|
||
|
|
||
|
logger = logger.parent_;
|
||
|
assert.strictEqual(logger.parent_, mgr.getLogger('foo'));
|
||
|
|
||
|
logger = logger.parent_;
|
||
|
assert.strictEqual(logger.parent_, mgr.getLogger(''));
|
||
|
|
||
|
assert.strictEqual(logger.parent_.parent_, null);
|
||
|
});
|
||
|
});
|
||
|
});
|
||
|
|
||
|
describe('Logger', function() {
|
||
|
describe('getEffectiveLevel()', function() {
|
||
|
it('defaults to OFF', function() {
|
||
|
assert.strictEqual(root.getLevel(), logging.Level.OFF);
|
||
|
assert.strictEqual(root.getEffectiveLevel(), logging.Level.OFF);
|
||
|
|
||
|
root.setLevel(null);
|
||
|
assert.strictEqual(root.getLevel(), null);
|
||
|
assert.strictEqual(root.getEffectiveLevel(), logging.Level.OFF);
|
||
|
});
|
||
|
|
||
|
it('uses own level if set', function() {
|
||
|
let logger = mgr.getLogger('foo.bar.baz');
|
||
|
assert.strictEqual(logger.getLevel(), null);
|
||
|
assert.strictEqual(logger.getEffectiveLevel(), logging.Level.OFF);
|
||
|
|
||
|
logger.setLevel(logging.Level.INFO);
|
||
|
assert.strictEqual(logger.getLevel(), logging.Level.INFO);
|
||
|
assert.strictEqual(logger.getEffectiveLevel(), logging.Level.INFO);
|
||
|
});
|
||
|
|
||
|
it('uses level from set on nearest parent', function() {
|
||
|
let ancestor = mgr.getLogger('foo');
|
||
|
ancestor.setLevel(logging.Level.SEVERE);
|
||
|
|
||
|
let logger = mgr.getLogger('foo.bar.baz');
|
||
|
assert.strictEqual(logger.getLevel(), null);
|
||
|
assert.strictEqual(logger.getEffectiveLevel(), logging.Level.SEVERE);
|
||
|
});
|
||
|
});
|
||
|
|
||
|
describe('isLoggable()', function() {
|
||
|
it('compares level against logger\'s effective level', function() {
|
||
|
const log1 = mgr.getLogger('foo');
|
||
|
log1.setLevel(logging.Level.WARNING);
|
||
|
|
||
|
const log2 = mgr.getLogger('foo.bar.baz');
|
||
|
|
||
|
assert(!log2.isLoggable(logging.Level.FINEST));
|
||
|
assert(!log2.isLoggable(logging.Level.INFO));
|
||
|
assert(log2.isLoggable(logging.Level.WARNING));
|
||
|
assert(log2.isLoggable(logging.Level.SEVERE));
|
||
|
|
||
|
log2.setLevel(logging.Level.INFO);
|
||
|
|
||
|
assert(!log2.isLoggable(logging.Level.FINEST));
|
||
|
assert(log2.isLoggable(logging.Level.INFO));
|
||
|
assert(log2.isLoggable(logging.Level.WARNING));
|
||
|
assert(log2.isLoggable(logging.Level.SEVERE));
|
||
|
|
||
|
log2.setLevel(logging.Level.ALL);
|
||
|
|
||
|
assert(log2.isLoggable(logging.Level.FINEST));
|
||
|
assert(log2.isLoggable(logging.Level.INFO));
|
||
|
assert(log2.isLoggable(logging.Level.WARNING));
|
||
|
assert(log2.isLoggable(logging.Level.SEVERE));
|
||
|
});
|
||
|
|
||
|
it('Level.OFF is never loggable', function() {
|
||
|
function test(level) {
|
||
|
root.setLevel(level);
|
||
|
assert(!root.isLoggable(logging.Level.OFF),
|
||
|
'OFF should not be loggable at ' + level);
|
||
|
}
|
||
|
|
||
|
test(logging.Level.ALL);
|
||
|
test(logging.Level.INFO);
|
||
|
test(logging.Level.OFF);
|
||
|
});
|
||
|
});
|
||
|
|
||
|
describe('log()', function() {
|
||
|
it('does not invoke loggable if message is not loggable', function() {
|
||
|
const log = mgr.getLogger('foo');
|
||
|
log.setLevel(logging.Level.OFF);
|
||
|
|
||
|
let callback = sinon.spy();
|
||
|
log.addHandler(callback);
|
||
|
root.addHandler(callback);
|
||
|
|
||
|
assert(!callback.called);
|
||
|
});
|
||
|
|
||
|
it('invokes handlers for each parent logger', function() {
|
||
|
const cb1 = sinon.spy();
|
||
|
const cb2 = sinon.spy();
|
||
|
const cb3 = sinon.spy();
|
||
|
const cb4 = sinon.spy();
|
||
|
|
||
|
const log1 = mgr.getLogger('foo');
|
||
|
const log2 = mgr.getLogger('foo.bar');
|
||
|
const log3 = mgr.getLogger('foo.bar.baz');
|
||
|
const log4 = mgr.getLogger('foo.bar.baz.quot');
|
||
|
|
||
|
log1.addHandler(cb1);
|
||
|
log1.setLevel(logging.Level.INFO);
|
||
|
|
||
|
log2.addHandler(cb2);
|
||
|
log2.setLevel(logging.Level.WARNING);
|
||
|
|
||
|
log3.addHandler(cb3);
|
||
|
log3.setLevel(logging.Level.FINER);
|
||
|
|
||
|
clock.tick(123456);
|
||
|
|
||
|
log4.finest('this is the finest message');
|
||
|
log4.finer('this is a finer message');
|
||
|
log4.info('this is an info message');
|
||
|
log4.warning('this is a warning message');
|
||
|
log4.severe('this is a severe message');
|
||
|
|
||
|
assert.equal(4, cb1.callCount);
|
||
|
assert.equal(4, cb2.callCount);
|
||
|
assert.equal(4, cb3.callCount);
|
||
|
|
||
|
const entry1 = new logging.Entry(
|
||
|
logging.Level.FINER,
|
||
|
'[foo.bar.baz.quot] this is a finer message',
|
||
|
123456);
|
||
|
const entry2 = new logging.Entry(
|
||
|
logging.Level.INFO,
|
||
|
'[foo.bar.baz.quot] this is an info message',
|
||
|
123456);
|
||
|
const entry3 = new logging.Entry(
|
||
|
logging.Level.WARNING,
|
||
|
'[foo.bar.baz.quot] this is a warning message',
|
||
|
123456);
|
||
|
const entry4 = new logging.Entry(
|
||
|
logging.Level.SEVERE,
|
||
|
'[foo.bar.baz.quot] this is a severe message',
|
||
|
123456);
|
||
|
|
||
|
check(cb1.getCall(0).args[0], entry1);
|
||
|
check(cb1.getCall(1).args[0], entry2);
|
||
|
check(cb1.getCall(2).args[0], entry3);
|
||
|
check(cb1.getCall(3).args[0], entry4);
|
||
|
|
||
|
check(cb2.getCall(0).args[0], entry1);
|
||
|
check(cb2.getCall(1).args[0], entry2);
|
||
|
check(cb2.getCall(2).args[0], entry3);
|
||
|
check(cb2.getCall(3).args[0], entry4);
|
||
|
|
||
|
check(cb3.getCall(0).args[0], entry1);
|
||
|
check(cb3.getCall(1).args[0], entry2);
|
||
|
check(cb3.getCall(2).args[0], entry3);
|
||
|
check(cb3.getCall(3).args[0], entry4);
|
||
|
|
||
|
function check(entry, expected) {
|
||
|
assert.equal(entry.level, expected.level, 'wrong level');
|
||
|
assert.equal(entry.message, expected.message, 'wrong message');
|
||
|
assert.equal(entry.timestamp, expected.timestamp, 'wrong time');
|
||
|
}
|
||
|
});
|
||
|
|
||
|
it('does not invoke removed handler', function() {
|
||
|
root.setLevel(logging.Level.INFO);
|
||
|
const cb = sinon.spy();
|
||
|
|
||
|
root.addHandler(cb);
|
||
|
root.info('hi');
|
||
|
assert.equal(1, cb.callCount);
|
||
|
|
||
|
assert(root.removeHandler(cb));
|
||
|
root.info('bye');
|
||
|
assert.equal(1, cb.callCount);
|
||
|
|
||
|
assert(!root.removeHandler(cb));
|
||
|
});
|
||
|
});
|
||
|
});
|
||
|
|
||
|
describe('getLevel()', function() {
|
||
|
it('converts named levels', function() {
|
||
|
assert.strictEqual(logging.Level.DEBUG, logging.getLevel('DEBUG'));
|
||
|
assert.strictEqual(logging.Level.ALL, logging.getLevel('FAKE'));
|
||
|
});
|
||
|
|
||
|
it('converts numeric levels', function() {
|
||
|
assert.strictEqual(
|
||
|
logging.Level.DEBUG,
|
||
|
logging.getLevel(logging.Level.DEBUG.value));
|
||
|
});
|
||
|
|
||
|
it('normalizes numeric levels', function() {
|
||
|
assert.strictEqual(
|
||
|
logging.Level.OFF,
|
||
|
logging.getLevel(logging.Level.OFF.value * 2));
|
||
|
|
||
|
let diff = logging.Level.SEVERE.value - logging.Level.WARNING.value;
|
||
|
assert.strictEqual(
|
||
|
logging.Level.WARNING,
|
||
|
logging.getLevel(logging.Level.WARNING.value + (diff * .5)));
|
||
|
|
||
|
assert.strictEqual(logging.Level.ALL, logging.getLevel(0));
|
||
|
assert.strictEqual(logging.Level.ALL, logging.getLevel(-1));
|
||
|
});
|
||
|
});
|
||
|
|
||
|
describe('Preferences', function() {
|
||
|
it('can be converted to JSON', function() {
|
||
|
let prefs = new logging.Preferences;
|
||
|
assert.equal('{}', JSON.stringify(prefs));
|
||
|
|
||
|
prefs.setLevel('foo', logging.Level.DEBUG);
|
||
|
assert.equal('{"foo":"DEBUG"}', JSON.stringify(prefs));
|
||
|
|
||
|
prefs.setLevel(logging.Type.BROWSER, logging.Level.FINE);
|
||
|
assert.equal('{"foo":"DEBUG","browser":"FINE"}', JSON.stringify(prefs));
|
||
|
});
|
||
|
});
|
||
|
});
|