Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions examples/demo.commander.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,24 @@ program
.option('-v, --verbose', 'enable verbose output');

// Add commands
const devCommand = program
.command('dev')
.description('Start dev server')
.option('-H, --host [host]', `Specify hostname`)
.option('-p, --port <port>', `Specify port`)
.option('-v, --verbose', `Enable verbose logging`)
.option('--quiet', `Suppress output`)
.action((options) => {});
// subcommands of dev
devCommand
.command('start')
.description('Start development server')
.action((options) => {});
devCommand
.command('build')
.description('Build project')
.action((options) => {});

program
.command('serve')
.description('Start the server')
Expand Down
54 changes: 54 additions & 0 deletions tests/__snapshots__/cli.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -626,6 +626,60 @@ my-tool My tool
"
`;

exports[`cli completion tests for commander > cli option completion tests > should complete option for partial input '{ partial: '--p', expected: '--port' }' 1`] = `
"--port Specify port
:4
"
`;

exports[`cli completion tests for commander > cli option completion tests > should complete option for partial input '{ partial: '-H', expected: '-H' }' 1`] = `
"-H Specify hostname
:4
"
`;

exports[`cli completion tests for commander > cli option completion tests > should complete option for partial input '{ partial: '-p', expected: '-p' }' 1`] = `
"-p Specify port
:4
"
`;

exports[`cli completion tests for commander > cli option exclusion tests > should not suggest already specified option '{ specified: '--config', shouldNotContain: '--config' }' 1`] = `
":4
"
`;

exports[`cli completion tests for commander > cli option value handling > should handle unknown options with no completions 1`] = `":4"`;

exports[`cli completion tests for commander > cli option value handling > should not show duplicate options 1`] = `
"--version output the version number
--config specify config file
--debug enable debugging
--verbose enable verbose output
:4
"
`;

exports[`cli completion tests for commander > cli option value handling > should resolve config option values correctly 1`] = `
":4
"
`;

exports[`cli completion tests for commander > cli option value handling > should resolve port value correctly 1`] = `
":4
"
`;

exports[`cli completion tests for commander > should complete cli options 1`] = `
"dev Start dev server
serve Start the server
build Build the project
deploy Deploy the application
lint Lint source files
:4
"
`;

exports[`cli completion tests for t > --config option tests > should complete --config option values 1`] = `
"vite.config.ts Vite config file
vite.config.js Vite config file
Expand Down
21 changes: 9 additions & 12 deletions tests/cli.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,24 +14,21 @@ function runCommand(command: string): Promise<string> {
}

const cliTools = ['t', 'citty', 'cac', 'commander'];
// const cliTools = ['commander']; // TEMP For quick testing of commander-specific behavior, uncomment this line and comment out the line above.

describe.each(cliTools)('cli completion tests for %s', (cliTool) => {
// For Commander, we need to skip most of the tests since it handles completion differently
// Legacy comment? Reenabling tests...
const shouldSkipTest = cliTool === 'commander';

// Commander uses a different command structure for completion
// TODO: why commander does that? our convention is the -- part which should be always there.
const commandPrefix =
cliTool === 'commander'
? `pnpm tsx examples/demo.${cliTool}.ts complete`
: `pnpm tsx examples/demo.${cliTool}.ts complete --`;
const commandPrefix = `pnpm tsx examples/demo.${cliTool}.ts complete --`;

it.runIf(!shouldSkipTest)('should complete cli options', async () => {
it('should complete cli options', async () => {
const output = await runCommand(`${commandPrefix}`);
expect(output).toMatchSnapshot();
});

describe.runIf(!shouldSkipTest)('cli option completion tests', () => {
describe('cli option completion tests', () => {
const optionTests = [
{ partial: '--p', expected: '--port' },
{ partial: '-p', expected: '-p' }, // Test short flag completion
Expand All @@ -48,7 +45,7 @@ describe.each(cliTools)('cli completion tests for %s', (cliTool) => {
);
});

describe.runIf(!shouldSkipTest)('cli option exclusion tests', () => {
describe('cli option exclusion tests', () => {
const alreadySpecifiedTests = [
{ specified: '--config', shouldNotContain: '--config' },
];
Expand All @@ -63,7 +60,7 @@ describe.each(cliTools)('cli completion tests for %s', (cliTool) => {
);
});

describe.runIf(!shouldSkipTest)('cli option value handling', () => {
describe('cli option value handling', () => {
it('should resolve port value correctly', async () => {
const command = `${commandPrefix} dev --port=3`;
const output = await runCommand(command);
Expand All @@ -89,7 +86,7 @@ describe.each(cliTools)('cli completion tests for %s', (cliTool) => {
});
});

describe.runIf(!shouldSkipTest)('boolean option handling', () => {
describe('boolean option handling', () => {
it('should complete subcommands and arguments after boolean options', async () => {
const command = `${commandPrefix} dev --verbose ""`;
const output = await runCommand(command);
Expand Down Expand Up @@ -118,7 +115,7 @@ describe.each(cliTools)('cli completion tests for %s', (cliTool) => {
it('should not interfere with option completion after boolean options', async () => {
const command = `${commandPrefix} dev --verbose --h`;
const output = await runCommand(command);
// Should complete subcommands that start with 's' even after a boolean option
// Should complete options that start with '--h' even after a boolean option
expect(output).toContain('--host');
});
});
Expand Down
Loading