mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-05-03 20:51:58 +00:00
merge main into rh-test
This commit is contained in:
@@ -5,7 +5,7 @@ import { LinkConnector } from '@/lib/litegraph/src/litegraph'
|
||||
import { MovingOutputLink } from '@/lib/litegraph/src/litegraph'
|
||||
import { ToOutputRenderLink } from '@/lib/litegraph/src/litegraph'
|
||||
import { LGraphNode, LLink } from '@/lib/litegraph/src/litegraph'
|
||||
import { NodeInputSlot } from '@/lib/litegraph/src/litegraph'
|
||||
import type { NodeInputSlot } from '@/lib/litegraph/src/litegraph'
|
||||
|
||||
import { createTestSubgraph } from '../subgraph/fixtures/subgraphHelpers'
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { describe } from 'vitest'
|
||||
|
||||
import { LGraph, LiteGraph } from '@/lib/litegraph/src/litegraph'
|
||||
import { LGraph, LGraphNode, LiteGraph } from '@/lib/litegraph/src/litegraph'
|
||||
|
||||
import { test } from './fixtures/testExtensions'
|
||||
|
||||
@@ -128,6 +128,54 @@ describe('Floating Links / Reroutes', () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe('Graph Clearing and Callbacks', () => {
|
||||
test('clear() calls both node.onRemoved() and graph.onNodeRemoved()', ({
|
||||
expect
|
||||
}) => {
|
||||
const graph = new LGraph()
|
||||
|
||||
// Create test nodes with onRemoved callbacks
|
||||
const node1 = new LGraphNode('TestNode1')
|
||||
const node2 = new LGraphNode('TestNode2')
|
||||
|
||||
// Add nodes to graph
|
||||
graph.add(node1)
|
||||
graph.add(node2)
|
||||
|
||||
// Track callback invocations
|
||||
const nodeRemovedCallbacks = new Set<string>()
|
||||
const graphRemovedCallbacks = new Set<string>()
|
||||
|
||||
// Set up node.onRemoved() callbacks
|
||||
node1.onRemoved = () => {
|
||||
nodeRemovedCallbacks.add(String(node1.id))
|
||||
}
|
||||
node2.onRemoved = () => {
|
||||
nodeRemovedCallbacks.add(String(node2.id))
|
||||
}
|
||||
|
||||
// Set up graph.onNodeRemoved() callback
|
||||
graph.onNodeRemoved = (node) => {
|
||||
graphRemovedCallbacks.add(String(node.id))
|
||||
}
|
||||
|
||||
// Verify nodes are in graph before clearing
|
||||
expect(graph.nodes.length).toBe(2)
|
||||
|
||||
// Clear the graph
|
||||
graph.clear()
|
||||
|
||||
// Verify both types of callbacks were called
|
||||
expect(nodeRemovedCallbacks).toContain(String(node1.id))
|
||||
expect(nodeRemovedCallbacks).toContain(String(node2.id))
|
||||
expect(graphRemovedCallbacks).toContain(String(node1.id))
|
||||
expect(graphRemovedCallbacks).toContain(String(node2.id))
|
||||
|
||||
// Verify nodes were actually removed
|
||||
expect(graph.nodes.length).toBe(0)
|
||||
})
|
||||
})
|
||||
|
||||
describe('Legacy LGraph Compatibility Layer', () => {
|
||||
test('can be extended via prototype', ({ expect, minimalGraph }) => {
|
||||
// @ts-expect-error Should always be an error.
|
||||
|
||||
@@ -621,39 +621,10 @@ describe('LGraphNode', () => {
|
||||
expect(node.getInputSlotPos(inputSlot)).toEqual([expectedX, expectedY])
|
||||
delete (node.constructor as any).slot_start_y
|
||||
})
|
||||
})
|
||||
|
||||
describe('getInputPos', () => {
|
||||
test('should call getInputSlotPos with the correct input slot from inputs array', () => {
|
||||
const input0: INodeInputSlot = {
|
||||
name: 'in0',
|
||||
type: 'string',
|
||||
link: null,
|
||||
boundingRect: new Float32Array([0, 0, 0, 0])
|
||||
}
|
||||
const input1: INodeInputSlot = {
|
||||
name: 'in1',
|
||||
type: 'number',
|
||||
link: null,
|
||||
boundingRect: new Float32Array([0, 0, 0, 0]),
|
||||
pos: [5, 45]
|
||||
}
|
||||
node.inputs = [input0, input1]
|
||||
const spy = vi.spyOn(node, 'getInputSlotPos')
|
||||
node.getInputPos(1)
|
||||
expect(spy).toHaveBeenCalledWith(input1)
|
||||
const expectedPos: Point = [100 + 5, 200 + 45]
|
||||
expect(node.getInputPos(1)).toEqual(expectedPos)
|
||||
spy.mockClear()
|
||||
node.getInputPos(0)
|
||||
expect(spy).toHaveBeenCalledWith(input0)
|
||||
const slotIndex = 0
|
||||
const nodeOffsetY = (node.constructor as any).slot_start_y || 0
|
||||
const expectedDefaultY =
|
||||
200 + (slotIndex + 0.7) * LiteGraph.NODE_SLOT_HEIGHT + nodeOffsetY
|
||||
const expectedDefaultX = 100 + LiteGraph.NODE_SLOT_HEIGHT * 0.5
|
||||
expect(node.getInputPos(0)).toEqual([expectedDefaultX, expectedDefaultY])
|
||||
spy.mockRestore()
|
||||
test('should not overwrite onMouseDown prototype', () => {
|
||||
expect(Object.prototype.hasOwnProperty.call(node, 'onMouseDown')).toEqual(
|
||||
false
|
||||
)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { describe, expect, it, vi } from 'vitest'
|
||||
|
||||
import { LGraphButton } from '@/lib/litegraph/src/litegraph'
|
||||
import { LGraphCanvas } from '@/lib/litegraph/src/litegraph'
|
||||
import type { LGraphCanvas } from '@/lib/litegraph/src/litegraph'
|
||||
import { LGraphNode } from '@/lib/litegraph/src/litegraph'
|
||||
|
||||
describe('LGraphNode Title Buttons', () => {
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
// TODO: Fix these tests after migration
|
||||
import { afterEach, describe, expect, vi } from 'vitest'
|
||||
|
||||
import type { LGraph, Reroute } from '@/lib/litegraph/src/litegraph'
|
||||
import {
|
||||
type CanvasPointerEvent,
|
||||
LGraph,
|
||||
LGraphNode,
|
||||
LLink,
|
||||
LinkConnector,
|
||||
Reroute,
|
||||
type RerouteId
|
||||
} from '@/lib/litegraph/src/litegraph'
|
||||
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
import { describe, expect, it } from 'vitest'
|
||||
|
||||
import { INodeInputSlot, INodeOutputSlot } from '@/lib/litegraph/src/litegraph'
|
||||
import type {
|
||||
INodeInputSlot,
|
||||
INodeOutputSlot
|
||||
} from '@/lib/litegraph/src/litegraph'
|
||||
import {
|
||||
inputAsSerialisable,
|
||||
outputAsSerialisable
|
||||
|
||||
@@ -62,6 +62,7 @@ LGraph {
|
||||
"bgcolor": undefined,
|
||||
"block_delete": undefined,
|
||||
"boxcolor": undefined,
|
||||
"changeTracker": undefined,
|
||||
"clip_area": undefined,
|
||||
"clonable": undefined,
|
||||
"color": undefined,
|
||||
@@ -133,6 +134,7 @@ LGraph {
|
||||
"bgcolor": undefined,
|
||||
"block_delete": undefined,
|
||||
"boxcolor": undefined,
|
||||
"changeTracker": undefined,
|
||||
"clip_area": undefined,
|
||||
"clonable": undefined,
|
||||
"color": undefined,
|
||||
@@ -205,6 +207,7 @@ LGraph {
|
||||
"bgcolor": undefined,
|
||||
"block_delete": undefined,
|
||||
"boxcolor": undefined,
|
||||
"changeTracker": undefined,
|
||||
"clip_area": undefined,
|
||||
"clonable": undefined,
|
||||
"color": undefined,
|
||||
|
||||
@@ -102,16 +102,7 @@ LiteGraphGlobal {
|
||||
"Reroute": [Function],
|
||||
"SPLINE_LINK": 2,
|
||||
"STRAIGHT_LINK": 0,
|
||||
"SlotDirection": {
|
||||
"1": "Up",
|
||||
"2": "Down",
|
||||
"3": "Left",
|
||||
"4": "Right",
|
||||
"Down": 2,
|
||||
"Left": 3,
|
||||
"Right": 4,
|
||||
"Up": 1,
|
||||
},
|
||||
"SlotDirection": {},
|
||||
"SlotShape": {
|
||||
"1": "Box",
|
||||
"3": "Circle",
|
||||
@@ -164,9 +155,11 @@ LiteGraphGlobal {
|
||||
"do_add_triggers_slots": false,
|
||||
"highlight_selected_group": true,
|
||||
"isInsideRectangle": [Function],
|
||||
"leftMouseClickBehavior": "panning",
|
||||
"macGesturesRequireMac": true,
|
||||
"macTrackpadGestures": false,
|
||||
"middle_click_slot_add_default_node": false,
|
||||
"mouseWheelScroll": "panning",
|
||||
"node_box_coloured_by_mode": false,
|
||||
"node_box_coloured_when_on": false,
|
||||
"node_images_path": "",
|
||||
@@ -199,5 +192,6 @@ LiteGraphGlobal {
|
||||
"truncateWidgetValuesFirst": false,
|
||||
"use_uuids": false,
|
||||
"uuidv4": [Function],
|
||||
"vueNodesMode": false,
|
||||
}
|
||||
`;
|
||||
|
||||
@@ -7,10 +7,10 @@ import type {
|
||||
SerialisableGraph
|
||||
} from '@/lib/litegraph/src/types/serialisation'
|
||||
|
||||
import floatingBranch from './assets/floatingBranch.json'
|
||||
import floatingLink from './assets/floatingLink.json'
|
||||
import linkedNodes from './assets/linkedNodes.json'
|
||||
import reroutesComplex from './assets/reroutesComplex.json'
|
||||
import floatingBranch from './assets/floatingBranch.json' with { type: 'json' }
|
||||
import floatingLink from './assets/floatingLink.json' with { type: 'json' }
|
||||
import linkedNodes from './assets/linkedNodes.json' with { type: 'json' }
|
||||
import reroutesComplex from './assets/reroutesComplex.json' with { type: 'json' }
|
||||
import {
|
||||
basicSerialisableGraph,
|
||||
minimalSerialisableGraph,
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
// TODO: Fix these tests after migration
|
||||
import { assert, describe, expect, it } from 'vitest'
|
||||
|
||||
import type { LGraph } from '@/lib/litegraph/src/litegraph'
|
||||
import {
|
||||
ISlotType,
|
||||
LGraph,
|
||||
type ISlotType,
|
||||
LGraphGroup,
|
||||
LGraphNode,
|
||||
LiteGraph
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
import { describe, expect, it, vi } from 'vitest'
|
||||
|
||||
import { LGraphButton } from '@/lib/litegraph/src/litegraph'
|
||||
import { LGraphCanvas } from '@/lib/litegraph/src/litegraph'
|
||||
import type { LGraphCanvas } from '@/lib/litegraph/src/litegraph'
|
||||
|
||||
import {
|
||||
createTestSubgraph,
|
||||
|
||||
@@ -5,8 +5,8 @@ import { LinkConnector } from '@/lib/litegraph/src/litegraph'
|
||||
import { ToInputFromIoNodeLink } from '@/lib/litegraph/src/litegraph'
|
||||
import { SUBGRAPH_INPUT_ID } from '@/lib/litegraph/src/litegraph'
|
||||
import { LGraphNode, type LinkNetwork } from '@/lib/litegraph/src/litegraph'
|
||||
import { NodeInputSlot } from '@/lib/litegraph/src/litegraph'
|
||||
import { NodeOutputSlot } from '@/lib/litegraph/src/litegraph'
|
||||
import type { NodeInputSlot } from '@/lib/litegraph/src/litegraph'
|
||||
import type { NodeOutputSlot } from '@/lib/litegraph/src/litegraph'
|
||||
import {
|
||||
isSubgraphInput,
|
||||
isSubgraphOutput
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
// TODO: Fix these tests after migration
|
||||
import { describe, expect, it } from 'vitest'
|
||||
|
||||
import type { ISlotType } from '@/lib/litegraph/src/litegraph'
|
||||
import { LGraphNode, Subgraph } from '@/lib/litegraph/src/litegraph'
|
||||
import type { ISlotType, Subgraph } from '@/lib/litegraph/src/litegraph'
|
||||
import { LGraphNode } from '@/lib/litegraph/src/litegraph'
|
||||
import type { TWidgetType } from '@/lib/litegraph/src/litegraph'
|
||||
import { BaseWidget } from '@/lib/litegraph/src/litegraph'
|
||||
|
||||
|
||||
@@ -5,8 +5,9 @@
|
||||
* in their test files. Each fixture provides a clean, pre-configured subgraph
|
||||
* setup for different testing scenarios.
|
||||
*/
|
||||
import { LGraph, Subgraph } from '@/lib/litegraph/src/litegraph'
|
||||
import { SubgraphNode } from '@/lib/litegraph/src/subgraph/SubgraphNode'
|
||||
import type { Subgraph } from '@/lib/litegraph/src/litegraph'
|
||||
import { LGraph } from '@/lib/litegraph/src/litegraph'
|
||||
import type { SubgraphNode } from '@/lib/litegraph/src/subgraph/SubgraphNode'
|
||||
|
||||
import { test } from '../../core/fixtures/testExtensions'
|
||||
import {
|
||||
@@ -16,7 +17,7 @@ import {
|
||||
createTestSubgraphNode
|
||||
} from './subgraphHelpers'
|
||||
|
||||
export interface SubgraphFixtures {
|
||||
interface SubgraphFixtures {
|
||||
/** A minimal subgraph with no inputs, outputs, or nodes */
|
||||
emptySubgraph: Subgraph
|
||||
|
||||
@@ -169,140 +170,3 @@ export const subgraphTest = test.extend<SubgraphFixtures>({
|
||||
capture.cleanup()
|
||||
}
|
||||
})
|
||||
|
||||
/**
|
||||
* Fixtures that test edge cases and error conditions.
|
||||
* These may leave the system in an invalid state and should be used carefully.
|
||||
*/
|
||||
export interface EdgeCaseFixtures {
|
||||
/** Subgraph with circular references (for testing recursion detection) */
|
||||
circularSubgraph: {
|
||||
rootGraph: LGraph
|
||||
subgraphA: Subgraph
|
||||
subgraphB: Subgraph
|
||||
nodeA: SubgraphNode
|
||||
nodeB: SubgraphNode
|
||||
}
|
||||
|
||||
/** Deeply nested subgraphs approaching the theoretical limit */
|
||||
deeplyNestedSubgraph: ReturnType<typeof createNestedSubgraphs>
|
||||
|
||||
/** Subgraph with maximum inputs and outputs */
|
||||
maxIOSubgraph: Subgraph
|
||||
}
|
||||
|
||||
/**
|
||||
* Test with edge case fixtures. Use sparingly and with caution.
|
||||
* These tests may intentionally create invalid states.
|
||||
*/
|
||||
export const edgeCaseTest = subgraphTest.extend<EdgeCaseFixtures>({
|
||||
// @ts-expect-error TODO: Fix after merge - fixture use parameter type
|
||||
// eslint-disable-next-line no-empty-pattern
|
||||
circularSubgraph: async ({}, use: (value: unknown) => Promise<void>) => {
|
||||
const rootGraph = new LGraph()
|
||||
|
||||
// Create two subgraphs that will reference each other
|
||||
const subgraphA = createTestSubgraph({
|
||||
name: 'Subgraph A',
|
||||
inputs: [{ name: 'input', type: '*' }],
|
||||
outputs: [{ name: 'output', type: '*' }]
|
||||
})
|
||||
|
||||
const subgraphB = createTestSubgraph({
|
||||
name: 'Subgraph B',
|
||||
inputs: [{ name: 'input', type: '*' }],
|
||||
outputs: [{ name: 'output', type: '*' }]
|
||||
})
|
||||
|
||||
// Create instances (this doesn't create circular refs by itself)
|
||||
const nodeA = createTestSubgraphNode(subgraphA, { pos: [100, 100] })
|
||||
const nodeB = createTestSubgraphNode(subgraphB, { pos: [300, 100] })
|
||||
|
||||
// Add nodes to root graph
|
||||
rootGraph.add(nodeA)
|
||||
rootGraph.add(nodeB)
|
||||
|
||||
await use({
|
||||
rootGraph,
|
||||
subgraphA,
|
||||
subgraphB,
|
||||
nodeA,
|
||||
nodeB
|
||||
})
|
||||
},
|
||||
|
||||
// @ts-expect-error TODO: Fix after merge - fixture use parameter type
|
||||
// eslint-disable-next-line no-empty-pattern
|
||||
deeplyNestedSubgraph: async ({}, use: (value: unknown) => Promise<void>) => {
|
||||
// Create a very deep nesting structure (but not exceeding MAX_NESTED_SUBGRAPHS)
|
||||
const nested = createNestedSubgraphs({
|
||||
depth: 50, // Deep but reasonable
|
||||
nodesPerLevel: 1,
|
||||
inputsPerSubgraph: 1,
|
||||
outputsPerSubgraph: 1
|
||||
})
|
||||
|
||||
await use(nested)
|
||||
},
|
||||
|
||||
// @ts-expect-error TODO: Fix after merge - fixture use parameter type
|
||||
// eslint-disable-next-line no-empty-pattern
|
||||
maxIOSubgraph: async ({}, use: (value: unknown) => Promise<void>) => {
|
||||
// Create a subgraph with many inputs and outputs
|
||||
const inputs = Array.from({ length: 20 }, (_, i) => ({
|
||||
name: `input_${i}`,
|
||||
type: i % 2 === 0 ? 'number' : ('string' as const)
|
||||
}))
|
||||
|
||||
const outputs = Array.from({ length: 20 }, (_, i) => ({
|
||||
name: `output_${i}`,
|
||||
type: i % 2 === 0 ? 'number' : ('string' as const)
|
||||
}))
|
||||
|
||||
const subgraph = createTestSubgraph({
|
||||
name: 'Max IO Subgraph',
|
||||
inputs,
|
||||
outputs,
|
||||
nodeCount: 10
|
||||
})
|
||||
|
||||
await use(subgraph)
|
||||
}
|
||||
})
|
||||
|
||||
/**
|
||||
* Helper to verify fixture integrity.
|
||||
* Use this in tests to ensure fixtures are properly set up.
|
||||
*/
|
||||
export function verifyFixtureIntegrity<T extends Record<string, unknown>>(
|
||||
fixture: T,
|
||||
expectedProperties: (keyof T)[]
|
||||
): void {
|
||||
for (const prop of expectedProperties) {
|
||||
if (!(prop in fixture)) {
|
||||
throw new Error(`Fixture missing required property: ${String(prop)}`)
|
||||
}
|
||||
if (fixture[prop] === undefined || fixture[prop] === null) {
|
||||
throw new Error(`Fixture property ${String(prop)} is null or undefined`)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a snapshot-friendly representation of a subgraph for testing.
|
||||
* Useful for serialization tests and regression detection.
|
||||
*/
|
||||
export function createSubgraphSnapshot(subgraph: Subgraph) {
|
||||
return {
|
||||
id: subgraph.id,
|
||||
name: subgraph.name,
|
||||
inputCount: subgraph.inputs.length,
|
||||
outputCount: subgraph.outputs.length,
|
||||
nodeCount: subgraph.nodes.length,
|
||||
linkCount: subgraph.links.size,
|
||||
inputs: subgraph.inputs.map((i) => ({ name: i.name, type: i.type })),
|
||||
outputs: subgraph.outputs.map((o) => ({ name: o.name, type: o.type })),
|
||||
hasInputNode: !!subgraph.inputNode,
|
||||
hasOutputNode: !!subgraph.outputNode
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ import type {
|
||||
import type { UUID } from '@/lib/litegraph/src/utils/uuid'
|
||||
import { createUuidv4 } from '@/lib/litegraph/src/utils/uuid'
|
||||
|
||||
export interface TestSubgraphOptions {
|
||||
interface TestSubgraphOptions {
|
||||
id?: UUID
|
||||
name?: string
|
||||
nodeCount?: number
|
||||
@@ -27,20 +27,20 @@ export interface TestSubgraphOptions {
|
||||
outputs?: Array<{ name: string; type: ISlotType }>
|
||||
}
|
||||
|
||||
export interface TestSubgraphNodeOptions {
|
||||
interface TestSubgraphNodeOptions {
|
||||
id?: NodeId
|
||||
pos?: [number, number]
|
||||
size?: [number, number]
|
||||
}
|
||||
|
||||
export interface NestedSubgraphOptions {
|
||||
interface NestedSubgraphOptions {
|
||||
depth?: number
|
||||
nodesPerLevel?: number
|
||||
inputsPerSubgraph?: number
|
||||
outputsPerSubgraph?: number
|
||||
}
|
||||
|
||||
export interface SubgraphStructureExpectation {
|
||||
interface SubgraphStructureExpectation {
|
||||
inputCount?: number
|
||||
outputCount?: number
|
||||
nodeCount?: number
|
||||
@@ -49,7 +49,7 @@ export interface SubgraphStructureExpectation {
|
||||
hasOutputNode?: boolean
|
||||
}
|
||||
|
||||
export interface CapturedEvent<T = unknown> {
|
||||
interface CapturedEvent<T = unknown> {
|
||||
type: string
|
||||
detail: T
|
||||
timestamp: number
|
||||
@@ -382,76 +382,6 @@ export function createTestSubgraphData(
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a complex subgraph with multiple nodes and connections.
|
||||
* Useful for testing realistic scenarios.
|
||||
* @param nodeCount Number of internal nodes to create
|
||||
* @returns Complex subgraph data structure
|
||||
*/
|
||||
export function createComplexSubgraphData(
|
||||
nodeCount: number = 5
|
||||
): ExportedSubgraph {
|
||||
const nodes = []
|
||||
const links: Record<
|
||||
string,
|
||||
{
|
||||
id: number
|
||||
origin_id: number
|
||||
origin_slot: number
|
||||
target_id: number
|
||||
target_slot: number
|
||||
type: string
|
||||
}
|
||||
> = {}
|
||||
|
||||
// Create internal nodes
|
||||
for (let i = 0; i < nodeCount; i++) {
|
||||
nodes.push({
|
||||
id: i + 1, // Start from 1 to avoid conflicts with IO nodes
|
||||
type: 'basic/test',
|
||||
pos: [100 + i * 150, 200],
|
||||
size: [120, 60],
|
||||
inputs: [{ name: 'in', type: '*', link: null }],
|
||||
outputs: [{ name: 'out', type: '*', links: [] }],
|
||||
properties: { value: i },
|
||||
flags: {},
|
||||
mode: 0
|
||||
})
|
||||
}
|
||||
|
||||
// Create some internal links
|
||||
for (let i = 0; i < nodeCount - 1; i++) {
|
||||
const linkId = i + 1
|
||||
links[linkId] = {
|
||||
id: linkId,
|
||||
origin_id: i + 1,
|
||||
origin_slot: 0,
|
||||
target_id: i + 2,
|
||||
target_slot: 0,
|
||||
type: '*'
|
||||
}
|
||||
}
|
||||
|
||||
return createTestSubgraphData({
|
||||
// @ts-expect-error TODO: Fix after merge - nodes parameter type
|
||||
nodes,
|
||||
// @ts-expect-error TODO: Fix after merge - links parameter type
|
||||
links,
|
||||
inputs: [
|
||||
// @ts-expect-error TODO: Fix after merge - input object type
|
||||
{ name: 'input1', type: 'number', pos: [0, 0] },
|
||||
// @ts-expect-error TODO: Fix after merge - input object type
|
||||
{ name: 'input2', type: 'string', pos: [0, 1] }
|
||||
],
|
||||
outputs: [
|
||||
// @ts-expect-error TODO: Fix after merge - output object type
|
||||
{ name: 'output1', type: 'number', pos: [0, 0] },
|
||||
// @ts-expect-error TODO: Fix after merge - output object type
|
||||
{ name: 'output2', type: 'string', pos: [0, 1] }
|
||||
]
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an event capture system for testing event sequences.
|
||||
* @param eventTarget The event target to monitor
|
||||
@@ -492,40 +422,3 @@ export function createEventCapture<T = unknown>(
|
||||
capturedEvents.filter((e) => e.type === type)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility to log subgraph structure for debugging tests.
|
||||
* @param subgraph The subgraph to inspect
|
||||
* @param label Optional label for the log output
|
||||
*/
|
||||
export function logSubgraphStructure(
|
||||
subgraph: Subgraph,
|
||||
label: string = 'Subgraph'
|
||||
): void {
|
||||
console.log(`\n=== ${label} Structure ===`)
|
||||
console.log(`Name: ${subgraph.name}`)
|
||||
console.log(`ID: ${subgraph.id}`)
|
||||
console.log(`Inputs: ${subgraph.inputs.length}`)
|
||||
console.log(`Outputs: ${subgraph.outputs.length}`)
|
||||
console.log(`Nodes: ${subgraph.nodes.length}`)
|
||||
console.log(`Links: ${subgraph.links.size}`)
|
||||
|
||||
if (subgraph.inputs.length > 0) {
|
||||
console.log(
|
||||
'Input details:',
|
||||
subgraph.inputs.map((i) => ({ name: i.name, type: i.type }))
|
||||
)
|
||||
}
|
||||
|
||||
if (subgraph.outputs.length > 0) {
|
||||
console.log(
|
||||
'Output details:',
|
||||
subgraph.outputs.map((o) => ({ name: o.name, type: o.type }))
|
||||
)
|
||||
}
|
||||
|
||||
console.log('========================\n')
|
||||
}
|
||||
|
||||
// Re-export expect from vitest for convenience
|
||||
export { expect } from 'vitest'
|
||||
|
||||
Reference in New Issue
Block a user