Skip to content

Commit ee3f0a8

Browse files
committed
test: strengthen ECS migration coverage
Amp-Thread-ID: https://ampcode.com/threads/T-01a00769-0047-7184-b6ca-2bc56dcd5f71
1 parent 2ff65d0 commit ee3f0a8

6 files changed

Lines changed: 69 additions & 37 deletions

File tree

src/lib/litegraph/src/__fixtures__/nodeHelpers.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,13 @@ export function createTestWidgetNode(graph: LGraph | Subgraph): LGraphNode {
4747
}
4848
}
4949
LiteGraph.registered_node_types[WIDGET_NODE_TYPE] = WidgetTestNode
50+
onTestFinished(() => {
51+
if (
52+
LiteGraph.registered_node_types[WIDGET_NODE_TYPE] === WidgetTestNode
53+
) {
54+
delete LiteGraph.registered_node_types[WIDGET_NODE_TYPE]
55+
}
56+
})
5057
}
5158
const node = LiteGraph.createNode(WIDGET_NODE_TYPE)
5259
if (!node) throw new Error('Failed to create widget node')

src/lib/litegraph/src/node/slotUtils.test.ts

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,21 +5,23 @@ import { beforeEach, describe, expect, it } from 'vitest'
55
import type { INodeOutputSlot } from '@/lib/litegraph/src/interfaces'
66
import type { IWidget } from '@/lib/litegraph/src/litegraph'
77
import { LGraph, LGraphNode } from '@/lib/litegraph/src/litegraph'
8+
import { toLinkId } from '@/types/linkId'
89

910
import { outputAsSerialisable } from './slotUtils'
1011

1112
type OutputSlotParam = INodeOutputSlot & { widget?: IWidget }
1213

