Skip to content

test(cyclopts): cover the reported-error exit codes - #76

Merged
tsvikas merged 1 commit into
mainfrom
cyclopts-cli-coverage
Sep 27, 2026
Merged

tsvikas merged 1 commit into
mainfrom
cyclopts-cli-coverage

Conversation

@tsvikas

@tsvikas tsvikas commented Sep 27, 2026 •

Copy link
Copy Markdown
Owner

New projects generated with the cyclopts CLI (the default, also used by the docs test case) started at 85% coverage. The no-CLI and Typer variants were already at 100%.

Cause

main() maps three errors to sysexits codes through _fail(): FileNotFoundError → 66, PermissionError → 77, ConnectionError → 69. No test covered those branches (cli.py lines 63-64, 84, 86, 88). The existing tests covered only usage errors (2) and the catch-all crash (70).

Change

A parametrized test_main_reported_error, in the same monkeypatch style as test_main_unhandled_error. It swaps app for a function that raises each error, then checks the exit code and that stderr is exactly error: <message>. A fourth case, ConnectionRefusedError, checks that a subclass lands on its parent's code, as the comment in cli.py promises.

The template still sets no fail_under, so a coverage drop is visible but doesn't fail CI.

Verification

TMPDIR=/tmp uv run ctt -t cli_c -t docs (the three cyclopts variants) passes lint, tests and release. Each runs 9 tests, and coverage is 100% in all three (cli_c_vcs 34/34, cli_c_no_vcs 33/33, docs 33/33 statements), up from 85%.

Patching cli.app instead of the registered command is deliberate: these tests check main()'s mapping, and keep working when a project replaces the placeholder command or moves to subcommands only. Patching app.default_command would also test that cyclopts lets command exceptions through (checked by hand: FileNotFoundError → exit 66), but it would break once there is no default command.

🤖 Generated with Claude Code

https://claude.ai/code/session_01GyMoD8tx4oz1bpJ1tEL845

The cyclopts CLI template started new projects at 85% coverage: nothing
exercised the FileNotFoundError, PermissionError and ConnectionError
branches of `main`, nor `_fail`. A parametrized test checks each exit
code and the `error: ...` line, plus a ConnectionError subclass.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01GyMoD8tx4oz1bpJ1tEL845

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've reviewed your changes and they look great!

Sourcery assessment

Approved.


Sourcery is free for open source - if you like our reviews please consider sharing them ✨

@tsvikas
tsvikas merged commit 7c91a6d into main Sep 27, 2026
5 checks passed
@tsvikas
tsvikas deleted the cyclopts-cli-coverage branch September 27, 2026 18:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant