use kcode_k1_chat_boxes::{
BoxId, ChatBox, ToolCallId, ToolMessageMetadata, USER_MESSAGE_TYPE, named_tool_message_box,
};
use kcode_k1_chat_thread_web_code_open_targets::{
NON_TEXT_SENTINEL, TargetRejection, classify_anchor, classify_file_target, present_create,
present_open,
};
use kcode_k1_transaction_id::TxId;
use kcode_k1_web_code_document::CodeDocument;
use kcode_k1_web_package::{AuthorityId, SourceFile, WebFamily};
fn call() -> ToolCallId {
ToolCallId::new([2; 12], 4)
}
fn document() -> CodeDocument {
CodeDocument::new(
WebFamily::new(AuthorityId::new(TxId::from_bytes([1; 12])), "alpha").unwrap(),
vec![
SourceFile::new(
"src/main.odd",
b"export async function runTests(){ return true; }\r\n".to_vec(),
),
SourceFile::new("assets/pixel.bin", vec![0xff, 0x00, 0x7f]),
SourceFile::new("Documentation.md", b"Exact docs\r\n".to_vec()),
],
)
.unwrap()
}
fn assign(id: u64, value: ChatBox) -> ChatBox {
ChatBox::new(
BoxId::new(id),
value.box_type().to_owned(),
value.contents().to_owned(),
value.hidden_type().to_owned(),
value.hidden_contents().to_owned(),
)
}
fn message(
id: u64,
originating_call: BoxId,
tool_call_id: ToolCallId,
index: u64,
title: &str,
body: &str,
) -> ChatBox {
assign(
id,
named_tool_message_box(
&ToolMessageMetadata {
tool_call_id,
originating_call,
message_index: index,
message: body.to_owned(),
},
title,
)
.unwrap(),
)
}
#[test]
fn every_complete_file_is_one_sorted_named_message() {
let document = document();
let opened = present_open(BoxId::new(7), call(), &document, "1.2.3");
assert_eq!(
opened.output.message_titles,
[
Some("File: Documentation.md".to_owned()),
Some("File: assets/pixel.bin".to_owned()),
Some("File: src/main.odd".to_owned()),
]
);
assert_eq!(opened.output.messages[0], "Exact docs\r\n");
assert_eq!(opened.output.messages[1], NON_TEXT_SENTINEL);
assert_eq!(
opened.output.messages[2],
"export async function runTests(){ return true; }\r\n"
);
assert_eq!(opened.output.result, Ok("Opened 1.2.3.".to_owned()));
assert_eq!(opened.layout.file_count(), 3);
assert!(!opened.output.metadata_contents.contains("authority"));
let created = present_create(BoxId::new(7), call(), &document, "010101010101010101010101");
assert_eq!(
created.output.result,
Ok("Created 010101010101010101010101.".to_owned())
);
assert_eq!(created.output.messages, opened.output.messages);
assert_eq!(created.output.message_titles, opened.output.message_titles);
}
#[test]
fn source_messages_are_anchors_and_current_file_targets() {
let value = present_open(BoxId::new(7), call(), &document(), "1.2.3");
let history = vec![
message(
10,
BoxId::new(7),
call(),
1,
"File: Documentation.md",
&value.output.messages[0],
),
message(
11,
BoxId::new(7),
call(),
2,
"File: assets/pixel.bin",
&value.output.messages[1],
),
message(
12,
BoxId::new(7),
call(),
3,
"File: src/main.odd",
&value.output.messages[2],
),
ChatBox::new(
BoxId::new(13),
USER_MESSAGE_TYPE.to_owned(),
"ordinary".to_owned(),
String::new(),
String::new(),
),
];
assert_eq!(
classify_anchor(&history, BoxId::new(10), &value.layout)
.unwrap()
.path(),
"Documentation.md"
);
let binary = classify_file_target(&history, BoxId::new(11), &value.layout).unwrap();
assert_eq!(binary.path(), "assets/pixel.bin");
assert!(!binary.is_text());
let text = classify_file_target(&history, BoxId::new(12), &value.layout).unwrap();
assert_eq!(text.path(), "src/main.odd");
assert!(text.is_text());
assert_eq!(
classify_file_target(&history, BoxId::new(13), &value.layout),
Err(TargetRejection::NotSourceMessage)
);
assert_eq!(
classify_anchor(&history, BoxId::new(99), &value.layout),
Err(TargetRejection::HistoryAbsent)
);
}
#[test]
fn retired_file_messages_remain_anchors_only() {
let value = present_open(BoxId::new(7), call(), &document(), "1.2.3");
let binary = message(
11,
BoxId::new(7),
call(),
2,
"File: assets/pixel.bin",
&value.output.messages[1],
);
let history = [binary];
let mut layout = value.layout;
layout.retire_file("assets/pixel.bin").unwrap();
assert_eq!(
classify_anchor(&history, BoxId::new(11), &layout)
.unwrap()
.path(),
"assets/pixel.bin"
);
assert_eq!(
classify_file_target(&history, BoxId::new(11), &layout),
Err(TargetRejection::RetiredFile)
);
}