Skip to content

Commit

Permalink
[core] Fix #6377: Handle URI#getAllLocations for paths with no parent
Browse files Browse the repository at this point in the history
- Adds `Path#hasDir`
- Adds `location.path.hasDir` check in while loop of `URI#allLocations`
- Adds some tests

Fixes #6377

Signed-off-by: Cornelius A. Ludmann <cornelius.ludmann@typefox.io>
  • Loading branch information
corneliusludmann committed Oct 14, 2019
1 parent b98c5fb commit b59987e
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 5 deletions.
9 changes: 9 additions & 0 deletions packages/core/src/common/path.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ describe('Path', () => {
assert.deepEqual(path.isAbsolute, true);
assert.deepEqual(path.root!.toString(), '/');
assert.deepEqual(path.dir.toString(), '/foo/bar');
assert.deepEqual(path.hasDir, true);
assert.deepEqual(path.base, 'file.txt');
assert.deepEqual(path.name, 'file');
assert.deepEqual(path.ext, '.txt');
Expand All @@ -36,6 +37,7 @@ describe('Path', () => {
assert.deepEqual(path.isAbsolute, false);
assert.deepEqual(path.root, undefined);
assert.deepEqual(path.dir.toString(), 'foo/bar');
assert.deepEqual(path.hasDir, true);
assert.deepEqual(path.base, 'file.txt');
assert.deepEqual(path.name, 'file');
assert.deepEqual(path.ext, '.txt');
Expand All @@ -47,6 +49,7 @@ describe('Path', () => {
assert.deepEqual(path.isAbsolute, true);
assert.deepEqual(path.root!.toString(), '/');
assert.deepEqual(path.dir.toString(), '/');
assert.deepEqual(path.hasDir, true);
assert.deepEqual(path.base, 'foo');
assert.deepEqual(path.name, 'foo');
assert.deepEqual(path.ext, '');
Expand All @@ -58,6 +61,7 @@ describe('Path', () => {
assert.deepEqual(path.isAbsolute, false);
assert.deepEqual(path.root, undefined);
assert.deepEqual(path.dir.toString(), 'foo');
assert.deepEqual(path.hasDir, false);
assert.deepEqual(path.base, 'foo');
assert.deepEqual(path.name, 'foo');
assert.deepEqual(path.ext, '');
Expand All @@ -69,6 +73,7 @@ describe('Path', () => {
assert.deepEqual(path.isAbsolute, true);
assert.deepEqual(path.root!.toString(), '/');
assert.deepEqual(path.dir.toString(), '/');
assert.deepEqual(path.hasDir, false);
assert.deepEqual(path.base, '');
assert.deepEqual(path.name, '');
assert.deepEqual(path.ext, '');
Expand All @@ -80,6 +85,7 @@ describe('Path', () => {
assert.deepEqual(path.isAbsolute, true);
assert.deepEqual(path.root!.toString(), '/c:');
assert.deepEqual(path.dir.toString(), '/c:/foo/bar');
assert.deepEqual(path.hasDir, true);
assert.deepEqual(path.base, 'file.txt');
assert.deepEqual(path.name, 'file');
assert.deepEqual(path.ext, '.txt');
Expand All @@ -91,6 +97,7 @@ describe('Path', () => {
assert.deepEqual(path.isAbsolute, true);
assert.deepEqual(path.root!.toString(), '/c:');
assert.deepEqual(path.dir.toString(), '/c:');
assert.deepEqual(path.hasDir, true);
assert.deepEqual(path.base, 'foo');
assert.deepEqual(path.name, 'foo');
assert.deepEqual(path.ext, '');
Expand All @@ -102,6 +109,7 @@ describe('Path', () => {
assert.deepEqual(path.isAbsolute, true);
assert.deepEqual(path.root!.toString(), '/c:');
assert.deepEqual(path.dir.toString(), '/c:');
assert.deepEqual(path.hasDir, true);
assert.deepEqual(path.base, '');
assert.deepEqual(path.name, '');
assert.deepEqual(path.ext, '');
Expand All @@ -113,6 +121,7 @@ describe('Path', () => {
assert.deepEqual(path.isAbsolute, true);
assert.deepEqual(path.root!.toString(), '/c:');
assert.deepEqual(path.dir.toString(), '/c:');
assert.deepEqual(path.hasDir, false);
assert.deepEqual(path.base, 'c:');
assert.deepEqual(path.name, 'c:');
assert.deepEqual(path.ext, '');
Expand Down
18 changes: 14 additions & 4 deletions packages/core/src/common/path.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,21 +108,31 @@ export class Path {
return new Path(this.raw.substr(0, index)).root;
}

/**
* Returns the parent directory if it exists (`hasDir === true`) or `this` otherwise.
*/
get dir(): Path {
if (this._dir === undefined) {
this._dir = this.computeDir();
}
return this._dir;
}

/**
* Returns `true` if this has a parent directory, `false` otherwise.
*
* _This implementation returns `true` if and only if this is not the root dir and
* there is a path separator in the raw path._
*/
get hasDir(): boolean {
return !this.isRoot && this.raw.lastIndexOf(Path.separator) !== -1;
}

protected computeDir(): Path {
if (this.isRoot) {
if (!this.hasDir) {
return this;
}
const lastIndex = this.raw.lastIndexOf(Path.separator);
if (lastIndex === -1) {
return this;
}
if (this.isAbsolute) {
const firstIndex = this.raw.indexOf(Path.separator);
if (firstIndex === lastIndex) {
Expand Down
36 changes: 36 additions & 0 deletions packages/core/src/common/uri.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,42 @@ const expect = chai.expect;

describe('uri', () => {

describe('#getAllLocations', () => {

it('of /foo/bar/file.txt', () => {
expect(new URI('/foo/bar/file.txt').allLocations.map(x => x.toString()))
.deep.equals([
new URI('/foo/bar/file.txt').toString(),
new URI('/foo/bar').toString(),
new URI('/foo').toString(),
new URI('/').toString()
]);
});

it('of foo', () => {
expect(new URI('foo').allLocations.map(x => x.toString()))
.deep.equals([
new URI('foo').toString(),
new URI('/').toString()
]);
});

it('of foo:bar.txt', () => {
expect(new URI().withScheme('foo').withPath('bar.txt').allLocations.map(x => x.toString()))
.deep.equals([
'foo:bar.txt'
]);
});

it('of foo:bar/foobar.txt', () => {
expect(new URI().withScheme('foo').withPath('bar/foobar.txt').allLocations.map(x => x.toString()))
.deep.equals([
new URI().withScheme('foo').withPath('bar/foobar.txt').toString(),
new URI().withScheme('foo').withPath('bar').toString()
]);
});
});

describe('#getParent', () => {

it('of file:///foo/bar.txt', () => {
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/common/uri.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ export default class URI {
get allLocations(): URI[] {
const locations = [];
let location: URI = this;
while (!location.path.isRoot) {
while (!location.path.isRoot && location.path.hasDir) {
locations.push(location);
location = location.parent;
}
Expand Down

0 comments on commit b59987e

Please sign in to comment.