From 3b827edaa8c4c94779e0cc367dc30fbeb5fa2633 Mon Sep 17 00:00:00 2001 From: rennerdo30 <9086097+rennerdo30@users.noreply.github.com> Date: Sat, 27 Jun 2026 19:23:41 +0900 Subject: [PATCH] chore(ui): coordinated toolchain major bumps (vitest 4, plugin-react 6, vite 8) Land the coupled UI devDependency major upgrades together, since merging the individual dependabot branches conflicts and the bumps share peer constraints: - vitest 3 -> 4 (^4.1.0) supersedes #45 - @vitest/coverage-v8 3 -> 4 (^4.1.0) supersedes #46 - @vitejs/plugin-react 5 -> 6 (^6.0.1) supersedes #43 - add vite ^8.1.0 (required peer of @vitejs/plugin-react 6) Mock migration for the vitest 4 mock API change (vi.fn().mockImplementation / vi.fn(() => obj) is no longer constructable with `new`): - ui/vitest.setup.ts: global ResizeObserver mock -> class MockResizeObserver - ui/src/components/hls-player.test.tsx: Hls constructor mock -> class MockHls with static isSupported/Events/ErrorTypes Verification: `npm run build` passes; `npx vitest run` -> 712 passed / 1 failed, where the single failure is the pre-existing unrelated popover.test.tsx case (known-good baseline). eslint 9 -> 10 (#40) intentionally NOT included: eslint-config-next still depends on eslint-plugin-react ^7.37.0, whose latest release (7.37.5) declares `peer eslint: ^...^9.7` and uses the old rule-context API that eslint 10 removed. No published eslint-plugin-react / eslint-config-next yet supports eslint 10, so #40 remains upstream-blocked. Co-Authored-By: Claude Opus 4.8 --- ui/package.json | 7 +++-- ui/src/components/hls-player.test.tsx | 43 ++++++++++++--------------- ui/vitest.setup.ts | 15 ++++++---- 3 files changed, 32 insertions(+), 33 deletions(-) diff --git a/ui/package.json b/ui/package.json index 1b0189a..8f3ba10 100644 --- a/ui/package.json +++ b/ui/package.json @@ -51,13 +51,14 @@ "@types/node": "^25", "@types/react": "^19", "@types/react-dom": "^19", - "@vitejs/plugin-react": "^5.1.3", - "@vitest/coverage-v8": "^3.2.3", + "@vitejs/plugin-react": "^6.0.1", + "@vitest/coverage-v8": "^4.1.0", "eslint": "^9", "eslint-config-next": "16.1.6", "jsdom": "^29.0.0", "tailwindcss": "^4", "typescript": "^5", - "vitest": "^3.2.3" + "vite": "^8.1.0", + "vitest": "^4.1.0" } } diff --git a/ui/src/components/hls-player.test.tsx b/ui/src/components/hls-player.test.tsx index bdb1d1c..d2c8d87 100644 --- a/ui/src/components/hls-player.test.tsx +++ b/ui/src/components/hls-player.test.tsx @@ -1,31 +1,26 @@ import { describe, it, expect, vi, beforeEach } from 'vitest' import { render, screen } from '@testing-library/react' -// Mock hls.js before imports +// Mock hls.js before imports. +// Use a class so `new Hls()` works under vitest 4 (vi.fn(() => instance) is no longer +// constructable). Static members (isSupported/Events/ErrorTypes) are attached to the class. vi.mock('hls.js', () => { - const mockHlsInstance = { - loadSource: vi.fn(), - attachMedia: vi.fn(), - on: vi.fn(), - destroy: vi.fn(), - recoverMediaError: vi.fn(), - } - - const MockHls = vi.fn(() => mockHlsInstance) as unknown as { - isSupported: () => boolean - Events: Record - ErrorTypes: Record - new(): typeof mockHlsInstance - } - - MockHls.isSupported = vi.fn().mockReturnValue(true) - MockHls.Events = { - MANIFEST_PARSED: 'hlsManifestParsed', - ERROR: 'hlsError', - } - MockHls.ErrorTypes = { - NETWORK_ERROR: 'networkError', - MEDIA_ERROR: 'mediaError', + class MockHls { + loadSource = vi.fn() + attachMedia = vi.fn() + on = vi.fn() + destroy = vi.fn() + recoverMediaError = vi.fn() + + static isSupported = vi.fn().mockReturnValue(true) + static Events = { + MANIFEST_PARSED: 'hlsManifestParsed', + ERROR: 'hlsError', + } + static ErrorTypes = { + NETWORK_ERROR: 'networkError', + MEDIA_ERROR: 'mediaError', + } } return { diff --git a/ui/vitest.setup.ts b/ui/vitest.setup.ts index 0517844..b474028 100644 --- a/ui/vitest.setup.ts +++ b/ui/vitest.setup.ts @@ -4,12 +4,15 @@ import React from 'react' // Mock scrollIntoView for Radix UI components Element.prototype.scrollIntoView = vi.fn() -// Mock ResizeObserver for Radix UI components -global.ResizeObserver = vi.fn().mockImplementation(() => ({ - observe: vi.fn(), - unobserve: vi.fn(), - disconnect: vi.fn(), -})) +// Mock ResizeObserver for Radix UI components. +// Use a class so `new ResizeObserver()` works under vitest 4 (vi.fn().mockImplementation +// no longer produces a constructable mock). +class MockResizeObserver { + observe = vi.fn() + unobserve = vi.fn() + disconnect = vi.fn() +} +global.ResizeObserver = MockResizeObserver as unknown as typeof ResizeObserver // Mock PointerEvent for Radix UI components class MockPointerEvent extends Event {