This commit is contained in:
Daniel Edrisian
2025-08-25 18:42:57 -07:00
parent 1a5c12cf63
commit 6714afe2d7
2 changed files with 79 additions and 0 deletions

View File

@@ -1988,4 +1988,34 @@ mod tests {
let imgs = composer.take_recent_submission_images();
assert_eq!(imgs, vec![tmp_path.clone()]);
}
#[test]
fn selecting_custom_prompt_submits_file_contents() {
let tmp = tempdir().expect("create TempDir");
let home = tmp.path();
let prompts_dir = home.join(".codex").join("prompts");
std::fs::create_dir_all(&prompts_dir).expect("mkdir -p ~/.codex/prompts");
let prompt_path = prompts_dir.join("my-prompt");
let prompt_text = "Hello from saved prompt";
std::fs::write(&prompt_path, prompt_text).unwrap();
unsafe { std::env::set_var("HOME", home) };
let (tx, _rx) = unbounded_channel::<AppEvent>();
let sender = AppEventSender::new(tx);
let mut composer =
ChatComposer::new(true, sender, false, "Ask Codex to do anything".to_string());
// Type the prompt name to focus it in the slash popup and press Enter.
for ch in ['/', 'm', 'y', '-', 'p', 'r', 'o', 'm', 'p', 't'] {
let _ = composer.handle_key_event(KeyEvent::new(KeyCode::Char(ch), KeyModifiers::NONE));
}
let (result, _needs_redraw) =
composer.handle_key_event(KeyEvent::new(KeyCode::Enter, KeyModifiers::NONE));
match result {
InputResult::Submitted(s) => assert_eq!(s, prompt_text),
_ => panic!("expected Submitted with prompt contents"),
}
}
}

View File

@@ -229,6 +229,7 @@ impl WidgetRef for CommandPopup {
#[cfg(test)]
mod tests {
use super::*;
use tempfile::tempdir;
#[test]
fn filter_includes_init_when_typing_prefix() {
@@ -264,4 +265,52 @@ mod tests {
None => panic!("expected a selected command for exact match"),
}
}
#[test]
fn prompt_discovery_lists_custom_prompts() {
let tmp = tempdir().expect("create TempDir");
let home = tmp.path();
let prompts_dir = home.join(".codex").join("prompts");
std::fs::create_dir_all(&prompts_dir).expect("mkdir -p ~/.codex/prompts");
std::fs::write(prompts_dir.join("foo"), b"hello from foo").unwrap();
std::fs::write(prompts_dir.join("bar"), b"hello from bar").unwrap();
// Point HOME to the temp dir so discovery uses our fixtures.
unsafe { std::env::set_var("HOME", home) };
let popup = CommandPopup::new();
let items = popup.filtered_items();
let mut prompt_names: Vec<String> = items
.into_iter()
.filter_map(|it| match it {
CommandItem::Prompt(i) => popup.prompt_name(i).map(|s| s.to_string()),
_ => None,
})
.collect();
prompt_names.sort();
assert_eq!(prompt_names, vec!["bar".to_string(), "foo".to_string()]);
}
#[test]
fn prompt_name_collision_with_builtin_is_ignored() {
let tmp = tempdir().expect("create TempDir");
let home = tmp.path();
let prompts_dir = home.join(".codex").join("prompts");
std::fs::create_dir_all(&prompts_dir).expect("mkdir -p ~/.codex/prompts");
// Create a prompt with the same name as a builtin command (e.g. "init").
std::fs::write(prompts_dir.join("init"), b"should be ignored").unwrap();
unsafe { std::env::set_var("HOME", home) };
let popup = CommandPopup::new();
let items = popup.filtered_items();
let has_collision_prompt = items.into_iter().any(|it| match it {
CommandItem::Prompt(i) => popup.prompt_name(i) == Some("init"),
_ => false,
});
assert!(
!has_collision_prompt,
"prompt with builtin name should be ignored"
);
}
}