use super::*;
use std::path::PathBuf;
fn call(input: &str) -> Value {
json!({ INPUT_FIELD: input })
}
fn parsed(input: &str) -> Spawn {
parse(&call(input)).expect("this input parses")
}
fn refusal(input: &str) -> String {
parse(&call(input)).expect_err("this input does not parse")
}
fn preview_of(input: &str) -> ToolAuthorizationPreview {
let spawn = parsed(input);
let tool = SpawnTool::new();
preview(
&spawn,
PathBuf::from("/repo"),
&tool.descriptor(),
&call(input),
)
}
#[test]
fn a_leading_bang_means_run_this() {
let spawn = parsed("!cargo test -q");
assert_eq!(spawn.mode(), Mode::Command);
assert_eq!(spawn.body(), "cargo test -q");
}
#[test]
fn anything_else_is_a_task_for_a_subagent() {
let spawn = parsed("find every TODO under src/");
assert_eq!(spawn.mode(), Mode::Agent);
assert_eq!(spawn.body(), "find every TODO under src/");
}
#[test]
fn a_doubled_bang_delegates_a_task_that_starts_with_one() {
let spawn = parsed("!!important: summarise the diff");
assert_eq!(spawn.mode(), Mode::Agent);
assert_eq!(spawn.body(), "!important: summarise the diff");
let doubled = parsed("!!!still a prompt");
assert_eq!(doubled.mode(), Mode::Agent);
assert_eq!(doubled.body(), "!!still a prompt");
}
#[test]
fn the_string_is_trimmed_once_and_never_read_again() {
assert_eq!(parsed(" \n !ls -la ").mode(), Mode::Command);
assert_eq!(parsed(" \n !ls -la ").body(), "ls -la");
assert_eq!(parsed("\tread the README\n").body(), "read the README");
}
#[test]
fn an_empty_body_says_what_to_write_instead() {
assert!(refusal("!").contains("!cargo test"), "{}", refusal("!"));
assert!(refusal("! ").contains("!cargo test"));
assert!(refusal("").contains("delegate"), "{}", refusal(""));
assert!(refusal(" ").contains("delegate"));
}
#[test]
fn a_call_with_no_string_in_it_is_told_which_field_to_fill() {
for input in [json!({}), json!({ "input": 7 }), json!({ "command": "ls" })] {
let error = parse(&input).expect_err("only a string input parses");
assert!(error.contains(INPUT_FIELD), "{error}");
}
}
#[test]
fn the_mode_spelling_is_the_one_rules_are_written_against() {
assert_eq!(Mode::Command.as_str(), "command");
assert_eq!(Mode::Agent.as_str(), "agent");
}
#[test]
fn a_command_presents_as_a_process_and_a_delegation_as_local_state() {
assert_eq!(
preview_of("!rm -rf /").side_effect_level,
ToolSideEffectLevel::Process
);
assert_eq!(
preview_of("summarise the diff").side_effect_level,
ToolSideEffectLevel::LocalState
);
assert!(crate::approval::is_consequential(
preview_of("!rm -rf /").side_effect_level
));
assert!(crate::approval::is_consequential(
preview_of("summarise the diff").side_effect_level
));
}
#[test]
fn the_preview_carries_the_parsed_call_and_not_the_string() {
let preview = preview_of("!cargo test -q");
assert_eq!(
preview.structured_input,
json!({ "mode": "command", "body": "cargo test -q", "cwd": "/repo" })
);
assert_eq!(
preview.raw_input,
json!({ "input": "!cargo test -q" }),
"the string the model wrote is kept, beside the parse rather than instead of it"
);
assert_eq!(preview.working_directory, PathBuf::from("/repo"));
let delegation = preview_of("!!literally bang");
assert_eq!(
delegation.structured_input,
json!({ "mode": "agent", "body": "!literally bang", "cwd": "/repo" }),
"an escaped prompt reaches the approver as a prompt, escape already spent"
);
}
#[test]
fn each_mode_is_categorised_as_the_door_it_replaced() {
let command = preview_of("!ls");
assert_eq!(command.approval_category, ToolApprovalCategory::Process);
assert_eq!(
command.execution_category,
ToolExecutionCategory::ExclusiveLocalMutation
);
assert_eq!(
command.capabilities,
vec![ToolCapability::ProcessExec, ToolCapability::FilesystemWrite]
);
let agent = preview_of("read the README");
assert_eq!(agent.approval_category, ToolApprovalCategory::Delegation);
assert_eq!(agent.execution_category, ToolExecutionCategory::Delegation);
assert_eq!(agent.capabilities, vec![ToolCapability::Delegation]);
}
#[test]
fn neither_mode_may_be_batched_with_anything() {
let tool = SpawnTool::new();
for input in [call("!ls"), call("read the README"), json!({})] {
assert!(
!tool.execution_category(&input).allows_parallel(),
"{input} must not run in a parallel batch"
);
}
}
#[test]
fn the_static_descriptor_states_the_stronger_of_the_two_modes() {
let descriptor = SpawnTool::new().descriptor();
assert_eq!(descriptor.provider.name, SPAWN);
assert_eq!(descriptor.side_effect_level, ToolSideEffectLevel::Process);
assert_eq!(descriptor.approval_category, ToolApprovalCategory::Process);
assert!(!descriptor.terminal);
}
#[test]
fn the_description_teaches_the_convention_it_is_the_only_source_of() {
let descriptor = SpawnTool::new().descriptor();
let description = descriptor
.provider
.description
.clone()
.expect("the model is told what this does");
for taught in ["!cargo test -q", "!!", "subagent"] {
assert!(description.contains(taught), "{description}");
}
}
#[test]
fn the_schema_asks_for_one_string_and_no_decisions() {
let descriptor = SpawnTool::new().descriptor();
let schema = descriptor.provider.input_schema;
assert_eq!(schema["required"], json!([INPUT_FIELD]));
assert_eq!(schema["properties"][INPUT_FIELD]["type"], "string");
assert_eq!(
schema["properties"].as_object().map(serde_json::Map::len),
Some(1),
"a second field is a decision on every call"
);
}
#[test]
fn delegation_stops_at_the_floor_and_says_what_to_do_instead() {
let ledger = depth::Depth::default();
assert_eq!(ledger.authorize_delegation("root"), Ok(0));
let _first = ledger.entered("child", 1);
assert_eq!(ledger.authorize_delegation("child"), Ok(1));
let _second = ledger.entered("grandchild", MAX_DEPTH);
let refused = ledger
.authorize_delegation("grandchild")
.expect_err("the floor holds");
assert_eq!(
refused,
"this work is already 2 levels of delegation deep and spawn goes no deeper than 2; \
do it here rather than handing it on"
);
}
#[test]
fn a_finished_delegation_leaves_no_trace_in_the_ledger() {
let ledger = depth::Depth::default();
{
let _entered = ledger.entered("child", 1);
assert_eq!(ledger.authorize_delegation("child"), Ok(1));
}
assert_eq!(
ledger.authorize_delegation("child"),
Ok(0),
"an id mentra reused would otherwise inherit a depth it never had"
);
}
#[test]
fn a_command_is_never_refused_for_being_deep() {
let tool = SpawnTool::new();
let _entered = tool.depth.entered("deep", MAX_DEPTH);
assert!(tool.depth.authorize_delegation("deep").is_err());
assert_eq!(parsed("!cargo test").mode(), Mode::Command);
}