13-
function createConnectedGraph(targetCount: number) {
14+
function createConnectedGraph(linkIds: number[]) {
1415
const graph = new LGraph()
1516
const source = new LGraphNode('Source')
1617
source.addOutput('out', 'number')
1718
graph.add(source)
1819

19-
for (let i = 0; i < targetCount; i++) {
20+
for (const [i, linkId] of linkIds.entries()) {
2021
const target = new LGraphNode(`Target${i}`)
2122
target.addInput('in', 'number')
2223
graph.add(target)
24+
graph.state.lastLinkId = toLinkId(linkId - 1)
2325
source.connect(0, target, 0)
2426
}
2527

@@ -30,20 +32,22 @@ describe('outputAsSerialisable', () => {
3032
beforeEach(() => setActivePinia(createTestingPinia({ stubActions: false })))
3133

3234
it('serialises the links leaving the slot, ascending by id', () => {
33-
const { source } = createConnectedGraph(3)
35+
const { source } = createConnectedGraph([10, 2])
3436

3537
const serialised = outputAsSerialisable(
3638
source.outputs[0] as OutputSlotParam,
3739
source,
3840
0
3941
)
4042

41-
expect(serialised.links).toHaveLength(3)
42-
expect(serialised.links).toEqual([...serialised.links!].sort())
43+
expect(serialised.links).toEqual(
44+
[...serialised.links!].sort((a, b) => a - b)
45+
)
46+
expect(serialised.links).toEqual([2, 10])
4347
})
4448

4549
it('returns a snapshot unaffected by later graph changes', () => {
46-
const { source } = createConnectedGraph(2)
50+
const { source } = createConnectedGraph([1, 2])
4751

4852
const serialised = outputAsSerialisable(
4953
source.outputs[0] as OutputSlotParam,
@@ -57,7 +61,7 @@ describe('outputAsSerialisable', () => {
5761
})
5862

5963
it('serialises null when the slot has no links', () => {
60-
const { source } = createConnectedGraph(0)
64+
const { source } = createConnectedGraph([])
6165

6266
const serialised = outputAsSerialisable(
6367
source.outputs[0] as OutputSlotParam,

src/lib/litegraph/src/subgraph/__fixtures__/subgraphHelpers.test.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,28 @@ describe('enableSubgraphNodeCreation', () => {
6666
dispose()
6767

6868
expect(LiteGraph.createNode(subgraph.id)).toBeNull()
69+
70+
const laterSubgraph = rootGraph.createSubgraph(createTestSubgraphData())
71+
expect(LiteGraph.createNode(laterSubgraph.id)).toBeNull()
72+
})
73+
74+
it('only removes registrations owned by its invocation', () => {
75+
const firstRoot = createTestRootGraph()
76+
const secondRoot = createTestRootGraph()
77+
const disposeFirst = enableSubgraphNodeCreation(firstRoot)
78+
const disposeSecond = enableSubgraphNodeCreation(secondRoot)
79+
const data = createTestSubgraphData()
80+
firstRoot.createSubgraph(data)
81+
const secondSubgraph = secondRoot.createSubgraph(data)
82+
83+
disposeFirst()
84+
85+
expect(LiteGraph.createNode(data.id)).toMatchObject({
86+
subgraph: secondSubgraph
87+
})
88+
89+
disposeSecond()
90+
expect(LiteGraph.createNode(data.id)).toBeNull()
6991
})
7092
})
7193

src/lib/litegraph/src/subgraph/__fixtures__/subgraphHelpers.ts

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import {
1717
SUBGRAPH_INPUT_ID,
1818
SUBGRAPH_OUTPUT_ID
1919
} from '@/lib/litegraph/src/constants'
20+
import type { LGraphEventMap } from '@/lib/litegraph/src/infrastructure/LGraphEventMap'
2021
import type { SerializedNodeId } from '@/types/nodeId'
2122
import { toNodeId } from '@/types/nodeId'
2223
import {
@@ -60,22 +61,15 @@ function nextFixtureUuid(): UUID {
6061
export function resetSubgraphFixtureState(): void {
6162
fixtureUuidSequence = 1
6263
cleanupComplexPromotionFixtureNodeType()
63-
disposeSubgraphNodeCreation()
64-
}
65-
66-
const subgraphNodeTypesToDispose: string[] = []
67-
68-
function disposeSubgraphNodeCreation(): void {
69-
for (const type of subgraphNodeTypesToDispose) {
70-
delete LiteGraph.registered_node_types[type]
71-
}
72-
subgraphNodeTypesToDispose.length = 0
7364
}
7465

7566
export function enableSubgraphNodeCreation(rootGraph: LGraph): () => void {
76-
rootGraph.events.addEventListener('subgraph-created', (e) => {
67+
const registrations = new Map<string, typeof LGraphNode>()
68+
const listener = (
69+
e: CustomEvent<LGraphEventMap['subgraph-created']>
70+
): void => {
7771
const { subgraph } = e.detail
78-
LiteGraph.registered_node_types[subgraph.id] = class extends SubgraphNode {
72+
class TestSubgraphNode extends SubgraphNode {
7973
constructor() {
8074
super(rootGraph, subgraph, {
8175
id: -1,
@@ -90,9 +84,19 @@ export function enableSubgraphNodeCreation(rootGraph: LGraph): () => void {
9084
})
9185
}
9286
}
93-
subgraphNodeTypesToDispose.push(subgraph.id)
94-
})
95-
return disposeSubgraphNodeCreation
87+
LiteGraph.registered_node_types[subgraph.id] = TestSubgraphNode
88+
registrations.set(subgraph.id, TestSubgraphNode)
89+
}
90+
rootGraph.events.addEventListener('subgraph-created', listener)
91+
92+
return () => {
93+
rootGraph.events.removeEventListener('subgraph-created', listener)
94+
for (const [type, constructor] of registrations) {
95+
if (LiteGraph.registered_node_types[type] === constructor) {
96+
delete LiteGraph.registered_node_types[type]
97+
}
98+
}
99+
}
96100
}
97101

98102
export function createTestRootGraph(id: UUID = nextFixtureUuid()): LGraph {

src/renderer/core/canvas/litegraph/notifyLayoutChanges.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ describe('notifyLayoutChanges', () => {
8484

8585
resize(context)
8686
await vi.waitFor(() => expect(onResize).toHaveBeenCalled())
87+
expect([...onResize.mock.calls[0][0]]).toEqual([300, 200])
8788
})
8889

8990
it('leaves onResize alone when a bounds batch only moves', async () => {

src/systems/badgeSystem.pricing.test.ts

Lines changed: 9 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,27 +4,15 @@ import { beforeEach, describe, expect, it, vi } from 'vitest'
44

55
import { LGraph, LGraphNode } from '@/lib/litegraph/src/litegraph'
66
import { useLinkStore } from '@/stores/linkStore'
7-
import {
8-
graphScopeOf,
9-
toOwningGraphId,
10-
toRootGraphId
11-
} from '@/types/graphScopeId'
7+
import { toOwningGraphId, toRootGraphId } from '@/types/graphScopeId'
128
import { toLinkId } from '@/types/linkId'
139
import { toNodeId } from '@/types/nodeId'
1410
import type { UUID } from '@/utils/uuid'
1511

1612
import { nodeBadges } from './badgeSystem'
1713

18-
const getNodeDisplayPrice = vi.fn((node: LGraphNode) => {
19-
const graph = node.graph
20-
if (!graph) return '$disconnected'
21-
const connected = node.inputs.some(
22-
(input, index) =>
23-
(input.name === 'image' || input.name?.startsWith('ref_images.')) &&
24-
useLinkStore().isInputSlotConnected(graphScopeOf(graph), node.id, index)
25-
)
26-
return connected ? '$connected' : '$disconnected'
27-
})
14+
let displayPrice = '$disconnected'
15+
const getNodeDisplayPrice = vi.fn(() => displayPrice)
2816

2917
vi.mock('@/composables/node/useNodePricing', () => {
3018
return {
@@ -59,6 +47,7 @@ function scopeOf(id: string) {
5947
describe('badge derivation pricing input connectivity', () => {
6048
beforeEach(() => {
6149
setActivePinia(createTestingPinia({ stubActions: false }))
50+
displayPrice = '$disconnected'
6251
getNodeDisplayPrice.mockClear()
6352
})
6453

@@ -89,9 +78,11 @@ describe('badge derivation pricing input connectivity', () => {
8978
const { node } = setup(['image', 'other'])
9079
expect(nodeBadges(node).at(-1)?.text).toBe('$disconnected')
9180

81+
displayPrice = '$connected'
9282
connect(0, 1)
9383
expect(nodeBadges(node).at(-1)?.text).toBe('$connected')
9484

85+
displayPrice = '$disconnected'
9586
const linkStore = useLinkStore()
9687
const topology = linkStore.getInputSlotLink(
9788
scopeOf(graphId),
@@ -107,6 +98,7 @@ describe('badge derivation pricing input connectivity', () => {
10798

10899
expect(nodeBadges(node).at(-1)?.text).toBe('$disconnected')
109100

101+
displayPrice = '$connected'
110102
connect(1, 2)
111103
expect(nodeBadges(node).at(-1)?.text).toBe('$connected')
112104
})
@@ -117,6 +109,7 @@ describe('badge derivation pricing input connectivity', () => {
117109

118110
expect(nodeBadges(node).at(-1)?.text).toBe('$disconnected')
119111

112+
displayPrice = '$connected'
120113
connect(1, 3)
121114
expect(nodeBadges(node).at(-1)?.text).toBe('$disconnected')
122115
})
@@ -127,6 +120,7 @@ describe('badge derivation pricing input connectivity', () => {
127120

128121
const reloadedGraphId: UUID = 'graph-pricing-reloaded'
129122
node.graph!.rootGraph.id = reloadedGraphId
123+
displayPrice = '$connected'
130124
connect(0, 4, reloadedGraphId)
131125

132126
expect(nodeBadges(node).at(-1)?.text).toBe('$connected')

0 commit comments

Comments
 (0)