webext-schema 6.0.0 → 7.0.0
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/.github/FUNDING.yml +13 -0
- package/.github/workflows/node.js.yml +31 -0
- package/eslint.config.mjs +52 -0
- package/modules/schema.js +3 -4
- package/modules/update.js +0 -5
- package/package.json +13 -14
- package/schemas/beta/webext.json +9 -6
- package/schemas/central/webext.json +6 -3
- package/schemas/mail/mailext.json +312 -90
- package/test/browser.test.js +3040 -0
- package/test/commander.test.js +134 -0
- package/test/common.test.js +120 -0
- package/test/constant.test.js +34 -0
- package/test/file/test 2.cmd +2 -0
- package/test/file/test 2.sh +2 -0
- package/test/file/test.cmd +2 -0
- package/test/file/test.js +1 -0
- package/test/file/test.sh +2 -0
- package/test/file/test.txt +1 -0
- package/test/file-util.test.js +370 -0
- package/test/index.test.js +13 -0
- package/test/mocha/setup.js +40 -0
- package/test/schema.test.js +1280 -0
- package/test/update.test.js +1022 -0
- package/types/modules/update.d.ts +0 -1
- package/schemas/esr/webext.json +0 -21462
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
/* api */
|
|
2
|
+
import { strict as assert } from 'node:assert';
|
|
3
|
+
import fs from 'node:fs';
|
|
4
|
+
import path from 'node:path';
|
|
5
|
+
import sinon from 'sinon';
|
|
6
|
+
import { describe, it } from 'mocha';
|
|
7
|
+
|
|
8
|
+
/* test */
|
|
9
|
+
import {
|
|
10
|
+
commander, cleanDirectory, parseCommand
|
|
11
|
+
} from '../modules/commander.js';
|
|
12
|
+
|
|
13
|
+
describe('clean directory', () => {
|
|
14
|
+
it('should not call funtion', () => {
|
|
15
|
+
const stubRm = sinon.stub(fs, 'rmSync');
|
|
16
|
+
const dir = path.resolve('foo');
|
|
17
|
+
cleanDirectory({ dir });
|
|
18
|
+
const { called: rmCalled } = stubRm;
|
|
19
|
+
stubRm.restore();
|
|
20
|
+
assert.strictEqual(rmCalled, false, 'not called');
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
it('should call funtion', () => {
|
|
24
|
+
const stubRm = sinon.stub(fs, 'rmSync');
|
|
25
|
+
const stubInfo = sinon.stub(console, 'info');
|
|
26
|
+
const dir = path.resolve('test', 'file');
|
|
27
|
+
cleanDirectory({ dir });
|
|
28
|
+
const { calledOnce: rmCalled } = stubRm;
|
|
29
|
+
const { called: infoCalled } = stubInfo;
|
|
30
|
+
stubRm.restore();
|
|
31
|
+
stubInfo.restore();
|
|
32
|
+
assert.strictEqual(rmCalled, true, 'called');
|
|
33
|
+
assert.strictEqual(infoCalled, false, 'not called');
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
it('should call funtion', () => {
|
|
37
|
+
const stubRm = sinon.stub(fs, 'rmSync');
|
|
38
|
+
const stubInfo = sinon.stub(console, 'info');
|
|
39
|
+
const dir = path.resolve('test', 'file');
|
|
40
|
+
cleanDirectory({ dir, info: true });
|
|
41
|
+
const { calledOnce: rmCalled } = stubRm;
|
|
42
|
+
const { calledOnce: infoCalled } = stubInfo;
|
|
43
|
+
stubRm.restore();
|
|
44
|
+
stubInfo.restore();
|
|
45
|
+
assert.strictEqual(rmCalled, true, 'called');
|
|
46
|
+
assert.strictEqual(infoCalled, true, 'called');
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
describe('parse command', () => {
|
|
51
|
+
it('should not parse', () => {
|
|
52
|
+
const stubParse = sinon.stub(commander, 'parse');
|
|
53
|
+
const i = stubParse.callCount;
|
|
54
|
+
parseCommand();
|
|
55
|
+
assert.strictEqual(stubParse.callCount, i, 'not called');
|
|
56
|
+
stubParse.restore();
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
it('should not parse', () => {
|
|
60
|
+
const stubParse = sinon.stub(commander, 'parse');
|
|
61
|
+
const i = stubParse.callCount;
|
|
62
|
+
parseCommand([]);
|
|
63
|
+
assert.strictEqual(stubParse.callCount, i, 'not called');
|
|
64
|
+
stubParse.restore();
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
it('should not parse', () => {
|
|
68
|
+
const stubParse = sinon.stub(commander, 'parse');
|
|
69
|
+
const i = stubParse.callCount;
|
|
70
|
+
parseCommand([
|
|
71
|
+
'foo',
|
|
72
|
+
'bar',
|
|
73
|
+
'baz'
|
|
74
|
+
]);
|
|
75
|
+
assert.strictEqual(stubParse.callCount, i, 'not called');
|
|
76
|
+
stubParse.restore();
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
it('should parse', () => {
|
|
80
|
+
const stubParse = sinon.stub(commander, 'parse');
|
|
81
|
+
const stubVer = sinon.stub(commander, 'version');
|
|
82
|
+
const i = stubParse.callCount;
|
|
83
|
+
const j = stubVer.callCount;
|
|
84
|
+
parseCommand([
|
|
85
|
+
'foo',
|
|
86
|
+
'bar',
|
|
87
|
+
'-v'
|
|
88
|
+
]);
|
|
89
|
+
assert.strictEqual(stubParse.callCount, i + 1, 'called');
|
|
90
|
+
assert.strictEqual(stubVer.callCount, j + 1, 'called');
|
|
91
|
+
stubParse.restore();
|
|
92
|
+
stubVer.restore();
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
it('should parse', () => {
|
|
96
|
+
const stubParse = sinon.stub(commander, 'parse');
|
|
97
|
+
const stubVer = sinon.stub(commander, 'version');
|
|
98
|
+
const spyCmd = sinon.spy(commander, 'command');
|
|
99
|
+
const i = stubParse.callCount;
|
|
100
|
+
const j = stubVer.callCount;
|
|
101
|
+
const k = spyCmd.callCount;
|
|
102
|
+
parseCommand([
|
|
103
|
+
'foo',
|
|
104
|
+
'bar',
|
|
105
|
+
'clean'
|
|
106
|
+
]);
|
|
107
|
+
assert.strictEqual(stubParse.callCount, i + 1, 'called');
|
|
108
|
+
assert.strictEqual(stubVer.callCount, j + 1, 'called');
|
|
109
|
+
assert.strictEqual(spyCmd.callCount, k + 1, 'called');
|
|
110
|
+
stubParse.restore();
|
|
111
|
+
stubVer.restore();
|
|
112
|
+
spyCmd.restore();
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
it('should parse', () => {
|
|
116
|
+
const stubParse = sinon.stub(commander, 'parse');
|
|
117
|
+
const stubVer = sinon.stub(commander, 'version');
|
|
118
|
+
const spyCmd = sinon.spy(commander, 'command');
|
|
119
|
+
const i = stubParse.callCount;
|
|
120
|
+
const j = stubVer.callCount;
|
|
121
|
+
const k = spyCmd.callCount;
|
|
122
|
+
parseCommand([
|
|
123
|
+
'foo',
|
|
124
|
+
'bar',
|
|
125
|
+
'update'
|
|
126
|
+
]);
|
|
127
|
+
assert.strictEqual(stubParse.callCount, i + 1, 'called');
|
|
128
|
+
assert.strictEqual(stubVer.callCount, j + 1, 'called');
|
|
129
|
+
assert.strictEqual(spyCmd.callCount, k + 1, 'called');
|
|
130
|
+
stubParse.restore();
|
|
131
|
+
stubVer.restore();
|
|
132
|
+
spyCmd.restore();
|
|
133
|
+
});
|
|
134
|
+
});
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
/* api */
|
|
2
|
+
import { strict as assert } from 'node:assert';
|
|
3
|
+
import sinon from 'sinon';
|
|
4
|
+
import { describe, it } from 'mocha';
|
|
5
|
+
|
|
6
|
+
/* test */
|
|
7
|
+
import {
|
|
8
|
+
getType, isObjectNotEmpty, isString, logErr, logMsg, logWarn, throwErr
|
|
9
|
+
} from '../modules/common.js';
|
|
10
|
+
|
|
11
|
+
describe('getType', () => {
|
|
12
|
+
it('should get Undefined', () => {
|
|
13
|
+
assert.strictEqual(getType(), 'Undefined');
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
it('should get Null', () => {
|
|
17
|
+
assert.strictEqual(getType(null), 'Null');
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
it('should get Object', () => {
|
|
21
|
+
assert.strictEqual(getType({}), 'Object');
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
it('should get Array', () => {
|
|
25
|
+
assert.strictEqual(getType([]), 'Array');
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
it('should get Boolean', () => {
|
|
29
|
+
assert.strictEqual(getType(true), 'Boolean');
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
it('should get Number', () => {
|
|
33
|
+
assert.strictEqual(getType(1), 'Number');
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
it('should get String', () => {
|
|
37
|
+
assert.strictEqual(getType('a'), 'String');
|
|
38
|
+
});
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
describe('isObjectNotEmpty', () => {
|
|
42
|
+
it('should get false', () => {
|
|
43
|
+
const items = [{}, [], ['foo'], '', 'foo', undefined, null, 1, true];
|
|
44
|
+
for (const item of items) {
|
|
45
|
+
assert.strictEqual(isObjectNotEmpty(item), false);
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
it('should get true', () => {
|
|
50
|
+
const item = {
|
|
51
|
+
foo: 'bar'
|
|
52
|
+
};
|
|
53
|
+
assert.strictEqual(isObjectNotEmpty(item), true);
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
describe('isString', () => {
|
|
58
|
+
it('should get true if string is given', () => {
|
|
59
|
+
assert.strictEqual(isString('a'), true);
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
it('should get false if given argument is not string', () => {
|
|
63
|
+
assert.strictEqual(isString(1), false);
|
|
64
|
+
});
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
describe('logErr', () => {
|
|
68
|
+
it('should get false', () => {
|
|
69
|
+
const msg = 'Log Error test';
|
|
70
|
+
let errMsg;
|
|
71
|
+
const consoleError = sinon.stub(console, 'error').callsFake(e => {
|
|
72
|
+
errMsg = e.message;
|
|
73
|
+
});
|
|
74
|
+
const res = logErr(new Error(msg));
|
|
75
|
+
const { calledOnce } = consoleError;
|
|
76
|
+
consoleError.restore();
|
|
77
|
+
assert.strictEqual(calledOnce, true);
|
|
78
|
+
assert.strictEqual(errMsg, msg);
|
|
79
|
+
assert.strictEqual(res, false);
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
describe('logMsg', () => {
|
|
84
|
+
it('should get string', () => {
|
|
85
|
+
const msg = 'Log message test';
|
|
86
|
+
let logMessage;
|
|
87
|
+
const consoleLog = sinon.stub(console, 'log').callsFake(m => {
|
|
88
|
+
logMessage = m;
|
|
89
|
+
});
|
|
90
|
+
const res = logMsg(msg);
|
|
91
|
+
const { calledOnce } = consoleLog;
|
|
92
|
+
consoleLog.restore();
|
|
93
|
+
assert.strictEqual(calledOnce, true);
|
|
94
|
+
assert.strictEqual(logMessage, msg);
|
|
95
|
+
assert.strictEqual(res, msg);
|
|
96
|
+
});
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
describe('logWarn', () => {
|
|
100
|
+
it('should get false', () => {
|
|
101
|
+
const msg = 'Log warn test';
|
|
102
|
+
let warnMsg;
|
|
103
|
+
const consoleWarn = sinon.stub(console, 'warn').callsFake(m => {
|
|
104
|
+
warnMsg = m;
|
|
105
|
+
});
|
|
106
|
+
const res = logWarn(msg);
|
|
107
|
+
const { calledOnce } = consoleWarn;
|
|
108
|
+
consoleWarn.restore();
|
|
109
|
+
assert.strictEqual(calledOnce, true);
|
|
110
|
+
assert.strictEqual(warnMsg, msg);
|
|
111
|
+
assert.strictEqual(res, false);
|
|
112
|
+
});
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
describe('throwErr', () => {
|
|
116
|
+
it('should throw', () => {
|
|
117
|
+
const e = new Error('Error');
|
|
118
|
+
assert.throws(() => throwErr(e));
|
|
119
|
+
});
|
|
120
|
+
});
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/* api */
|
|
2
|
+
import { strict as assert } from 'node:assert';
|
|
3
|
+
import { describe, it } from 'mocha';
|
|
4
|
+
import { isString } from '../modules/common.js';
|
|
5
|
+
|
|
6
|
+
/* test */
|
|
7
|
+
import { CHAR, INDENT, IS_WIN } from '../modules/constant.js';
|
|
8
|
+
|
|
9
|
+
describe('string constants', () => {
|
|
10
|
+
it('should get string', () => {
|
|
11
|
+
const arr = [CHAR];
|
|
12
|
+
arr.forEach(i => {
|
|
13
|
+
assert.strictEqual(isString(i), true);
|
|
14
|
+
});
|
|
15
|
+
});
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
describe('number constants', () => {
|
|
19
|
+
it('should get number', () => {
|
|
20
|
+
const arr = [INDENT];
|
|
21
|
+
arr.forEach(i => {
|
|
22
|
+
assert.strictEqual(typeof i, 'number');
|
|
23
|
+
});
|
|
24
|
+
});
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
describe('boolean constants', () => {
|
|
28
|
+
it('should get boolean', () => {
|
|
29
|
+
const arr = [IS_WIN];
|
|
30
|
+
arr.forEach(i => {
|
|
31
|
+
assert.strictEqual(typeof i, 'boolean');
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
'use strict';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
test file
|
|
@@ -0,0 +1,370 @@
|
|
|
1
|
+
/* api */
|
|
2
|
+
import { strict as assert } from 'node:assert';
|
|
3
|
+
import fs from 'node:fs';
|
|
4
|
+
import os from 'node:os';
|
|
5
|
+
import path from 'node:path';
|
|
6
|
+
import process from 'node:process';
|
|
7
|
+
import { describe, it } from 'mocha';
|
|
8
|
+
import { IS_WIN } from '../modules/constant.js';
|
|
9
|
+
|
|
10
|
+
/* test */
|
|
11
|
+
import {
|
|
12
|
+
convertUriToFilePath, createDirectory, createFile,
|
|
13
|
+
getAbsPath, getFileNameFromFilePath, getFileTimestamp, getStat,
|
|
14
|
+
isDir, isExecutable, isFile, isSubDir, removeDir, removeDirectory, readFile
|
|
15
|
+
} from '../modules/file-util.js';
|
|
16
|
+
|
|
17
|
+
/* constants */
|
|
18
|
+
const DIR_CWD = process.cwd();
|
|
19
|
+
const PERM_EXEC = 0o700;
|
|
20
|
+
const PERM_FILE = 0o600;
|
|
21
|
+
const TMPDIR = process.env.TMP || process.env.TMPDIR || process.env.TEMP ||
|
|
22
|
+
os.tmpdir();
|
|
23
|
+
|
|
24
|
+
describe('convertUriToFilePath', () => {
|
|
25
|
+
it('should get string', () => {
|
|
26
|
+
const p = path.resolve('foo/bar');
|
|
27
|
+
let u;
|
|
28
|
+
if (IS_WIN) {
|
|
29
|
+
const reg = new RegExp(`\\${path.sep}`, 'g');
|
|
30
|
+
u = new URL(`file:///${p.replace(reg, '/')}`).href;
|
|
31
|
+
} else {
|
|
32
|
+
u = new URL(`file://${p}`).href;
|
|
33
|
+
}
|
|
34
|
+
assert.strictEqual(convertUriToFilePath(u), p);
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
it('should get string', () => {
|
|
38
|
+
const p = path.resolve('foo/bar baz');
|
|
39
|
+
let u;
|
|
40
|
+
if (IS_WIN) {
|
|
41
|
+
const reg = new RegExp(`\\${path.sep}`, 'g');
|
|
42
|
+
u = new URL(`file:///${p.replace(reg, '/')}`).href;
|
|
43
|
+
} else {
|
|
44
|
+
u = new URL(`file://${p}`).href;
|
|
45
|
+
}
|
|
46
|
+
assert.strictEqual(convertUriToFilePath(u), p);
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
it('should get string', () => {
|
|
50
|
+
const p = path.resolve('/foo/bar/baz');
|
|
51
|
+
let u;
|
|
52
|
+
if (IS_WIN) {
|
|
53
|
+
const reg = new RegExp(`\\${path.sep}`, 'g');
|
|
54
|
+
u = new URL(`file:///${p.replace(reg, '/')}`).href;
|
|
55
|
+
} else {
|
|
56
|
+
u = new URL(`file://${p}`).href;
|
|
57
|
+
}
|
|
58
|
+
assert.strictEqual(convertUriToFilePath(u), p);
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
it('should get string', () => {
|
|
62
|
+
const p = path.resolve('/foo/bar/baz');
|
|
63
|
+
let u;
|
|
64
|
+
if (IS_WIN) {
|
|
65
|
+
const reg = new RegExp(`\\${path.sep}`, 'g');
|
|
66
|
+
u = new URL(`file://localhost/${p.replace(reg, '/')}`).href;
|
|
67
|
+
} else {
|
|
68
|
+
u = new URL(`file://localhost${p}`).href;
|
|
69
|
+
}
|
|
70
|
+
assert.strictEqual(convertUriToFilePath(u), p);
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
it('should throw if string is not given', () => {
|
|
74
|
+
assert.throws(() => convertUriToFilePath(), TypeError,
|
|
75
|
+
'Expected String but got Undefined');
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
it('should get null if protocol does not match', () => {
|
|
79
|
+
const uri = 'http://example.com';
|
|
80
|
+
assert.deepEqual(convertUriToFilePath(uri), null);
|
|
81
|
+
});
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
describe('createDirectory', () => {
|
|
85
|
+
it('should get string', async () => {
|
|
86
|
+
const dirString = path.join(TMPDIR, 'webext-schema', '1');
|
|
87
|
+
const dir = await createDirectory(dirString);
|
|
88
|
+
assert.strictEqual(dir, dirString);
|
|
89
|
+
fs.rmdirSync(dirString);
|
|
90
|
+
fs.rmdirSync(path.join(TMPDIR, 'webext-schema'));
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
it('should throw if given argument is not a string', async () => {
|
|
94
|
+
await createDirectory().catch(e => {
|
|
95
|
+
assert.deepStrictEqual(e,
|
|
96
|
+
new TypeError('Expected String but got Undefined.'));
|
|
97
|
+
});
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
it('should throw if given second argument is not a number', async () => {
|
|
101
|
+
await createDirectory('/foo/bar', 'baz').catch(e => {
|
|
102
|
+
assert.deepStrictEqual(e,
|
|
103
|
+
new TypeError('Expected Number but got String.'));
|
|
104
|
+
});
|
|
105
|
+
});
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
describe('createFile', () => {
|
|
109
|
+
it('should get string', async () => {
|
|
110
|
+
const dirPath = path.join(TMPDIR, 'webext-schema');
|
|
111
|
+
fs.mkdirSync(dirPath);
|
|
112
|
+
const filePath = path.join(dirPath, 'test.txt');
|
|
113
|
+
const value = 'test file.\n';
|
|
114
|
+
const file = await createFile(filePath, value, {
|
|
115
|
+
encoding: 'utf8', flag: 'w', mode: PERM_FILE
|
|
116
|
+
});
|
|
117
|
+
assert.strictEqual(file, filePath);
|
|
118
|
+
fs.unlinkSync(file);
|
|
119
|
+
fs.rmdirSync(dirPath);
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
it('should throw if first argument is not a string', () => {
|
|
123
|
+
createFile().catch(e => {
|
|
124
|
+
assert.deepStrictEqual(e,
|
|
125
|
+
new TypeError('Expected String but got Undefined.'));
|
|
126
|
+
});
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
it(
|
|
130
|
+
'should throw if second argument is not string, buffer, uint8array',
|
|
131
|
+
() => {
|
|
132
|
+
const file = path.join(TMPDIR, 'webext-schema', 'test.txt');
|
|
133
|
+
createFile(file).catch(e => {
|
|
134
|
+
assert.deepStrictEqual(e,
|
|
135
|
+
new TypeError('Expected String, Buffer, Uint8Array but got Undefined.'));
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
);
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
describe('removeDir', () => {
|
|
142
|
+
it("should remove dir and it's files", async () => {
|
|
143
|
+
const dirPath = path.join(TMPDIR, 'webext-schema');
|
|
144
|
+
fs.mkdirSync(dirPath);
|
|
145
|
+
const subDirPath = path.join(dirPath, 'foo');
|
|
146
|
+
fs.mkdirSync(subDirPath);
|
|
147
|
+
const filePath = path.join(subDirPath, 'test.txt');
|
|
148
|
+
const value = 'test file.\n';
|
|
149
|
+
await createFile(filePath, value, {
|
|
150
|
+
encoding: 'utf8', flag: 'w', mode: PERM_FILE
|
|
151
|
+
});
|
|
152
|
+
const res1 = await Promise.all([
|
|
153
|
+
fs.existsSync(dirPath),
|
|
154
|
+
fs.existsSync(subDirPath),
|
|
155
|
+
fs.existsSync(filePath)
|
|
156
|
+
]);
|
|
157
|
+
removeDir(dirPath, TMPDIR);
|
|
158
|
+
const res2 = await Promise.all([
|
|
159
|
+
fs.existsSync(dirPath),
|
|
160
|
+
fs.existsSync(subDirPath),
|
|
161
|
+
fs.existsSync(filePath)
|
|
162
|
+
]);
|
|
163
|
+
assert.deepEqual(res1, [true, true, true]);
|
|
164
|
+
assert.deepEqual(res2, [false, false, false]);
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
it('should ignore if dir is not a directory', () => {
|
|
168
|
+
const foo = path.resolve('foo');
|
|
169
|
+
assert.strictEqual(isDir(foo), false);
|
|
170
|
+
assert.doesNotThrow(() => removeDir(foo, TMPDIR));
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
it('should throw if dir is not subdirectory of base dir', async () => {
|
|
174
|
+
const dirPath = path.join(TMPDIR, 'webext-schema');
|
|
175
|
+
const foo = path.join(TMPDIR, 'foo');
|
|
176
|
+
await fs.mkdirSync(dirPath);
|
|
177
|
+
await fs.mkdirSync(foo);
|
|
178
|
+
assert.throws(() => removeDir(foo, dirPath), Error,
|
|
179
|
+
`${foo} is not a subdirectory of ${dirPath}.`);
|
|
180
|
+
await fs.rmdirSync(dirPath);
|
|
181
|
+
await fs.rmdirSync(foo);
|
|
182
|
+
});
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
describe('removeDirectory', () => {
|
|
186
|
+
it("should remove dir and it's files", async () => {
|
|
187
|
+
const dirPath = path.join(TMPDIR, 'webext-schema');
|
|
188
|
+
fs.mkdirSync(dirPath);
|
|
189
|
+
const subDirPath = path.join(dirPath, 'foo');
|
|
190
|
+
fs.mkdirSync(subDirPath);
|
|
191
|
+
const filePath = path.join(subDirPath, 'test.txt');
|
|
192
|
+
const value = 'test file.\n';
|
|
193
|
+
await createFile(filePath, value, {
|
|
194
|
+
encoding: 'utf8', flag: 'w', mode: PERM_FILE
|
|
195
|
+
});
|
|
196
|
+
const res1 = await Promise.all([
|
|
197
|
+
fs.existsSync(dirPath),
|
|
198
|
+
fs.existsSync(subDirPath),
|
|
199
|
+
fs.existsSync(filePath)
|
|
200
|
+
]);
|
|
201
|
+
await removeDirectory(dirPath, TMPDIR);
|
|
202
|
+
const res2 = await Promise.all([
|
|
203
|
+
fs.existsSync(dirPath),
|
|
204
|
+
fs.existsSync(subDirPath),
|
|
205
|
+
fs.existsSync(filePath)
|
|
206
|
+
]);
|
|
207
|
+
assert.deepEqual(res1, [true, true, true]);
|
|
208
|
+
assert.deepEqual(res2, [false, false, false]);
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
it('should ignore if dir is not a directory', async () => {
|
|
212
|
+
const foo = path.resolve('foo');
|
|
213
|
+
assert.strictEqual(isDir(foo), false);
|
|
214
|
+
await removeDirectory(foo, TMPDIR).catch(e => {
|
|
215
|
+
assert.isUndefined(e);
|
|
216
|
+
});
|
|
217
|
+
});
|
|
218
|
+
|
|
219
|
+
it('should throw if dir is not subdirectory of base dir', async () => {
|
|
220
|
+
const dirPath = path.join(TMPDIR, 'webext-schema');
|
|
221
|
+
const foo = path.join(TMPDIR, 'foo');
|
|
222
|
+
await fs.mkdirSync(dirPath);
|
|
223
|
+
await fs.mkdirSync(foo);
|
|
224
|
+
await removeDirectory(foo, dirPath).catch(e => {
|
|
225
|
+
assert.deepStrictEqual(e,
|
|
226
|
+
new Error(`${foo} is not a subdirectory of ${dirPath}.`));
|
|
227
|
+
});
|
|
228
|
+
await fs.rmdirSync(dirPath);
|
|
229
|
+
await fs.rmdirSync(foo);
|
|
230
|
+
});
|
|
231
|
+
});
|
|
232
|
+
|
|
233
|
+
describe('getAbsPath', () => {
|
|
234
|
+
it('should get string', () => {
|
|
235
|
+
const p = 'test.txt';
|
|
236
|
+
const n = path.resolve(DIR_CWD, p);
|
|
237
|
+
assert.strictEqual(getAbsPath(p), n);
|
|
238
|
+
});
|
|
239
|
+
|
|
240
|
+
it('should get string', () => {
|
|
241
|
+
const p = '~/test.txt';
|
|
242
|
+
const n = path.resolve(DIR_CWD, '~/test.txt');
|
|
243
|
+
assert.strictEqual(getAbsPath(p), n);
|
|
244
|
+
});
|
|
245
|
+
|
|
246
|
+
it('should get string', () => {
|
|
247
|
+
const p = 'bar/../foo/test.txt';
|
|
248
|
+
const n = path.resolve(DIR_CWD, 'foo/test.txt');
|
|
249
|
+
assert.strictEqual(getAbsPath(p), n);
|
|
250
|
+
});
|
|
251
|
+
|
|
252
|
+
it('should throw', () => {
|
|
253
|
+
assert.throws(() => getAbsPath(),
|
|
254
|
+
'Expected String but got Undefined');
|
|
255
|
+
});
|
|
256
|
+
});
|
|
257
|
+
|
|
258
|
+
describe('getFileNameFromFilePath', () => {
|
|
259
|
+
it('should get string', () => {
|
|
260
|
+
const p = path.resolve(path.join('test', 'file', 'test.sh'));
|
|
261
|
+
assert.strictEqual(getFileNameFromFilePath(p), 'test');
|
|
262
|
+
});
|
|
263
|
+
|
|
264
|
+
it('should get default string', () => {
|
|
265
|
+
const p = path.resolve(path.join('test', 'file'));
|
|
266
|
+
assert.strictEqual(getFileNameFromFilePath(p), 'index');
|
|
267
|
+
});
|
|
268
|
+
});
|
|
269
|
+
|
|
270
|
+
describe('getFileTimestamp', () => {
|
|
271
|
+
it('should get positive integer', () => {
|
|
272
|
+
const p = path.resolve(path.join('test', 'file', 'test.sh'));
|
|
273
|
+
assert.strictEqual(getFileTimestamp(p) > 0, true);
|
|
274
|
+
});
|
|
275
|
+
|
|
276
|
+
it('should get 0 if file does not exist', () => {
|
|
277
|
+
const p = path.resolve(path.join('test', 'file', 'foo.txt'));
|
|
278
|
+
assert.strictEqual(getFileTimestamp(p), 0);
|
|
279
|
+
});
|
|
280
|
+
});
|
|
281
|
+
|
|
282
|
+
describe('getStat', () => {
|
|
283
|
+
it('should be an object', () => {
|
|
284
|
+
const p = path.resolve(path.join('test', 'file', 'test.sh'));
|
|
285
|
+
assert.strictEqual(typeof getStat(p), 'object');
|
|
286
|
+
});
|
|
287
|
+
|
|
288
|
+
it('should get null if given argument is not string', () => {
|
|
289
|
+
assert.deepEqual(getStat(), null);
|
|
290
|
+
});
|
|
291
|
+
|
|
292
|
+
it('should get null if file does not exist', () => {
|
|
293
|
+
const p = path.resolve(path.join('test', 'file', 'foo.txt'));
|
|
294
|
+
assert.deepEqual(getStat(p), null);
|
|
295
|
+
});
|
|
296
|
+
});
|
|
297
|
+
|
|
298
|
+
describe('isDir', () => {
|
|
299
|
+
it('should get true if dir exists', () => {
|
|
300
|
+
const p = path.resolve(path.join('test', 'file'));
|
|
301
|
+
assert.strictEqual(isDir(p), true);
|
|
302
|
+
});
|
|
303
|
+
|
|
304
|
+
it('should get false if dir does not exist', () => {
|
|
305
|
+
const p = path.resolve(path.join('test', 'foo'));
|
|
306
|
+
assert.strictEqual(isDir(p), false);
|
|
307
|
+
});
|
|
308
|
+
});
|
|
309
|
+
|
|
310
|
+
describe('isExecutable', () => {
|
|
311
|
+
it('should get true if file is executable', () => {
|
|
312
|
+
const p = path.resolve(IS_WIN
|
|
313
|
+
? path.join('test', 'file', 'test.cmd')
|
|
314
|
+
: path.join('test', 'file', 'test.sh')
|
|
315
|
+
);
|
|
316
|
+
fs.chmodSync(p, PERM_EXEC);
|
|
317
|
+
assert.strictEqual(isExecutable(p), true);
|
|
318
|
+
});
|
|
319
|
+
|
|
320
|
+
it('should get false if file is not executable', () => {
|
|
321
|
+
const p = path.resolve(path.join('test', 'file', 'test.txt'));
|
|
322
|
+
assert.strictEqual(isExecutable(p), false);
|
|
323
|
+
});
|
|
324
|
+
|
|
325
|
+
it('should get false if file does not exist', () => {
|
|
326
|
+
const p = path.resolve(path.join('test', 'file', 'foo.txt'));
|
|
327
|
+
assert.strictEqual(isExecutable(p), false);
|
|
328
|
+
});
|
|
329
|
+
});
|
|
330
|
+
|
|
331
|
+
describe('isFile', () => {
|
|
332
|
+
it('should get true if file exists', () => {
|
|
333
|
+
const p = path.resolve(path.join('test', 'file', 'test.txt'));
|
|
334
|
+
assert.strictEqual(isFile(p), true);
|
|
335
|
+
});
|
|
336
|
+
|
|
337
|
+
it('should get false if file does not exist', () => {
|
|
338
|
+
const p = path.resolve(path.join('test', 'file', 'foo.txt'));
|
|
339
|
+
assert.strictEqual(isFile(p), false);
|
|
340
|
+
});
|
|
341
|
+
});
|
|
342
|
+
|
|
343
|
+
describe('isSubDir', () => {
|
|
344
|
+
it('should get true if dir is subdirectory of base dir', () => {
|
|
345
|
+
const d = path.resolve(path.join('test', 'file'));
|
|
346
|
+
const b = path.resolve('test');
|
|
347
|
+
assert.strictEqual(isSubDir(d, b), true);
|
|
348
|
+
});
|
|
349
|
+
|
|
350
|
+
it('should get false if dir is not subdirectory of base dir', () => {
|
|
351
|
+
const d = path.resolve('foo');
|
|
352
|
+
const b = path.resolve('test');
|
|
353
|
+
assert.strictEqual(isSubDir(d, b), false);
|
|
354
|
+
});
|
|
355
|
+
});
|
|
356
|
+
|
|
357
|
+
describe('readFile', () => {
|
|
358
|
+
it('should throw', async () => {
|
|
359
|
+
await readFile('foo/bar').catch(e => {
|
|
360
|
+
assert.strictEqual(e.message, 'foo/bar is not a file.');
|
|
361
|
+
});
|
|
362
|
+
});
|
|
363
|
+
|
|
364
|
+
it('should get file', async () => {
|
|
365
|
+
const p = path.resolve(path.join('test', 'file', 'test.txt'));
|
|
366
|
+
const opt = { encoding: 'utf8', flag: 'r' };
|
|
367
|
+
const file = await readFile(p, opt);
|
|
368
|
+
assert.strictEqual(file, 'test file\n');
|
|
369
|
+
});
|
|
370
|
+
});
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/* api */
|
|
2
|
+
import { strict as assert } from 'node:assert';
|
|
3
|
+
import { describe, it } from 'mocha';
|
|
4
|
+
|
|
5
|
+
/* test */
|
|
6
|
+
import { Schema } from '../index.js';
|
|
7
|
+
|
|
8
|
+
describe('Schema', () => {
|
|
9
|
+
it('should be instance of Schema', () => {
|
|
10
|
+
const schema = new Schema();
|
|
11
|
+
assert.strictEqual(schema instanceof Schema, true);
|
|
12
|
+
});
|
|
13
|
+
});
|