first pass of merging in warp (doesn't build)
This commit is contained in:
@@ -2,9 +2,8 @@
|
||||
|
||||
use std::io::Write as _;
|
||||
|
||||
use crate::FileModel;
|
||||
|
||||
use super::*;
|
||||
use crate::FileModel;
|
||||
|
||||
fn make_accumulator(ranges: &[std::ops::Range<usize>], max_bytes: usize) -> TextFileAccumulator {
|
||||
TextFileAccumulator::new("test.txt".to_string(), None, ranges, max_bytes)
|
||||
@@ -118,14 +117,52 @@ fn unsorted_ranges_are_sorted() {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn empty_file_with_ranges_produces_no_segment() {
|
||||
fn empty_file_with_ranges_produces_empty_segment() {
|
||||
let acc = make_accumulator(&[1..5], 1000);
|
||||
let (segments, bytes_read) = acc.finalize();
|
||||
|
||||
assert_eq!(segments.len(), 0);
|
||||
assert_eq!(segments.len(), 1);
|
||||
assert_eq!(segments[0].content, "");
|
||||
assert_eq!(segments[0].line_range, Some(1..5));
|
||||
assert_eq!(segments[0].line_count, 0);
|
||||
assert_eq!(bytes_read, 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn range_past_eof_produces_empty_segment() {
|
||||
// File has 5 lines, but range requests lines 10..15 which are all past EOF.
|
||||
let mut acc = make_accumulator(&[10..15], 1000);
|
||||
for i in 1..=5 {
|
||||
push(&mut acc, &format!("line{i}"));
|
||||
}
|
||||
let (segments, bytes_read) = acc.finalize();
|
||||
|
||||
assert_eq!(segments.len(), 1);
|
||||
assert_eq!(segments[0].content, "");
|
||||
assert_eq!(segments[0].line_range, Some(10..15));
|
||||
assert_eq!(segments[0].line_count, 5);
|
||||
assert_eq!(bytes_read, 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn multiple_ranges_some_past_eof() {
|
||||
// First range is valid, second is entirely past EOF.
|
||||
let mut acc = make_accumulator(&[1..3, 10..15], 1000);
|
||||
for i in 1..=5 {
|
||||
push(&mut acc, &format!("line{i}"));
|
||||
}
|
||||
let (segments, _bytes_read) = acc.finalize();
|
||||
|
||||
assert_eq!(segments.len(), 2);
|
||||
assert_eq!(segments[0].content, "line1\nline2");
|
||||
assert_eq!(segments[0].line_range, Some(1..3));
|
||||
assert_eq!(segments[1].content, "");
|
||||
assert_eq!(segments[1].line_range, Some(10..15));
|
||||
for seg in &segments {
|
||||
assert_eq!(seg.line_count, 5);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn line_count_reflects_total_file_lines() {
|
||||
let mut acc = make_accumulator(&[2..4], 1000);
|
||||
@@ -156,6 +193,43 @@ fn range_truncated_at_byte_limit() {
|
||||
assert_eq!(bytes_read, 4);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn whole_file_truncated_on_first_line_yields_empty_range() {
|
||||
// Budget smaller than the very first line, so nothing is ever buffered.
|
||||
// The truncated range must be a valid empty `1..1`, not a reversed `1..0`.
|
||||
let mut acc = make_accumulator(&[], 4);
|
||||
push(&mut acc, "hello"); // 5 bytes > 4 → truncated, nothing buffered
|
||||
push(&mut acc, "world");
|
||||
let (segments, bytes_read) = acc.finalize();
|
||||
|
||||
assert_eq!(segments.len(), 1);
|
||||
assert_eq!(segments[0].content, "");
|
||||
assert_eq!(segments[0].line_range, Some(1..1));
|
||||
assert_eq!(segments[0].line_count, 2);
|
||||
assert_eq!(bytes_read, 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn range_truncated_on_first_in_range_line_yields_empty_range() {
|
||||
// The first line that falls inside the requested range already exceeds the
|
||||
// budget, so nothing is buffered for this range. The range must be the
|
||||
// empty `2..2`, not a reversed `2..0`.
|
||||
let mut acc = make_accumulator(&[2..6], 4);
|
||||
push(&mut acc, "skip"); // line 1, outside range
|
||||
push(&mut acc, "hello"); // line 2, 5 bytes > 4 → truncated, nothing buffered
|
||||
push(&mut acc, "world"); // line 3
|
||||
let (segments, bytes_read) = acc.finalize();
|
||||
|
||||
assert_eq!(segments.len(), 1);
|
||||
assert_eq!(segments[0].content, "");
|
||||
assert_eq!(segments[0].line_range, Some(2..2));
|
||||
let Some(range) = &segments[0].line_range else {
|
||||
panic!("expected a line range");
|
||||
};
|
||||
assert!(range.start <= range.end, "range must not be reversed");
|
||||
assert_eq!(bytes_read, 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn global_budget_shared_across_ranges() {
|
||||
// Budget of 12 bytes. First range uses 5, leaving 7 for the second.
|
||||
|
||||
Reference in New Issue
Block a user