Complete the end-to-end CLI parity audit

This commit is contained in:
Hermes Agent
2026-08-10 01:51:47 +00:00
parent 4bd39b1ef2
commit 0a905e5e14
14 changed files with 1476 additions and 95 deletions

View File

@@ -3,9 +3,10 @@
use std::{error::Error, num::NonZeroUsize, path::Path};
use ironstorage::command::{
CliAction, CommandRequest, EXIT_USAGE, GeneratedPresentation, GitConfigRequest,
GitRemoteRequest, GitRequest, HelpTopic, InputPlan, InsertInput, OtpInputSource, OtpRequest,
OtpUriPresentation, Presentation, help_text, otp_version_text, parse_from, version_text,
CliAction, CommandRequest, CompletionShell, EXIT_USAGE, GeneratedPresentation,
GitConfigRequest, GitRemoteRequest, GitRequest, HelpTopic, InputPlan, InsertInput,
OtpInputSource, OtpRequest, OtpUriPresentation, Presentation, completion_script, help_text,
otp_version_text, parse_from, version_text,
};
type TestResult = Result<(), Box<dyn Error>>;
@@ -19,6 +20,39 @@ fn request(arguments: &[&str]) -> Result<CommandRequest, Box<dyn Error>> {
}
}
#[test]
fn completion_scripts_are_generated_in_process_for_supported_shells() -> TestResult {
for (name, shell, marker) in [
("bash", CompletionShell::Bash, "complete"),
("elvish", CompletionShell::Elvish, "edit:completion"),
("fish", CompletionShell::Fish, "complete"),
(
"powershell",
CompletionShell::PowerShell,
"Register-ArgumentCompleter",
),
("zsh", CompletionShell::Zsh, "compdef"),
] {
assert_eq!(
request(&["completion", name])?,
CommandRequest::Completion { shell }
);
let script = String::from_utf8(completion_script(shell))?;
assert!(script.contains("ironstorage"));
assert!(
script.contains(marker),
"missing {marker} in {name} completion"
);
}
assert_eq!(
parse_from(["ironstorage", "completion", "unsupported"])
.unwrap_err()
.exit_code(),
EXIT_USAGE
);
Ok(())
}
#[test]
fn implicit_show_and_list_aliases_are_canonical_requests() -> TestResult {
assert!(matches!(

View File

@@ -4,6 +4,8 @@ mod support;
use std::collections::{BTreeMap, BTreeSet};
use ironstorage::command::parse_from;
use support::compatibility::{
FixtureSet, TestResult, decrypt_entry_with_passphrase, validate_entry_record,
validate_key_record, validate_recipient_signature, validate_repository,
@@ -154,6 +156,37 @@ fn behavior_catalog_covers_the_milestone_contract() -> TestResult {
Ok(())
}
#[test]
fn every_compatibility_case_reaches_the_typed_command_contract() -> TestResult {
let fixture = FixtureSet::load()?;
for case in &fixture.behavior.cases {
let arguments = std::iter::once("ironstorage").chain(case.argv.iter().map(String::as_str));
let parsed = parse_from(arguments);
let parser_rejection = case.outcome.contains("usage-error")
|| case.outcome.contains("unsupported-option")
|| matches!(
case.id.as_str(),
"generate-zero" | "git-unsupported-passthrough"
);
assert_eq!(
parsed.is_err(),
parser_rejection,
"unexpected command-contract result for {}: {:?}",
case.id,
parsed
);
if let Err(error) = parsed {
assert_eq!(
error.exit_code(),
case.status as u8,
"status for {}",
case.id
);
}
}
Ok(())
}
#[test]
fn generated_openpgp_fixtures_are_self_consistent() -> TestResult {
let fixture = FixtureSet::load()?;

View File

@@ -65,6 +65,11 @@ fn local_git_workflow_stages_commits_diffs_logs_and_deletes() -> TestResult {
let diff = git.diff(&[])?;
assert_eq!(diff[0].old(), Some(b"ALICE\n".as_slice()));
assert_eq!(diff[0].current(), Some(b"BOB\n".as_slice()));
let fixture = FixtureSet::load()?;
let keys = KeyStore::load(fixture.path("keys"))?;
let rendered = git.render_diff(&[], &keys, &mut SigningSecret(Vec::new()))?;
assert!(rendered.expose().windows(7).any(|part| part == b"-ALICE\n"));
assert!(rendered.expose().windows(5).any(|part| part == b"+BOB\n"));
git.stage(&[".gpg-id".into()])?;
assert_eq!(git.status()?.staged()[0].kind(), GitChangeKind::Modified);