//! Byte cursor bridge tests, including oriented Unicode selections. use egui::text::{CCursor, CCursorRange}; use egui::text_edit::TextEditState; use notescraft_editor::editor::{byte_cursor_range, set_byte_cursor_range}; #[test] fn unicode_ranges_round_trip_without_reversing_primary_and_anchor() { let ctx = egui::Context::default(); let id = egui::Id::new("cursor-bridge"); let text = "aé🦀z"; for range in [(0, 0), (1, 7), (7, 1), (3, 8), (8, 8)] { set_byte_cursor_range(&ctx, id, text, range).expect("valid byte range"); assert_eq!(byte_cursor_range(&ctx, id, text), range); } } #[test] fn invalid_ranges_leave_stored_selection_unchanged() { let ctx = egui::Context::default(); let id = egui::Id::new("invalid-cursor"); let text = "aé🦀z"; set_byte_cursor_range(&ctx, id, text, (7, 1)).expect("valid byte range"); for range in [(2, 0), (0, 2), (4, 7), (7, 6), (9, 0), (0, usize::MAX)] { assert!(set_byte_cursor_range(&ctx, id, text, range).is_err()); assert_eq!(byte_cursor_range(&ctx, id, text), (7, 1)); } } #[test] fn missing_or_stale_egui_cursors_return_valid_byte_boundaries() { let ctx = egui::Context::default(); let id = egui::Id::new("stale-cursor"); assert_eq!(byte_cursor_range(&ctx, id, "é"), (0, 0)); let mut state = TextEditState::default(); state.cursor.set_char_range(Some(CCursorRange::two(CCursor::new(1), CCursor::new(usize::MAX)))); state.store(&ctx, id); assert_eq!(byte_cursor_range(&ctx, id, "é🦀"), (6, 2)); }