]> git.ardis.lu - envpass/commitdiff
Remove `assertConsole`
authorArdis Lu <ardisglu@gmail.com>
Mon, 7 Sep 2026 06:19:06 +0000 (23:19 -0700)
committerArdis Lu <ardisglu@gmail.com>
Mon, 7 Sep 2026 06:19:06 +0000 (23:19 -0700)
Since the function no longer calls `console` by default, it does not make sense to test the `console` implementation when there is `MockLogger`. Removing this assertion also reduces flakiness with concurrent tests because the global console mocks no longer fight with each other across tests.

test/index.test.js
test/setup.js

index 679f5cda48c81ac09f96a021f5ce73432ec15c4a..79aeeae39b505a246fe1a6dcfbc1279cb76e0b85 100644 (file)
@@ -4,7 +4,7 @@ import childProcess from 'node:child_process';
 
 import { encrypt, decrypt } from '#src/index.js';
 import { WINDOW_EXPIRATION_DURATION } from '#src/getPrf.js';
-import { setupPlaywright, setupEnv, assertConsole, MockLogger, fileEqual, fileNotEqual } from '#test/setup.js';
+import { setupPlaywright, setupEnv, 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';
@@ -17,7 +17,6 @@ suite('e2e', () => {
   test('encrypt and decrypt .env', async (t) => {
     const { page } = await setupPlaywright(t);
     const envFile = await setupEnv(t, STD_ENV);
-    assertConsole(t, { debug: 0, info: 0, warn: 0, error: 0 });
 
     await fileEqual(envFile, STD_ENV);
     await encrypt({ inFile: envFile, getPrfOptions: { onListening: url => page.goto(url) } });
@@ -25,23 +24,9 @@ suite('e2e', () => {
     await decrypt({ inFile: envFile, getPrfOptions: { onListening: url => page.goto(url) } });
     await fileEqual(envFile, STD_ENV);
   });
-  test('console logger works', async (t) => {
+  test('logger works', async (t) => {
     const { page } = await setupPlaywright(t);
     const envFile = await setupEnv(t, STD_ENV);
-    assertConsole(t, { debug: 24, info: 6, warn: 0, error: 0 });
-
-    await fileEqual(envFile, STD_ENV);
-    await encrypt({ inFile: envFile, logger: console, getPrfOptions: { onListening: url => page.goto(url) } });
-    await encrypt({ inFile: envFile, logger: console, alreadyEncryptedValue: 'log', getPrfOptions: { onListening: url => page.goto(url) } });
-    await fileNotEqual(envFile, STD_ENV);
-    await decrypt({ inFile: envFile, logger: console, getPrfOptions: { onListening: url => page.goto(url) } });
-    await decrypt({ inFile: envFile, logger: console, notEncryptedValue: 'log', getPrfOptions: { onListening: url => page.goto(url) } });
-    await fileEqual(envFile, STD_ENV);
-  });
-  test('alternate logger works', async (t) => {
-    const { page } = await setupPlaywright(t);
-    const envFile = await setupEnv(t, STD_ENV);
-    assertConsole(t, { debug: 0, info: 0, warn: 0, error: 0 });
     const logger = new MockLogger();
 
     await fileEqual(envFile, STD_ENV);
@@ -59,7 +44,6 @@ suite('encrypt', () => {
   test('does nothing to empty .env file', async (t) => {
     const { page } = await setupPlaywright(t);
     const envFile = await setupEnv(t, '');
-    assertConsole(t, { debug: 0, info: 0, warn: 0, error: 0 });
 
     await fileEqual(envFile, '');
     await encrypt({ inFile: envFile, getPrfOptions: { onListening: url => page.goto(url) } });
@@ -68,15 +52,15 @@ suite('encrypt', () => {
   test('does nothing to empty .env file (with logs)', async (t) => {
     const { page } = await setupPlaywright(t);
     const envFile = await setupEnv(t, '');
-    assertConsole(t, { debug: 1, info: 1, warn: 0, error: 0 });
+    const logger = new MockLogger();
 
     await fileEqual(envFile, '');
-    await encrypt({ inFile: envFile, logger: console, getPrfOptions: { onListening: url => page.goto(url) } });
+    await encrypt({ inFile: envFile, logger, getPrfOptions: { onListening: url => page.goto(url) } });
     await fileEqual(envFile, '');
+    logger.assertCounts({ debug: 1, info: 1, warn: 0, error: 0 });
   });
   test('does nothing when all variables are already encrypted', async (t) => {
     const envFile = await setupEnv(t, ENCRYPTED_ENV);
-    assertConsole(t, { debug: 0, info: 0, warn: 0, error: 0 });
 
     await encrypt({ inFile: envFile });
 
@@ -85,7 +69,6 @@ suite('encrypt', () => {
   test("encrypts again when alreadyEncryptedValue: 'encrypt'", async (t) => {
     const { page } = await setupPlaywright(t);
     const envFile = await setupEnv(t, ENCRYPTED_ENV);
-    assertConsole(t, { debug: 0, info: 0, warn: 0, error: 0 });
 
     await encrypt({ inFile: envFile, alreadyEncryptedValue: 'encrypt', getPrfOptions: { onListening: url => page.goto(url) } });
 
@@ -93,7 +76,6 @@ suite('encrypt', () => {
   });
   test("throws when alreadyEncryptedValue: 'error'", async (t) => {
     const envFile = await setupEnv(t, ENCRYPTED_ENV);
-    assertConsole(t, { debug: 0, info: 0, warn: 0, error: 0 });
 
     await rejects(encrypt({ inFile: envFile, alreadyEncryptedValue: 'error' }), /Environment variable ".+" is already encrypted\./);
   });
@@ -102,7 +84,6 @@ suite('encrypt', () => {
     const { page, setAutomaticSignIn } = await setupPlaywright(t);
     await setAutomaticSignIn(false);
     const envFile = await setupEnv(t, STD_ENV);
-    assertConsole(t, { debug: 0, info: 0, warn: 0, error: 0 });
     const { promise: opened, resolve } = /** @type {PromiseWithResolvers<void>}*/(Promise.withResolvers());
     /** @type {(url: string) => Promise<void>} */
     const onListening = async url => {
@@ -121,7 +102,6 @@ suite('decrypt', () => {
   test('does nothing to empty .env file', async (t) => {
     await setupPlaywright(t);
     const envFile = await setupEnv(t, '');
-    assertConsole(t, { debug: 0, info: 0, warn: 0, error: 0 });
 
     await fileEqual(envFile, '');
     await decrypt({ inFile: envFile });
@@ -129,15 +109,15 @@ suite('decrypt', () => {
   });
   test('does nothing to empty .env file (with logs)', async (t) => {
     const envFile = await setupEnv(t, '');
-    assertConsole(t, { debug: 1, info: 1, warn: 0, error: 0 });
+    const logger = new MockLogger();
 
     await fileEqual(envFile, '');
-    await decrypt({ inFile: envFile, logger: console });
+    await decrypt({ inFile: envFile, logger });
     await fileEqual(envFile, '');
+    logger.assertCounts({ debug: 1, info: 1, warn: 0, error: 0 });
   });
   test('does nothing when all variables are already decrypted', async (t) => {
     const envFile = await setupEnv(t, STD_ENV);
-    assertConsole(t, { debug: 0, info: 0, warn: 0, error: 0 });
 
     await decrypt({ inFile: envFile });
 
@@ -145,7 +125,6 @@ suite('decrypt', () => {
   });
   test("throws error when notEncryptedValue='error'", async (t) => {
     const envFile = await setupEnv(t, STD_ENV);
-    assertConsole(t, { debug: 0, info: 0, warn: 0, error: 0 });
 
     await rejects(decrypt({ inFile: envFile, notEncryptedValue: 'error' }), /Environment variable ".+" is not encrypted\./);
   });
@@ -155,7 +134,6 @@ suite('decrypt', () => {
     await setAutomaticSignIn(false);
     const env = 'A=envpass:v1:AAA\nB=envpass:v1:BBB\nC=envpass:v1:CCC\n';
     const envFile = await setupEnv(t, env);
-    assertConsole(t, { debug: 0, info: 0, warn: 0, error: 0 });
     const { promise: opened, resolve } = /** @type {PromiseWithResolvers<void>}*/(Promise.withResolvers());
     /** @type {(url: string) => Promise<void>} */
     const onListening = async url => {
@@ -170,7 +148,6 @@ suite('decrypt', () => {
   });
   test('injects environment variables', async (t) => {
     const envFile = await setupEnv(t, INJECTED_ENV);
-    assertConsole(t, { debug: 0, info: 0, warn: 0, error: 0 });
 
     deepStrictEqual(process.env.INJECTION_TEST, undefined);
     await decrypt({ inFile: envFile, injectInProcess: true });
@@ -179,17 +156,17 @@ suite('decrypt', () => {
   });
   test('injects environment variables (with logs)', async (t) => {
     const envFile = await setupEnv(t, INJECTED_ENV);
-    assertConsole(t, { debug: 3, info: 0, warn: 0, error: 0 });
+    const logger = new MockLogger();
 
     deepStrictEqual(process.env.INJECTION_TEST, undefined);
-    await decrypt({ inFile: envFile, injectInProcess: true, logger: console });
+    await decrypt({ inFile: envFile, injectInProcess: true, logger });
     deepStrictEqual(process.env.INJECTION_TEST, 'INJECTED');
     delete process.env.INJECTION_TEST;
+    logger.assertCounts({ debug: 3, info: 0, warn: 0, error: 0 });
   });
   test('passes through excess args to execute', async (t) => {
     const execMock = t.mock.method(childProcess, 'execSync', () => { });
     const envFile = await setupEnv(t, STD_ENV);
-    assertConsole(t, { debug: 0, info: 0, warn: 0, error: 0 });
 
     await decrypt({ inFile: envFile }, { args: ['test', 'test', 'test'] });
     deepStrictEqual(execMock.mock.calls.length, 1);
@@ -197,9 +174,10 @@ suite('decrypt', () => {
   test('passes through excess args to execute (with logs)', async (t) => {
     const execMock = t.mock.method(childProcess, 'execSync', () => { });
     const envFile = await setupEnv(t, STD_ENV);
-    assertConsole(t, { debug: 4, info: 0, warn: 0, error: 0 });
+    const logger = new MockLogger();
 
-    await decrypt({ inFile: envFile, logger: console }, { args: ['test', 'test', 'test'] });
+    await decrypt({ inFile: envFile, logger }, { args: ['test', 'test', 'test'] });
     deepStrictEqual(execMock.mock.calls.length, 1);
+    logger.assertCounts({ debug: 4, info: 0, warn: 0, error: 0 });
   });
 });
index 2d66492c252f71f06703b652a0269eb0daefbbff..fc9b72ee0db9838a665a67b252b4eeeef1b90e4e 100644 (file)
@@ -113,33 +113,14 @@ export async function setupFolder(t, env = '') {
 }
 
 /**
- * @typedef AssertConsoleCounts The total number of times `console.debug`, `console.info`, `console.warn`, and
- * `console.error` are expected to be called.
- * @property {number} [debug] The number of times `console.debug` is expected to be called. The default value is 0.
- * @property {number} [info] The number of times `console.info` is expected to be called. The default value is 0.
- * @property {number} [warn] The number of times `console.warn` is expected to be called. The default value is 0.
- * @property {number} [error] The number of times `console.error` is expected to be called. The default value is 0.
+ * @typedef AssertLoggerCounts The total number of times `Logger.debug`, `Logger.info`, `Logger.warn`, and
+ * `Logger.error` are expected to be called.
+ * @property {number} [debug] The number of times `Logger.debug` is expected to be called. The default value is 0.
+ * @property {number} [info] The number of times `Logger.info` is expected to be called. The default value is 0.
+ * @property {number} [warn] The number of times `Logger.warn` is expected to be called. The default value is 0.
+ * @property {number} [error] The number of times `Logger.error` is expected to be called. The default value is 0.
  */
 
-/**
- * Silences console functions during a test and asserts a given number of calls were made during the test. 
- * 
- * Console will only be silenced AFTER this function is called, and only until the test ends. Call this
- * function early in the test to avoid unexpected console calls.
- * @param {TestContext} t Test context to mock the `console` functions for.
- * @param {AssertConsoleCounts} [expected] Counts for the total number of times console functions are expected
- * to be called.
- */
-export function assertConsole(t, expected = {}) {
-  const actual = { debug: 0, info: 0, warn: 0, error: 0 };
-  expected = { ...actual, ...expected };
-
-  for (const m of /** @type {Array<keyof typeof actual>} */(Object.keys(actual))) {
-    t.mock.method(console, m, () => actual[m]++);
-    t.after(() => deepStrictEqual(actual[m], expected[m], `expected ${expected[m]} console.${m} calls, got ${actual[m]}`));
-  }
-}
-
 /** @typedef {'debug'|'info'|'warn'|'error'} LoggerMethod A supported logger method. */
 /** @typedef {unknown[]} LoggerCall The arguments passed to a single logger method invocation. */
 /**
@@ -189,7 +170,7 @@ export class MockLogger {
 
   /**
    * Asserts that each logger method was called the expected number of times.
-   * @param {AssertConsoleCounts} counts
+   * @param {AssertLoggerCounts} counts
    */
   assertCounts(counts) {
     for (const method of /** @type {const} */(['debug', 'info', 'warn', 'error'])) {
This page took 0.045352 seconds and 4 git commands to generate.