implement MockLoggerService.ts testing utility
This commit is contained in:
parent
5a28c4e110
commit
c45d6ea452
2 changed files with 87 additions and 3 deletions
|
|
@ -23,13 +23,16 @@ export type DataElement = DataObject | Error | string | null;
|
||||||
// https://stackoverflow.com/questions/61148466/typescript-type-that-matches-any-object-but-not-arrays
|
// https://stackoverflow.com/questions/61148466/typescript-type-that-matches-any-object-but-not-arrays
|
||||||
export type DataObject = Record<string, unknown> | (object & { length?: never; });
|
export type DataObject = Record<string, unknown> | (object & { length?: never; });
|
||||||
|
|
||||||
|
export type Console = Pick<typeof global.console, 'error' | 'warn' | 'info' | 'log' | 'debug'>;
|
||||||
|
export const nativeConsole: Console = global.console;
|
||||||
|
|
||||||
const levelFuncs = {
|
const levelFuncs = {
|
||||||
error: 'error',
|
error: 'error',
|
||||||
warning: 'warn',
|
warning: 'warn',
|
||||||
success: 'info',
|
success: 'info',
|
||||||
info: 'log',
|
info: 'log',
|
||||||
debug: 'debug',
|
debug: 'debug',
|
||||||
} as const satisfies Record<Level, keyof typeof console>;
|
} as const satisfies Record<Level, keyof Console>;
|
||||||
|
|
||||||
// eslint-disable-next-line import/no-default-export
|
// eslint-disable-next-line import/no-default-export
|
||||||
export default class Logger {
|
export default class Logger {
|
||||||
|
|
@ -37,12 +40,19 @@ export default class Logger {
|
||||||
private parentLogger: Logger | null = null;
|
private parentLogger: Logger | null = null;
|
||||||
public readonly verbose: boolean;
|
public readonly verbose: boolean;
|
||||||
|
|
||||||
constructor(context: string, color?: KEYWORD, verbose?: boolean) {
|
/**
|
||||||
|
* Where to send the actual log strings.
|
||||||
|
* Defaults to the native global.console instance.
|
||||||
|
*/
|
||||||
|
private readonly console: Console;
|
||||||
|
|
||||||
|
constructor(context: string, color?: KEYWORD, verbose?: boolean, console?: Console) {
|
||||||
this.context = {
|
this.context = {
|
||||||
name: context,
|
name: context,
|
||||||
color: color,
|
color: color,
|
||||||
};
|
};
|
||||||
this.verbose = verbose ?? envOption.verbose;
|
this.verbose = verbose ?? envOption.verbose;
|
||||||
|
this.console = console ?? nativeConsole;
|
||||||
}
|
}
|
||||||
|
|
||||||
@bindThis
|
@bindThis
|
||||||
|
|
@ -94,7 +104,7 @@ export default class Logger {
|
||||||
} else if (data != null) {
|
} else if (data != null) {
|
||||||
args.push(data);
|
args.push(data);
|
||||||
}
|
}
|
||||||
console[levelFuncs[level]](...args);
|
this.console[levelFuncs[level]](...args);
|
||||||
}
|
}
|
||||||
|
|
||||||
@bindThis
|
@bindThis
|
||||||
|
|
|
||||||
74
packages/backend/test/misc/MockLoggerService.ts
Normal file
74
packages/backend/test/misc/MockLoggerService.ts
Normal file
|
|
@ -0,0 +1,74 @@
|
||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: hazelnoot and other Sharkey contributors
|
||||||
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { jest } from '@jest/globals';
|
||||||
|
import { Injectable } from '@nestjs/common';
|
||||||
|
import type { KEYWORD } from 'color-convert/conversions.js';
|
||||||
|
import type { Config } from '@/config.js';
|
||||||
|
import Logger, { type Console } from '@/logger.js';
|
||||||
|
import { LoggerService } from '@/core/LoggerService.js';
|
||||||
|
import { bindThis } from '@/decorators.js';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mocked implementation of LoggerService.
|
||||||
|
* Suppresses all log output to prevent console spam, and records calls for assertions.
|
||||||
|
*/
|
||||||
|
@Injectable()
|
||||||
|
export class MockLoggerService extends LoggerService {
|
||||||
|
/**
|
||||||
|
* Mocked Console implementation.
|
||||||
|
* All logs from all logger instances will be sent here.
|
||||||
|
*/
|
||||||
|
public readonly console: jest.Mocked<Console> = {
|
||||||
|
error: jest.fn(),
|
||||||
|
warn: jest.fn(),
|
||||||
|
info: jest.fn(),
|
||||||
|
log: jest.fn(),
|
||||||
|
debug: jest.fn(),
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Controls the verbose flag for logger instances.
|
||||||
|
* Defaults to false (not verbose).
|
||||||
|
*/
|
||||||
|
public verbose: boolean;
|
||||||
|
|
||||||
|
constructor(config?: Config) {
|
||||||
|
config ??= { logging: { verbose: false } } as Config;
|
||||||
|
super(config);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resets the instance to initial state.
|
||||||
|
* Mocks are reset, and verbose flag is cleared.
|
||||||
|
*/
|
||||||
|
@bindThis
|
||||||
|
public reset() {
|
||||||
|
this.console.error.mockReset();
|
||||||
|
this.console.warn.mockReset();
|
||||||
|
this.console.info.mockReset();
|
||||||
|
this.console.log.mockReset();
|
||||||
|
this.console.debug.mockReset();
|
||||||
|
|
||||||
|
this.verbose = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Asserts that no errors and/or warnings have been logged.
|
||||||
|
*/
|
||||||
|
@bindThis
|
||||||
|
public assertNoErrors(opts?: { orWarnings?: boolean }): void {
|
||||||
|
expect(this.console.error).not.toHaveBeenCalled();
|
||||||
|
|
||||||
|
if (opts?.orWarnings) {
|
||||||
|
expect(this.console.warn).not.toHaveBeenCalled();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@bindThis
|
||||||
|
getLogger(domain: string, color?: KEYWORD | undefined): Logger {
|
||||||
|
return new Logger(domain, color, this.verbose, this.console);
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue