fail-on-console 1.1.1 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
  # Changelog
2
2
 
3
+ ## [1.2.0](https://github.com/benquarmby/fail-on-console/compare/v1.1.2...v1.2.0) (2026-07-25)
4
+
5
+
6
+ ### Features
7
+
8
+ * do not require expect API in setupConsole ([04c0bad](https://github.com/benquarmby/fail-on-console/commit/04c0bad55f39773e6fb326f6364a5c64d46b3e0f))
9
+
10
+ ## [1.1.2](https://github.com/benquarmby/fail-on-console/compare/v1.1.1...v1.1.2) (2026-07-22)
11
+
12
+
13
+ ### Bug Fixes
14
+
15
+ * guard against invalid and unsupported console methods ([504fa30](https://github.com/benquarmby/fail-on-console/commit/504fa301e245d0965afdfaf3c31d2d3b9a0cb10c))
16
+
3
17
  ## [1.1.1](https://github.com/benquarmby/fail-on-console/compare/v1.1.0...v1.1.1) (2026-07-08)
4
18
 
5
19
 
package/README.md CHANGED
@@ -35,10 +35,10 @@ Initialize `setupConsole` inside a configured [`setupFiles`](https://vitest.dev/
35
35
 
36
36
  ```js
37
37
  // vitest.setup.js
38
- import {beforeEach, afterEach, expect} from "vitest";
38
+ import {beforeEach, afterEach} from "vitest";
39
39
  import {setupConsole} from "fail-on-console";
40
40
 
41
- setupConsole({beforeEach, afterEach, expect});
41
+ setupConsole({beforeEach, afterEach});
42
42
  ```
43
43
 
44
44
  ### With Jest
@@ -47,10 +47,10 @@ Initialize `setupConsole` inside a configured [`setupFilesAfterEnv`](https://jes
47
47
 
48
48
  ```js
49
49
  // jest.setup.js
50
- import {beforeEach, afterEach, expect} from "@jest/globals";
50
+ import {beforeEach, afterEach} from "@jest/globals";
51
51
  import {setupConsole} from "fail-on-console";
52
52
 
53
- setupConsole({beforeEach, afterEach, expect});
53
+ setupConsole({beforeEach, afterEach});
54
54
  ```
55
55
 
56
56
  ### Customizing Monitored Methods
@@ -61,7 +61,6 @@ By default, `debug` is not monitored but `error`, `warn`, `info`, and `log` are.
61
61
  setupConsole({
62
62
  beforeEach,
63
63
  afterEach,
64
- expect,
65
64
  // Fail on console.error, console.warn, and console.debug.
66
65
  methods: ["error", "warn", "debug"]
67
66
  });
@@ -97,7 +96,6 @@ Initializes console spies that monitor active tests.
97
96
 
98
97
  - `options.beforeEach`: The framework's `beforeEach` hook.
99
98
  - `options.afterEach`: The framework's `afterEach` hook.
100
- - `options.expect`: The framework's `expect` object (must expose `getState()`).
101
99
  - `options.methods`: _(Optional)_ Array of `console` methods to track. Defaults to `["error", "warn", "info", "log"]`.
102
100
 
103
101
  ### `allowConsole(method, rules)`
@@ -112,8 +110,18 @@ Registers a temporary or global allowlist rule for a monitored console method.
112
110
 
113
111
  ## Limitations
114
112
 
113
+ ### Concurrency
114
+
115
115
  `fail-on-console` is not compatible with concurrent asynchronous tests (e.g., `test.concurrent`). Because concurrent tests execute simultaneously within the same environment context, console logs cannot be isolated reliably per individual test. For suites requiring specific log suppression, tests must be run sequentially.
116
116
 
117
+ ### Assert
118
+
119
+ Monitoring `console.assert` is currently unsupported. It has a distinct signature and unique assertion mechanics compared to standard logging methods.
120
+
121
+ ### Mocha
122
+
123
+ Mocha is unsupported due to API incompatibilities related to test context. There are no clean or reliable workarounds for integration.
124
+
117
125
  ## Credits & Prior Art
118
126
 
119
127
  This package is inspired by and builds on the excellent foundation laid by:
package/index.d.ts CHANGED
@@ -15,7 +15,10 @@ export interface LifecycleHookLike {
15
15
  export interface TestApi {
16
16
  beforeEach: LifecycleHookLike;
17
17
  afterEach: LifecycleHookLike;
18
- expect: ExpectLike;
18
+ /**
19
+ * @deprecated No longer needed. This option can be omitted.
20
+ */
21
+ expect?: ExpectLike;
19
22
  }
20
23
 
21
24
  export interface SetupOptions extends TestApi {
@@ -37,25 +40,24 @@ export function setup(options: SetupOptions): void;
37
40
  /**
38
41
  * Installs console spies that fail the current test if any monitored console
39
42
  * method is called. Call once at the top of the test setup file, passing the
40
- * lifecycle hooks and expect function from the test framework. Compatible with
41
- * any Jest-compatible API (Jest, Vitest, etc.).
43
+ * lifecycle hooks from the test framework. Compatible with any Jest-like API
44
+ * (Vitest, Jest, etc.).
42
45
  * @param {Object} options
43
46
  * @param {Function} options.beforeEach The beforeEach hook from the test framework.
44
47
  * @param {Function} options.afterEach The afterEach hook from the test framework.
45
- * @param {Object} options.expect The expect object from the test framework. Must expose getState().
46
48
  * @param {string[]} [options.methods=["error","warn","info","log"]] Console methods to monitor.
47
49
  * @example
48
- * // Jest
49
- * import {beforeEach, afterEach, expect} from "@jest/globals";
50
+ * // Vitest
51
+ * import {beforeEach, afterEach} from "vitest";
50
52
  * import {setup} from "fail-on-console";
51
53
  *
52
- * setup({beforeEach, afterEach, expect});
54
+ * setup({beforeEach, afterEach});
53
55
  * @example
54
- * // Vitest
55
- * import {beforeEach, afterEach, expect} from "vitest";
56
+ * // Jest
57
+ * import {beforeEach, afterEach} from "@jest/globals";
56
58
  * import {setup} from "fail-on-console";
57
59
  *
58
- * setup({beforeEach, afterEach, expect});
60
+ * setup({beforeEach, afterEach});
59
61
  */
60
62
  export function setupConsole(options: SetupOptions): void;
61
63
 
package/index.js CHANGED
@@ -1,9 +1,40 @@
1
- let testApi;
2
- const defaultMethods = ["error", "warn", "info", "log"];
3
- const allowed = new Map();
1
+ const supportedMethods = ["error", "warn", "info", "log", "debug"];
2
+ // Everything but console.debug is monitored by default. Debug logging in tests
3
+ // is usually intentional.
4
+ const defaultMethods = supportedMethods.slice(0, -1);
4
5
  // %s string, %d/%i integer, %o object, %f float
5
6
  const printfPattern = /%[sdiof]/g;
6
7
 
8
+ // Module scoped variables to manage test state. Not safe for concurrent tests.
9
+ // Test frameworks run tests serially by default.
10
+ let testApi;
11
+ let isInsideTest = false;
12
+ const allowed = new Map();
13
+
14
+ function quoteString(value) {
15
+ return `"${value}"`;
16
+ }
17
+
18
+ function assertSupportedMethods(methods) {
19
+ if (!Array.isArray(methods)) {
20
+ throw new Error("fail-on-console: Expected an array of console methods.");
21
+ }
22
+
23
+ const unsupported = methods.filter((method) => !supportedMethods.includes(method));
24
+
25
+ if (!unsupported.length) {
26
+ return;
27
+ }
28
+
29
+ const method = unsupported.length === 1 ? "method" : "methods";
30
+ const invalidList = unsupported.map(quoteString).join(", ");
31
+ const validList = supportedMethods.map(quoteString).join(", ");
32
+
33
+ throw new Error(
34
+ `fail-on-console: Unsupported console ${method} provided: ${invalidList}. Supported methods are: ${validList}.`
35
+ );
36
+ }
37
+
7
38
  /**
8
39
  * Basic implementation of node:util/format for console message formatting.
9
40
  * Covers only the most common uses. Does not handle all specifiers (such as
@@ -46,14 +77,23 @@ function isAllowed(message, rule) {
46
77
  return rule.test(message);
47
78
  }
48
79
 
49
- function setupConsole({beforeEach, afterEach, expect, methods = defaultMethods}) {
80
+ function setupConsole({beforeEach, afterEach, methods = defaultMethods}) {
50
81
  if (testApi) {
51
82
  throw new Error("fail-on-console: Call setupConsole() only once.");
52
83
  }
53
84
 
54
- testApi = {beforeEach, afterEach, expect};
85
+ assertSupportedMethods(methods);
55
86
 
56
- beforeEach(() => allowed.clear());
87
+ testApi = {beforeEach, afterEach};
88
+
89
+ beforeEach(function () {
90
+ isInsideTest = true;
91
+ allowed.clear();
92
+ });
93
+
94
+ afterEach(function () {
95
+ isInsideTest = false;
96
+ });
57
97
 
58
98
  methods.forEach(function (method) {
59
99
  const original = console[method];
@@ -98,8 +138,9 @@ function allowConsole(method, rules) {
98
138
  throw new Error("fail-on-console: Call setupConsole() before using allowConsole().");
99
139
  }
100
140
 
141
+ assertSupportedMethods([method]);
142
+
101
143
  const normalized = Array.isArray(rules) ? rules : [rules];
102
- const isInsideTest = !!testApi.expect.getState().currentTestName;
103
144
 
104
145
  function addRules() {
105
146
  const existing = allowed.get(method) ?? [];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fail-on-console",
3
- "version": "1.1.1",
3
+ "version": "1.2.0",
4
4
  "description": "Fail Vitest or Jest tests when unexpected console logs, warnings or errors occur.",
5
5
  "keywords": [
6
6
  "jest",
@@ -20,19 +20,20 @@
20
20
  ],
21
21
  "devDependencies": {
22
22
  "@commitlint/config-conventional": "^21.2.0",
23
- "@vitest/coverage-v8": "4.1.9",
24
- "commitlint": "^21.2.0",
23
+ "@vitest/coverage-v8": "4.1.10",
24
+ "commitlint": "^21.2.1",
25
25
  "jest": "^30.4.2",
26
- "prettier": "^3.8.4",
26
+ "npm-run-all2": "^9.0.2",
27
+ "prettier": "^3.9.6",
27
28
  "prettier-plugin-packagejson": "^3.0.2",
28
- "vitest": "^4.1.9"
29
+ "vitest": "^4.1.10"
29
30
  },
30
31
  "scripts": {
31
32
  "commit:check": "commitlint --from-last-tag",
32
33
  "format": "prettier --write .",
33
34
  "format:check": "prettier --check .",
34
- "test": "vitest run",
35
- "test:compat": "jest",
36
- "test:cover": "vitest run --coverage"
35
+ "test:jest": "jest",
36
+ "test:vitest": "vitest run --coverage",
37
+ "verify": "run-s format:check test:vitest test:jest"
37
38
  }
38
39
  }