Skip to content

Commit 93e8eec

Browse files
test: compare round-tripped links and groups whole, not by count
Count-based assertions pass when a link is renumbered, repointed at a different slot, or replaced. All three fixtures also ship groups: [], so the group assertion compared nothing to nothing. Links and floating links now compare full entity sets including endpoints; groups are asserted against a fixture that actually has them. Verified by mutation: repointing one link endpoint, one floating-link slot and one group title fails 7 of the 21 tests.
1 parent 03351a3 commit 93e8eec

1 file changed

Lines changed: 45 additions & 8 deletions

File tree

src/lib/litegraph/src/LGraph.roundTrip.test.ts

Lines changed: 45 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,9 @@ import reroutesComplex from './__fixtures__/assets/reroutesComplex.json'
1616
* workflow, save it, and everything you had is still there.
1717
*
1818
* Serialisation deliberately normalises — schema version is rewritten and
19-
* conflicting ids are reassigned — so this compares entity sets and counts
20-
* rather than bytes.
19+
* conflicting ids are reassigned — so this compares entity sets rather than
20+
* bytes. It compares them whole: a count survives an entity being renumbered,
21+
* repointed at a different slot, or replaced outright.
2122
*/
2223

2324
interface RoundTripFixture {
@@ -49,6 +50,38 @@ function rerouteIds(graph: { extra?: { reroutes?: { id: number }[] } }) {
4950
.sort(ascending)
5051
}
5152

53+
/**
54+
* Links and groups are compared whole, not counted. A count survives a link
55+
* being renumbered, repointed at a different slot, or replaced outright.
56+
*/
57+
function linkKeys(graph: Pick<ISerialisedGraph, 'links'>) {
58+
return (graph.links ?? []).map((link) => JSON.stringify(link)).sort()
59+
}
60+
61+
function floatingLinkKeys(graph: Pick<ISerialisedGraph, 'floatingLinks'>) {
62+
return (graph.floatingLinks ?? []).map((link) => JSON.stringify(link)).sort()
63+
}
64+
65+
function groupKeys(graph: Pick<ISerialisedGraph, 'groups'>) {
66+
return (graph.groups ?? [])
67+
.map(({ id, title, bounding }) => JSON.stringify({ id, title, bounding }))
68+
.sort()
69+
}
70+
71+
/**
72+
* Every fixture ships with `groups: []`, so a group assertion against them
73+
* unmodified compares nothing to nothing.
74+
*/
75+
function withGroups(graph: ISerialisedGraph): ISerialisedGraph {
76+
return {
77+
...structuredClone(graph),
78+
groups: [
79+
{ id: 1, title: 'first', bounding: [0, 0, 140, 90] },
80+
{ id: 2, title: 'second', bounding: [200, 40, 180, 120] }
81+
]
82+
}
83+
}
84+
5285
describe('LGraph round trip preserves the input', () => {
5386
for (const { name, graph } of fixtures) {
5487
describe(name, () => {
@@ -61,20 +94,24 @@ describe('LGraph round trip preserves the input', () => {
6194
expect(after).toEqual(before)
6295
})
6396

64-
test('keeps every link', () => {
65-
const before = graph.links?.length ?? 0
97+
test('keeps every link, with its endpoints', () => {
98+
expect(linkKeys(roundTrip(graph))).toEqual(linkKeys(graph))
99+
})
66100

67-
expect(roundTrip(graph).links?.length ?? 0).toBe(before)
101+
test('keeps every floating link, with its endpoints', () => {
102+
expect(floatingLinkKeys(roundTrip(graph))).toEqual(
103+
floatingLinkKeys(graph)
104+
)
68105
})
69106

70107
test('keeps every reroute, by id', () => {
71108
expect(rerouteIds(roundTrip(graph))).toEqual(rerouteIds(graph))
72109
})
73110

74-
test('keeps every group', () => {
75-
const before = graph.groups?.length ?? 0
111+
test('keeps every group, by identity and bounds', () => {
112+
const grouped = withGroups(graph)
76113

77-
expect(roundTrip(graph).groups?.length ?? 0).toBe(before)
114+
expect(groupKeys(roundTrip(grouped))).toEqual(groupKeys(grouped))
78115
})
79116

80117
test('does not mutate the workflow it was given', () => {

0 commit comments

Comments
 (0)