-
-
Notifications
You must be signed in to change notification settings - Fork 11
Expand file tree
/
Copy pathcli.test.ts
More file actions
179 lines (153 loc) · 5.61 KB
/
Copy pathcli.test.ts
File metadata and controls
179 lines (153 loc) · 5.61 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
import { exec } from 'child_process';
import { describe, it, expect, test } from 'vitest';
function runCommand(command: string): Promise<string> {
return new Promise((resolve, reject) => {
exec(command, (error, stdout, stderr) => {
if (error) {
reject(stderr);
} else {
resolve(stdout);
}
});
});
}
const cliTools = ['citty', 'cac'];
// const cliTools = ['citty', 'cac'];
describe.each(cliTools)('cli completion tests for %s', (cliTool) => {
const commandPrefix = `pnpm tsx demo.${cliTool}.ts complete --`;
it('should complete cli options', async () => {
const output = await runCommand(`${commandPrefix}`);
expect(output).toMatchSnapshot();
});
describe('cli option completion tests', () => {
const optionTests = [
{ partial: '--p', expected: '--port' },
{ partial: '-p', expected: '-p' }, // Test short flag completion
{ partial: '-H', expected: '-H' }, // Test another short flag completion
];
test.each(optionTests)(
"should complete option for partial input '%s'",
async ({ partial }) => {
const command = `${commandPrefix} dev ${partial}`;
const output = await runCommand(command);
expect(output).toMatchSnapshot();
}
);
});
describe('cli option exclusion tests', () => {
const alreadySpecifiedTests = [
{ specified: '--config', shouldNotContain: '--config' },
];
test.each(alreadySpecifiedTests)(
"should not suggest already specified option '%s'",
async ({ specified }) => {
const command = `${commandPrefix} ${specified} --`;
const output = await runCommand(command);
console.log(output);
expect(output).toMatchSnapshot();
}
);
});
describe('cli option value handling', () => {
it('should resolve port value correctly', async () => {
const command = `${commandPrefix} dev --port=3`;
const output = await runCommand(command);
expect(output).toMatchSnapshot();
});
it('should not show duplicate options', async () => {
const command = `${commandPrefix} --config vite.config.js --`;
const output = await runCommand(command);
expect(output).toMatchSnapshot();
});
it('should resolve config option values correctly', async () => {
const command = `${commandPrefix} --config vite.config`;
const output = await runCommand(command);
expect(output).toMatchSnapshot();
});
it('should handle unknown options with no completions', async () => {
const command = `${commandPrefix} --unknownoption`;
const output = await runCommand(command);
expect(output.trim()).toMatchSnapshot();
});
});
describe('edge case completions for end with space', () => {
//TOOD: remove this
it('should suggest port values if user ends with space after `--port`', async () => {
const command = `${commandPrefix} dev --port ""`;
const output = await runCommand(command);
expect(output).toMatchSnapshot();
});
it("should keep suggesting the --port option if user typed partial but didn't end with space", async () => {
const command = `${commandPrefix} dev --po`;
const output = await runCommand(command);
expect(output).toMatchSnapshot();
});
it("should suggest port values if user typed `--port=` and hasn't typed a space or value yet", async () => {
const command = `${commandPrefix} dev --port=`;
const output = await runCommand(command);
expect(output).toMatchSnapshot();
});
});
describe('short flag handling', () => {
it('should handle short flag value completion', async () => {
const command = `${commandPrefix} dev -p `;
const output = await runCommand(command);
expect(output).toMatchSnapshot();
});
it('should handle short flag with equals sign', async () => {
const command = `${commandPrefix} dev -p=3`;
const output = await runCommand(command);
expect(output).toMatchSnapshot();
});
it('should handle global short flags', async () => {
const command = `${commandPrefix} -c `;
const output = await runCommand(command);
expect(output).toMatchSnapshot();
});
it('should not show duplicate options when short flag is used', async () => {
const command = `${commandPrefix} -c vite.config.js --`;
const output = await runCommand(command);
expect(output).toMatchSnapshot();
});
});
// single positional command: `lint [file]`
// vite ""
// -> src/
// -> ./
// vite src/ ""
// -> nothing
// should not suggest anything
// multiple postiionals command `lint [...files]`
// vite ""
// -> src/
// -> ./
// vite src/ ""
// -> src/
// -> ./
describe('positional argument completions', () => {
it.runIf(cliTool !== 'citty')(
'should complete multiple positional arguments when ending with space',
async () => {
const command = `${commandPrefix} lint ""`;
const output = await runCommand(command);
expect(output).toMatchSnapshot();
}
);
it.runIf(cliTool !== 'citty')(
'should complete multiple positional arguments when ending with part of the value',
async () => {
const command = `${commandPrefix} lint ind`;
const output = await runCommand(command);
expect(output).toMatchSnapshot();
}
);
it.runIf(cliTool !== 'citty')(
'should complete single positional argument when ending with space',
async () => {
const command = `${commandPrefix} lint main.ts ""`;
const output = await runCommand(command);
expect(output).toMatchSnapshot();
}
);
});
});