Skip to content

Commit 3e1b726

Browse files
committed
test: cover shared snapshot ancestor traversal
1 parent 8b06c2b commit 3e1b726

2 files changed

Lines changed: 50 additions & 0 deletions

File tree

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import { test } from 'vitest';
2+
import assert from 'node:assert/strict';
3+
import {
4+
buildSnapshotNodeByIndex,
5+
findNearestAncestor,
6+
findSnapshotAncestor,
7+
} from '../snapshot-processing.ts';
8+
import type { SnapshotNode } from '../snapshot.ts';
9+
10+
test('findSnapshotAncestor walks non-contiguous parent indexes until resolver returns a value', () => {
11+
const nodes: SnapshotNode[] = [
12+
{ ref: 'e10', index: 10, type: 'Window' },
13+
{ ref: 'e30', index: 30, parentIndex: 20, type: 'Text' },
14+
{ ref: 'e20', index: 20, parentIndex: 10, type: 'Cell' },
15+
];
16+
const visited: number[] = [];
17+
18+
const ancestor = findSnapshotAncestor(
19+
nodes,
20+
nodes[1]!,
21+
buildSnapshotNodeByIndex(nodes),
22+
(node) => {
23+
visited.push(node.index);
24+
return node.type === 'Window' ? node : null;
25+
},
26+
);
27+
28+
assert.deepEqual(visited, [20, 10]);
29+
assert.equal(ancestor?.index, 10);
30+
});
31+
32+
test('findNearestAncestor resolves parents by snapshot index rather than array position', () => {
33+
const nodes: SnapshotNode[] = [
34+
{ ref: 'e10', index: 10, type: 'Window' },
35+
{ ref: 'e30', index: 30, parentIndex: 20, type: 'Text' },
36+
{ ref: 'e20', index: 20, parentIndex: 10, type: 'Cell' },
37+
];
38+
39+
const ancestor = findNearestAncestor(nodes, nodes[1]!, (node) => node.type === 'Window');
40+
41+
assert.equal(ancestor?.index, 10);
42+
});

src/utils/snapshot-processing.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,11 @@ export function buildSnapshotNodeByIndex(nodes: SnapshotState['nodes']): Map<num
109109
return new Map(nodes.map((candidate) => [candidate.index, candidate]));
110110
}
111111

112+
/**
113+
* Walks from the given node through its parent chain and returns the first
114+
* non-null value produced by `resolve`. Returning null from `resolve` skips
115+
* that ancestor and continues walking toward the root.
116+
*/
112117
export function findSnapshotAncestor<T>(
113118
nodes: SnapshotState['nodes'],
114119
node: SnapshotNode,
@@ -140,6 +145,9 @@ export function isDescendantOfSnapshotNode(
140145
);
141146
}
142147

148+
/**
149+
* Returns the nearest ancestor matching `predicate`; false means keep walking.
150+
*/
143151
export function findNearestAncestor(
144152
nodes: SnapshotState['nodes'],
145153
node: SnapshotState['nodes'][number],

0 commit comments

Comments
 (0)