134 lines
3.9 KiB
Rust
134 lines
3.9 KiB
Rust
use super::*;
|
|
|
|
fn layout(text: &str, width: usize) -> Vec<Segment> {
|
|
let mut cache = WrapCache::default();
|
|
cache.prepare((1, 0), width);
|
|
cache.segments(0, text).to_vec()
|
|
}
|
|
|
|
#[test]
|
|
fn words_and_long_words_preserve_every_source_cell() {
|
|
assert_eq!(
|
|
layout("one two three", 8),
|
|
vec![Segment { start: 0, end: 8 }, Segment { start: 8, end: 13 },]
|
|
);
|
|
let segments = layout("abcdefgh", 3);
|
|
assert_eq!(
|
|
segments,
|
|
vec![
|
|
Segment { start: 0, end: 3 },
|
|
Segment { start: 3, end: 6 },
|
|
Segment { start: 6, end: 8 },
|
|
]
|
|
);
|
|
assert_eq!(caret_segment(&segments, 3), 1);
|
|
assert_eq!(caret_segment(&segments, 8), 2);
|
|
}
|
|
|
|
#[test]
|
|
fn long_words_do_not_wrap_indentation_onto_an_empty_visual_row() {
|
|
for source in [
|
|
" abcdefghijk",
|
|
"\tabcdefghijk",
|
|
"head abcdefghijk",
|
|
] {
|
|
let expanded = source.replace('\t', " ");
|
|
let segments = layout(source, 8);
|
|
assert_eq!(segments.first().unwrap().start, 0);
|
|
assert_eq!(segments.last().unwrap().end, expanded.len());
|
|
assert!(segments.windows(2).all(|pair| pair[0].end == pair[1].start));
|
|
for segment in segments
|
|
.iter()
|
|
.filter(|segment| segment.start < segment.end)
|
|
{
|
|
assert!(
|
|
!expanded[segment.start..segment.end].trim().is_empty(),
|
|
"whitespace-only visual row {segment:?} in {source:?}"
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn tabs_use_source_stops_and_unicode_graphemes_remain_intact() {
|
|
assert_eq!(
|
|
layout("ab\t界e\u{301} z", 4),
|
|
vec![
|
|
Segment { start: 0, end: 4 },
|
|
Segment { start: 4, end: 8 },
|
|
Segment { start: 8, end: 9 },
|
|
]
|
|
);
|
|
assert_eq!(
|
|
layout("界界界", 3),
|
|
vec![
|
|
Segment { start: 0, end: 2 },
|
|
Segment { start: 2, end: 4 },
|
|
Segment { start: 4, end: 6 },
|
|
]
|
|
);
|
|
assert_eq!(
|
|
layout(" \t ", 3),
|
|
vec![Segment { start: 0, end: 3 }, Segment { start: 3, end: 5 },]
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn narrow_tabs_preserve_all_expanded_cells_at_original_stops() {
|
|
assert_eq!(
|
|
layout("\tX", 2),
|
|
[
|
|
Segment { start: 0, end: 2 },
|
|
Segment { start: 2, end: 4 },
|
|
Segment { start: 4, end: 5 },
|
|
]
|
|
);
|
|
assert_eq!(
|
|
layout("a\tX", 2),
|
|
[
|
|
Segment { start: 0, end: 1 },
|
|
Segment { start: 1, end: 3 },
|
|
Segment { start: 3, end: 5 },
|
|
Segment { start: 5, end: 5 },
|
|
]
|
|
);
|
|
for source in ["\t", "a\t", "ab\tX", "\t\tX"] {
|
|
let segments = layout(source, 1);
|
|
assert!(
|
|
segments
|
|
.iter()
|
|
.all(|segment| segment.end - segment.start <= 1)
|
|
);
|
|
assert!(segments.windows(2).all(|pair| pair[0].end == pair[1].start));
|
|
let end = source.graphemes(true).fold(0, |column, grapheme| {
|
|
column
|
|
+ if grapheme == "\t" {
|
|
TAB_WIDTH - column % TAB_WIDTH
|
|
} else {
|
|
1
|
|
}
|
|
});
|
|
assert_eq!(segments.last().unwrap(), &Segment { start: end, end });
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn full_lines_have_an_insertion_cell_and_cache_invalidation_is_lazy() {
|
|
let mut cache = WrapCache::default();
|
|
cache.prepare((7, 2), 4);
|
|
assert_eq!(
|
|
cache.segments(90, "abcd"),
|
|
[Segment { start: 0, end: 4 }, Segment { start: 4, end: 4 },]
|
|
);
|
|
assert_eq!(caret_segment(cache.segments(90, "abcd"), 4), 1);
|
|
assert_eq!(cache.rows.len(), 1);
|
|
cache.prepare((7, 2), 4);
|
|
assert_eq!(cache.rows.len(), 1);
|
|
cache.prepare((7, 2), 8);
|
|
assert!(cache.rows.is_empty());
|
|
cache.segments(90, "abcd");
|
|
cache.prepare((7, 3), 8);
|
|
assert!(cache.rows.is_empty());
|
|
assert_eq!(layout("", 0), [Segment { start: 0, end: 0 }]);
|
|
}
|