use crate::analysis::prompt::build_analysis_prompt;
fn assert_opening_names(prompt: &str, display_name: &str) {
let first = prompt.lines().next().unwrap_or_default();
assert!(
first.contains(display_name),
"the prompt must open by naming the language `{display_name}`, got first line: {first}"
);
}
use crate::languages::definitions::{GO, PYTHON};
use crate::languages::spec::LanguageSupport;
#[test]
fn python_prompt_carries_display_name_and_every_convention() {
let prompt = build_analysis_prompt(&PYTHON);
assert_opening_names(&prompt, PYTHON.display_name);
for convention in PYTHON.conventions {
assert!(
prompt.contains(convention),
"Python prompt must list every convention entry, missing `{convention}` in:\n{prompt}"
);
}
}
#[test]
fn go_prompt_carries_display_name_and_every_convention() {
let prompt = build_analysis_prompt(&GO);
assert_opening_names(&prompt, GO.display_name);
for convention in GO.conventions {
assert!(
prompt.contains(convention),
"Go prompt must list every convention entry, missing `{convention}` in:\n{prompt}"
);
}
}
#[test]
fn language_with_no_conventions_omits_the_concerns_block() {
let lang = LanguageSupport {
name: "anon",
display_name: "Anon",
extensions: &[".anon"],
tools: &[],
conventions: &[],
vendored_dirs: &[],
};
let prompt = build_analysis_prompt(&lang);
assert!(
!prompt.contains("-specific concerns:"),
"an empty conventions list must drop the heading entirely, got:\n{prompt}"
);
let doubled = prompt
.lines()
.collect::<Vec<_>>()
.windows(2)
.any(|pair| pair[0].trim().is_empty() && pair[1].trim().is_empty());
assert!(
!doubled,
"an empty conventions block must not leave a doubled blank line, got:\n{prompt}"
);
let populated = build_analysis_prompt(&PYTHON);
assert!(
populated.contains("**Python-specific concerns:**"),
"a language with conventions must get the heading, got:\n{populated}"
);
}
#[test]
fn prompt_includes_the_linter_separation_instruction() {
let prompt = build_analysis_prompt(&PYTHON);
assert!(
prompt.contains(
"Do not report subjective style issues, and do not report anything a\n\
formatter or linter would catch"
),
"the prompt must instruct the model to defer to the linter layer, got:\n{prompt}"
);
}
#[test]
fn prompt_tells_the_model_to_use_the_gutter_line_number() {
let prompt = build_analysis_prompt(&PYTHON);
assert!(
prompt.contains("gutter"),
"the prompt must refer to the gutter line number, got:\n{prompt}"
);
assert!(
prompt.contains("line-numbered excerpt"),
"the prompt must state the input is a line-numbered excerpt, got:\n{prompt}"
);
}