use super::TEMPLATE_PROVIDERS;
use crate::model_pick::{Effort, Tuning, tuning::plan};
fn tuned() -> String {
TEMPLATE_PROVIDERS.replace(
" model: gpt-5.4\n tools:",
" model: gpt-5.4\n effort: low\n priority: true\n tools:",
)
}
fn effort(role: &str, level: Option<Effort>) -> Tuning {
Tuning::Effort {
workspace: "ws".to_owned(),
role: role.to_owned(),
level,
}
}
fn priority(role: &str, on: bool) -> Tuning {
Tuning::Priority {
workspace: "ws".to_owned(),
role: role.to_owned(),
on,
}
}
#[test]
fn a_level_is_added_to_a_role_that_had_none_and_nothing_else_moves() {
let out = plan(TEMPLATE_PROVIDERS, &effort("worker", Some(Effort::High))).expect("planned");
assert!(out.contains(" effort: high\n"), "{out}");
assert!(out.contains(" provider: codex\n"), "{out}");
assert!(
out.contains(" tools: [bash, read_file, load_skill]\n"),
"{out}"
);
assert!(out.contains(" compactor:\n"), "{out}");
let worker = out.split(" compactor:").next().expect("worker block");
assert!(worker.contains("effort: high"), "{out}");
}
#[test]
fn a_level_on_a_role_that_had_one_is_moved_not_duplicated() {
let out = plan(&tuned(), &effort("worker", Some(Effort::Medium))).expect("planned");
assert_eq!(out.matches("effort:").count(), 1, "{out}");
assert!(out.contains(" effort: medium\n"), "{out}");
assert!(out.contains(" priority: true\n"), "{out}");
}
#[test]
fn off_removes_the_line_rather_than_writing_a_word_for_absence() {
let out = plan(&tuned(), &effort("worker", None)).expect("planned");
assert!(!out.contains("effort"), "{out}");
assert!(out.contains(" priority: true\n"), "{out}");
assert!(out.contains(" model: gpt-5.4\n"), "{out}");
}
#[test]
fn clearing_a_knob_a_role_never_carried_is_the_file_unchanged() {
let out = plan(TEMPLATE_PROVIDERS, &effort("worker", None)).expect("planned");
assert_eq!(out, TEMPLATE_PROVIDERS);
let out = plan(TEMPLATE_PROVIDERS, &priority("worker", false)).expect("planned");
assert_eq!(out, TEMPLATE_PROVIDERS);
}
#[test]
fn priority_writes_true_or_nothing_at_all() {
let on = plan(TEMPLATE_PROVIDERS, &priority("worker", true)).expect("planned");
assert!(on.contains(" priority: true\n"), "{on}");
let off = plan(&on, &priority("worker", false)).expect("planned");
assert_eq!(off, TEMPLATE_PROVIDERS);
assert!(!off.contains("priority"), "{off}");
}
#[test]
fn the_two_knobs_are_written_independently_and_both_survive() {
let out = plan(TEMPLATE_PROVIDERS, &effort("worker", Some(Effort::Low))).expect("planned");
let out = plan(&out, &priority("worker", true)).expect("planned");
assert!(out.contains(" effort: low\n"), "{out}");
assert!(out.contains(" priority: true\n"), "{out}");
assert!(
out.contains(" tools: [bash, read_file, load_skill]\n"),
"{out}"
);
}
#[test]
fn a_role_the_file_does_not_declare_refuses_on_both_arms() {
let set =
plan(TEMPLATE_PROVIDERS, &effort("nonesuch", Some(Effort::Low))).expect_err("no such role");
assert!(set.to_string().contains("nonesuch"), "{set}");
assert!(set.to_string().contains("providers.yaml"), "{set}");
let clear = plan(TEMPLATE_PROVIDERS, &effort("nonesuch", None)).expect_err("no such role");
assert_eq!(
clear.to_string(),
set.to_string(),
"one sentence, both paths"
);
let toggle = plan(TEMPLATE_PROVIDERS, &priority("nonesuch", false)).expect_err("no such role");
assert_eq!(toggle.to_string(), set.to_string());
}
#[test]
fn a_file_with_no_roles_block_declares_no_role() {
for gesture in [
priority("worker", true),
priority("worker", false),
effort("worker", Some(Effort::Low)),
effort("worker", None),
] {
let said = plan("models: {}\n", &gesture).expect_err("nothing declared");
assert!(said.to_string().contains("worker"), "{said}");
assert!(said.to_string().contains("providers.yaml"), "{said}");
}
}
#[test]
fn the_level_vocabulary_is_closed_and_round_trips() {
for level in [Effort::Low, Effort::Medium, Effort::High] {
assert_eq!(Effort::parse(&level.as_str()), Some(level));
}
for word in ["off", "none", "LOW", "highest", ""] {
assert_eq!(Effort::parse(word), None, "{word}");
}
}
#[test]
fn the_carrier_answers_the_workspace_and_the_role_for_both_members() {
let mut one = effort("worker", Some(Effort::Low));
let mut two = priority("compactor", true);
assert_eq!(one.workspace_slot(), "ws");
assert_eq!(two.workspace_slot(), "ws");
"elsewhere".clone_into(two.workspace_slot());
assert_eq!(two.workspace_slot(), "elsewhere");
assert_eq!(one.role(), "worker");
assert_eq!(two.role(), "compactor");
}
#[test]
fn a_blank_line_inside_the_entry_keeps_its_place_and_the_field_joins_the_run() {
let spaced = "roles:\n worker:\n provider: codex\n model: gpt-5.4\n\n compactor:\n \
provider: codex\n model: gpt-5.4-mini\n";
let out = plan(spaced, &effort("worker", Some(Effort::High))).expect("planned");
assert_eq!(
out,
"roles:\n worker:\n provider: codex\n model: gpt-5.4\n effort: high\n\n \
compactor:\n provider: codex\n model: gpt-5.4-mini\n"
);
}
#[test]
fn an_inline_roles_key_refuses_on_every_arm() {
let inline = "roles: {}\n";
for gesture in [
effort("worker", Some(Effort::Low)),
effort("worker", None),
priority("worker", true),
priority("worker", false),
] {
let said = plan(inline, &gesture).expect_err("inline is never rewritten");
assert!(said.to_string().contains("roles"), "{said}");
}
}