Skip to content

Commit

Permalink
Reconstruct partial new file from diff
Browse files Browse the repository at this point in the history
  • Loading branch information
sourcefrog committed Nov 13, 2023
1 parent 9169e68 commit dec840d
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 1 deletion.
50 changes: 49 additions & 1 deletion src/in_diff.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,8 +125,41 @@ fn affected_lines(patch: &Patch) -> Vec<usize> {
r
}

/// Recreate a partial view of the new file from a Patch.
///
/// This contains lines present as adedd or context. Typically not all context
/// will be covered, so the output is a list of line numbers and their text.
fn partial_new_file<'d>(patch: &Patch<'d>) -> Vec<(usize, &'d str)> {
let mut r: Vec<(usize, &'d str)> = Vec::new();
for hunk in &patch.hunks {
let mut lineno: usize = hunk.new_range.start.try_into().unwrap();
for line in &hunk.lines {
match line {
Line::Context(text) | Line::Add(text) => {
debug_assert!(lineno >= 1, "{lineno}");
debug_assert!(
r.last().map_or(true, |last| last.0 < lineno),
"{lineno} {r:?}"
);
r.push((lineno, text));
lineno += 1;
}
Line::Remove(_) => {}
}
}
debug_assert_eq!(
lineno,
(hunk.new_range.start + hunk.new_range.count) as usize,
"Wrong number of resulting lines?"
);
}
r
}

#[cfg(test)]
mod test_super {
use std::fs::read_to_string;

use assert_cmd::assert;
use pretty_assertions::assert_eq;
use similar::TextDiff;
Expand Down Expand Up @@ -170,7 +203,7 @@ index eb42779..a0091b7 100644
TextDiff::from_lines(old, new)
.unified_diff()
.context_radius(2)
.header("a/file", "b/file")
.header("a/file.rs", "b/file.rs")
.to_string()
}

Expand Down Expand Up @@ -263,4 +296,19 @@ index eb42779..a0091b7 100644
}
}
}

#[test]
fn reconstruct_partial_new_file() {
let old = read_to_string("testdata/tree/diff0/src/lib.rs").unwrap();
let new = read_to_string("testdata/tree/diff1/src/lib.rs").unwrap();
let diff = make_diff(&old, &new);
let patch = Patch::from_single(&diff).unwrap();
let reconstructed = partial_new_file(&patch);
println!("{reconstructed:#?}");
assert_eq!(reconstructed.len(), 16);
let new_lines = new.lines().collect_vec();
for (lineno, text) in reconstructed {
assert_eq!(text, new_lines[lineno - 1]);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,11 @@ src/in_diff.rs: replace strip_patch_path -> &Utf8Path with &Default::default()
src/in_diff.rs: replace affected_lines -> Vec<usize> with vec![]
src/in_diff.rs: replace affected_lines -> Vec<usize> with vec![0]
src/in_diff.rs: replace affected_lines -> Vec<usize> with vec![1]
src/in_diff.rs: replace partial_new_file -> Vec<(usize, &'d str)> with vec![]
src/in_diff.rs: replace partial_new_file -> Vec<(usize, &'d str)> with vec![(0, "")]
src/in_diff.rs: replace partial_new_file -> Vec<(usize, &'d str)> with vec![(0, "xyzzy")]
src/in_diff.rs: replace partial_new_file -> Vec<(usize, &'d str)> with vec![(1, "")]
src/in_diff.rs: replace partial_new_file -> Vec<(usize, &'d str)> with vec![(1, "xyzzy")]
src/interrupt.rs: replace install_handler with ()
src/lab.rs: replace test_mutants -> Result<LabOutcome> with Ok(Default::default())
src/lab.rs: replace test_mutants -> Result<LabOutcome> with Err(::anyhow::anyhow!("mutated!"))
Expand Down

0 comments on commit dec840d

Please sign in to comment.