The built termux-janitor executable starts with standard input disconnected from a terminal and an
empty isolated working directory.
Each listed invocation violates the command-line grammar: an unregistered option, a short option, an
operand before or after the option terminator, a repeated option, an option that must appear alone
combined with another option, a missing or empty option value, or a value attached with =.
Three invocations exercise the registered diagnostic echo bound with arguments one byte below it,
exactly at it, and one byte above it. Two more carry a control byte and an invalid UTF-8 byte.
When
The executable starts once per listed invocation.
Required invariants
INV-USAGE-STATUS: Every listed invocation exits with the registered usage status.
INV-USAGE-DIAGNOSTIC:
Every listed invocation writes one bounded stderr diagnostic that names the executable, states one
concise reason, quotes the rejected argument, and repeats the usage summary.
INV-USAGE-ECHO-BOUND:
The quoted argument never exceeds the registered diagnostic argument bound, and an argument beyond
that bound is marked truncated.
INV-USAGE-ECHO-SANITIZED:
The quoted argument equals the expected sanitized text, and the diagnostic contains no control
byte and no invalid UTF-8 sequence.
Forbidden effects
NO-USAGE-STDOUT: Standard output remains empty for every listed invocation.
NO-USAGE-FIXTURE-MUTATION:
The isolated working directory remains empty.
Accepted invocations belong to the help and version fixtures. Configuration-file errors, terminal
requirements, and cancellation are separate scenarios owned by their own fixtures.
Limitations
This fixture observes exit status, both streams, and writes beneath its isolated working directory.
It does not trace system calls and therefore cannot prove that no other path was read.
# Rejected command lines
**Fixture:** `fixture-cli-usage@1`
## Given
The built `termux-janitor` executable starts with standard input disconnected from a terminal and an
empty isolated working directory.
Each listed invocation violates the command-line grammar: an unregistered option, a short option, an
operand before or after the option terminator, a repeated option, an option that must appear alone
combined with another option, a missing or empty option value, or a value attached with `=`.
Three invocations exercise the registered diagnostic echo bound with arguments one byte below it,
exactly at it, and one byte above it. Two more carry a control byte and an invalid UTF-8 byte.
## When
The executable starts once per listed invocation.
## Required invariants
- **`INV-USAGE-STATUS`:** Every listed invocation exits with the registered usage status.
- **`INV-USAGE-DIAGNOSTIC`:**
Every listed invocation writes one bounded stderr diagnostic that names the executable, states one
concise reason, quotes the rejected argument, and repeats the usage summary.
- **`INV-USAGE-ECHO-BOUND`:**
The quoted argument never exceeds the registered diagnostic argument bound, and an argument beyond
that bound is marked truncated.
- **`INV-USAGE-ECHO-SANITIZED`:**
The quoted argument equals the expected sanitized text, and the diagnostic contains no control
byte and no invalid UTF-8 sequence.
## Forbidden effects
- **`NO-USAGE-STDOUT`:** Standard output remains empty for every listed invocation.
- **`NO-USAGE-FIXTURE-MUTATION`:**
The isolated working directory remains empty.
## Instrumentation
```zig tj-test
try fixture.given_program("termux-janitor");
try fixture.given_standard_input(.ignored);
try fixture.given_working_directory(.empty);
try fixture.given_rejected_invocation(&.{"--nope"}, "--nope");
try fixture.given_rejected_invocation(&.{"--nope=1"}, "--nope");
try fixture.given_rejected_invocation(&.{"-h"}, "-h");
try fixture.given_rejected_invocation(&.{"cleanup"}, "cleanup");
try fixture.given_rejected_invocation(&.{ "--", "cleanup" }, "cleanup");
try fixture.given_rejected_invocation(&.{ "--ascii", "--ascii" }, "--ascii");
try fixture.given_rejected_invocation(&.{ "--dry-run", "--dry-run" }, "--dry-run");
try fixture.given_rejected_invocation(&.{ "--help", "--version" }, "--help");
try fixture.given_rejected_invocation(&.{ "--help", "--ascii" }, "--help");
try fixture.given_rejected_invocation(&.{"--config"}, "--config");
try fixture.given_rejected_invocation(&.{ "--config", "" }, "--config");
try fixture.given_rejected_invocation(&.{"--config=/tmp/x"}, "--config");
try fixture.given_rejected_invocation(&.{"--a\x01b"}, "--a<01>b");
try fixture.given_rejected_invocation(&.{"--a\xffb"}, "--a?b");
try fixture.given_rejected_invocation(&.{"--" ++ "a" ** 61}, "--" ++ "a" ** 61);
try fixture.given_rejected_invocation(&.{"--" ++ "a" ** 62}, "--" ++ "a" ** 62);
try fixture.given_rejected_invocation(&.{"--" ++ "a" ** 63}, "--" ++ "a" ** 62 ++ "...");
try fixture.when_run_each();
try fixture.then_inv_usage_status();
try fixture.then_inv_usage_diagnostic();
try fixture.then_inv_usage_echo_bound();
try fixture.then_inv_usage_echo_sanitized();
try fixture.forbid_no_usage_stdout();
try fixture.forbid_no_usage_fixture_mutation();
```
## Variations
Accepted invocations belong to the help and version fixtures. Configuration-file errors, terminal
requirements, and cancellation are separate scenarios owned by their own fixtures.
## Limitations
This fixture observes exit status, both streams, and writes beneath its isolated working directory.
It does not trace system calls and therefore cannot prove that no other path was read.