Skip to content
Open
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
53 changes: 53 additions & 0 deletions src/test/view/treeNodes/directoryTreeNode.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -206,4 +206,57 @@ describe('DirectoryTreeNode', function () {
assert.strictEqual(rootDir.checkboxState?.state, vscode.TreeItemCheckboxState.Unchecked);
});
});

describe('parent pointer after phantom-root pull-up', function () {
// When a tree has multiple top-level directories, a temporary DirectoryTreeNode
// with label='' (phantom root) is used to build the tree, then its children are
// pulled up to the actual container. If children are not re-parented, getParent()
// still returns the phantom DirectoryTreeNode and processCheckboxUpdates fires
// refresh() on an invisible node, so checkbox state never updates visually.

it('getParent() returns undefined after child is re-parented to the container', function () {
const container = createMockParent();
const phantomRoot = new DirectoryTreeNode(container, '');
const subDir = new DirectoryTreeNode(phantomRoot, 'src');

// Before re-parenting: parent is the phantom root DirectoryTreeNode
assert.ok(subDir.getParent() instanceof DirectoryTreeNode, 'sanity: should point to phantom root before re-parenting');

// Simulate the pull-up re-parenting fix applied in filesCategoryNode / pullRequestNode / commitNode
subDir.parent = container;

// After re-parenting: container is not a TreeNode, so getParent() returns undefined.
// This means the ancestor walk in processCheckboxUpdates stops here and refresh()
// is called on the visible subDir node, not the invisible phantom root.
assert.strictEqual(subDir.getParent(), undefined, 'after re-parenting, getParent() should not return the phantom root');
});
Comment thread
alexr00 marked this conversation as resolved.

it('ancestor walk stops at the topmost visible directory after re-parenting', function () {
const container = createMockParent();
const phantomRoot = new DirectoryTreeNode(container, '');
const topDir = new DirectoryTreeNode(phantomRoot, 'cloud');
const subDir = new DirectoryTreeNode(topDir, 'helm');
const file = new MockFileNode(subDir);
file.checkboxState = { state: vscode.TreeItemCheckboxState.Checked };

(subDir._children as any[]).push(file);
topDir._children.push(subDir);

// Re-parent: simulate fix
topDir.parent = container;

// Walk ancestors from file, mimicking processCheckboxUpdates
const ancestors: TreeNode[] = [];
let current = file.getParent();
while (current instanceof DirectoryTreeNode) {
ancestors.push(current);
current = current.getParent();
}

// Should find subDir and topDir, but NOT the phantom root
assert.strictEqual(ancestors.length, 2);
assert.strictEqual(ancestors[0], subDir);
assert.strictEqual(ancestors[1], topDir);
});
});
});
1 change: 1 addition & 0 deletions src/view/treeNodes/commitNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ export class CommitNode extends TreeNode implements vscode.TreeItem {
dirNode.finalize();
if (dirNode.label === '') {
// nothing on the root changed, pull children to parent
dirNode._children.forEach(child => { child.parent = this; });
result.push(...dirNode._children);
} else {
result.push(dirNode);
Expand Down
1 change: 1 addition & 0 deletions src/view/treeNodes/filesCategoryNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ export class FilesCategoryNode extends TreeNode implements vscode.TreeItem {
if (dirNode.label === '') {
// nothing on the root changed, pull children to parent
this.directories = dirNode._children;
this.directories.forEach(child => { child.parent = this; });
} else {
this.directories = [dirNode];
}
Expand Down
1 change: 1 addition & 0 deletions src/view/treeNodes/pullRequestNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ export class PRNode extends TreeNode implements vscode.CommentingRangeProvider2
dirNode.finalize();
if (dirNode.label === '') {
// nothing on the root changed, pull children to parent
dirNode._children.forEach(child => { child.parent = this; });
result.push(...dirNode._children);
} else {
result.push(dirNode);
Expand Down
Loading