bod 5.15.2 → 5.16.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/dist/bod.js +2 -1
- package/dist/commands/__tests__/BaseCommand.test.d.ts +1 -0
- package/dist/commands/__tests__/BaseCommand.test.js +36 -0
- package/dist/commands/__tests__/CreateCommand.test.d.ts +1 -0
- package/dist/commands/__tests__/CreateCommand.test.js +82 -0
- package/dist/commands/__tests__/InfoCommand.test.d.ts +1 -0
- package/dist/commands/__tests__/InfoCommand.test.js +24 -0
- package/dist/commands/__tests__/index.test.d.ts +1 -0
- package/dist/commands/__tests__/index.test.js +65 -0
- package/dist/utils/__tests__/index.test.d.ts +1 -0
- package/dist/utils/__tests__/index.test.js +13 -0
- package/package.json +7 -6
package/dist/bod.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var _a;
|
|
2
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
4
|
const tslib_1 = require("tslib");
|
|
4
5
|
const node_fs_1 = tslib_1.__importDefault(require("node:fs"));
|
|
@@ -8,7 +9,7 @@ const utils_1 = require("./utils");
|
|
|
8
9
|
const index_1 = require("./index");
|
|
9
10
|
const packageJsonPath = node_path_1.default.join(__dirname, '../package.json');
|
|
10
11
|
const packageJson = JSON.parse(node_fs_1.default.readFileSync(packageJsonPath, { encoding: 'utf-8' }));
|
|
11
|
-
utils_1.program.version(packageJson.version, '-v, --version');
|
|
12
|
+
utils_1.program.version((_a = packageJson.version) !== null && _a !== void 0 ? _a : '0.0.1', '-v, --version');
|
|
12
13
|
for (const command of index_1.CommandFactory.values()) {
|
|
13
14
|
utils_1.program
|
|
14
15
|
.command(command.getUsage())
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const tslib_1 = require("tslib");
|
|
4
|
+
const BaseCommand_1 = tslib_1.__importDefault(require("../BaseCommand"));
|
|
5
|
+
const options = {
|
|
6
|
+
name: 'base',
|
|
7
|
+
description: 'Base command description',
|
|
8
|
+
usage: 'base',
|
|
9
|
+
alias: 'c',
|
|
10
|
+
};
|
|
11
|
+
describe('baseCommand', () => {
|
|
12
|
+
it('should have [name] field', () => {
|
|
13
|
+
const baseCommand = new BaseCommand_1.default(options);
|
|
14
|
+
expect(baseCommand.getName()).toBe(options.name);
|
|
15
|
+
});
|
|
16
|
+
it('should have [description] field', () => {
|
|
17
|
+
const baseCommand = new BaseCommand_1.default(options);
|
|
18
|
+
expect(baseCommand.getDescription()).toBe(options.description);
|
|
19
|
+
});
|
|
20
|
+
it('should have [usage] field', () => {
|
|
21
|
+
const baseCommand = new BaseCommand_1.default(options);
|
|
22
|
+
expect(baseCommand.getUsage()).toBe(options.usage);
|
|
23
|
+
});
|
|
24
|
+
it('should have [alias] field', () => {
|
|
25
|
+
const baseCommand = new BaseCommand_1.default(options);
|
|
26
|
+
expect(baseCommand.getAlias()).toBe(options.alias);
|
|
27
|
+
});
|
|
28
|
+
it('should set [alias] field to first character of [name] field by default', () => {
|
|
29
|
+
const baseCommand = new BaseCommand_1.default(Object.assign(Object.assign({}, options), { alias: undefined }));
|
|
30
|
+
expect(baseCommand.getAlias()).toBe(options.name[0]);
|
|
31
|
+
});
|
|
32
|
+
it('should have [run] method', () => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
|
|
33
|
+
const baseCommand = new BaseCommand_1.default(options);
|
|
34
|
+
yield expect(baseCommand.run()).resolves.toBeUndefined();
|
|
35
|
+
}));
|
|
36
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const tslib_1 = require("tslib");
|
|
4
|
+
const node_path_1 = tslib_1.__importDefault(require("node:path"));
|
|
5
|
+
const ci_info_1 = require("ci-info");
|
|
6
|
+
const rimraf_1 = require("rimraf");
|
|
7
|
+
const utils_1 = require("../../utils");
|
|
8
|
+
const CreateCommand_1 = tslib_1.__importDefault(require("../CreateCommand"));
|
|
9
|
+
const appPath = node_path_1.default.join(process.cwd(), '..', 'bod-unit-tests');
|
|
10
|
+
describe('createCommand', () => {
|
|
11
|
+
beforeEach(() => (0, rimraf_1.sync)(appPath));
|
|
12
|
+
afterEach(() => (0, rimraf_1.sync)(appPath));
|
|
13
|
+
it('should extends [BaseCommand] fields', () => {
|
|
14
|
+
const createCommand = new CreateCommand_1.default();
|
|
15
|
+
expect(createCommand.getName()).toBe('create');
|
|
16
|
+
expect(createCommand.getDescription()).toBe('Create a new project powered by @sabertazimi/react-scripts');
|
|
17
|
+
expect(createCommand.getUsage()).toBe('create <appName>');
|
|
18
|
+
expect(createCommand.getAlias()).toBe('c');
|
|
19
|
+
});
|
|
20
|
+
it.each(CreateCommand_1.default.TemplateActions)('should get correct command/args and invoke [inquirer] via template choice [$name]', (_a) => tslib_1.__awaiter(void 0, [_a], void 0, function* ({ value }) {
|
|
21
|
+
const mockPrompt = jest
|
|
22
|
+
.spyOn(utils_1.inquirer, 'prompt')
|
|
23
|
+
.mockImplementation(() => {
|
|
24
|
+
const promise = new Promise((resolve) => {
|
|
25
|
+
resolve({ templateName: value });
|
|
26
|
+
});
|
|
27
|
+
return promise;
|
|
28
|
+
});
|
|
29
|
+
const mockSpawn = jest.spyOn(utils_1.spawn, 'sync').mockImplementation(() => {
|
|
30
|
+
return {
|
|
31
|
+
status: 0,
|
|
32
|
+
};
|
|
33
|
+
});
|
|
34
|
+
const createCommand = new CreateCommand_1.default();
|
|
35
|
+
yield expect(createCommand.run(appPath)).resolves.toBeUndefined();
|
|
36
|
+
const { command, args } = CreateCommand_1.default.TemplateActions.find(action => action.value === value);
|
|
37
|
+
expect(createCommand.getCommand()).toBe(command);
|
|
38
|
+
expect(createCommand.getCommandArgs()).toHaveLength(args.length + 1);
|
|
39
|
+
expect(createCommand.getCommandArgs()).toStrictEqual(args.concat(appPath));
|
|
40
|
+
expect(mockPrompt).toBeCalledTimes(1);
|
|
41
|
+
expect(mockSpawn).toBeCalledTimes(1);
|
|
42
|
+
mockPrompt.mockRestore();
|
|
43
|
+
mockSpawn.mockRestore();
|
|
44
|
+
}));
|
|
45
|
+
it.each(CreateCommand_1.default.TemplateActions)('should throw error when exited with non zero via template choice [$name]', (_b) => tslib_1.__awaiter(void 0, [_b], void 0, function* ({ value }) {
|
|
46
|
+
const mockPrompt = jest
|
|
47
|
+
.spyOn(utils_1.inquirer, 'prompt')
|
|
48
|
+
.mockImplementation(() => {
|
|
49
|
+
const promise = new Promise((resolve) => {
|
|
50
|
+
resolve({ templateName: value });
|
|
51
|
+
});
|
|
52
|
+
return promise;
|
|
53
|
+
});
|
|
54
|
+
const mockSpawn = jest.spyOn(utils_1.spawn, 'sync').mockImplementation(() => {
|
|
55
|
+
return {
|
|
56
|
+
status: 1,
|
|
57
|
+
};
|
|
58
|
+
});
|
|
59
|
+
const createCommand = new CreateCommand_1.default();
|
|
60
|
+
yield expect(createCommand.run(appPath)).rejects.toThrowError();
|
|
61
|
+
expect(mockPrompt).toBeCalledTimes(1);
|
|
62
|
+
expect(mockSpawn).toBeCalledTimes(1);
|
|
63
|
+
mockPrompt.mockRestore();
|
|
64
|
+
mockSpawn.mockRestore();
|
|
65
|
+
}));
|
|
66
|
+
it.each(CreateCommand_1.default.TemplateActions)('should initialize app directory via template choice [$name]', (_c) => tslib_1.__awaiter(void 0, [_c], void 0, function* ({ value }) {
|
|
67
|
+
const mockPrompt = jest
|
|
68
|
+
.spyOn(utils_1.inquirer, 'prompt')
|
|
69
|
+
.mockImplementation(() => {
|
|
70
|
+
const promise = new Promise((resolve) => {
|
|
71
|
+
resolve({ templateName: value });
|
|
72
|
+
});
|
|
73
|
+
return promise;
|
|
74
|
+
});
|
|
75
|
+
const createCommand = new CreateCommand_1.default();
|
|
76
|
+
if (ci_info_1.isCI) {
|
|
77
|
+
yield expect(createCommand.run(appPath)).resolves.toBeUndefined();
|
|
78
|
+
expect(mockPrompt).toBeCalledTimes(1);
|
|
79
|
+
}
|
|
80
|
+
mockPrompt.mockRestore();
|
|
81
|
+
}));
|
|
82
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const tslib_1 = require("tslib");
|
|
4
|
+
const utils_1 = require("../../utils");
|
|
5
|
+
const InfoCommand_1 = tslib_1.__importDefault(require("../InfoCommand"));
|
|
6
|
+
describe('infoCommand', () => {
|
|
7
|
+
jest.setTimeout(20000);
|
|
8
|
+
it('should extends [BaseCommand] fields', () => {
|
|
9
|
+
const infoCommand = new InfoCommand_1.default();
|
|
10
|
+
expect(infoCommand.getName()).toBe('info');
|
|
11
|
+
expect(infoCommand.getDescription()).toBe('Print debugging information about your environment');
|
|
12
|
+
expect(infoCommand.getUsage()).toBe('info');
|
|
13
|
+
expect(infoCommand.getAlias()).toBe('i');
|
|
14
|
+
});
|
|
15
|
+
it('should print environment variables', () => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
|
|
16
|
+
const mockConsoleInfo = jest
|
|
17
|
+
.spyOn(utils_1.printer, 'info')
|
|
18
|
+
.mockImplementation(jest.fn());
|
|
19
|
+
const infoCommand = new InfoCommand_1.default();
|
|
20
|
+
yield expect(infoCommand.run()).resolves.toBeUndefined();
|
|
21
|
+
expect(mockConsoleInfo).toHaveBeenCalledTimes(2);
|
|
22
|
+
mockConsoleInfo.mockRestore();
|
|
23
|
+
}));
|
|
24
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const index_1 = require("../index");
|
|
4
|
+
describe('commands', () => {
|
|
5
|
+
let commands;
|
|
6
|
+
let counts;
|
|
7
|
+
beforeEach(() => {
|
|
8
|
+
commands = new Set([
|
|
9
|
+
new index_1.BaseCommand({
|
|
10
|
+
name: 'base',
|
|
11
|
+
description: 'Base command description',
|
|
12
|
+
usage: 'base',
|
|
13
|
+
}),
|
|
14
|
+
new index_1.CreateCommand(),
|
|
15
|
+
new index_1.InfoCommand(),
|
|
16
|
+
]);
|
|
17
|
+
counts = new Map();
|
|
18
|
+
});
|
|
19
|
+
afterEach(() => {
|
|
20
|
+
commands.clear();
|
|
21
|
+
counts.clear();
|
|
22
|
+
});
|
|
23
|
+
it('should has unique name', () => {
|
|
24
|
+
for (const command of commands) {
|
|
25
|
+
const name = command.getName();
|
|
26
|
+
if (counts.has(name))
|
|
27
|
+
counts.set(name, counts.get(name) + 1);
|
|
28
|
+
else
|
|
29
|
+
counts.set(name, 1);
|
|
30
|
+
expect(command).toBeDefined();
|
|
31
|
+
}
|
|
32
|
+
for (const [name, count] of counts) {
|
|
33
|
+
expect(name).toBeTruthy();
|
|
34
|
+
expect(count).toBe(1);
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
it('should has unique usage', () => {
|
|
38
|
+
for (const command of commands) {
|
|
39
|
+
const usage = command.getUsage();
|
|
40
|
+
if (counts.has(usage))
|
|
41
|
+
counts.set(usage, counts.get(usage) + 1);
|
|
42
|
+
else
|
|
43
|
+
counts.set(usage, 1);
|
|
44
|
+
expect(command).toBeDefined();
|
|
45
|
+
}
|
|
46
|
+
for (const [usage, count] of counts) {
|
|
47
|
+
expect(usage).toBeTruthy();
|
|
48
|
+
expect(count).toBe(1);
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
it('should has unique alias', () => {
|
|
52
|
+
for (const command of commands) {
|
|
53
|
+
const alias = command.getAlias();
|
|
54
|
+
if (counts.has(alias))
|
|
55
|
+
counts.set(alias, counts.get(alias) + 1);
|
|
56
|
+
else
|
|
57
|
+
counts.set(alias, 1);
|
|
58
|
+
expect(command).toBeDefined();
|
|
59
|
+
}
|
|
60
|
+
for (const [alias, count] of counts) {
|
|
61
|
+
expect(alias).toBeTruthy();
|
|
62
|
+
expect(count).toBe(1);
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const index_1 = require("../index");
|
|
4
|
+
describe('utils', () => {
|
|
5
|
+
it('should execute chalk correctly', () => {
|
|
6
|
+
expect((0, index_1.color)('raw text')).toStrictEqual('raw text');
|
|
7
|
+
});
|
|
8
|
+
it('should execute program correctly', () => {
|
|
9
|
+
const mockParse = jest.spyOn(index_1.program, 'parse').mockImplementation(jest.fn());
|
|
10
|
+
expect(process.env.__BOD__).toStrictEqual('__BOD__');
|
|
11
|
+
mockParse.mockRestore();
|
|
12
|
+
});
|
|
13
|
+
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "bod",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.16.0",
|
|
4
4
|
"description": "Boilerplate CLI App",
|
|
5
5
|
"author": "sabertazimi <sabertazimi@gmail.com>",
|
|
6
6
|
"license": "MIT",
|
|
@@ -30,11 +30,11 @@
|
|
|
30
30
|
"types": "dist/index.d.ts",
|
|
31
31
|
"bin": "bin/bod.js",
|
|
32
32
|
"files": [
|
|
33
|
+
"!dist/**/*.test.d.ts",
|
|
34
|
+
"!dist/**/*.test.js",
|
|
33
35
|
"bin/bod.js",
|
|
34
|
-
"dist/**/*.js",
|
|
35
36
|
"dist/**/*.d.ts",
|
|
36
|
-
"
|
|
37
|
-
"!dist/**/*.test.d.ts"
|
|
37
|
+
"dist/**/*.js"
|
|
38
38
|
],
|
|
39
39
|
"engines": {
|
|
40
40
|
"node": ">=18.0.0"
|
|
@@ -65,7 +65,8 @@
|
|
|
65
65
|
"@types/inquirer": "^8.2.10",
|
|
66
66
|
"@types/rimraf": "^4.0.5",
|
|
67
67
|
"ci-info": "^4.0.0",
|
|
68
|
-
"rimraf": "^5.0.5"
|
|
68
|
+
"rimraf": "^5.0.5",
|
|
69
|
+
"type-fest": "^4.14.0"
|
|
69
70
|
},
|
|
70
|
-
"gitHead": "
|
|
71
|
+
"gitHead": "5fc2f0beb64314994b9b2c4915533c289bc066e7"
|
|
71
72
|
}
|