mirror of
https://github.com/langgenius/dify.git
synced 2026-03-06 16:16:38 +08:00
144 lines
4.6 KiB
TypeScript
144 lines
4.6 KiB
TypeScript
/**
|
|
* Shared mutable ReactFlow mock state for hook/component tests.
|
|
*
|
|
* Mutate `rfState` in `beforeEach` to configure nodes/edges,
|
|
* then assert on `rfState.setNodes`, `rfState.setEdges`, etc.
|
|
*
|
|
* Usage (one line at top of test file):
|
|
* ```ts
|
|
* vi.mock('reactflow', async () =>
|
|
* (await import('../../__tests__/reactflow-mock-state')).createReactFlowModuleMock(),
|
|
* )
|
|
* ```
|
|
*/
|
|
import * as React from 'react'
|
|
|
|
type MockNode = {
|
|
id: string
|
|
position: { x: number, y: number }
|
|
width?: number
|
|
height?: number
|
|
parentId?: string
|
|
data: Record<string, unknown>
|
|
}
|
|
|
|
type MockEdge = {
|
|
id: string
|
|
source: string
|
|
target: string
|
|
sourceHandle?: string
|
|
data: Record<string, unknown>
|
|
}
|
|
|
|
type ReactFlowMockState = {
|
|
nodes: MockNode[]
|
|
edges: MockEdge[]
|
|
transform: [number, number, number]
|
|
setViewport: ReturnType<typeof vi.fn>
|
|
setNodes: ReturnType<typeof vi.fn>
|
|
setEdges: ReturnType<typeof vi.fn>
|
|
}
|
|
|
|
export const rfState: ReactFlowMockState = {
|
|
nodes: [],
|
|
edges: [],
|
|
transform: [0, 0, 1],
|
|
setViewport: vi.fn(),
|
|
setNodes: vi.fn(),
|
|
setEdges: vi.fn(),
|
|
}
|
|
|
|
export function resetReactFlowMockState() {
|
|
rfState.nodes = []
|
|
rfState.edges = []
|
|
rfState.transform = [0, 0, 1]
|
|
rfState.setViewport.mockReset()
|
|
rfState.setNodes.mockReset()
|
|
rfState.setEdges.mockReset()
|
|
}
|
|
|
|
export function createReactFlowModuleMock() {
|
|
return {
|
|
Position: { Left: 'left', Right: 'right', Top: 'top', Bottom: 'bottom' },
|
|
MarkerType: { Arrow: 'arrow', ArrowClosed: 'arrowclosed' },
|
|
ConnectionMode: { Strict: 'strict', Loose: 'loose' },
|
|
|
|
useStoreApi: vi.fn(() => ({
|
|
getState: () => ({
|
|
getNodes: () => rfState.nodes,
|
|
setNodes: rfState.setNodes,
|
|
edges: rfState.edges,
|
|
setEdges: rfState.setEdges,
|
|
transform: rfState.transform,
|
|
nodeInternals: new Map(),
|
|
d3Selection: null,
|
|
d3Zoom: null,
|
|
}),
|
|
setState: vi.fn(),
|
|
subscribe: vi.fn().mockReturnValue(vi.fn()),
|
|
})),
|
|
|
|
useReactFlow: vi.fn(() => ({
|
|
setViewport: rfState.setViewport,
|
|
setCenter: vi.fn(),
|
|
fitView: vi.fn(),
|
|
zoomIn: vi.fn(),
|
|
zoomOut: vi.fn(),
|
|
zoomTo: vi.fn(),
|
|
getNodes: () => rfState.nodes,
|
|
getEdges: () => rfState.edges,
|
|
setNodes: rfState.setNodes,
|
|
setEdges: rfState.setEdges,
|
|
getViewport: () => ({ x: 0, y: 0, zoom: 1 }),
|
|
screenToFlowPosition: (pos: { x: number, y: number }) => pos,
|
|
flowToScreenPosition: (pos: { x: number, y: number }) => pos,
|
|
deleteElements: vi.fn(),
|
|
addNodes: vi.fn(),
|
|
addEdges: vi.fn(),
|
|
getNode: vi.fn(),
|
|
toObject: vi.fn().mockReturnValue({ nodes: [], edges: [], viewport: { x: 0, y: 0, zoom: 1 } }),
|
|
viewportInitialized: true,
|
|
})),
|
|
|
|
useStore: vi.fn().mockReturnValue(null),
|
|
useNodes: vi.fn(() => rfState.nodes),
|
|
useEdges: vi.fn(() => rfState.edges),
|
|
useViewport: vi.fn(() => ({ x: 0, y: 0, zoom: 1 })),
|
|
useKeyPress: vi.fn(() => false),
|
|
useOnSelectionChange: vi.fn(),
|
|
useOnViewportChange: vi.fn(),
|
|
useUpdateNodeInternals: vi.fn(() => vi.fn()),
|
|
useNodeId: vi.fn(() => null),
|
|
|
|
useNodesState: vi.fn((initial: unknown[] = []) => [initial, vi.fn(), vi.fn()]),
|
|
useEdgesState: vi.fn((initial: unknown[] = []) => [initial, vi.fn(), vi.fn()]),
|
|
|
|
ReactFlowProvider: ({ children }: { children?: React.ReactNode }) =>
|
|
React.createElement(React.Fragment, null, children),
|
|
ReactFlow: ({ children }: { children?: React.ReactNode }) =>
|
|
React.createElement('div', { 'data-testid': 'reactflow-mock' }, children),
|
|
Background: () => null,
|
|
MiniMap: () => null,
|
|
Controls: () => null,
|
|
Handle: (props: Record<string, unknown>) => React.createElement('div', props),
|
|
BaseEdge: (props: Record<string, unknown>) => React.createElement('path', props),
|
|
EdgeLabelRenderer: ({ children }: { children?: React.ReactNode }) =>
|
|
React.createElement('div', null, children),
|
|
|
|
getOutgoers: vi.fn().mockReturnValue([]),
|
|
getIncomers: vi.fn().mockReturnValue([]),
|
|
getConnectedEdges: vi.fn().mockReturnValue([]),
|
|
isNode: vi.fn().mockReturnValue(true),
|
|
isEdge: vi.fn().mockReturnValue(false),
|
|
addEdge: vi.fn().mockImplementation((_e: unknown, edges: unknown[]) => edges),
|
|
applyNodeChanges: vi.fn().mockImplementation((_c: unknown[], nodes: unknown[]) => nodes),
|
|
applyEdgeChanges: vi.fn().mockImplementation((_c: unknown[], edges: unknown[]) => edges),
|
|
getBezierPath: vi.fn().mockReturnValue(['M 0 0', 0, 0]),
|
|
getSmoothStepPath: vi.fn().mockReturnValue(['M 0 0', 0, 0]),
|
|
getStraightPath: vi.fn().mockReturnValue(['M 0 0', 0, 0]),
|
|
internalsSymbol: Symbol('internals'),
|
|
}
|
|
}
|
|
|
|
export type { MockEdge, MockNode, ReactFlowMockState }
|