mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-05-14 01:36:14 +00:00
## Summary Harden subgraph test coverage: remove low-value change-detector tests, consolidate fixtures, add behavioral coverage, and fix test infrastructure issues. Includes minor production code corrections discovered during test hardening. ## Changes - **What**: Comprehensive subgraph test suite overhaul across 6 phases - Removed change-detector tests and redundant assertions - Consolidated fixture helpers into `subgraphHelpers.ts` / `subgraphFixtures.ts` - Added Pinia initialization and fixture reset to all test files - Fixed barrel import violations (circular dependency prevention) - Added behavioral coverage for slot connections, events, edge cases - Added E2E helper and smoke test for subgraph promotion - Exported `SubgraphSlotBase` from litegraph barrel for test access - **Production code changes** (minor correctness fixes found during testing): - `resolveSubgraphInputLink.ts`: iterate forward (first-connected-wins) to match `_resolveLinkedPromotionBySubgraphInput` - `promotionSchema.ts`: return `[]` instead of throwing on invalid `proxyWidgets`; console.warn always (not DEV-only) - `LGraph.ts`: disconnect-after-veto ordering fix - `litegraph.ts`: barrel export swap for `SubgraphSlotBase` - **Stats**: 349 tests passing, 0 skipped across 26 test files ## Review Focus - Tests that merely asserted default property values were deleted (change detectors) - Fixture state is now reset via `resetSubgraphFixtureState()` in `beforeEach` - All imports use `@/lib/litegraph/src/litegraph` barrel to avoid circular deps - Production changes are small and directly motivated by test findings --------- Co-authored-by: Amp <amp@ampcode.com> Co-authored-by: bymyself <cbyrne@comfy.org>
147 lines
4.9 KiB
TypeScript
147 lines
4.9 KiB
TypeScript
/**
|
|
* Core Subgraph Tests
|
|
*
|
|
* This file implements fundamental tests for the Subgraph class that establish
|
|
* patterns for the rest of the testing team. These tests cover construction
|
|
* and basic I/O management.
|
|
*/
|
|
import { createTestingPinia } from '@pinia/testing'
|
|
import { setActivePinia } from 'pinia'
|
|
import { beforeEach, describe, expect, it } from 'vitest'
|
|
|
|
import type { LGraph } from '@/lib/litegraph/src/litegraph'
|
|
import { createUuidv4, Subgraph } from '@/lib/litegraph/src/litegraph'
|
|
|
|
import { subgraphTest } from './__fixtures__/subgraphFixtures'
|
|
import {
|
|
assertSubgraphStructure,
|
|
createTestSubgraph,
|
|
createTestSubgraphData,
|
|
resetSubgraphFixtureState
|
|
} from './__fixtures__/subgraphHelpers'
|
|
|
|
beforeEach(() => {
|
|
setActivePinia(createTestingPinia({ stubActions: false }))
|
|
resetSubgraphFixtureState()
|
|
})
|
|
|
|
describe('Subgraph Construction', () => {
|
|
it('should create a subgraph with minimal data', () => {
|
|
const subgraph = createTestSubgraph()
|
|
|
|
assertSubgraphStructure(subgraph, {
|
|
inputCount: 0,
|
|
outputCount: 0,
|
|
nodeCount: 0,
|
|
name: 'Test Subgraph'
|
|
})
|
|
|
|
expect(subgraph.id).toMatch(
|
|
/^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i
|
|
)
|
|
expect(subgraph.inputNode).toBeDefined()
|
|
expect(subgraph.outputNode).toBeDefined()
|
|
expect(subgraph.inputNode.id).toBe(-10)
|
|
expect(subgraph.outputNode.id).toBe(-20)
|
|
})
|
|
|
|
it('should require a root graph', () => {
|
|
const subgraphData = createTestSubgraphData()
|
|
const createWithoutRoot = () =>
|
|
new Subgraph(null as unknown as LGraph, subgraphData)
|
|
|
|
expect(createWithoutRoot).toThrow('Root graph is required')
|
|
})
|
|
|
|
it('should accept custom name and ID', () => {
|
|
const customId = createUuidv4()
|
|
const customName = 'My Custom Subgraph'
|
|
|
|
const subgraph = createTestSubgraph({
|
|
id: customId,
|
|
name: customName
|
|
})
|
|
|
|
expect(subgraph.id).toBe(customId)
|
|
expect(subgraph.name).toBe(customName)
|
|
})
|
|
})
|
|
|
|
describe('Subgraph Input/Output Management', () => {
|
|
subgraphTest('should add a single input', ({ emptySubgraph }) => {
|
|
const input = emptySubgraph.addInput('test_input', 'number')
|
|
|
|
expect(emptySubgraph.inputs).toHaveLength(1)
|
|
expect(input.name).toBe('test_input')
|
|
expect(input.type).toBe('number')
|
|
expect(emptySubgraph.inputs.indexOf(input)).toBe(0)
|
|
})
|
|
|
|
subgraphTest('should add a single output', ({ emptySubgraph }) => {
|
|
const output = emptySubgraph.addOutput('test_output', 'string')
|
|
|
|
expect(emptySubgraph.outputs).toHaveLength(1)
|
|
expect(output.name).toBe('test_output')
|
|
expect(output.type).toBe('string')
|
|
expect(emptySubgraph.outputs.indexOf(output)).toBe(0)
|
|
})
|
|
|
|
subgraphTest(
|
|
'should maintain correct indices when adding multiple inputs',
|
|
({ emptySubgraph }) => {
|
|
const input1 = emptySubgraph.addInput('input_1', 'number')
|
|
const input2 = emptySubgraph.addInput('input_2', 'string')
|
|
const input3 = emptySubgraph.addInput('input_3', 'boolean')
|
|
|
|
expect(emptySubgraph.inputs.indexOf(input1)).toBe(0)
|
|
expect(emptySubgraph.inputs.indexOf(input2)).toBe(1)
|
|
expect(emptySubgraph.inputs.indexOf(input3)).toBe(2)
|
|
expect(emptySubgraph.inputs).toHaveLength(3)
|
|
}
|
|
)
|
|
|
|
subgraphTest(
|
|
'should maintain correct indices when adding multiple outputs',
|
|
({ emptySubgraph }) => {
|
|
const output1 = emptySubgraph.addOutput('output_1', 'number')
|
|
const output2 = emptySubgraph.addOutput('output_2', 'string')
|
|
const output3 = emptySubgraph.addOutput('output_3', 'boolean')
|
|
|
|
expect(emptySubgraph.outputs.indexOf(output1)).toBe(0)
|
|
expect(emptySubgraph.outputs.indexOf(output2)).toBe(1)
|
|
expect(emptySubgraph.outputs.indexOf(output3)).toBe(2)
|
|
expect(emptySubgraph.outputs).toHaveLength(3)
|
|
}
|
|
)
|
|
|
|
subgraphTest('should remove inputs correctly', ({ simpleSubgraph }) => {
|
|
// Add a second input first
|
|
simpleSubgraph.addInput('second_input', 'string')
|
|
expect(simpleSubgraph.inputs).toHaveLength(2)
|
|
|
|
// Remove the first input
|
|
const firstInput = simpleSubgraph.inputs[0]
|
|
simpleSubgraph.removeInput(firstInput)
|
|
|
|
expect(simpleSubgraph.inputs).toHaveLength(1)
|
|
expect(simpleSubgraph.inputs[0].name).toBe('second_input')
|
|
// Verify it's at index 0 in the array
|
|
expect(simpleSubgraph.inputs.indexOf(simpleSubgraph.inputs[0])).toBe(0)
|
|
})
|
|
|
|
subgraphTest('should remove outputs correctly', ({ simpleSubgraph }) => {
|
|
// Add a second output first
|
|
simpleSubgraph.addOutput('second_output', 'string')
|
|
expect(simpleSubgraph.outputs).toHaveLength(2)
|
|
|
|
// Remove the first output
|
|
const firstOutput = simpleSubgraph.outputs[0]
|
|
simpleSubgraph.removeOutput(firstOutput)
|
|
|
|
expect(simpleSubgraph.outputs).toHaveLength(1)
|
|
expect(simpleSubgraph.outputs[0].name).toBe('second_output')
|
|
// Verify it's at index 0 in the array
|
|
expect(simpleSubgraph.outputs.indexOf(simpleSubgraph.outputs[0])).toBe(0)
|
|
})
|
|
})
|