bxctl: chat --speaker NAME, the speaker on every turn of the chat
Co-Authored-By: ornith-1.5-35b-a3b <agent@wntrmute.dev>
This commit is contained in:
@@ -38,6 +38,7 @@ fn chat_defaults_come_from_home() {
|
||||
show_thinking: true,
|
||||
say: None,
|
||||
json: false,
|
||||
speaker: None,
|
||||
})
|
||||
);
|
||||
}
|
||||
@@ -55,6 +56,8 @@ fn chat_takes_every_flag_in_any_order() {
|
||||
"--no-thinking",
|
||||
"--session",
|
||||
"s-1",
|
||||
"--speaker",
|
||||
"kyle",
|
||||
"--socket",
|
||||
"/tmp/l.sock",
|
||||
]),
|
||||
@@ -65,6 +68,7 @@ fn chat_takes_every_flag_in_any_order() {
|
||||
show_thinking: false,
|
||||
say: Some("hello there".to_string()),
|
||||
json: true,
|
||||
speaker: Some("kyle".to_string()),
|
||||
})
|
||||
);
|
||||
}
|
||||
@@ -80,6 +84,63 @@ fn chat_usage_errors() {
|
||||
bad(&["chat", "stray"]);
|
||||
}
|
||||
|
||||
/// `chat` with only `--speaker NAME`: everything else at its default.
|
||||
fn chat_as(name: &str) -> Command {
|
||||
let mut opts = ChatOptions::default(Path::new(HOME));
|
||||
opts.speaker = Some(name.to_string());
|
||||
Command::Chat(opts)
|
||||
}
|
||||
|
||||
/// The speaker is the argument after `--speaker`, kept as it is: a `.` is not mapped, letters
|
||||
/// outside ASCII are kept (`memoryd` checks Honcho's pattern, not `bxctl`), and a value that
|
||||
/// looks like a flag is a value.
|
||||
#[test]
|
||||
fn chat_speaker_is_the_value_after_the_flag() {
|
||||
assert_eq!(ok(&["chat", "--speaker", "kyle"]), chat_as("kyle"));
|
||||
assert_eq!(
|
||||
ok(&["chat", "--speaker", "first.last"]),
|
||||
chat_as("first.last")
|
||||
);
|
||||
assert_eq!(ok(&["chat", "--speaker", "zo\u{eb}"]), chat_as("zo\u{eb}"));
|
||||
assert_eq!(ok(&["chat", "--speaker", "--json"]), chat_as("--json"));
|
||||
assert_eq!(ok(&["chat", "--speaker", "k"]), chat_as("k"));
|
||||
let Command::Chat(opts) = ok(&["chat", "--speaker", "kyle", "--json"]) else {
|
||||
panic!("not chat")
|
||||
};
|
||||
assert_eq!(opts.speaker.as_deref(), Some("kyle"));
|
||||
assert!(opts.json, "the flag after the name is read as a flag");
|
||||
}
|
||||
|
||||
/// A speaker that is empty, or holds whitespace or a control character anywhere, is a usage
|
||||
/// error; so are a missing value and a second `--speaker`, even with the same name.
|
||||
#[test]
|
||||
fn a_bad_speaker_is_a_usage_error() {
|
||||
for name in [
|
||||
"",
|
||||
" ",
|
||||
"first last",
|
||||
" kyle",
|
||||
"kyle ",
|
||||
"kyle\t",
|
||||
"kyle\n",
|
||||
"\rkyle",
|
||||
"ky\u{a0}le",
|
||||
"ky\u{2003}le",
|
||||
"ky\u{3000}le",
|
||||
"ky\u{7}le",
|
||||
"ky\u{1b}le",
|
||||
"ky\u{7f}le",
|
||||
"ky\u{85}le",
|
||||
"ky\u{9b}le",
|
||||
] {
|
||||
bad(&["chat", "--speaker", name]);
|
||||
}
|
||||
bad(&["chat", "--speaker"]);
|
||||
bad(&["chat", "--json", "--speaker"]);
|
||||
bad(&["chat", "--speaker", "kyle", "--speaker", "eve"]);
|
||||
bad(&["chat", "--speaker", "kyle", "--speaker", "kyle"]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn approvals() {
|
||||
assert_eq!(
|
||||
@@ -245,6 +306,28 @@ fn usage_names_every_command() {
|
||||
}
|
||||
}
|
||||
|
||||
/// The chat lines of the usage text, exactly, and the indentation of every line: two spaces
|
||||
/// before a command, six before its explanation.
|
||||
#[test]
|
||||
fn usage_explains_the_speaker_flag() {
|
||||
let chat = concat!(
|
||||
"\n bxctl chat [--socket PATH] [--admin-socket PATH] [--session ID] [--say TEXT] ",
|
||||
"[--no-thinking] [--json] [--speaker NAME]\n",
|
||||
" Talk to loopd.\n",
|
||||
" With --speaker NAME (no spaces), the turns are NAME's and are synced to Honcho as ",
|
||||
"that person.\n\n bxctl approvals ",
|
||||
);
|
||||
assert!(USAGE.contains(chat), "{USAGE}");
|
||||
for line in USAGE.lines().skip(1) {
|
||||
let command = line.starts_with(" bxctl ");
|
||||
let explanation = line.starts_with(" ") && !line.starts_with(" ");
|
||||
assert!(
|
||||
line.is_empty() || command || explanation,
|
||||
"badly indented: {line:?}"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn the_binary_prints_usage_and_exits_2() {
|
||||
for words in [
|
||||
|
||||
Reference in New Issue
Block a user