Complete the end-to-end CLI parity audit
This commit is contained in:
@@ -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!(
|
||||
|
||||
@@ -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()?;
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user