-
Notifications
You must be signed in to change notification settings - Fork 39
fix: Map short options in generate command to prevent silent exit #183
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,15 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { test } from '@oclif/test'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| describe('generate', () => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| test | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .stdout() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .command(['generate', '-o', 'a']) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .exit(2) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .it('runs generate with option "a" and correctly attempts to find app.json'); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| test | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .stdout() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .command(['generate', '-o', 'x']) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .exit(2) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .it('fails when passing an invalid option not in a,b,c'); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+2
to
+14
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| describe('generate', () => { | |
| test | |
| .stdout() | |
| .command(['generate', '-o', 'a']) | |
| .exit(2) | |
| .it('runs generate with option "a" and correctly attempts to find app.json'); | |
| test | |
| .stdout() | |
| .command(['generate', '-o', 'x']) | |
| .exit(2) | |
| .it('fails when passing an invalid option not in a,b,c'); | |
| import * as fs from 'fs'; | |
| import * as path from 'path'; | |
| import * as os from 'os'; | |
| describe('generate', () => { | |
| let tempDir: string; | |
| beforeEach(() => { | |
| tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'generate-test-')); | |
| // Minimal app.json so FolderDetails.readInfoFile() succeeds | |
| const appJsonPath = path.join(tempDir, 'app.json'); | |
| fs.writeFileSync(appJsonPath, JSON.stringify({ name: 'test-app' }), 'utf8'); | |
| // Dummy class file if the command expects one to exist | |
| const classFilePath = path.join(tempDir, 'classFile.cls'); | |
| fs.writeFileSync(classFilePath, '// dummy class file\n', 'utf8'); | |
| }); | |
| afterEach(() => { | |
| if (tempDir && fs.existsSync(tempDir)) { | |
| fs.rmSync(tempDir, { recursive: true, force: true }); | |
| } | |
| }); | |
| test | |
| .stdout() | |
| .cwd(() => tempDir) | |
| .command(['generate', '-o', 'a']) | |
| .it('runs generate with option "a" using a valid app.json fixture'); | |
| test | |
| .stderr() | |
| .cwd(() => tempDir) | |
| .command(['generate', '-o', 'x']) | |
| .exit(2) | |
| .it('fails when passing an invalid option not in a,b,c', ctx => { | |
| if (!ctx.stderr || ctx.stderr.length === 0) { | |
| throw new Error('Expected error output for invalid option "x".'); | |
| } | |
| }); |
Copilot
AI
Mar 22, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test only checks for exit code and doesn't assert on stdout/stderr content, so it may pass even if the command silently exits again. Adding an assertion on the expected error output (invalid flag value) and/or a side effect for the valid shorthand case would make this regression test meaningful.
| describe('generate', () => { | |
| test | |
| .stdout() | |
| .command(['generate', '-o', 'a']) | |
| .exit(2) | |
| .it('runs generate with option "a" and correctly attempts to find app.json'); | |
| test | |
| .stdout() | |
| .command(['generate', '-o', 'x']) | |
| .exit(2) | |
| .it('fails when passing an invalid option not in a,b,c'); | |
| import { expect } from 'chai'; | |
| describe('generate', () => { | |
| test | |
| .stdout() | |
| .command(['generate', '-o', 'a']) | |
| .exit(2) | |
| .it('runs generate with option "a" and correctly attempts to find app.json', ctx => { | |
| expect(ctx.stdout).to.not.equal(''); | |
| }); | |
| test | |
| .stdout() | |
| .stderr() | |
| .command(['generate', '-o', 'x']) | |
| .exit(2) | |
| .it('fails when passing an invalid option not in a,b,c', ctx => { | |
| expect(ctx.stderr).to.not.equal(''); | |
| }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The shorthand mapping uses two parallel arrays (['a','b','c'] and categories) and relies on them staying in sync by index. To avoid future mismatches when categories change, prefer a single explicit mapping (e.g., a record keyed by the short option) or switch directly on the short values.