Skip to content

Commit 074e8de

Browse files
committed
test(cli): add test cases for basic commands
1 parent 1f09f90 commit 074e8de

File tree

7 files changed

+142
-63
lines changed

7 files changed

+142
-63
lines changed

.gitignore

+2-1
Original file line numberDiff line numberDiff line change
@@ -39,4 +39,5 @@ testem.log
3939
Thumbs.db
4040

4141
# testing folder from cli
42-
my-first-vulcan-project
42+
my-first-vulcan-project
43+
test-vulcan-project

packages/cli/src/cli.ts

+61
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
import { program } from 'commander';
2+
import { handleInit, handleStart, handleVersion } from './commands';
3+
import { handleBuild } from './commands/build';
4+
import { handleServe } from './commands/serve';
5+
6+
program.exitOverride();
7+
8+
program
9+
.command('version')
10+
.description('show the version of CLI and Vulcan packages')
11+
.action(async () => {
12+
await handleVersion();
13+
});
14+
15+
program
16+
.command('init')
17+
.description('create a new Vulcan project')
18+
.option('-p --project-name <project-name>', 'specify project name')
19+
.action(async (options) => {
20+
await handleInit(options);
21+
});
22+
23+
program
24+
.command('build')
25+
.description('build Vulcan project')
26+
.option(
27+
'-c --config <config-path>',
28+
'path to Vulcan config file',
29+
'./vulcan.yaml'
30+
)
31+
.action(async (options) => {
32+
await handleBuild(options);
33+
});
34+
35+
program
36+
.command('serve')
37+
.description('serve Vulcan project')
38+
.option(
39+
'-c --config <config-path>',
40+
'path to Vulcan config file',
41+
'./vulcan.yaml'
42+
)
43+
.option('-p --port <port>', 'server port', '3000')
44+
.action(async (options) => {
45+
await handleServe(options);
46+
});
47+
48+
program
49+
.command('start')
50+
.description('build and serve Vulcan project')
51+
.option(
52+
'-c --config <config-path>',
53+
'path to Vulcan config file',
54+
'./vulcan.yaml'
55+
)
56+
.option('-p --port <port>', 'server port', '3000')
57+
.action(async (options) => {
58+
await handleStart(options);
59+
});
60+
61+
export { program };

packages/cli/src/commands/init.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,8 @@ export const createProject = async (
5252
name: options.projectName,
5353
dependencies: {
5454
'@vulcan-sql/core': options.version,
55-
// TODO: Install build/serve package when they are ready
55+
'@vulcan-sql/build': options.version,
56+
'@vulcan-sql/serve': options.version,
5657
},
5758
},
5859
null,

packages/cli/src/index.ts

+1-59
Original file line numberDiff line numberDiff line change
@@ -1,65 +1,7 @@
11
#!/usr/bin/env node
22

3-
import { program } from 'commander';
4-
import { handleInit, handleStart, handleVersion } from './commands';
5-
import { handleBuild } from './commands/build';
6-
import { handleServe } from './commands/serve';
73
import { logger } from './utils';
8-
9-
program.exitOverride();
10-
11-
program
12-
.command('version')
13-
.description('show the version of CLI and Vulcan packages')
14-
.action(async () => {
15-
await handleVersion();
16-
});
17-
18-
program
19-
.command('init')
20-
.description('create a new Vulcan project')
21-
.option('-p --project-name <project-name>', 'specify project name')
22-
.action(async (options) => {
23-
await handleInit(options);
24-
});
25-
26-
program
27-
.command('build')
28-
.description('build Vulcan project')
29-
.option(
30-
'-c --config <config-path>',
31-
'path to Vulcan config file',
32-
'./vulcan.yaml'
33-
)
34-
.action(async (options) => {
35-
await handleBuild(options);
36-
});
37-
38-
program
39-
.command('serve')
40-
.description('serve Vulcan project')
41-
.option(
42-
'-c --config <config-path>',
43-
'path to Vulcan config file',
44-
'./vulcan.yaml'
45-
)
46-
.option('-p --port <port>', 'server port', '3000')
47-
.action(async (options) => {
48-
await handleServe(options);
49-
});
50-
51-
program
52-
.command('start')
53-
.description('build and serve Vulcan project')
54-
.option(
55-
'-c --config <config-path>',
56-
'path to Vulcan config file',
57-
'./vulcan.yaml'
58-
)
59-
.option('-p --port <port>', 'server port', '3000')
60-
.action(async (options) => {
61-
await handleStart(options);
62-
});
4+
import { program } from './cli';
635

