Skip to content

Commit

Permalink
feat: dir property, utilize path.join (#2)
Browse files Browse the repository at this point in the history
* feat: dir property, utilize path.join

Adds a `dir` property to get the full path of the directory for the given FilePath instance. Mirrors `file`.

Uses `path.join` when building `path`, and `dir` to normalize `..` and `.`. These are kept in `folders` for posterity.

* chore: method comments

* refactor: set folders directly (#3)

* refactor: set folders attribute directly

* test: remove erroneous test addition

* docs: readme mistake

Co-authored-by: Matt Forster <matt@autovance.com>
  • Loading branch information
Tyler Stewart and Matt Forster authored Jun 10, 2020
1 parent eba7e1f commit 56050ef
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 6 deletions.
17 changes: 14 additions & 3 deletions lib/index.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
/* eslint-disable no-restricted-syntax */

import { extname, basename, dirname, sep } from 'path';
import { extname, basename, dirname, sep, join } from 'path';

export class FilePath {
/** The string representing the file name excluding the extension */
public filename: string | undefined;

/** An ordered array of folder names. folders[0] represents the root of the path.
* If absolute, it will be an empty string (required), if relative, it will be the folder reference '.' or '..'
* If absolute, it will be an empty string (required), if relative it will be the first folder, '.', or '..'
*/
public folders: string[] = [];

Expand All @@ -28,7 +28,18 @@ export class FilePath {

/** Get: the current path */
public get path(): string {
return `${this.folders.join(sep)}${sep}${this.file ? this.file : ''}`;
return join(this.folders.join(sep), this.file ? this.file : sep);
}

/** Get: the current directory */
public get dir(): string {
// Inner .join to keep the root empty string delimiter if present
return join(this.folders.join(sep));
}

/** Set: change the current directory */
public set dir(dir: string) {
this.folders = dir.split(sep);
}

/** Set: the full file name including the extension */
Expand Down
27 changes: 24 additions & 3 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,25 @@ console.log(path.file, path.filename, path.extension, path.path);
> 'this/is/a/new'
```

### dir

Set: change the directory (without the file)
Get: get the directory (without the file)

```js
const path = new FilePath('this/is/a/file.jpeg');
path.dir = '/this/is/the'

console.log(path.dir, path.file, path.filename, path.extension, path.path);

> '/this/is/the'
> 'file.jpeg'
> 'file'
> 'jpeg'
> 'this/is/the/file.jpeg'

```

### filename

Set: set the filename (without extension)
Expand Down Expand Up @@ -92,18 +111,20 @@ console.log(path.extension, path.file, path.path);

### folders

An ordered array of folder names. folders[0] represents the root of the path. If absolute, it will be empty '' (required), if relative, it will be the first folder, or reference '.' or '..'
An ordered array of folder names. folders[0] represents the root of the path. If absolute, it will be empty '' (required), if relative, it will be the first folder, or reference '.' or '..'.

The recommended use it to change a specific folder in the path, using the index.

```js
const path = new FilePath('/this/is/a/file.jpeg');
console.log(path.folders);

> ['', 'this', 'is', 'a']

path.path = 'this/is/a/file.jpeg';
path.path = 'this/is/the/file.jpeg';
console.log(path.folders);

> ['this', 'is', 'a']
> ['this', 'is', 'the']

path.folders.unshift('..');
path.folders[path.folders.length - 1] = 'relative';
Expand Down
25 changes: 25 additions & 0 deletions tests/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ describe('FilePath', () => {
expect(path.extension).toEqual('jpeg');
expect(path.file).toEqual('path.jpeg');
expect(path.path).toEqual('/this/is/a/full/path.jpeg');
expect(path.dir).toEqual('/this/is/a/full');
});

it('parses a relative path', () => {
Expand All @@ -19,6 +20,7 @@ describe('FilePath', () => {
expect(path.extension).toEqual('jpeg');
expect(path.file).toEqual('path.jpeg');
expect(path.path).toEqual('this/is/a/full/path.jpeg');
expect(path.dir).toEqual('this/is/a/full');

path.folders.unshift('.');
path.folders[path.folders.length - 1] = 'relative';
Expand All @@ -29,6 +31,17 @@ describe('FilePath', () => {
expect(path.path).toEqual('../this/is/a/relative/path.jpeg');
});

it('normalizes path', () => {
const path = new FilePath('this/is/../is/../is/./a/full/path.jpeg');

expect(path.folders).toEqual(['this', 'is', '..', 'is', '..', 'is', '.', 'a', 'full']);
expect(path.filename).toEqual('path');
expect(path.extension).toEqual('jpeg');
expect(path.file).toEqual('path.jpeg');
expect(path.path).toEqual('this/is/a/full/path.jpeg');
expect(path.dir).toEqual('this/is/a/full');
});

it('handles an extensionless path', () => {
const path = new FilePath('/this/is/a/web_upload');

Expand All @@ -53,6 +66,18 @@ describe('FilePath', () => {
expect(path.filename).toEqual('thumbnail_low');
expect(path.file).toEqual('thumbnail_low.jpeg');
expect(path.path).toEqual('/this/is/the/thumbnail_low.jpeg');
expect(path.dir).toEqual('/this/is/the');
});

it('sets directory independent of the file', () => {
const path = new FilePath('/this/is/the/original_file.pdf');
path.dir = 'new/location';

expect(path.extension).toEqual('pdf');
expect(path.filename).toEqual('original_file');
expect(path.file).toEqual('original_file.pdf');
expect(path.path).toEqual('new/location/original_file.pdf');
expect(path.dir).toEqual('new/location');
});

it('can clear out a file completely', () => {
Expand Down

0 comments on commit 56050ef

Please sign in to comment.