use clap::CommandFactory;
use phoxal_runtime_contract::contract_surface::{
ContractRecord, ContractSurface, LaunchArgument, LaunchValueShape,
};
use crate::participant::launch::SupervisedLaunch;
#[must_use]
pub fn contract_surface() -> String {
ContractSurface::new([ContractRecord::launch(launch_arguments())]).canonical_json()
}
fn launch_arguments() -> Vec<LaunchArgument> {
SupervisedLaunch::command()
.get_arguments()
.map(|argument| {
LaunchArgument::new(
argument
.get_long()
.map_or_else(|| argument.get_id().to_string(), ToString::to_string),
argument.is_required_set(),
matches!(argument.get_action(), clap::ArgAction::Append),
if argument.get_action().takes_values() {
LaunchValueShape::Text
} else {
LaunchValueShape::Flag
},
)
})
.collect()
}
#[cfg(test)]
mod tests {
use super::{contract_surface, launch_arguments};
use phoxal_runtime_contract::contract_surface::{
ContractRecord, ContractSurface, LaunchArgument, LaunchValueShape,
};
#[test]
fn the_launch_record_is_the_supervisor_owned_argv_contract() {
let expected = ContractSurface::new([ContractRecord::launch([
LaunchArgument::new("execution-id", true, false, LaunchValueShape::Text),
LaunchArgument::new("participant-id", true, false, LaunchValueShape::Text),
LaunchArgument::new("bundle-root", true, false, LaunchValueShape::Text),
LaunchArgument::new("connect", true, true, LaunchValueShape::Text),
LaunchArgument::new("execution-origin", false, false, LaunchValueShape::Text),
LaunchArgument::new("shutdown-grace-ms", false, false, LaunchValueShape::Text),
])]);
assert_eq!(contract_surface(), expected.canonical_json());
}
#[test]
fn the_surface_is_deterministic_json() {
let rendered = contract_surface();
serde_json::from_str::<serde_json::Value>(&rendered).expect("the surface is JSON");
assert_eq!(contract_surface(), rendered);
assert!(rendered.contains(r#""record":"launch""#), "{rendered}");
}
#[test]
fn every_supervisor_owned_argument_consumes_a_value() {
for argument in launch_arguments() {
assert_eq!(
argument.value,
LaunchValueShape::Text,
"{} is not a value-taking option",
argument.name
);
}
}
}