From 87c01c981934bce66c3c3a42fe2bda750b89141f Mon Sep 17 00:00:00 2001 From: Johnpaul Date: Thu, 22 Jan 2026 22:09:19 +0100 Subject: [PATCH] refactor: remove as any from 5 test files (batch 12) Fixed 31 instances across: - typeGuardUtil.test.ts: Use Parameters utility type for partial mocks - graphTraversalUtil.test.ts: Use proper type assertions for property mutations and invalid input testing - subgraphNavigationStore.viewport.test.ts: Import Subgraph type, fix mock canvas typing - useCanvasManager.test.ts: Use as unknown as Type for mutable mock store properties - useCanvasTools.test.ts: Use as unknown as Type for mutable mock store properties The canvas mock store pattern now uses as unknown as HTMLCanvasElement/CanvasRenderingContext2D at both declaration and assignment points to allow partial mocks while maintaining type safety. --- .../maskeditor/useCanvasManager.test.ts | 36 +++++++++---------- .../maskeditor/useCanvasTools.test.ts | 36 +++++++++---------- .../subgraphNavigationStore.viewport.test.ts | 27 ++++++++------ src/utils/graphTraversalUtil.test.ts | 16 +++++---- src/utils/typeGuardUtil.test.ts | 10 +++--- 5 files changed, 67 insertions(+), 58 deletions(-) diff --git a/src/composables/maskeditor/useCanvasManager.test.ts b/src/composables/maskeditor/useCanvasManager.test.ts index 4fe40df6e9..3970187cfb 100644 --- a/src/composables/maskeditor/useCanvasManager.test.ts +++ b/src/composables/maskeditor/useCanvasManager.test.ts @@ -3,13 +3,13 @@ import { beforeEach, describe, expect, it, vi } from 'vitest' import { MaskBlendMode } from '@/extensions/core/maskeditor/types' import { useCanvasManager } from '@/composables/maskeditor/useCanvasManager' const mockStore = { - imgCanvas: null as any, - maskCanvas: null as any, - rgbCanvas: null as any, - imgCtx: null as any, - maskCtx: null as any, - rgbCtx: null as any, - canvasBackground: null as any, + imgCanvas: null as unknown as HTMLCanvasElement, + maskCanvas: null as unknown as HTMLCanvasElement, + rgbCanvas: null as unknown as HTMLCanvasElement, + imgCtx: null as unknown as CanvasRenderingContext2D, + maskCtx: null as unknown as CanvasRenderingContext2D, + rgbCtx: null as unknown as CanvasRenderingContext2D, + canvasBackground: null as unknown as HTMLElement, maskColor: { r: 0, g: 0, b: 0 }, maskBlendMode: MaskBlendMode.Black, maskOpacity: 0.8 @@ -40,7 +40,7 @@ describe('useCanvasManager', () => { mockStore.imgCtx = { drawImage: vi.fn() - } + } as unknown as CanvasRenderingContext2D mockStore.maskCtx = { drawImage: vi.fn(), @@ -48,16 +48,16 @@ describe('useCanvasManager', () => { putImageData: vi.fn(), globalCompositeOperation: 'source-over', fillStyle: '' - } + } as unknown as CanvasRenderingContext2D mockStore.rgbCtx = { drawImage: vi.fn() - } + } as unknown as CanvasRenderingContext2D mockStore.imgCanvas = { width: 0, height: 0 - } + } as unknown as HTMLCanvasElement mockStore.maskCanvas = { width: 0, @@ -66,18 +66,18 @@ describe('useCanvasManager', () => { mixBlendMode: '', opacity: '' } - } + } as unknown as HTMLCanvasElement mockStore.rgbCanvas = { width: 0, height: 0 - } + } as unknown as HTMLCanvasElement mockStore.canvasBackground = { style: { backgroundColor: '' } - } + } as unknown as HTMLElement mockStore.maskColor = { r: 0, g: 0, b: 0 } mockStore.maskBlendMode = MaskBlendMode.Black @@ -163,7 +163,7 @@ describe('useCanvasManager', () => { it('should throw error when canvas missing', async () => { const manager = useCanvasManager() - mockStore.imgCanvas = null + mockStore.imgCanvas = null as unknown as HTMLCanvasElement const origImage = createMockImage(512, 512) const maskImage = createMockImage(512, 512) @@ -176,7 +176,7 @@ describe('useCanvasManager', () => { it('should throw error when context missing', async () => { const manager = useCanvasManager() - mockStore.imgCtx = null + mockStore.imgCtx = null as unknown as CanvasRenderingContext2D const origImage = createMockImage(512, 512) const maskImage = createMockImage(512, 512) @@ -259,7 +259,7 @@ describe('useCanvasManager', () => { it('should return early when canvas missing', async () => { const manager = useCanvasManager() - mockStore.maskCanvas = null + mockStore.maskCanvas = null as unknown as HTMLCanvasElement await manager.updateMaskColor() @@ -269,7 +269,7 @@ describe('useCanvasManager', () => { it('should return early when context missing', async () => { const manager = useCanvasManager() - mockStore.maskCtx = null + mockStore.maskCtx = null as unknown as CanvasRenderingContext2D await manager.updateMaskColor() diff --git a/src/composables/maskeditor/useCanvasTools.test.ts b/src/composables/maskeditor/useCanvasTools.test.ts index 991d19c00c..b1b2d922ed 100644 --- a/src/composables/maskeditor/useCanvasTools.test.ts +++ b/src/composables/maskeditor/useCanvasTools.test.ts @@ -9,12 +9,12 @@ const mockCanvasHistory = { } const mockStore = { - maskCtx: null as any, - imgCtx: null as any, - maskCanvas: null as any, - imgCanvas: null as any, - rgbCtx: null as any, - rgbCanvas: null as any, + maskCtx: null as unknown as CanvasRenderingContext2D, + imgCtx: null as unknown as CanvasRenderingContext2D, + maskCanvas: null as unknown as HTMLCanvasElement, + imgCanvas: null as unknown as HTMLCanvasElement, + rgbCtx: null as unknown as CanvasRenderingContext2D, + rgbCanvas: null as unknown as HTMLCanvasElement, maskColor: { r: 255, g: 255, b: 255 }, paintBucketTolerance: 10, fillOpacity: 100, @@ -61,30 +61,30 @@ describe('useCanvasTools', () => { getImageData: vi.fn(() => mockMaskImageData), putImageData: vi.fn(), clearRect: vi.fn() - } + } as unknown as CanvasRenderingContext2D mockStore.imgCtx = { getImageData: vi.fn(() => mockImgImageData) - } + } as unknown as CanvasRenderingContext2D mockStore.rgbCtx = { clearRect: vi.fn() - } + } as unknown as CanvasRenderingContext2D mockStore.maskCanvas = { width: 100, height: 100 - } + } as unknown as HTMLCanvasElement mockStore.imgCanvas = { width: 100, height: 100 - } + } as unknown as HTMLCanvasElement mockStore.rgbCanvas = { width: 100, height: 100 - } + } as unknown as HTMLCanvasElement mockStore.maskColor = { r: 255, g: 255, b: 255 } mockStore.paintBucketTolerance = 10 @@ -158,7 +158,7 @@ describe('useCanvasTools', () => { }) it('should return early when canvas missing', () => { - mockStore.maskCanvas = null + mockStore.maskCanvas = null as unknown as HTMLCanvasElement const tools = useCanvasTools() @@ -243,7 +243,7 @@ describe('useCanvasTools', () => { }) it('should return early when canvas missing', async () => { - mockStore.imgCanvas = null + mockStore.imgCanvas = null as unknown as HTMLCanvasElement const tools = useCanvasTools() @@ -363,7 +363,7 @@ describe('useCanvasTools', () => { }) it('should return early when canvas missing', () => { - mockStore.maskCanvas = null + mockStore.maskCanvas = null as unknown as HTMLCanvasElement const tools = useCanvasTools() @@ -373,7 +373,7 @@ describe('useCanvasTools', () => { }) it('should return early when context missing', () => { - mockStore.maskCtx = null + mockStore.maskCtx = null as unknown as CanvasRenderingContext2D const tools = useCanvasTools() @@ -395,7 +395,7 @@ describe('useCanvasTools', () => { }) it('should handle missing mask canvas', () => { - mockStore.maskCanvas = null + mockStore.maskCanvas = null as unknown as HTMLCanvasElement const tools = useCanvasTools() @@ -406,7 +406,7 @@ describe('useCanvasTools', () => { }) it('should handle missing rgb canvas', () => { - mockStore.rgbCanvas = null + mockStore.rgbCanvas = null as unknown as HTMLCanvasElement const tools = useCanvasTools() diff --git a/src/stores/subgraphNavigationStore.viewport.test.ts b/src/stores/subgraphNavigationStore.viewport.test.ts index 6dbf85a6b9..184ccb9b99 100644 --- a/src/stores/subgraphNavigationStore.viewport.test.ts +++ b/src/stores/subgraphNavigationStore.viewport.test.ts @@ -2,11 +2,14 @@ import { createPinia, setActivePinia } from 'pinia' import { beforeEach, describe, expect, it, vi } from 'vitest' import { nextTick } from 'vue' +import type { Subgraph } from '@/lib/litegraph/src/litegraph' import { useWorkflowStore } from '@/platform/workflow/management/stores/workflowStore' import type { ComfyWorkflow } from '@/platform/workflow/management/stores/workflowStore' import { app } from '@/scripts/app' import { useSubgraphNavigationStore } from '@/stores/subgraphNavigationStore' +const mockSetDirty = vi.fn() + vi.mock('@/scripts/app', () => { const mockCanvas = { subgraph: null, @@ -18,7 +21,7 @@ vi.mock('@/scripts/app', () => { offset: [0, 0] } }, - setDirty: vi.fn() + setDirty: mockSetDirty } return { @@ -37,12 +40,12 @@ vi.mock('@/scripts/app', () => { // Mock canvasStore vi.mock('@/renderer/core/canvas/canvasStore', () => ({ useCanvasStore: () => ({ - getCanvas: () => (app as any).canvas + getCanvas: () => app.canvas }) })) // Get reference to mock canvas -const mockCanvas = app.canvas as any +const mockCanvas = app.canvas describe('useSubgraphNavigationStore - Viewport Persistence', () => { beforeEach(() => { @@ -52,7 +55,7 @@ describe('useSubgraphNavigationStore - Viewport Persistence', () => { mockCanvas.ds.offset = [0, 0] mockCanvas.ds.state.scale = 1 mockCanvas.ds.state.offset = [0, 0] - mockCanvas.setDirty.mockClear() + mockSetDirty.mockClear() }) describe('saveViewport', () => { @@ -98,7 +101,7 @@ describe('useSubgraphNavigationStore - Viewport Persistence', () => { // Mock being in a subgraph const mockSubgraph = { id: 'sub-456' } - workflowStore.activeSubgraph = mockSubgraph as any + workflowStore.activeSubgraph = mockSubgraph as unknown as Subgraph // Set viewport state mockCanvas.ds.state.scale = 3 @@ -158,7 +161,7 @@ describe('useSubgraphNavigationStore - Viewport Persistence', () => { // Reset canvas mockCanvas.ds.scale = 1 mockCanvas.ds.offset = [0, 0] - mockCanvas.setDirty.mockClear() + mockSetDirty.mockClear() // Try to restore non-existent viewport navigationStore.restoreViewport('non-existent') @@ -166,7 +169,7 @@ describe('useSubgraphNavigationStore - Viewport Persistence', () => { // Canvas should not change expect(mockCanvas.ds.scale).toBe(1) expect(mockCanvas.ds.offset).toEqual([0, 0]) - expect(mockCanvas.setDirty).not.toHaveBeenCalled() + expect(mockSetDirty).not.toHaveBeenCalled() }) }) @@ -194,7 +197,7 @@ describe('useSubgraphNavigationStore - Viewport Persistence', () => { mockCanvas.ds.state.offset = [100, 100] // Navigate to subgraph - workflowStore.activeSubgraph = subgraph1 as any + workflowStore.activeSubgraph = subgraph1 as unknown as Subgraph await nextTick() // Root viewport should have been saved automatically @@ -239,10 +242,14 @@ describe('useSubgraphNavigationStore - Viewport Persistence', () => { const workflow1 = { path: 'workflow1.json' } as ComfyWorkflow const workflow2 = { path: 'workflow2.json' } as ComfyWorkflow - workflowStore.activeWorkflow = workflow1 as any + workflowStore.activeWorkflow = workflow1 as unknown as ReturnType< + typeof useWorkflowStore + >['activeWorkflow'] await nextTick() - workflowStore.activeWorkflow = workflow2 as any + workflowStore.activeWorkflow = workflow2 as unknown as ReturnType< + typeof useWorkflowStore + >['activeWorkflow'] await nextTick() // Cache should be preserved (LRU will manage memory) diff --git a/src/utils/graphTraversalUtil.test.ts b/src/utils/graphTraversalUtil.test.ts index 2b3f1bfbc2..5c82aa75d8 100644 --- a/src/utils/graphTraversalUtil.test.ts +++ b/src/utils/graphTraversalUtil.test.ts @@ -96,8 +96,8 @@ describe('graphTraversalUtil', () => { it('should return null for invalid input', () => { expect(parseExecutionId('')).toBeNull() - expect(parseExecutionId(null as any)).toBeNull() - expect(parseExecutionId(undefined as any)).toBeNull() + expect(parseExecutionId(null as unknown as string)).toBeNull() + expect(parseExecutionId(undefined as unknown as string)).toBeNull() }) }) @@ -415,7 +415,7 @@ describe('graphTraversalUtil', () => { // Add a title property to each node forEachNode(graph, (node) => { - ;(node as any).title = `Node ${node.id}` + ;(node as unknown as { title: string }).title = `Node ${node.id}` }) expect(nodes[0]).toHaveProperty('title', 'Node 1') @@ -653,7 +653,7 @@ describe('graphTraversalUtil', () => { it('should return root graph from subgraph', () => { const rootGraph = createMockGraph([]) const subgraph = createMockSubgraph('sub-uuid', []) - ;(subgraph as any).rootGraph = rootGraph + ;(subgraph as Subgraph & { rootGraph: LGraph }).rootGraph = rootGraph expect(getRootGraph(subgraph)).toBe(rootGraph) }) @@ -663,8 +663,10 @@ describe('graphTraversalUtil', () => { const midSubgraph = createMockSubgraph('mid-uuid', []) const deepSubgraph = createMockSubgraph('deep-uuid', []) - ;(midSubgraph as any).rootGraph = rootGraph - ;(deepSubgraph as any).rootGraph = midSubgraph + ;(midSubgraph as Subgraph & { rootGraph: LGraph }).rootGraph = rootGraph + ;( + deepSubgraph as Subgraph & { rootGraph: LGraph | Subgraph } + ).rootGraph = midSubgraph expect(getRootGraph(deepSubgraph)).toBe(rootGraph) }) @@ -726,7 +728,7 @@ describe('graphTraversalUtil', () => { const graph = createMockGraph(nodes) forEachSubgraphNode(graph, subgraphId, (node) => { - ;(node as any).title = 'Updated Title' + ;(node as unknown as { title: string }).title = 'Updated Title' }) expect(nodes[0]).toHaveProperty('title', 'Updated Title') diff --git a/src/utils/typeGuardUtil.test.ts b/src/utils/typeGuardUtil.test.ts index 9c06892713..3f23d198c9 100644 --- a/src/utils/typeGuardUtil.test.ts +++ b/src/utils/typeGuardUtil.test.ts @@ -7,7 +7,7 @@ describe('typeGuardUtil', () => { it('should identify SubgraphInputNode as IO node', () => { const node = { constructor: { comfyClass: 'SubgraphInputNode' } - } as any + } as unknown as Parameters[0] expect(isSubgraphIoNode(node)).toBe(true) }) @@ -15,7 +15,7 @@ describe('typeGuardUtil', () => { it('should identify SubgraphOutputNode as IO node', () => { const node = { constructor: { comfyClass: 'SubgraphOutputNode' } - } as any + } as unknown as Parameters[0] expect(isSubgraphIoNode(node)).toBe(true) }) @@ -23,13 +23,13 @@ describe('typeGuardUtil', () => { it('should not identify regular nodes as IO nodes', () => { const node = { constructor: { comfyClass: 'CLIPTextEncode' } - } as any + } as unknown as Parameters[0] expect(isSubgraphIoNode(node)).toBe(false) }) it('should handle nodes without constructor', () => { - const node = {} as any + const node = {} as unknown as Parameters[0] expect(isSubgraphIoNode(node)).toBe(false) }) @@ -37,7 +37,7 @@ describe('typeGuardUtil', () => { it('should handle nodes without comfyClass', () => { const node = { constructor: {} - } as any + } as unknown as Parameters[0] expect(isSubgraphIoNode(node)).toBe(false) })