pmacs/tests/tab_width_acceptance.rs

89 lines
3.1 KiB
Rust

//! Cross-frontend tab-stop acceptance for core/TUI rendering.
use std::sync::{Arc, Mutex};
use pmacs::buffer::{Buffer, BufferId};
use pmacs::cell::{Cell, CellCoord, CellGrid, CellSize, Glyph, Style};
use pmacs::overlay::{BufferStyleOverlay, BufferStyleSpan, SharedBufferStyleSpans};
use pmacs::text_view::TextView;
use pmacs::view::{DisplayCoord, View, Viewport};
fn viewport(rows: u32, cols: u32, buffer_end: u64) -> Viewport<'static> {
Viewport {
buffer_start: 0,
buffer_end,
cell_origin: CellCoord::new(0, 0),
cell_size: CellSize::new(rows, cols),
gutter_w: 0,
folds: None,
}
}
fn render_text(buf: &Buffer, rows: u32, cols: u32) -> Vec<Cell> {
let mut cells = vec![Cell::default(); (rows * cols) as usize];
let mut grid = CellGrid {
cells: &mut cells,
stride: cols,
size: CellSize::new(rows, cols),
};
TextView::new(buf).render(buf, viewport(rows, cols, buf.len()), &mut grid);
cells
}
#[test]
fn plain_text_projects_tabs_without_changing_source_bytes() {
let source = b"\tx\n1234567\ty\n12345678\tz";
let buf = Buffer::from_bytes(BufferId::next(), "tabs", source);
let cells = render_text(&buf, 3, 20);
let view = TextView::new(&buf);
assert_eq!(view.pos_to_display(&buf, 1), Some(DisplayCoord::new(0, 8)));
assert_eq!(view.pos_to_display(&buf, 11), Some(DisplayCoord::new(1, 8)));
assert_eq!(
view.pos_to_display(&buf, 22),
Some(DisplayCoord::new(2, 16))
);
for cell in cells.iter().take(8) {
assert_eq!(cell.glyph, Glyph::Char(' '));
}
assert_eq!(cells[8].glyph, Glyph::Char('x'));
assert_eq!(cells[20 + 8].glyph, Glyph::Char('y'));
assert_eq!(cells[40 + 16].glyph, Glyph::Char('z'));
let mut retained = vec![0; buf.len() as usize];
buf.snapshot_rope().slice(0, buf.len(), &mut retained);
assert_eq!(retained, source, "rendering must not replace source tabs");
}
#[test]
fn buffer_style_overlay_covers_the_same_expanded_tab_columns_as_plain_text() {
let source = b"a\tb";
let buf = Buffer::from_bytes(BufferId::next(), "styled-tab", source);
let mut cells = render_text(&buf, 1, 12);
let spans: SharedBufferStyleSpans = Arc::new(Mutex::new(vec![BufferStyleSpan {
start: 1,
end: 2,
style: Style {
bold: true,
..Style::default()
},
}]));
let mut overlay = BufferStyleOverlay::new(spans);
let mut grid = CellGrid {
cells: &mut cells,
stride: 12,
size: CellSize::new(1, 12),
};
overlay.render(&buf, viewport(1, 12, buf.len()), &mut grid);
assert_eq!(grid.get(CellCoord::new(0, 0)).glyph, Glyph::Char('a'));
assert!(!grid.get(CellCoord::new(0, 0)).style.bold);
for col in 1..8 {
let cell = grid.get(CellCoord::new(0, col));
assert_eq!(cell.glyph, Glyph::Char(' '), "expanded tab column {col}");
assert!(cell.style.bold, "overlay missed expanded tab column {col}");
}
assert_eq!(grid.get(CellCoord::new(0, 8)).glyph, Glyph::Char('b'));
assert!(!grid.get(CellCoord::new(0, 8)).style.bold);
}