646
(async () => {
657
try {

packages/cli/src/utils/shutdown.ts

+5-1
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,13 @@ export const addShutdownJob = (job: JobBeforeShutdown) => {
88
shutdownJobs.push(job);
99
};
1010

11-
process.on('SIGINT', async () => {
11+
export const runShutdownJobs = async () => {
1212
logger.info('Ctrl-C signal caught, stopping services...');
1313
await Promise.all(shutdownJobs.map((job) => job()));
1414
logger.info('Bye.');
15+
};
16+
17+
process.on('SIGINT', async () => {
18+
await runShutdownJobs();
1519
process.exit(0);
1620
});

packages/cli/test/cli.spec.ts

+64
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
import { program } from '../src/cli';
2+
import { promises as fs } from 'fs';
3+
import * as jsYAML from 'js-yaml';
4+
import * as path from 'path';
5+
import { runShutdownJobs } from '../src/utils';
6+
import * as supertest from 'supertest';
7+
8+
const projectName = 'test-vulcan-project';
9+
10+
const workspaceRoot = path.resolve(__dirname, '..', '..', '..');
11+
const projectRoot = path.resolve(workspaceRoot, projectName);
12+
13+
beforeAll(async () => {
14+
await fs.rm(projectRoot, { recursive: true, force: true });
15+
await program.parseAsync(['node', 'vulcan', 'init', '-p', projectName]);
16+
process.chdir(projectRoot);
17+
}, 30000);
18+
19+
afterAll(async () => {
20+
await fs.rm(projectRoot, { recursive: true, force: true });
21+
});
22+
23+
afterEach(async () => {
24+
await runShutdownJobs();
25+
});
26+
27+
it('Init command should create new folder with default config', async () => {
28+
// Action
29+
const config: any = jsYAML.load(
30+
await fs.readFile(path.resolve(projectRoot, 'vulcan.yaml'), 'utf8')
31+
);
32+
// Assert
33+
expect(config.name).toBe(projectName);
34+
});
35+
36+
it('Build command should make result.json', async () => {
37+
// Action
38+
await program.parseAsync(['node', 'vulcan', 'build']);
39+
// Assert
40+
expect(
41+
fs.readFile(path.resolve(projectRoot, 'result.json'), 'utf-8')
42+
).resolves.not.toThrow();
43+
});
44+
45+
it('Serve command should start Vulcan server', async () => {
46+
// Action
47+
await program.parseAsync(['node', 'vulcan', 'build']);
48+
await program.parseAsync(['node', 'vulcan', 'serve', '-p', '12345']);
49+
const agent = supertest('http://localhost:12345');
50+
const result = await agent.get('/');
51+
// Assert
52+
expect(result.statusCode).toBe(200);
53+
await runShutdownJobs();
54+
});
55+
56+
it('Start command should build the project and start Vulcan server', async () => {
57+
// Action
58+
await program.parseAsync(['node', 'vulcan', 'start', '-p', '12345']);
59+
const agent = supertest('http://localhost:12345');
60+
const result = await agent.get('/');
61+
// Assert
62+
expect(result.statusCode).toBe(200);
63+
await runShutdownJobs();
64+
});

packages/cli/tsconfig.spec.json

+7-1
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,11 @@
55
"module": "commonjs",
66
"types": ["jest", "node"]
77
},
8-
"include": ["jest.config.ts", "**/*.test.ts", "**/*.spec.ts", "**/*.d.ts"]
8+
"include": [
9+
"jest.config.ts",
10+
"**/*.test.ts",
11+
"**/*.spec.ts",
12+
"**/*.d.ts.",
13+
"../../types/*.d.ts"
14+
]
915
}

0 commit comments

Comments
 (0)