Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 31 additions & 3 deletions src/composables/graph/useGraphNodeManager.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,9 @@ describe('Nested promoted widget mapping', () => {
})

it('maps store identity to deepest concrete widget for two-layer promotions', () => {
const store = usePromotionStore()

// Inner layer: subgraphA contains innerNode with a combo widget
const subgraphA = createTestSubgraph({
inputs: [{ name: 'a_input', type: '*' }]
})
Expand All @@ -287,23 +290,48 @@ describe('Nested promoted widget mapping', () => {
innerNode.addWidget('combo', 'picker', 'a', () => undefined, {
values: ['a', 'b']
})
innerInput.widget = { name: 'picker' }
subgraphA.add(innerNode)
// Connect without .widget so SubgraphInput creates a real link
subgraphA.inputNode.slots[0].connect(innerInput, innerNode)
innerInput.widget = { name: 'picker' }

const subgraphNodeA = createTestSubgraphNode(subgraphA, { id: 11 })

// Outer layer: subgraphB contains subgraphNodeA
const subgraphB = createTestSubgraph({
inputs: [{ name: 'b_input', type: '*' }]
})
const subgraphNodeA = createTestSubgraphNode(subgraphA, { id: 11 })
subgraphB.add(subgraphNodeA)
subgraphNodeA._internalConfigureAfterSlots()
// Connect without .widget so SubgraphInput creates a real link
const savedWidget = subgraphNodeA.inputs[0].widget
delete (subgraphNodeA.inputs[0] as unknown as Record<string, unknown>)
.widget
subgraphB.inputNode.slots[0].connect(subgraphNodeA.inputs[0], subgraphNodeA)
subgraphNodeA.inputs[0].widget = savedWidget

// Root: graph contains subgraphNodeB
const subgraphNodeB = createTestSubgraphNode(subgraphB, { id: 22 })
const graph = subgraphNodeB.graph as LGraph
graph.add(subgraphNodeB)

// Register promotions using rootGraph IDs as seen at lookup time:
// - subgraphNodeA.rootGraph resolves through subgraphB to its rootGraph
// - subgraphNodeB.rootGraph is the top-level graph
store.promote(
subgraphNodeA.rootGraph.id,
subgraphNodeA.id,
String(innerNode.id),
'picker'
)
// Outer promotion references the inner promoted view's widget name ('picker'),
// not the subgraph input name ('a_input')
store.promote(
subgraphNodeB.rootGraph.id,
subgraphNodeB.id,
String(subgraphNodeA.id),
'picker'
)

const { vueNodeData } = useGraphNodeManager(graph)
const nodeData = vueNodeData.get(String(subgraphNodeB.id))
const mappedWidget = nodeData?.widgets?.[0]
Expand Down
1 change: 0 additions & 1 deletion src/composables/graph/useGraphNodeManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,6 @@ function safeWidgetMapper(

const promotedInputName = node.inputs?.find((input) => {
if (input.name === widget.name) return true
if (input._widget === widget) return true
return false
})?.name
const displayName = promotedInputName ?? widget.name
Expand Down
Loading
Loading