From 7d37ed0a020f302bc6993af944cfc0d5acfd8ce8 Mon Sep 17 00:00:00 2001 From: Ardis Lu Date: Fri, 17 Jul 2026 22:04:06 -0700 Subject: [PATCH] Add test for alternate logger --- test/index.test.js | 18 +++++++++++++- test/setup.js | 60 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 77 insertions(+), 1 deletion(-) diff --git a/test/index.test.js b/test/index.test.js index 861bb65..40459de 100644 --- a/test/index.test.js +++ b/test/index.test.js @@ -3,7 +3,7 @@ import { deepStrictEqual } from 'node:assert'; import { encrypt, decrypt } from '#src/index.js'; import { BROWSER } from '#src/getPrf.js'; -import { setupPlaywright, setupEnv, mockOpen, assertConsole, fileEqual, fileNotEqual } from '#test/setup.js'; +import { setupPlaywright, setupEnv, mockOpen, assertConsole, MockLogger, fileEqual, fileNotEqual } from '#test/setup.js'; /** Standard value of the .env file used for most setups. */ const STD_ENV = 'A=123\nB=456\nC=789\n'; @@ -35,6 +35,22 @@ suite('e2e', () => { await decrypt({ inFile: envFile, logger: console, notEncryptedValue: 'log' }); await fileEqual(envFile, STD_ENV); }); + test('alternate logger works', async (t) => { + const { page } = await setupPlaywright(t); + const envFile = await setupEnv(t, STD_ENV); + mockOpen(t, page); + assertConsole(t, { debug: 0, info: 0, warn: 0, error: 0 }); + const logger = new MockLogger(); + + await fileEqual(envFile, STD_ENV); + await encrypt({ inFile: envFile, logger }); + await encrypt({ inFile: envFile, logger, alreadyEncryptedValue: 'log' }); + await fileNotEqual(envFile, STD_ENV); + await decrypt({ inFile: envFile, logger }); + await decrypt({ inFile: envFile, logger, notEncryptedValue: 'log' }); + await fileEqual(envFile, STD_ENV); + logger.assertCounts({ debug: 24, info: 6, warn: 0, error: 0 }); + }); test('does nothing to empty .env file', async (t) => { const { page } = await setupPlaywright(t); const envFile = await setupEnv(t, ''); diff --git a/test/setup.js b/test/setup.js index 700fd24..698b8df 100644 --- a/test/setup.js +++ b/test/setup.js @@ -151,6 +151,66 @@ export function assertConsole(t, expected = {}) { } } +/** @typedef {'debug'|'info'|'warn'|'error'} LoggerMethod A supported logger method. */ +/** @typedef {unknown[]} LoggerCall The arguments passed to a single logger method invocation. */ +/** + * @typedef Logs Captured logger calls, grouped by logger method. + * @property {LoggerCall[]} debug All calls made to `logger.debug()`. + * @property {LoggerCall[]} info All calls made to `logger.info()`. + * @property {LoggerCall[]} warn All calls made to `logger.warn()`. + * @property {LoggerCall[]} error All calls made to `logger.error()`. + */ + +/** + * A mock `Logger` that records a simple history of calls and provides helper methods to make assertions + * about these calls. + */ +export class MockLogger { + /** @type {Logs} */ + #logs = { debug: [], info: [], warn: [], error: [] }; + + /** + * Records a `debug()` call. + * @param {...unknown} args + */ + debug(...args) { this.#logs.debug.push(args); } + + /** + * Records a `info()` call. + * @param {...unknown} args + */ + info(...args) { this.#logs.info.push(args); } + + /** + * Records a `warn()` call. + * @param {...unknown} args + */ + warn(...args) { this.#logs.warn.push(args); } + + /** + * Records a `error()` call. + * @param {...unknown} args + */ + error(...args) { this.#logs.error.push(args); } + + /** Record of all the logs made to this logger. */ + get logs() { + return this.#logs; + } + + /** + * Asserts that each logger method was called the expected number of times. + * @param {AssertConsoleCounts} counts + */ + assertCounts(counts) { + for (const method of /** @type {const} */(['debug', 'info', 'warn', 'error'])) { + const actual = this.#logs[method].length; + const expected = counts[method] ?? 0; + deepStrictEqual(actual, expected, `expected ${expected} ${method} call(s), got ${actual}`); + } + } +} + /** * Assert a text file's contents are equal to expected contents. * @param {string} path Path to a text file. -- 2.47.3