feat: scaffold v0.1 foundation
This commit is contained in:
parent
c4fb0c6a01
commit
170ca32f58
34 changed files with 6175 additions and 5 deletions
43
tests/cli.rs
Normal file
43
tests/cli.rs
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
#![allow(clippy::expect_used)]
|
||||
#![doc = "Black-box CLI framing and exit-status tests."]
|
||||
|
||||
use std::process::Command;
|
||||
|
||||
#[test]
|
||||
fn unimplemented_operation_is_a_typed_json_runtime_failure() {
|
||||
let output = Command::new(env!("CARGO_BIN_EXE_ghidr"))
|
||||
.arg("doctor")
|
||||
.output()
|
||||
.expect("run ghidr");
|
||||
assert_eq!(output.status.code(), Some(1));
|
||||
assert!(output.stdout.is_empty());
|
||||
let error: serde_json::Value =
|
||||
serde_json::from_slice(&output.stderr).expect("valid JSON error");
|
||||
assert_eq!(error["error"]["code"], "internal_not_implemented");
|
||||
assert_eq!(error["error"]["details"]["operation"], "doctor");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn invalid_invocation_is_one_json_document_on_stderr() {
|
||||
let output = Command::new(env!("CARGO_BIN_EXE_ghidr"))
|
||||
.args(["functions", "sample", "--limit", "0"])
|
||||
.output()
|
||||
.expect("run ghidr");
|
||||
assert_eq!(output.status.code(), Some(2));
|
||||
assert!(output.stdout.is_empty());
|
||||
let error: serde_json::Value =
|
||||
serde_json::from_slice(&output.stderr).expect("valid JSON error");
|
||||
assert_eq!(error["error"]["code"], "invalid_arguments");
|
||||
assert_eq!(output.stderr.last(), Some(&b'\n'));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn explicit_human_parse_failure_is_not_json() {
|
||||
let output = Command::new(env!("CARGO_BIN_EXE_ghidr"))
|
||||
.args(["--format", "human", "decompile", "sample"])
|
||||
.output()
|
||||
.expect("run ghidr");
|
||||
assert_eq!(output.status.code(), Some(2));
|
||||
assert!(output.stdout.is_empty());
|
||||
assert!(serde_json::from_slice::<serde_json::Value>(&output.stderr).is_err());
|
||||
}
|
||||
58
tests/contracts.rs
Normal file
58
tests/contracts.rs
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
#![allow(clippy::expect_used)]
|
||||
#![doc = "Published schema, registry, and reviewed-fixture parity tests."]
|
||||
|
||||
use std::{collections::BTreeSet, fs, path::PathBuf};
|
||||
|
||||
use ghidra_cli::{
|
||||
error::ErrorEnvelope,
|
||||
operation::{
|
||||
CleanupData, DecompilationData, DoctorData, FunctionsData, InspectionData, OPERATIONS,
|
||||
QueryProvenance, SuccessEnvelope, ToolProvenance,
|
||||
},
|
||||
};
|
||||
|
||||
fn root(relative: &str) -> PathBuf {
|
||||
PathBuf::from(env!("CARGO_MANIFEST_DIR")).join(relative)
|
||||
}
|
||||
|
||||
fn fixture(name: &str) -> String {
|
||||
fs::read_to_string(root(&format!("fixtures/golden/v1/{name}"))).expect("read fixture")
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn registry_has_exact_schema_and_golden_coverage() {
|
||||
let mut operations = BTreeSet::new();
|
||||
for descriptor in OPERATIONS {
|
||||
assert!(operations.insert(descriptor.operation.as_str()));
|
||||
assert!(root(&format!("schemas/v1/{}", descriptor.schema)).is_file());
|
||||
assert!(root(&format!("fixtures/golden/v1/{}", descriptor.golden)).is_file());
|
||||
let value: serde_json::Value =
|
||||
serde_json::from_str(&fixture(descriptor.golden)).expect("fixture JSON");
|
||||
assert_eq!(value["kind"], descriptor.public_kind);
|
||||
}
|
||||
assert_eq!(
|
||||
operations,
|
||||
BTreeSet::from(["clean", "decompile", "doctor", "functions", "inspect"])
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn reviewed_goldens_deserialize_through_public_contracts() {
|
||||
serde_json::from_str::<SuccessEnvelope<ToolProvenance, DoctorData>>(&fixture("doctor.json"))
|
||||
.expect("doctor contract");
|
||||
serde_json::from_str::<SuccessEnvelope<QueryProvenance, InspectionData>>(&fixture(
|
||||
"inspection.json",
|
||||
))
|
||||
.expect("inspection contract");
|
||||
serde_json::from_str::<SuccessEnvelope<QueryProvenance, FunctionsData>>(&fixture(
|
||||
"functions.json",
|
||||
))
|
||||
.expect("functions contract");
|
||||
serde_json::from_str::<SuccessEnvelope<QueryProvenance, DecompilationData>>(&fixture(
|
||||
"decompilation.json",
|
||||
))
|
||||
.expect("decompilation contract");
|
||||
serde_json::from_str::<SuccessEnvelope<ToolProvenance, CleanupData>>(&fixture("cleanup.json"))
|
||||
.expect("cleanup contract");
|
||||
serde_json::from_str::<ErrorEnvelope>(&fixture("error.json")).expect("error contract");
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue