use std::path::Path;
use std::process::Command;
use zisk_asm_runner::{AsmRHData, AsmRunnerOptions, AsmRunnerTraceLevel, AsmService, AsmServices};
fn applied_args(opts: &AsmRunnerOptions, service: AsmService) -> Vec<String> {
let mut cmd = Command::new("ziskemuasm");
opts.apply_to_command(&mut cmd, &service, "ZISK_1_0", "ZISK_1_h_0");
cmd.get_args().map(|a| a.to_string_lossy().into_owned()).collect()
}
#[test]
fn options_builder_and_command_flags_are_consistent() {
let opts = AsmRunnerOptions::new()
.with_verbose(true)
.with_metrics(true)
.with_trace_level(AsmRunnerTraceLevel::ExtendedTrace);
let args = applied_args(&opts, AsmService::MO);
for expected in
["-s", "--gen=7", "--stdio", "--open_all_shm", "--share_input_shm", "-v", "-m", "-tt"]
{
assert!(args.iter().any(|a| a == expected), "missing {expected} in {args:?}");
}
let i = args.iter().position(|a| a == "--shm_prefix").unwrap();
assert_eq!(args[i + 1], "ZISK_1_0");
}
#[test]
fn service_identity_is_the_documented_wire_contract() {
assert_eq!(AsmServices::SERVICES, [AsmService::MO, AsmService::MT, AsmService::RH]);
assert_eq!(AsmService::MO.gen_index(), 7);
assert_eq!(AsmService::MT.gen_index(), 1);
assert_eq!(AsmService::RH.gen_index(), 2);
assert_eq!(AsmService::RH.as_str(), "RH");
assert_eq!(
AsmService::RH.command_path_for("/opt/zisk/ziskemuasm"),
"/opt/zisk/ziskemuasm-rh.bin"
);
}
#[test]
fn rom_histogram_payload_round_trips_through_public_api() {
let data = AsmRHData::new(123, vec![1, 2, 3, 4]);
assert_eq!(data.steps, 123);
assert_eq!(data.inst_count, vec![1, 2, 3, 4]);
}
#[test]
fn asm_services_new_rejects_paths_without_the_bin_suffix() {
let opts = AsmRunnerOptions::new();
assert!(
AsmServices::new(0, 0, "deadbeef".into(), Path::new("foo"), false, opts.clone()).is_err()
);
assert!(AsmServices::new(
0,
0,
"deadbeef".into(),
Path::new("abcdefg.bin"),
false,
opts.clone()
)
.is_err());
assert!(
AsmServices::new(0, 0, "deadbeef".into(), Path::new("/x/binary.txt"), false, opts).is_err()
);
}