file-path-helper 1.4.3 → 1.4.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## 1.4.4 - 2022-02-01
11
+
12
+ - Handling [Control Codes](https://en.wikipedia.org/wiki/C0_and_C1_control_codes) in `sanitize` method.
13
+ - Update dependencies.
14
+
10
15
  ## 1.4.3 - 2021-05-11
11
16
 
12
17
  - Update dependencies.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "file-path-helper",
3
- "version": "1.4.3",
3
+ "version": "1.4.4",
4
4
  "types": "index.d.ts",
5
5
  "description": "Helpful methods for handling file path.",
6
6
  "main": "src/index.js",
@@ -14,11 +14,11 @@
14
14
  "license": "MIT",
15
15
  "dependencies": {
16
16
  "fs-extra": "^10.0.0",
17
- "glob": "^7.1.7"
17
+ "glob": "^7.2.0"
18
18
  },
19
19
  "devDependencies": {
20
- "@types/jest": "^26.0.23",
21
- "eslint": "^7.26.0",
22
- "jest": "^26.6.3"
20
+ "@types/jest": "^27.4.0",
21
+ "eslint": "^8.8.0",
22
+ "jest": "^27.4.7"
23
23
  }
24
24
  }
package/src/file.js CHANGED
@@ -1,174 +1,174 @@
1
- const { parse } = require('path');
2
- const glob = require('glob');
3
- const { pathExists } = require('fs-extra');
4
-
5
- /**
6
- * @typedef {'/'|'\\'} Separator Directory Separator
7
- * @typedef {import('glob').IOptions} GlobOptions Glob Options
8
- */
9
-
10
- /**
11
- * Glob promise.
12
- *
13
- * @param {string} pattern
14
- * @param {GlobOptions} options
15
- * @returns {Promise<string[], Error>}
16
- */
17
- function globPromise(pattern, options) {
18
- return new Promise((resolve, reject) => {
19
- glob(pattern, options, (err, files) => {
20
- err === null ? resolve(files) : reject(err);
21
- });
22
- });
23
- }
24
-
25
- /**
26
- * Replace directory separator.
27
- *
28
- * @param {string} path
29
- * @param {Separator} separator default: '/'
30
- * @returns {string}
31
- */
32
- function replaceSeparator(path, separator = '/') {
33
- return path.replace(/(\\|\/)/g, separator);
34
- }
35
-
36
- /**
37
- * Append last slash to directory.
38
- *
39
- * @param {string} dir
40
- * @param {Separator} separator default: '/'
41
- */
42
- function trimDir(dir, separator = '/') {
43
- if (!dir) return '';
44
- return !/[/\\]$/.test(dir) ? dir + separator : dir;
45
- }
46
-
47
- /**
48
- * Set directory part of path.
49
- *
50
- * @param {string} path
51
- * @param {string} dir
52
- * @param {Separator} separator default: '/'
53
- * @returns {string}
54
- */
55
- function setDir(path, dir, separator = '/') {
56
- const regex = /^(.*[/\\])/;
57
- dir = trimDir(dir, separator);
58
- return regex.test(path) ? path.replace(regex, dir) : dir + path;
59
- }
60
-
61
-
62
- /**
63
- * Get last number from path.
64
- *
65
- * @param {string} path
66
- * @returns {string}
67
- */
68
- function getLastNumber(path) {
69
- const name = parse(path).name;
70
- const reg = /(\d+|[({[]\d+[)}\]])$/;
71
- const match = name.match(reg);
72
- return match ? /\d+/.exec(match[0])[0] : '' ;
73
- }
74
-
75
- /**
76
- * Remove last number from file name.
77
- *
78
- * @param {string} file
79
- * @returns {string}
80
- */
81
- function removeLastNumber(file) {
82
- const { dir, name, ext } = parse(file);
83
- const reg = /(\d+|[({[]\d+[)}\]])$/;
84
- const newName = name.replace(reg, '').replace(/(\W|_)$/, '');
85
- return trimDir(dir) + newName + ext;
86
- }
87
-
88
- /**
89
- * Auto increase path.
90
- * If the same file exists, It's returns filename what increased number.
91
- *
92
- * @param {string} path
93
- * @returns {Promise<string>} auto increased path.
94
- */
95
- async function autoIncrease(path) {
96
- // TODO: add parameter `template`: "(n)" or "[n]" ...
97
- let { dir, name, ext } = parse(path);
98
- const reg = /\((\d+)\)$/;
99
- const numbering = name => {
100
- const num = parseInt(name.match(reg)[1]);
101
- return name.replace(reg, `(${num + 1})`);
102
- };
103
- const newPath = () => trimDir(dir) + name + ext;
104
- if (await pathExists(newPath())) {
105
- name = reg.test(name) ? numbering(name) : `${name} (2)`;
106
- return await autoIncrease(newPath());
107
- } else {
108
- return newPath();
109
- }
110
- }
111
-
112
- /**
113
- * Resolve output file name.
114
- *
115
- * @param {string} output
116
- * @param {string} source
117
- * @returns {string}
118
- */
119
- function resolveOutputFile(output, source) {
120
- const src = parse(source);
121
- return output.replace(/{(source|name)}/, src.name)
122
- .replace(/\.{ext}$/, src.ext);
123
- }
124
-
125
- /**
126
- * Convert size in bytes.
127
- * @see https://stackoverflow.com/questions/15900485/correct-way-to-convert-size-in-bytes-to-kb-mb-gb-in-javascript
128
- *
129
- * @param {number} bytes
130
- * @param {number} decimals default: 2
131
- * @returns {string}
132
- */
133
- function bytesToSize(bytes, decimals = 2) {
134
- if (bytes === 0) return '0 Bytes';
135
- const k = 1024;
136
- const dm = decimals < 0 ? 0 : decimals;
137
- const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
138
- const i = Math.floor(Math.log(bytes) / Math.log(k));
139
- const size = parseFloat((bytes / Math.pow(k, i)).toFixed(dm));
140
- return `${size} ${sizes[i]}`;
141
- }
142
-
143
- /**
144
- * Parses string that includes file size and operator.
145
- * @typedef {Object} Size
146
- * @property {number} bytes
147
- * @property {string} operator
148
- *
149
- * @param {string} size e.g '10.5mb' '>1GB' '=<10kb'
150
- * @returns {Size} Size
151
- */
152
- function parseSize(size) {
153
- const [, o, n, s] = size.match(/(^[><=]*)\s?([0-9]*\.?[0-9]*)\s?([A-Za-z]*)/);
154
- const k = 1024;
155
- const sizes = ['BYTES', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
156
- const i = s ? sizes.indexOf(s.toUpperCase()) : 0;
157
- return {
158
- bytes: parseFloat(n) * Math.pow(k, i),
159
- operator: o ? o : '=',
160
- };
161
- }
162
-
163
- module.exports = {
164
- globPromise,
165
- replaceSeparator,
166
- trimDir,
167
- setDir,
168
- getLastNumber,
169
- removeLastNumber,
170
- autoIncrease,
171
- resolveOutputFile,
172
- bytesToSize,
173
- parseSize,
174
- };
1
+ const { parse } = require('path');
2
+ const glob = require('glob');
3
+ const { pathExists } = require('fs-extra');
4
+
5
+ /**
6
+ * @typedef {'/'|'\\'} Separator Directory Separator
7
+ * @typedef {import('glob').IOptions} GlobOptions Glob Options
8
+ */
9
+
10
+ /**
11
+ * Glob promise.
12
+ *
13
+ * @param {string} pattern
14
+ * @param {GlobOptions} options
15
+ * @returns {Promise<string[], Error>}
16
+ */
17
+ function globPromise(pattern, options) {
18
+ return new Promise((resolve, reject) => {
19
+ glob(pattern, options, (err, files) => {
20
+ err === null ? resolve(files) : reject(err);
21
+ });
22
+ });
23
+ }
24
+
25
+ /**
26
+ * Replace directory separator.
27
+ *
28
+ * @param {string} path
29
+ * @param {Separator} separator default: '/'
30
+ * @returns {string}
31
+ */
32
+ function replaceSeparator(path, separator = '/') {
33
+ return path.replace(/(\\|\/)/g, separator);
34
+ }
35
+
36
+ /**
37
+ * Append last slash to directory.
38
+ *
39
+ * @param {string} dir
40
+ * @param {Separator} separator default: '/'
41
+ */
42
+ function trimDir(dir, separator = '/') {
43
+ if (!dir) return '';
44
+ return !/[/\\]$/.test(dir) ? dir + separator : dir;
45
+ }
46
+
47
+ /**
48
+ * Set directory part of path.
49
+ *
50
+ * @param {string} path
51
+ * @param {string} dir
52
+ * @param {Separator} separator default: '/'
53
+ * @returns {string}
54
+ */
55
+ function setDir(path, dir, separator = '/') {
56
+ const regex = /^(.*[/\\])/;
57
+ dir = trimDir(dir, separator);
58
+ return regex.test(path) ? path.replace(regex, dir) : dir + path;
59
+ }
60
+
61
+
62
+ /**
63
+ * Get last number from path.
64
+ *
65
+ * @param {string} path
66
+ * @returns {string}
67
+ */
68
+ function getLastNumber(path) {
69
+ const name = parse(path).name;
70
+ const reg = /(\d+|[({[]\d+[)}\]])$/;
71
+ const match = name.match(reg);
72
+ return match ? /\d+/.exec(match[0])[0] : '' ;
73
+ }
74
+
75
+ /**
76
+ * Remove last number from file name.
77
+ *
78
+ * @param {string} file
79
+ * @returns {string}
80
+ */
81
+ function removeLastNumber(file) {
82
+ const { dir, name, ext } = parse(file);
83
+ const reg = /(\d+|[({[]\d+[)}\]])$/;
84
+ const newName = name.replace(reg, '').replace(/(\W|_)$/, '');
85
+ return trimDir(dir) + newName + ext;
86
+ }
87
+
88
+ /**
89
+ * Auto increase path.
90
+ * If the same file exists, It's returns filename what increased number.
91
+ *
92
+ * @param {string} path
93
+ * @returns {Promise<string>} auto increased path.
94
+ */
95
+ async function autoIncrease(path) {
96
+ // TODO: add parameter `template`: "(n)" or "[n]" ...
97
+ let { dir, name, ext } = parse(path);
98
+ const reg = /\((\d+)\)$/;
99
+ const numbering = name => {
100
+ const num = parseInt(name.match(reg)[1]);
101
+ return name.replace(reg, `(${num + 1})`);
102
+ };
103
+ const newPath = () => trimDir(dir) + name + ext;
104
+ if (await pathExists(newPath())) {
105
+ name = reg.test(name) ? numbering(name) : `${name} (2)`;
106
+ return await autoIncrease(newPath());
107
+ } else {
108
+ return newPath();
109
+ }
110
+ }
111
+
112
+ /**
113
+ * Resolve output file name.
114
+ *
115
+ * @param {string} output
116
+ * @param {string} source
117
+ * @returns {string}
118
+ */
119
+ function resolveOutputFile(output, source) {
120
+ const src = parse(source);
121
+ return output.replace(/{(source|name)}/, src.name)
122
+ .replace(/\.{ext}$/, src.ext);
123
+ }
124
+
125
+ /**
126
+ * Convert size in bytes.
127
+ * @see https://stackoverflow.com/questions/15900485/correct-way-to-convert-size-in-bytes-to-kb-mb-gb-in-javascript
128
+ *
129
+ * @param {number} bytes
130
+ * @param {number} decimals default: 2
131
+ * @returns {string}
132
+ */
133
+ function bytesToSize(bytes, decimals = 2) {
134
+ if (bytes === 0) return '0 Bytes';
135
+ const k = 1024;
136
+ const dm = decimals < 0 ? 0 : decimals;
137
+ const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
138
+ const i = Math.floor(Math.log(bytes) / Math.log(k));
139
+ const size = parseFloat((bytes / Math.pow(k, i)).toFixed(dm));
140
+ return `${size} ${sizes[i]}`;
141
+ }
142
+
143
+ /**
144
+ * Parses string that includes file size and operator.
145
+ * @typedef {Object} Size
146
+ * @property {number} bytes
147
+ * @property {string} operator
148
+ *
149
+ * @param {string} size e.g '10.5mb' '>1GB' '=<10kb'
150
+ * @returns {Size} Size
151
+ */
152
+ function parseSize(size) {
153
+ const [, o, n, s] = size.match(/(^[><=]*)\s?([0-9]*\.?[0-9]*)\s?([A-Za-z]*)/);
154
+ const k = 1024;
155
+ const sizes = ['BYTES', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
156
+ const i = s ? sizes.indexOf(s.toUpperCase()) : 0;
157
+ return {
158
+ bytes: parseFloat(n) * Math.pow(k, i),
159
+ operator: o ? o : '=',
160
+ };
161
+ }
162
+
163
+ module.exports = {
164
+ globPromise,
165
+ replaceSeparator,
166
+ trimDir,
167
+ setDir,
168
+ getLastNumber,
169
+ removeLastNumber,
170
+ autoIncrease,
171
+ resolveOutputFile,
172
+ bytesToSize,
173
+ parseSize,
174
+ };
package/src/str.js CHANGED
@@ -1,33 +1,36 @@
1
- /**
2
- * truncate string.
3
- *
4
- * @param {string} str
5
- * @param {number} length default: 40
6
- * @param {string} ellipsis default: '…'
7
- * @returns {string}
8
- */
9
- function truncate(str, length = 40, ellipsis = '…') {
10
- return str.length < length
11
- ? str
12
- : str.substr(0, length - ellipsis.length) + ellipsis;
13
- }
14
-
15
- /**
16
- * Sanitize string for safe filename.
17
- * @see https://github.com/parshap/node-sanitize-filename#readme
18
- *
19
- * @param {string} str
20
- * @param {string} replacer default: `''`
21
- * @returns {string}
22
- */
23
- function sanitize(str, replacer = '') {
24
- return str.replace(/(https|http)/g, '') // remove 'http'
25
- .replace(/\t|[ ]{2,}/g, ' ') // two spaces or tab -> one space
26
- .replace(/[/:?<>\\*|"]/g, replacer) // sanitize
27
- .trim();
28
- }
29
-
30
- module.exports = {
31
- truncate,
32
- sanitize,
33
- };
1
+ /**
2
+ * truncate string.
3
+ *
4
+ * @param {string} str
5
+ * @param {number} length default: 40
6
+ * @param {string} ellipsis default: '…'
7
+ * @returns {string}
8
+ */
9
+ function truncate(str, length = 40, ellipsis = '…') {
10
+ return str.length < length
11
+ ? str
12
+ : str.substring(0, length - ellipsis.length) + ellipsis;
13
+ }
14
+
15
+ /**
16
+ * Sanitize string for safe filename.
17
+ * @see https://github.com/parshap/node-sanitize-filename#readme
18
+ * @see https://en.wikipedia.org/wiki/C0_and_C1_control_codes
19
+ *
20
+ * @param {string} str
21
+ * @param {string} replacer default: `''`
22
+ * @returns {string}
23
+ */
24
+ function sanitize(str, replacer = '') {
25
+ // eslint-disable-next-line no-control-regex
26
+ return str.replace(/[\x00-\x1f\x80-\x9f]/g, replacer) // control codes
27
+ .replace(/(https|http)/g, '') // remove 'http'
28
+ .replace(/\t|[ ]{2,}/g, ' ') // two spaces or tab -> one space
29
+ .replace(/[/:?<>\\*|"]/g, replacer) // sanitize
30
+ .trim();
31
+ }
32
+
33
+ module.exports = {
34
+ truncate,
35
+ sanitize,
36
+ };
@@ -1,320 +1,322 @@
1
- const {
2
- replaceSeparator,
3
- trimDir,
4
- setDir,
5
- getLastNumber,
6
- removeLastNumber,
7
- naturalSort,
8
- autoIncrease,
9
- resolveOutputFile,
10
- bytesToSize,
11
- parseSize,
12
- truncate,
13
- sanitize,
14
- filter,
15
- chunks,
16
- parseDate,
17
- diffDays,
18
- getDates,
19
- } = require('../src/index');
20
-
21
- describe('#replaceSeparator', () => {
22
- it('can replace back-slash to slash.', () => {
23
- const file = 'C:\\dir\\subDir\\filename.txt';
24
- expect(replaceSeparator(file)).toEqual('C:/dir/subDir/filename.txt');
25
- });
26
-
27
- it('can also replace slash to back-slash.', () => {
28
- const file = 'C:/dir/filename.txt';
29
- expect(replaceSeparator(file, '\\')).toEqual('C:\\dir\\filename.txt');
30
- });
31
- });
32
-
33
- describe('#trimDir', () => {
34
- it('appends slash to last of string', () => {
35
- expect(trimDir('dir')).toBe('dir/');
36
- expect(trimDir('dir/')).toBe('dir/');
37
- });
38
-
39
- it('also works as back-slash', () => {
40
- expect(trimDir('dir', '\\')).toBe('dir\\');
41
- });
42
-
43
- it('should return empty if dir parameter is empty.', () => {
44
- expect(trimDir('', '/')).toBe('');
45
- });
46
- });
47
-
48
- describe('#setDir', () => {
49
- it('set directory part of path.', () => {
50
- const path = './example/image.jpg';
51
- const directory = './good/';
52
- expect(setDir(path, directory)).toBe('./good/image.jpg');
53
- });
54
-
55
- it('available only directory name.', () => {
56
- const path = './example/image.jpg';
57
- const directory = './good';
58
- expect(setDir(path, directory)).toBe('./good/image.jpg');
59
- });
60
-
61
- it('should set directory when only file as path.', () => {
62
- const path = 'image.jpg';
63
- const directory = './dir';
64
- expect(setDir(path, directory)).toBe('./dir/image.jpg');
65
- });
66
-
67
- it('could set current dir via "" or "./"', () => {
68
- expect(setDir('dir/file.txt', '')).toBe('file.txt');
69
- expect(setDir('dir/file.txt', './')).toBe('./file.txt');
70
- });
71
- });
72
-
73
- describe('#getLastNumber', () => {
74
- it('get last number of path.', () => {
75
- expect(getLastNumber('file 1.mp4')).toEqual('1');
76
- expect(getLastNumber('file01.mp4')).toEqual('01');
77
- expect(getLastNumber('file0_1.mp4')).toEqual('1');
78
- expect(getLastNumber('file-0150.mp4')).toEqual('0150');
79
- expect(getLastNumber('file.mp4')).toEqual('');
80
- });
81
-
82
- it('should works', () => {
83
- expect(getLastNumber('test (1).txt')).toEqual('1');
84
- expect(getLastNumber('test [21].txt')).toEqual('21');
85
- expect(getLastNumber('2019_test_{11}.txt')).toEqual('11');
86
- expect(getLastNumber('2019 test.txt')).toEqual('');
87
- });
88
- });
89
-
90
- describe('#removeLastNumber', () => {
91
- it('removes last number on path.', () => {
92
- expect(removeLastNumber('dir/filename1.mp4')).toEqual('dir/filename.mp4');
93
- expect(removeLastNumber('dir/file 01.mp4')).toEqual('dir/file.mp4');
94
- expect(removeLastNumber('test_00_001.txt')).toEqual('test_00.txt');
95
- expect(removeLastNumber('test-01.txt')).toEqual('test.txt');
96
- });
97
-
98
- it('does not changes if path has not last number.', () => {
99
- expect(removeLastNumber('dir/12_monkeys.mp4')).toEqual('dir/12_monkeys.mp4');
100
- });
101
-
102
- it('should works also.', () => {
103
- expect(removeLastNumber('test (1).txt')).toEqual('test.txt');
104
- expect(removeLastNumber('test [21].txt')).toEqual('test.txt');
105
- expect(removeLastNumber('2019_test_{11}.txt')).toEqual('2019_test.txt');
106
- expect(removeLastNumber('2019 test.txt')).toEqual('2019 test.txt');
107
- });
108
- });
109
-
110
- describe('#naturalSort', () => {
111
- it('works.', () => {
112
- const files = [
113
- 'test/video file 1.mp4',
114
- 'test/video file 14.mp4',
115
- 'test/video file 2.mp4',
116
- 'test/video file 5.mp4',
117
- 'test/video file 003.mp4',
118
- ];
119
- const sorted = [
120
- 'test/video file 1.mp4',
121
- 'test/video file 2.mp4',
122
- 'test/video file 003.mp4',
123
- 'test/video file 5.mp4',
124
- 'test/video file 14.mp4',
125
- ];
126
- expect(naturalSort(files)).toEqual(sorted);
127
- });
128
-
129
- it('works between different file names.', () => {
130
- const files = [
131
- 'other test 2.mp4',
132
- 'test 14.mp4',
133
- '2 test 11.mp4',
134
- 'test 2.mp4',
135
- 'other test 15.mp4',
136
- '2 test 3.mp4',
137
- ];
138
- const sorted = [
139
- '2 test 3.mp4',
140
- '2 test 11.mp4',
141
- 'other test 2.mp4',
142
- 'other test 15.mp4',
143
- 'test 2.mp4',
144
- 'test 14.mp4',
145
- ];
146
- expect(naturalSort(files)).toEqual(sorted);
147
- });
148
-
149
- it('works also.', () => {
150
- const files = [
151
- 'test_14.mp4',
152
- '2 test (11).mp4',
153
- 'test_2.mp4',
154
- '2 test (3).mp4',
155
- ];
156
- const sorted = [
157
- '2 test (3).mp4',
158
- '2 test (11).mp4',
159
- 'test_2.mp4',
160
- 'test_14.mp4',
161
- ];
162
- expect(naturalSort(files)).toEqual(sorted);
163
- });
164
- });
165
-
166
- describe('#autoIncrease', () => {
167
- it('auto increase last number if path is exists.', async () => {
168
- const newPath = await autoIncrease('./test/utils.test.js');
169
- expect(newPath).toEqual('./test/utils.test (2).js');
170
- });
171
- });
172
-
173
- describe('#resolveOutputFile', () => {
174
- it('can set output file name reference from source file name via {source} or {name} template.', () => {
175
- const source = 'dir/sourceFile123.txt';
176
- expect(resolveOutputFile('{source}.md', source)).toEqual('sourceFile123.md');
177
- expect(resolveOutputFile('{name}.md', source)).toEqual('sourceFile123.md');
178
- });
179
-
180
- it('can also works extension part via {ext} template', () => {
181
- const source = 'sourceFile.m4a';
182
- expect(resolveOutputFile('output.{ext}', source)).toEqual('output.m4a');
183
- });
184
- });
185
-
186
- describe('#bytesToSize', () => {
187
- it('works.', () => {
188
- expect(bytesToSize(0)).toBe('0 Bytes');
189
- expect(bytesToSize(2048)).toBe('2 KB');
190
- expect(bytesToSize(1048576)).toBe('1 MB');
191
- });
192
- });
193
-
194
- describe('#parseSize', () => {
195
- it('works.', () => {
196
- expect(parseSize('500').bytes).toBe(500);
197
- expect(parseSize('500bytes').bytes).toBe(500);
198
- expect(parseSize('2 kb').bytes).toBe(2048);
199
- expect(parseSize('1MB').bytes).toBe(1048576);
200
- });
201
-
202
- it('works also with operator', () => {
203
- const size = parseSize('>2kb');
204
- expect(size.bytes).toBe(2048);
205
- expect(size.operator).toBe('>');
206
-
207
- expect(parseSize('<1MB').operator).toBe('<');
208
- expect(parseSize('<= 1 MB').operator).toBe('<=');
209
- expect(parseSize('=<1MB').operator).toBe('=<');
210
- expect(parseSize('>=1MB').operator).toBe('>=');
211
- expect(parseSize('=>1MB').operator).toBe('=>');
212
- expect(parseSize('= 1MB').operator).toBe('=');
213
- expect(parseSize('1MB').operator).toBe('=');
214
- });
215
-
216
- it('works with float number.', () => {
217
- expect(parseSize('>= 1.5 Mb').bytes).toBe(1572864);
218
- });
219
- });
220
-
221
- describe('#sanitize', () => {
222
- it('sanitize string for filename.', () => {
223
- expect(sanitize(' he*llo?')).toBe('hello');
224
- expect(sanitize(' he*llo?', ' ')).toBe('he llo');
225
- expect(sanitize(' he*llo/_<wo:rld')).toBe('hello_world');
226
- expect(sanitize('https://github.com/')).toBe('github.com');
227
- });
228
- });
229
-
230
- describe('#truncate', () => {
231
- it('truncate string', () => {
232
- expect(truncate('1234567890', 6)).toBe('12345…');
233
- expect(truncate('1234567890', 8, '...')).toBe('12345...');
234
- });
235
- });
236
-
237
- describe('#filter', () => {
238
- it('works.', async () => {
239
- const arr = [1, 2, 3, 4, 5];
240
- const doSomething = () => Promise.resolve();
241
-
242
- const res = await filter(arr, async v => {
243
- await doSomething();
244
- return (v % 2) == 1;
245
- });
246
- expect(res).toStrictEqual([1, 3, 5]);
247
- });
248
-
249
- it('index arg test', async () => {
250
- const arr = [1, 2, 3, 4, 5];
251
- const doSomething = () => Promise.resolve();
252
-
253
- const res = await filter(arr, async (v, i) => {
254
- await doSomething();
255
- return (i % 2) == 1;
256
- });
257
- expect(res).toStrictEqual([2, 4]);
258
- });
259
- });
260
-
261
- describe('#chunks', () => {
262
- it('works.', () => {
263
- const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0];
264
- expect(chunks(arr, 3)).toStrictEqual([[1, 2, 3], [4, 5, 6], [7, 8, 9], [0]]);
265
- });
266
-
267
- it('if set size to 0, chunk size is arr.length', () => {
268
- const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0];
269
- expect(chunks(arr, 0)).toStrictEqual([[1, 2, 3, 4, 5, 6, 7, 8, 9, 0]]);
270
- });
271
-
272
- it('if given array is smaller than size, chunk size is arr.length', () => {
273
- const arr = [1, 2, 3];
274
- expect(chunks(arr, 10)).toStrictEqual([[1, 2, 3]]);
275
- });
276
- });
277
-
278
- describe('#parseDate', () => {
279
- it('works.', () => {
280
- const date = parseDate('2019-12-25');
281
- expect(date.year).toBe(2019);
282
- expect(date.month).toBe(12);
283
- expect(date.day).toBe(25);
284
- expect(date.date).toBeInstanceOf(Date);
285
- expect(date.toDateString()).toBe('2019-12-25');
286
- });
287
-
288
- it('also works.', () => {
289
- const date = parseDate('2019-1-5');
290
- expect(date.year).toBe(2019);
291
- expect(date.month).toBe(1);
292
- expect(date.day).toBe(5);
293
- expect(date.date).toBeInstanceOf(Date);
294
- expect(date.toDateString()).toBe('2019-01-05');
295
- });
296
- });
297
-
298
- describe('#diffDays', () => {
299
- it('works.', () => {
300
- const d1 = new Date('2020-01-01');
301
- const d2 = new Date('2020-01-10');
302
- expect(diffDays(d1, d2)).toBe(9);
303
- });
304
-
305
- it('also can using date as string.', () => {
306
- expect(diffDays('2020-02-24', '2020-03-02')).toBe(7);
307
- });
308
- });
309
-
310
- describe('#getDates', () => {
311
- it('works.', () => {
312
- expect(getDates('2020-01-01~2020-01-05')).toStrictEqual([
313
- '2020-01-01',
314
- '2020-01-02',
315
- '2020-01-03',
316
- '2020-01-04',
317
- '2020-01-05',
318
- ]);
319
- });
320
- });
1
+ const {
2
+ replaceSeparator,
3
+ trimDir,
4
+ setDir,
5
+ getLastNumber,
6
+ removeLastNumber,
7
+ naturalSort,
8
+ autoIncrease,
9
+ resolveOutputFile,
10
+ bytesToSize,
11
+ parseSize,
12
+ truncate,
13
+ sanitize,
14
+ filter,
15
+ chunks,
16
+ parseDate,
17
+ diffDays,
18
+ getDates,
19
+ } = require('../src/index');
20
+
21
+ describe('#replaceSeparator', () => {
22
+ it('can replace back-slash to slash.', () => {
23
+ const file = 'C:\\dir\\subDir\\filename.txt';
24
+ expect(replaceSeparator(file)).toEqual('C:/dir/subDir/filename.txt');
25
+ });
26
+
27
+ it('can also replace slash to back-slash.', () => {
28
+ const file = 'C:/dir/filename.txt';
29
+ expect(replaceSeparator(file, '\\')).toEqual('C:\\dir\\filename.txt');
30
+ });
31
+ });
32
+
33
+ describe('#trimDir', () => {
34
+ it('appends slash to last of string', () => {
35
+ expect(trimDir('dir')).toBe('dir/');
36
+ expect(trimDir('dir/')).toBe('dir/');
37
+ });
38
+
39
+ it('also works as back-slash', () => {
40
+ expect(trimDir('dir', '\\')).toBe('dir\\');
41
+ });
42
+
43
+ it('should return empty if dir parameter is empty.', () => {
44
+ expect(trimDir('', '/')).toBe('');
45
+ });
46
+ });
47
+
48
+ describe('#setDir', () => {
49
+ it('set directory part of path.', () => {
50
+ const path = './example/image.jpg';
51
+ const directory = './good/';
52
+ expect(setDir(path, directory)).toBe('./good/image.jpg');
53
+ });
54
+
55
+ it('available only directory name.', () => {
56
+ const path = './example/image.jpg';
57
+ const directory = './good';
58
+ expect(setDir(path, directory)).toBe('./good/image.jpg');
59
+ });
60
+
61
+ it('should set directory when only file as path.', () => {
62
+ const path = 'image.jpg';
63
+ const directory = './dir';
64
+ expect(setDir(path, directory)).toBe('./dir/image.jpg');
65
+ });
66
+
67
+ it('could set current dir via "" or "./"', () => {
68
+ expect(setDir('dir/file.txt', '')).toBe('file.txt');
69
+ expect(setDir('dir/file.txt', './')).toBe('./file.txt');
70
+ });
71
+ });
72
+
73
+ describe('#getLastNumber', () => {
74
+ it('get last number of path.', () => {
75
+ expect(getLastNumber('file 1.mp4')).toEqual('1');
76
+ expect(getLastNumber('file01.mp4')).toEqual('01');
77
+ expect(getLastNumber('file0_1.mp4')).toEqual('1');
78
+ expect(getLastNumber('file-0150.mp4')).toEqual('0150');
79
+ expect(getLastNumber('file.mp4')).toEqual('');
80
+ });
81
+
82
+ it('should works', () => {
83
+ expect(getLastNumber('test (1).txt')).toEqual('1');
84
+ expect(getLastNumber('test [21].txt')).toEqual('21');
85
+ expect(getLastNumber('2019_test_{11}.txt')).toEqual('11');
86
+ expect(getLastNumber('2019 test.txt')).toEqual('');
87
+ });
88
+ });
89
+
90
+ describe('#removeLastNumber', () => {
91
+ it('removes last number on path.', () => {
92
+ expect(removeLastNumber('dir/filename1.mp4')).toEqual('dir/filename.mp4');
93
+ expect(removeLastNumber('dir/file 01.mp4')).toEqual('dir/file.mp4');
94
+ expect(removeLastNumber('test_00_001.txt')).toEqual('test_00.txt');
95
+ expect(removeLastNumber('test-01.txt')).toEqual('test.txt');
96
+ });
97
+
98
+ it('does not changes if path has not last number.', () => {
99
+ expect(removeLastNumber('dir/12_monkeys.mp4')).toEqual('dir/12_monkeys.mp4');
100
+ });
101
+
102
+ it('should works also.', () => {
103
+ expect(removeLastNumber('test (1).txt')).toEqual('test.txt');
104
+ expect(removeLastNumber('test [21].txt')).toEqual('test.txt');
105
+ expect(removeLastNumber('2019_test_{11}.txt')).toEqual('2019_test.txt');
106
+ expect(removeLastNumber('2019 test.txt')).toEqual('2019 test.txt');
107
+ });
108
+ });
109
+
110
+ describe('#naturalSort', () => {
111
+ it('works.', () => {
112
+ const files = [
113
+ 'test/video file 1.mp4',
114
+ 'test/video file 14.mp4',
115
+ 'test/video file 2.mp4',
116
+ 'test/video file 5.mp4',
117
+ 'test/video file 003.mp4',
118
+ ];
119
+ const sorted = [
120
+ 'test/video file 1.mp4',
121
+ 'test/video file 2.mp4',
122
+ 'test/video file 003.mp4',
123
+ 'test/video file 5.mp4',
124
+ 'test/video file 14.mp4',
125
+ ];
126
+ expect(naturalSort(files)).toEqual(sorted);
127
+ });
128
+
129
+ it('works between different file names.', () => {
130
+ const files = [
131
+ 'other test 2.mp4',
132
+ 'test 14.mp4',
133
+ '2 test 11.mp4',
134
+ 'test 2.mp4',
135
+ 'other test 15.mp4',
136
+ '2 test 3.mp4',
137
+ ];
138
+ const sorted = [
139
+ '2 test 3.mp4',
140
+ '2 test 11.mp4',
141
+ 'other test 2.mp4',
142
+ 'other test 15.mp4',
143
+ 'test 2.mp4',
144
+ 'test 14.mp4',
145
+ ];
146
+ expect(naturalSort(files)).toEqual(sorted);
147
+ });
148
+
149
+ it('works also.', () => {
150
+ const files = [
151
+ 'test_14.mp4',
152
+ '2 test (11).mp4',
153
+ 'test_2.mp4',
154
+ '2 test (3).mp4',
155
+ ];
156
+ const sorted = [
157
+ '2 test (3).mp4',
158
+ '2 test (11).mp4',
159
+ 'test_2.mp4',
160
+ 'test_14.mp4',
161
+ ];
162
+ expect(naturalSort(files)).toEqual(sorted);
163
+ });
164
+ });
165
+
166
+ describe('#autoIncrease', () => {
167
+ it('auto increase last number if path is exists.', async () => {
168
+ const newPath = await autoIncrease('./test/utils.test.js');
169
+ expect(newPath).toEqual('./test/utils.test (2).js');
170
+ });
171
+ });
172
+
173
+ describe('#resolveOutputFile', () => {
174
+ it('can set output file name reference from source file name via {source} or {name} template.', () => {
175
+ const source = 'dir/sourceFile123.txt';
176
+ expect(resolveOutputFile('{source}.md', source)).toEqual('sourceFile123.md');
177
+ expect(resolveOutputFile('{name}.md', source)).toEqual('sourceFile123.md');
178
+ });
179
+
180
+ it('can also works extension part via {ext} template', () => {
181
+ const source = 'sourceFile.m4a';
182
+ expect(resolveOutputFile('output.{ext}', source)).toEqual('output.m4a');
183
+ });
184
+ });
185
+
186
+ describe('#bytesToSize', () => {
187
+ it('works.', () => {
188
+ expect(bytesToSize(0)).toBe('0 Bytes');
189
+ expect(bytesToSize(2048)).toBe('2 KB');
190
+ expect(bytesToSize(1048576)).toBe('1 MB');
191
+ });
192
+ });
193
+
194
+ describe('#parseSize', () => {
195
+ it('works.', () => {
196
+ expect(parseSize('500').bytes).toBe(500);
197
+ expect(parseSize('500bytes').bytes).toBe(500);
198
+ expect(parseSize('2 kb').bytes).toBe(2048);
199
+ expect(parseSize('1MB').bytes).toBe(1048576);
200
+ });
201
+
202
+ it('works also with operator', () => {
203
+ const size = parseSize('>2kb');
204
+ expect(size.bytes).toBe(2048);
205
+ expect(size.operator).toBe('>');
206
+
207
+ expect(parseSize('<1MB').operator).toBe('<');
208
+ expect(parseSize('<= 1 MB').operator).toBe('<=');
209
+ expect(parseSize('=<1MB').operator).toBe('=<');
210
+ expect(parseSize('>=1MB').operator).toBe('>=');
211
+ expect(parseSize('=>1MB').operator).toBe('=>');
212
+ expect(parseSize('= 1MB').operator).toBe('=');
213
+ expect(parseSize('1MB').operator).toBe('=');
214
+ });
215
+
216
+ it('works with float number.', () => {
217
+ expect(parseSize('>= 1.5 Mb').bytes).toBe(1572864);
218
+ });
219
+ });
220
+
221
+ describe('#sanitize', () => {
222
+ it('sanitize string for filename.', () => {
223
+ expect(sanitize(' he*llo?')).toBe('hello');
224
+ expect(sanitize(' he*llo?', ' ')).toBe('he llo');
225
+ expect(sanitize(' he*llo/_<wo:rld')).toBe('hello_world');
226
+ expect(sanitize('https://github.com/')).toBe('github.com');
227
+ expect(sanitize('string\btest', ' ')).toBe('string test');
228
+ });
229
+ });
230
+
231
+ describe('#truncate', () => {
232
+ it('truncate string', () => {
233
+ expect(truncate('1234567890', 6)).toBe('12345');
234
+ expect(truncate('1234567890', 8, '...')).toBe('12345...');
235
+ expect(truncate('a가나다라bcd', 3, '')).toBe('a가나');
236
+ });
237
+ });
238
+
239
+ describe('#filter', () => {
240
+ it('works.', async () => {
241
+ const arr = [1, 2, 3, 4, 5];
242
+ const doSomething = () => Promise.resolve();
243
+
244
+ const res = await filter(arr, async v => {
245
+ await doSomething();
246
+ return (v % 2) == 1;
247
+ });
248
+ expect(res).toStrictEqual([1, 3, 5]);
249
+ });
250
+
251
+ it('index arg test', async () => {
252
+ const arr = [1, 2, 3, 4, 5];
253
+ const doSomething = () => Promise.resolve();
254
+
255
+ const res = await filter(arr, async (v, i) => {
256
+ await doSomething();
257
+ return (i % 2) == 1;
258
+ });
259
+ expect(res).toStrictEqual([2, 4]);
260
+ });
261
+ });
262
+
263
+ describe('#chunks', () => {
264
+ it('works.', () => {
265
+ const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0];
266
+ expect(chunks(arr, 3)).toStrictEqual([[1, 2, 3], [4, 5, 6], [7, 8, 9], [0]]);
267
+ });
268
+
269
+ it('if set size to 0, chunk size is arr.length', () => {
270
+ const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0];
271
+ expect(chunks(arr, 0)).toStrictEqual([[1, 2, 3, 4, 5, 6, 7, 8, 9, 0]]);
272
+ });
273
+
274
+ it('if given array is smaller than size, chunk size is arr.length', () => {
275
+ const arr = [1, 2, 3];
276
+ expect(chunks(arr, 10)).toStrictEqual([[1, 2, 3]]);
277
+ });
278
+ });
279
+
280
+ describe('#parseDate', () => {
281
+ it('works.', () => {
282
+ const date = parseDate('2019-12-25');
283
+ expect(date.year).toBe(2019);
284
+ expect(date.month).toBe(12);
285
+ expect(date.day).toBe(25);
286
+ expect(date.date).toBeInstanceOf(Date);
287
+ expect(date.toDateString()).toBe('2019-12-25');
288
+ });
289
+
290
+ it('also works.', () => {
291
+ const date = parseDate('2019-1-5');
292
+ expect(date.year).toBe(2019);
293
+ expect(date.month).toBe(1);
294
+ expect(date.day).toBe(5);
295
+ expect(date.date).toBeInstanceOf(Date);
296
+ expect(date.toDateString()).toBe('2019-01-05');
297
+ });
298
+ });
299
+
300
+ describe('#diffDays', () => {
301
+ it('works.', () => {
302
+ const d1 = new Date('2020-01-01');
303
+ const d2 = new Date('2020-01-10');
304
+ expect(diffDays(d1, d2)).toBe(9);
305
+ });
306
+
307
+ it('also can using date as string.', () => {
308
+ expect(diffDays('2020-02-24', '2020-03-02')).toBe(7);
309
+ });
310
+ });
311
+
312
+ describe('#getDates', () => {
313
+ it('works.', () => {
314
+ expect(getDates('2020-01-01~2020-01-05')).toStrictEqual([
315
+ '2020-01-01',
316
+ '2020-01-02',
317
+ '2020-01-03',
318
+ '2020-01-04',
319
+ '2020-01-05',
320
+ ]);
321
+ });
322
+ });