test: add unit tests for handler, logger, manager, and config

Cover Handler property accessors, format delegation, emit contract,
and close lifecycle. Cover Logger level methods, isEnabledFor caching,
manager property assignment, handler management, debug invocation,
and makeRecord extra key collision. Cover Manager getLogger hierarchy
setup, placeholder fixup, disable level, and loggerClass validation.
Cover basicConfig option handling, force flag, mutual exclusion of
stream/filename/handlers, and formatter assignment.
This commit is contained in:
Tiara Rodney 2026-03-13 22:49:12 +01:00
parent 0b87f5516a
commit 3b6b116b00
No known key found for this signature in database
GPG key ID: 5CD8EC1D46106723
4 changed files with 494 additions and 0 deletions

128
tests/unit/manager.test.ts Normal file
View file

@ -0,0 +1,128 @@
import {expect, jest, test} from '@jest/globals';
import { Manager } from '../../src/manager';
import { Logger, RootLogger } from '../../src/logger';
import { WARNING, DEBUG, NOTSET } from '../../src/log-level';
function makeManager(): Manager {
return new Manager(new RootLogger(WARNING));
}
describe('Manager', () => {
describe('constructor', () => {
test('stores the root logger', () => {
const root = new RootLogger(WARNING);
const manager = new Manager(root);
expect(manager.root).toBe(root);
});
});
describe('getLogger', () => {
test('returns a Logger instance', () => {
const manager = makeManager();
const logger = manager.getLogger('app');
expect(logger).toBeInstanceOf(Logger);
expect(logger.scope).toBe('app');
});
test('returns the same logger for the same scope', () => {
const manager = makeManager();
const a = manager.getLogger('app');
const b = manager.getLogger('app');
expect(a).toBe(b);
});
test('returns different loggers for different scopes', () => {
const manager = makeManager();
const a = manager.getLogger('app');
const b = manager.getLogger('lib');
expect(a).not.toBe(b);
});
test('sets parent to root for top-level loggers', () => {
const manager = makeManager();
const logger = manager.getLogger('app');
expect(logger.parent).toBe(manager.root);
});
test('sets parent to existing parent logger', () => {
const manager = makeManager();
const parent = manager.getLogger('app');
const child = manager.getLogger('app.module');
expect(child.parent).toBe(parent);
});
test('establishes hierarchy for deeply nested loggers', () => {
const manager = makeManager();
const top = manager.getLogger('a');
const mid = manager.getLogger('a.b');
const leaf = manager.getLogger('a.b.c');
expect(leaf.parent).toBe(mid);
expect(mid.parent).toBe(top);
expect(top.parent).toBe(manager.root);
});
test('creates placeholders for intermediate loggers', () => {
const manager = makeManager();
const leaf = manager.getLogger('a.b.c');
expect(leaf.parent).toBe(manager.root);
const mid = manager.getLogger('a.b');
expect(leaf.parent).toBe(mid);
expect(mid.parent).toBe(manager.root);
});
test('fixes up children when intermediate logger is created', () => {
const manager = makeManager();
const leaf = manager.getLogger('a.b.c');
const top = manager.getLogger('a');
expect(top.parent).toBe(manager.root);
const mid = manager.getLogger('a.b');
expect(leaf.parent).toBe(mid);
});
});
describe('disable', () => {
test('defaults to 0', () => {
const manager = makeManager();
expect(manager.disable).toBe(0);
});
test('can be set to a level', () => {
const manager = makeManager();
manager.disable = WARNING;
expect(manager.disable).toBe(WARNING);
});
});
describe('loggerClass', () => {
test('accepts Logger subclass', () => {
const manager = makeManager();
class CustomLogger extends Logger {}
expect(() => { manager.loggerClass = CustomLogger as any }).not.toThrow();
});
test('rejects non-Logger class', () => {
const manager = makeManager();
class NotALogger {}
expect(() => {
manager.loggerClass = NotALogger as any;
}).toThrow(TypeError);
});
test('accepts Logger itself', () => {
const manager = makeManager();
expect(() => { manager.loggerClass = Logger as any }).not.toThrow();
});
});
describe('clear', () => {
test('clears logger caches', () => {
const manager = makeManager();
const logger = manager.getLogger('test');
logger.isEnabledFor(DEBUG);
manager.clear();
});
});
});