Skip to content

Commit

Permalink
fix: recursively sync children steps to fix rename
Browse files Browse the repository at this point in the history
  • Loading branch information
jorenbroekema committed Dec 13, 2021
1 parent c2c4e65 commit 43e8222
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 2 deletions.
24 changes: 24 additions & 0 deletions src/__tests__/volume/renameSync.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,30 @@ describe('renameSync(fromPath, toPath)', () => {
expect(tryGetChildNode(vol.root, 'baz').isFile()).toBe(true);
expect(vol.readFileSync('/baz', 'utf8')).toBe('bar');
});
it('Updates deep links properly when renaming a directory', () => {
const vol = create({});
vol.mkdirpSync('/foo/bar/qux');
vol.writeFileSync('/foo/bar/qux/a.txt', 'hello');
vol.renameSync('/foo/', '/faa/');
expect(vol.toJSON()).toEqual({
'/faa/bar/qux/a.txt': 'hello',
});

vol.renameSync('/faa/bar/qux/a.txt', '/faa/bar/qux/b.txt');
expect(vol.toJSON()).toEqual({
'/faa/bar/qux/b.txt': 'hello',
});

vol.renameSync('/faa/', '/fuu/');
expect(vol.toJSON()).toEqual({
'/fuu/bar/qux/b.txt': 'hello',
});

vol.renameSync('/fuu/bar/', '/fuu/bur/');
expect(vol.toJSON()).toEqual({
'/fuu/bur/qux/b.txt': 'hello',
});
});
it('Rename file two levels deep', () => {
const vol = create({ '/1/2': 'foobar' });
vol.renameSync('/1/2', '/1/3');
Expand Down
23 changes: 21 additions & 2 deletions src/node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ export class Link extends EventEmitter {
children: { [child: string]: Link | undefined } = {};

// Path to this node as Array: ['usr', 'bin', 'node'].
steps: string[] = [];
private _steps: string[] = [];

// "i-node" of this hard link.
node: Node;
Expand All @@ -250,11 +250,26 @@ export class Link extends EventEmitter {
// Number of children.
length: number = 0;

name: string;

get steps() {
return this._steps;
}

// Recursively sync children steps, e.g. in case of dir rename
set steps(val) {
this._steps = val;
for (const child of Object.values(this.children)) {
child?.syncSteps()
}
}

constructor(vol: Volume, parent: Link, name: string) {
super();
this.vol = vol;
this.parent = parent;
this.steps = parent ? parent.steps.concat([name]) : [name];
this.name = name;
this.syncSteps();
}

setNode(node: Node) {
Expand Down Expand Up @@ -347,6 +362,10 @@ export class Link extends EventEmitter {
children: Object.keys(this.children),
};
}

syncSteps() {
this.steps = this.parent ? this.parent.steps.concat([this.name]) : [this.name];
}
}

/**
Expand Down
1 change: 1 addition & 0 deletions src/volume.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1626,6 +1626,7 @@ export class Volume {

// Rename should overwrite the new path, if that exists.
const name = newPathSteps[newPathSteps.length - 1];
link.name = name;
link.steps = [...newPathDirLink.steps, name];
newPathDirLink.setChild(link.getName(), link);
}
Expand Down

0 comments on commit 43e8222

Please sign in to comment.