#[path = "../src/buffer/store.rs"]
mod store;
#[path = "../src/buffer/view.rs"]
mod view;
use store::BufferStore;
use view::{BufferReadRequest, BufferView};
#[test]
fn append_and_read_preserve_order_and_line_numbers() {
let mut store = BufferStore::new(32);
store.append_bytes(b"one\ntwo\nthree\n");
let page = store
.read(&BufferReadRequest::new(10))
.expect("buffer read should succeed");
assert_eq!(page.returned, 3);
assert_eq!(page.total_lines, 3);
assert_eq!(
page.lines
.iter()
.map(|line| (line.line_number, line.text.as_str()))
.collect::<Vec<_>>(),
vec![(1, "one"), (2, "two"), (3, "three")]
);
}
#[test]
fn regex_filter_and_view_modes_work_together() {
let mut store = BufferStore::new(32);
store.append_bytes(b"\x1b[31mError\x1b[0m happened\nINFO done\nraw\x03\n");
let mut plain_read = BufferReadRequest::new(10);
plain_read.pattern = Some("error".to_string());
plain_read.ignore_case = true;
plain_read.view = BufferView::Plain;
let plain_page = store.read(&plain_read).expect("plain filter should work");
assert_eq!(plain_page.returned, 1);
assert_eq!(plain_page.lines[0].text, "Error happened");
let mut ansi_read = BufferReadRequest::new(10);
ansi_read.pattern = Some("Error".to_string());
ansi_read.view = BufferView::Ansi;
let ansi_page = store.read(&ansi_read).expect("ansi filter should work");
assert_eq!(ansi_page.returned, 1);
assert!(ansi_page.lines[0].text.contains("\x1b[31m"));
let mut raw_read = BufferReadRequest::new(10);
raw_read.pattern = Some(r"\\x03".to_string());
raw_read.view = BufferView::Raw;
let raw_page = store.read(&raw_read).expect("raw filter should work");
assert_eq!(raw_page.returned, 1);
assert_eq!(raw_page.lines[0].text, "raw\\x03");
}
#[test]
fn invalid_regex_error_contains_pattern_context() {
let mut store = BufferStore::new(32);
store.append_bytes(b"alpha\nbeta\n");
let mut request = BufferReadRequest::new(10);
request.pattern = Some("(".to_string());
let error = store.read(&request).expect_err("invalid regex must fail");
let text = format!("{error:#}");
assert!(text.contains("invalid regex pattern for buffer read"));
assert!(text.contains("pattern=("));
}
#[test]
fn retention_trims_old_lines_and_keeps_monotonic_numbering() {
let mut store = BufferStore::new(3);
assert_eq!(store.max_lines(), 3);
store.append_bytes(b"l1\nl2\nl3\n");
store.set_max_lines(3);
store.append_bytes(b"l4\n");
store.append_bytes(b"l5");
let page = store
.read(&BufferReadRequest::new(10))
.expect("buffer read should succeed");
assert_eq!(page.total_lines, 3);
assert_eq!(
page.lines
.iter()
.map(|line| (line.line_number, line.text.as_str()))
.collect::<Vec<_>>(),
vec![(3, "l3"), (4, "l4"), (5, "l5")]
);
let stats = store.stats();
assert_eq!(stats.total_lines_seen, 5);
assert_eq!(stats.dropped_lines, 2);
}