Skip to content

Commit c0be918

Browse files
committed
Re-add slider test v1 to compare both versions
1 parent 618c37a commit c0be918

File tree

1 file changed

+166
-3
lines changed

1 file changed

+166
-3
lines changed

gix-diff/tests/diff/blob/slider.rs

Lines changed: 166 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,132 @@
1-
use gix_diff::blob::v2::{Algorithm, BasicLineDiffPrinter, Diff, InternedInput, UnifiedDiffConfig};
21
use gix_object::bstr::ByteSlice;
32
use gix_testtools::bstr::{BString, ByteVec};
43
use pretty_assertions::StrComparison;
54

65
#[test]
7-
fn baseline() -> gix_testtools::Result {
6+
fn baseline_v1() -> gix_testtools::Result {
7+
use gix_diff::blob::{unified_diff::ContextSize, Algorithm, UnifiedDiff};
8+
9+
let worktree_path = gix_testtools::scripted_fixture_read_only_standalone("make_diff_for_sliders_repo.sh")?;
10+
let asset_dir = worktree_path.join("assets");
11+
12+
let dir = std::fs::read_dir(&worktree_path)?;
13+
14+
let mut diffs = Vec::new();
15+
16+
for entry in dir {
17+
let entry = entry?;
18+
let file_name = entry.file_name().into_string().expect("to be string");
19+
20+
if !file_name.ends_with(".baseline") {
21+
continue;
22+
}
23+
24+
let parts: Vec<_> = file_name.split('.').collect();
25+
let [name, algorithm, ..] = parts[..] else {
26+
unreachable!()
27+
};
28+
let algorithm = match algorithm {
29+
"myers" => Algorithm::Myers,
30+
"histogram" => Algorithm::Histogram,
31+
_ => unreachable!(),
32+
};
33+
34+
let parts: Vec<_> = name.split('-').collect();
35+
let [old_blob_id, new_blob_id] = parts[..] else {
36+
unreachable!();
37+
};
38+
39+
let old_data = std::fs::read(asset_dir.join(format!("{old_blob_id}.blob")))?;
40+
let new_data = std::fs::read(asset_dir.join(format!("{new_blob_id}.blob")))?;
41+
42+
let interner = gix_diff::blob::intern::InternedInput::new(
43+
tokens_for_diffing(old_data.as_slice()),
44+
tokens_for_diffing(new_data.as_slice()),
45+
);
46+
47+
let actual = gix_diff::blob::diff(
48+
algorithm,
49+
&interner,
50+
UnifiedDiff::new(
51+
&interner,
52+
baseline::DiffHunkRecorder::new(),
53+
ContextSize::symmetrical(3),
54+
),
55+
)?;
56+
57+
let baseline_path = worktree_path.join(&file_name);
58+
let baseline = std::fs::read(baseline_path)?;
59+
let baseline = baseline::Baseline::new(&baseline);
60+
61+
let actual = actual
62+
.iter()
63+
.fold(BString::default(), |mut acc, diff_hunk| {
64+
acc.push_str(diff_hunk.header.to_string().as_str());
65+
acc.push(b'\n');
66+
67+
acc.extend_from_slice(&diff_hunk.lines);
68+
69+
acc
70+
})
71+
.to_string();
72+
73+
let baseline = baseline
74+
.fold(BString::default(), |mut acc, diff_hunk| {
75+
acc.push_str(diff_hunk.header.to_string().as_str());
76+
acc.push(b'\n');
77+
78+
acc.extend_from_slice(&diff_hunk.lines);
79+
80+
acc
81+
})
82+
.to_string();
83+
84+
let actual_matches_baseline = actual == baseline;
85+
diffs.push((actual, baseline, actual_matches_baseline, file_name));
86+
}
87+
88+
if diffs.is_empty() {
89+
eprintln!("Slider baseline isn't setup - look at ./gix-diff/tests/README.md for instructions");
90+
}
91+
92+
let total_diffs = diffs.len();
93+
let matching_diffs = diffs
94+
.iter()
95+
.filter(|(_, _, actual_matches_baseline, _)| *actual_matches_baseline)
96+
.count();
97+
98+
assert_eq!(
99+
matching_diffs,
100+
total_diffs,
101+
"matching diffs {} == total diffs {} [{:.2} %]\n\n{}",
102+
matching_diffs,
103+
total_diffs,
104+
((matching_diffs as f32) / (total_diffs as f32) * 100.0),
105+
{
106+
let first_non_matching_diff = diffs
107+
.iter()
108+
.find(|(_, _, actual_matches_baseline, _)| !actual_matches_baseline)
109+
.expect("at least one non-matching diff to be there");
110+
111+
format!(
112+
"affected baseline: `{}`\n\n{}",
113+
first_non_matching_diff.3,
114+
StrComparison::new(&first_non_matching_diff.0, &first_non_matching_diff.1)
115+
)
116+
}
117+
);
118+
119+
Ok(())
120+
}
121+
122+
fn tokens_for_diffing(data: &[u8]) -> impl gix_diff::blob::intern::TokenSource<Token = &[u8]> {
123+
gix_diff::blob::sources::byte_lines(data)
124+
}
125+
126+
#[test]
127+
fn baseline_v2() -> gix_testtools::Result {
128+
use gix_diff::blob::v2::{Algorithm, BasicLineDiffPrinter, Diff, InternedInput, UnifiedDiffConfig};
129+
8130
let worktree_path = gix_testtools::scripted_fixture_read_only_standalone("make_diff_for_sliders_repo.sh")?;
9131
let asset_dir = worktree_path.join("assets");
10132

@@ -108,7 +230,7 @@ mod baseline {
108230
use gix_object::bstr::ByteSlice;
109231
use std::iter::Peekable;
110232

111-
use gix_diff::blob::unified_diff::HunkHeader;
233+
use gix_diff::blob::unified_diff::{ConsumeHunk, HunkHeader};
112234
use gix_object::bstr::{self, BString};
113235

114236
static START_OF_HEADER: &[u8; 4] = b"@@ -";
@@ -119,6 +241,47 @@ mod baseline {
119241
pub lines: BString,
120242
}
121243

244+
pub struct DiffHunkRecorder {
245+
inner: Vec<DiffHunk>,
246+
}
247+
248+
impl DiffHunkRecorder {
249+
pub fn new() -> Self {
250+
Self { inner: Vec::new() }
251+
}
252+
}
253+
254+
impl ConsumeHunk for DiffHunkRecorder {
255+
type Out = Vec<DiffHunk>;
256+
257+
fn consume_hunk(
258+
&mut self,
259+
header: HunkHeader,
260+
lines: &[(gix_diff::blob::unified_diff::DiffLineKind, &[u8])],
261+
) -> std::io::Result<()> {
262+
let mut buf = Vec::new();
263+
264+
for &(kind, line) in lines {
265+
buf.push(kind.to_prefix() as u8);
266+
buf.extend_from_slice(line);
267+
buf.push(b'\n');
268+
}
269+
270+
let diff_hunk = DiffHunk {
271+
header,
272+
lines: buf.into(),
273+
};
274+
275+
self.inner.push(diff_hunk);
276+
277+
Ok(())
278+
}
279+
280+
fn finish(self) -> Self::Out {
281+
self.inner
282+
}
283+
}
284+
122285
type Lines<'a> = Peekable<bstr::Lines<'a>>;
123286

124287
pub struct Baseline<'a> {

0 commit comments

Comments
 (0)