From c30a7965d4d5b446890beace9a14e0ce1397b90c Mon Sep 17 00:00:00 2001 From: Matthew Anderson Date: Fri, 18 Sep 2026 23:51:00 -0500 Subject: [PATCH] test(web): make the ResizeObserver mock constructible under any vitest Recharts calls `new ResizeObserver(...)`, and the mock was built with `vi.fn().mockImplementation(...)`. Whether a vitest mock function can be used as a constructor is an implementation detail, and it changed in vitest 5: every Recharts-backed test fails there with "... is not a constructor", 10 of the 144 in this suite. A plain class does the same job without depending on that detail. Verified both ways: 144/144 on the pinned vitest 3.2.6, and 144/144 on vitest 5.0.1, which is what Dependabot #15 proposes. That PR cannot go green without this. Also stop the generated coverage/ directory leaking into lint and git. It was in neither web/.gitignore nor the eslint ignorePatterns, so running `vitest run --coverage` produced instrumented copies of the source that eslint then reported errors on, and left them untracked in the working tree. Co-Authored-By: Claude Opus 5 --- web/.eslintrc.cjs | 2 +- web/.gitignore | 1 + web/src/test/setup.js | 15 +++++++++------ 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/web/.eslintrc.cjs b/web/.eslintrc.cjs index a128a6c..770caf4 100644 --- a/web/.eslintrc.cjs +++ b/web/.eslintrc.cjs @@ -7,7 +7,7 @@ module.exports = { 'plugin:react/jsx-runtime', 'plugin:react-hooks/recommended', ], - ignorePatterns: ['dist', '.eslintrc.cjs'], + ignorePatterns: ['dist', 'coverage', '.eslintrc.cjs'], parserOptions: { ecmaVersion: 'latest', sourceType: 'module' }, settings: { react: { version: '18.2' } }, plugins: ['react-refresh'], diff --git a/web/.gitignore b/web/.gitignore index d600b6c..d700a72 100644 --- a/web/.gitignore +++ b/web/.gitignore @@ -10,6 +10,7 @@ lerna-debug.log* node_modules dist dist-ssr +coverage *.local # Editor directories and files diff --git a/web/src/test/setup.js b/web/src/test/setup.js index ddbd467..2c2fabb 100644 --- a/web/src/test/setup.js +++ b/web/src/test/setup.js @@ -16,12 +16,15 @@ if (globalThis.__VITEST_SETUP_LOADED__) { // Extend Vitest's expect with accessibility matchers expect.extend({ toHaveNoViolations }); - // Mock ResizeObserver (needed for Recharts) - globalThis.ResizeObserver = vi.fn().mockImplementation(() => ({ - observe: vi.fn(), - unobserve: vi.fn(), - disconnect: vi.fn(), - })); + // Mock ResizeObserver (needed for Recharts). A plain class rather than + // vi.fn().mockImplementation(): Recharts calls `new ResizeObserver(...)`, + // and whether a mock function is constructible is a vitest implementation + // detail that changed in v5. + globalThis.ResizeObserver = class ResizeObserver { + observe() {} + unobserve() {} + disconnect() {} + }; // Mock scrollIntoView (needed for Logs component) Element.prototype.scrollIntoView = vi.fn();