Repository navigation
Test the CLI entry point - #51
Merged
Merged
Conversation
Chunk 9. Adds src/cli.test.ts, 34 tests, and splits bin.ts. bin.ts called main() at import, so nothing could load it without starting a wizard. The body moves to src/cli.ts, which exports main and resolveCredential; bin.ts is now the shebang and two lines. The move is mechanical: main still exits the process itself on every path it did before, so there is no semantic change to review. The tests cover the credential ladder (flag beats env, -oauth beats plain, and --mock ignores SUBTEXT_API_KEY* from the environment while still honouring an explicit flag), the Node floor accepting 18.17.0 and rejecting 18.16.0, and bad invocations exiting non-zero rather than falling through into an autonomous agent run. Two things about the harness worth knowing. process.exit is modelled as a throw, but only while main runs synchronously — a throw from inside main's own .then/.catch just becomes an unhandled rejection, and vitest rightly flags those as a false-positive risk. And the suite stubs SUBTEXT_API_KEY* to empty in beforeEach: a real key in the developer's shell otherwise changes what these tests see.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Chunk 9 of the test plan.
src/cli.test.ts, 34 tests, plus the one file split the plan flagged.The split
bin.tscalledmain()at import, so no test could load it without starting a wizard as a side effect. The body moves tosrc/cli.ts(exportingmainandresolveCredential);bin.tsis now four lines.The move is mechanical.
mainstill callsprocess.exititself on every path it did before, so there's no semantic change hiding in here —--helpstill returns without exiting (which keeps--help | headfrom truncating), everything else still exits explicitly. The only addition is an optionalargvparameter that defaults toprocess.argv.slice(2)viaparseArgs.Rebuilt and re-smoke-tested:
--version,--help, and an unknown flag still exit 0/0/2.What's pinned
The credential ladder, because getting it wrong leaks or strands a credential:
--api-key-oauthbeats--api-keybeatsSUBTEXT_API_KEY_OAUTHbeatsSUBTEXT_API_KEY. Flags beat env deliberately, so a credential needn't appear in argv where it lands in shell history and the process list.--mockignores the environment but still honours an explicit flag. ASUBTEXT_API_KEYleft in the shell would otherwise be validated — and could be rejected — or short-circuit the canned mock auth, in a mode whose entire point is making no network calls. That asymmetry is deliberate and was previously undefended.Bad invocations exit non-zero, which matters more than the message: a typo must not fall through into an autonomous agent run. Unknown flag → 2, both credential flags → 2, positional args → 2, and
runWizardnever called in any of them.The Node floor accepts 18.17.0 and rejects 18.16.0 and 17.9.1.
Plus option mapping (
--dirresolved absolute,--integrationssplit/trimmed/de-blanked, region pinned tous), telemetry defaulting on and off via either the flag orDO_NOT_TRACK/DISABLE_TELEMETRY, and the wizard's resolved code becoming the exit code.Two notes on the harness
Both came out of getting this wrong first:
process.exitthrows only during main's synchronous phase. Throwing unconditionally is what stops main running on past a parse error — but a throw from inside main's own.then/.catchjust becomes an unhandled rejection, and vitest flags those as a false-positive risk (15 of them, in my first pass). Async exits are recorded instead.SUBTEXT_API_KEY*to empty inbeforeEach. I have a real one exported in my shell, and without this the credential tests pass locally for the wrong reason and would behave differently in CI.Verification
34 tests passing (87 on this branch), no unhandled errors,
typecheckclean, and the rebuiltdist/bin.jsverified by hand. Mutation-checked the--mockenv guard and the Node minor-version check; both caught, then reverted.Note
Low Risk
Mechanical entry-point split with no intended behavior change; new tests lock down credential resolution and failure paths on the CLI boundary.
Overview
Refactors the wizard CLI so it can be tested without side effects. Almost all logic moves from
bin.tsinto newsrc/cli.ts(main,resolveCredential, exportedHELP); the binary entry is now a four-line shim that callsmain().mainaccepts an optionalargvfor tests; runtime behavior (exit codes,--helpreturning without exit, credential rules) is intended to stay the same.Adds
src/cli.test.ts(34 tests) withrunWizardmocked. Coverage focuses on safety-sensitive behavior: credential precedence (flags over env, OAuth over plain key),--mockignoring env credentials unless a flag is explicit, invalid invocations exiting 2 without starting the wizard, Node 18.17+ gate, option mapping (--dir,--integrations, telemetry opt-out), and wizard exit/error handling. The harness models syncprocess.exitas throws and clears credential env vars inbeforeEachfor stable CI.Reviewed by Cursor Bugbot for commit 8ce07cb. Bugbot is set up for automated code reviews on this repo. Configure here.