use std::cell::RefCell;
use std::rc::Rc;
use std::sync::Arc;
use super::*;
use crate::widget::Widget;
const FONT_BYTES: &[u8] = include_bytes!("../../../../demo/assets/CascadiaCode.ttf");
fn font() -> Arc<Font> {
Arc::new(Font::from_slice(FONT_BYTES).expect("font"))
}
fn watch() -> Rc<RefCell<TextAreaScrollInfo>> {
Rc::new(RefCell::new(TextAreaScrollInfo::default()))
}
#[test]
fn scroll_watch_offset_mirrors_live_offset() {
let w = watch();
let text = (0..200)
.map(|i| format!("line{i}"))
.collect::<Vec<_>>()
.join("\n");
let mut ta = TextArea::new(font())
.with_font_size(13.0)
.with_text(text)
.with_scroll_watch(Rc::clone(&w));
ta.layout(Size::new(200.0, 80.0));
assert_eq!(w.borrow().offset_px, 0.0, "watch starts at the top");
assert!(
ta.max_scroll_y() > 0.0,
"200 lines must overflow an 80px box"
);
assert!(ta.scroll_by_wheel(-40.0), "wheel must move the offset");
assert!(ta.scroll_offset() > 0.0);
assert_eq!(
w.borrow().offset_px,
ta.scroll_offset(),
"offset after wheel"
);
ta.set_cursor_to_end();
ta.ensure_cursor_visible();
assert_eq!(
w.borrow().offset_px,
ta.scroll_offset(),
"offset after scroll-to-caret"
);
}
#[test]
fn source_line_rows_maps_wrapped_lines() {
let w = watch();
let text = "short\none two three four five six seven eight nine ten\nlast";
let mut ta = TextArea::new(font())
.with_font_size(13.0)
.with_text(text)
.with_scroll_watch(Rc::clone(&w));
ta.layout(Size::new(70.0, 400.0));
let rows = w.borrow().source_line_rows.clone();
assert_eq!(rows.len(), 3, "three source lines");
assert_eq!(rows[0], 0, "line 1 starts at row 0");
assert_eq!(
rows[1], 1,
"line 2 starts on the row after single-row line 1"
);
let wrapped_rows = rows[2] - rows[1];
assert!(
wrapped_rows >= 3,
"the long middle line must wrap into 3+ visual rows, got {wrapped_rows}"
);
assert!(
rows[2] < ta.visual_line_count(),
"the last source line's first row must land within the visual rows"
);
}
#[test]
fn source_line_rows_update_after_edit_changes_wrapping() {
let w = watch();
let text = "short\none two three four five six seven eight nine ten\nlast";
let mut ta = TextArea::new(font())
.with_font_size(13.0)
.with_text(text)
.with_scroll_watch(Rc::clone(&w));
ta.layout(Size::new(70.0, 400.0));
assert!(
w.borrow().source_line_rows[2] > 2,
"precondition: the middle line wraps before the edit"
);
{
let st = ta.edit_state();
let mut st = st.borrow_mut();
st.text = "short\ntiny\nlast".to_string();
st.cursor = 0;
st.anchor = 0;
st.note_text_change();
}
ta.layout(Size::new(70.0, 400.0));
assert_eq!(
w.borrow().source_line_rows,
vec![0, 1, 2],
"with no wrapping the map degenerates to rows[i]==i"
);
}