Compare commits

...

3 Commits

Author SHA1 Message Date
Michael B. Gale f56d0ec51b Add hasMessage to RecordingLogger 2026-02-24 20:45:41 +00:00
Michael B. Gale 33edb83959 Replace getRecordingLogger implementation with RecordingLogger 2026-02-24 20:40:41 +00:00
Michael B. Gale 33276bfbdb Add assertNotLogged test helper 2026-02-24 20:36:24 +00:00
+59 -42
View File
@@ -157,8 +157,8 @@ export interface LoggedMessage {
export class RecordingLogger implements Logger { export class RecordingLogger implements Logger {
messages: LoggedMessage[] = []; messages: LoggedMessage[] = [];
groups: string[] = []; readonly groups: string[] = [];
unfinishedGroups: Set<string> = new Set(); readonly unfinishedGroups: Set<string> = new Set();
private currentGroup: string | undefined = undefined; private currentGroup: string | undefined = undefined;
constructor(private readonly logToConsole: boolean = true) {} constructor(private readonly logToConsole: boolean = true) {}
@@ -172,6 +172,19 @@ export class RecordingLogger implements Logger {
} }
} }
/**
* Checks whether the logged messages contain `messageOrRegExp`.
*
* If `messageOrRegExp` is a string, this function returns true as long as
* `messageOrRegExp` appears as part of one of the `messages`.
*
* If `messageOrRegExp` is a regular expression, this function returns true as long as
* one of the `messages` matches `messageOrRegExp`.
*/
hasMessage(messageOrRegExp: string | RegExp): boolean {
return hasLoggedMessage(this.messages, messageOrRegExp);
}
isDebug() { isDebug() {
return true; return true;
} }
@@ -210,41 +223,37 @@ export function getRecordingLogger(
messages: LoggedMessage[], messages: LoggedMessage[],
{ logToConsole }: { logToConsole?: boolean } = { logToConsole: true }, { logToConsole }: { logToConsole?: boolean } = { logToConsole: true },
): Logger { ): Logger {
return { const logger = new RecordingLogger(logToConsole);
debug: (message: string) => { logger.messages = messages;
messages.push({ type: "debug", message }); return logger;
if (logToConsole) {
// eslint-disable-next-line no-console
console.debug(message);
}
},
info: (message: string) => {
messages.push({ type: "info", message });
if (logToConsole) {
// eslint-disable-next-line no-console
console.info(message);
}
},
warning: (message: string | Error) => {
messages.push({ type: "warning", message });
if (logToConsole) {
// eslint-disable-next-line no-console
console.warn(message);
}
},
error: (message: string | Error) => {
messages.push({ type: "error", message });
if (logToConsole) {
// eslint-disable-next-line no-console
console.error(message);
}
},
isDebug: () => true,
startGroup: () => undefined,
endGroup: () => undefined,
};
} }
/**
* Checks whether `messages` contains `messageOrRegExp`.
*
* If `messageOrRegExp` is a string, this function returns true as long as
* `messageOrRegExp` appears as part of one of the `messages`.
*
* If `messageOrRegExp` is a regular expression, this function returns true as long as
* one of the `messages` matches `messageOrRegExp`.
*/
function hasLoggedMessage(
messages: LoggedMessage[],
messageOrRegExp: string | RegExp,
): boolean {
const check = (val: string) =>
typeof messageOrRegExp === "string"
? val.includes(messageOrRegExp)
: messageOrRegExp.test(val);
return messages.some(
(msg) => typeof msg.message === "string" && check(msg.message),
);
}
/**
* Checks that `messages` contains all of `expectedMessages`.
*/
export function checkExpectedLogMessages( export function checkExpectedLogMessages(
t: ExecutionContext<any>, t: ExecutionContext<any>,
messages: LoggedMessage[], messages: LoggedMessage[],
@@ -253,13 +262,7 @@ export function checkExpectedLogMessages(
const missingMessages: string[] = []; const missingMessages: string[] = [];
for (const expectedMessage of expectedMessages) { for (const expectedMessage of expectedMessages) {
if ( if (!hasLoggedMessage(messages, expectedMessage)) {
!messages.some(
(msg) =>
typeof msg.message === "string" &&
msg.message.includes(expectedMessage),
)
) {
missingMessages.push(expectedMessage); missingMessages.push(expectedMessage);
} }
} }
@@ -276,6 +279,20 @@ export function checkExpectedLogMessages(
} }
} }
/**
* Asserts that `message` should not have been logged to `logger`.
*/
export function assertNotLogged(
t: ExecutionContext<any>,
logger: RecordingLogger,
message: string | RegExp,
) {
t.false(
logger.hasMessage(message),
`'${message}' should not have been logged, but was.`,
);
}
/** /**
* Initialises a recording logger and calls `body` with it. * Initialises a recording logger and calls `body` with it.
* *