Skip to content

Commit 1e3efab

Browse files
committed
refactor
- deduplicate a little, and do away with blanket `unreachable!()`.
1 parent c0be918 commit 1e3efab

File tree

1 file changed

+61
-93
lines changed

1 file changed

+61
-93
lines changed

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

Lines changed: 61 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
1+
use gix_diff::blob::Algorithm;
12
use gix_object::bstr::ByteSlice;
23
use gix_testtools::bstr::{BString, ByteVec};
34
use pretty_assertions::StrComparison;
5+
use std::ffi::OsStr;
6+
use std::path::Path;
47

58
#[test]
69
fn baseline_v1() -> gix_testtools::Result {
7-
use gix_diff::blob::{unified_diff::ContextSize, Algorithm, UnifiedDiff};
10+
use gix_diff::blob::{unified_diff::ContextSize, UnifiedDiff};
811

912
let worktree_path = gix_testtools::scripted_fixture_read_only_standalone("make_diff_for_sliders_repo.sh")?;
1013
let asset_dir = worktree_path.join("assets");
@@ -15,30 +18,10 @@ fn baseline_v1() -> gix_testtools::Result {
1518

1619
for entry in dir {
1720
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+
let Some((file_name, algorithm, old_data, new_data)) = parse_dir_entry(&asset_dir, &entry.file_name()) else {
2122
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!(),
3223
};
3324

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-
4225
let interner = gix_diff::blob::intern::InternedInput::new(
4326
tokens_for_diffing(old_data.as_slice()),
4427
tokens_for_diffing(new_data.as_slice()),
@@ -70,17 +53,7 @@ fn baseline_v1() -> gix_testtools::Result {
7053
})
7154
.to_string();
7255

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-
56+
let baseline = baseline.fold_to_unidiff().to_string();
8457
let actual_matches_baseline = actual == baseline;
8558
diffs.push((actual, baseline, actual_matches_baseline, file_name));
8659
}
@@ -89,32 +62,7 @@ fn baseline_v1() -> gix_testtools::Result {
8962
eprintln!("Slider baseline isn't setup - look at ./gix-diff/tests/README.md for instructions");
9063
}
9164

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-
);
65+
assert_diffs(&diffs);
11866

11967
Ok(())
12068
}
@@ -136,31 +84,16 @@ fn baseline_v2() -> gix_testtools::Result {
13684

13785
for entry in dir {
13886
let entry = entry?;
139-
let file_name = entry.file_name().into_string().expect("to be string");
140-
141-
if !file_name.ends_with(".baseline") {
87+
let Some((file_name, algorithm, old_data, new_data)) = parse_dir_entry(&asset_dir, &entry.file_name()) else {
14288
continue;
143-
}
144-
145-
let parts: Vec<_> = file_name.split('.').collect();
146-
let [name, algorithm, ..] = parts[..] else {
147-
unreachable!()
14889
};
149-
let algorithm = match algorithm {
150-
"myers" => Algorithm::Myers,
151-
"histogram" => Algorithm::Histogram,
152-
_ => unreachable!(),
153-
};
154-
155-
let parts: Vec<_> = name.split('-').collect();
156-
let [old_blob_id, new_blob_id] = parts[..] else {
157-
unreachable!();
158-
};
159-
160-
let old_data = std::fs::read(asset_dir.join(format!("{old_blob_id}.blob")))?;
161-
let new_data = std::fs::read(asset_dir.join(format!("{new_blob_id}.blob")))?;
16290

16391
let input = InternedInput::new(old_data.to_str().unwrap(), new_data.to_str().unwrap());
92+
let algorithm = match algorithm {
93+
gix_diff::blob::Algorithm::Myers => Algorithm::Myers,
94+
gix_diff::blob::Algorithm::Histogram => Algorithm::Histogram,
95+
gix_diff::blob::Algorithm::MyersMinimal => Algorithm::MyersMinimal,
96+
};
16497

16598
let mut diff = Diff::compute(algorithm, &input);
16699
diff.postprocess_lines(&input);
@@ -177,16 +110,7 @@ fn baseline_v2() -> gix_testtools::Result {
177110
let baseline = std::fs::read(baseline_path)?;
178111
let baseline = baseline::Baseline::new(&baseline);
179112

180-
let baseline = baseline
181-
.fold(BString::default(), |mut acc, diff_hunk| {
182-
acc.push_str(diff_hunk.header.to_string().as_str());
183-
acc.push(b'\n');
184-
185-
acc.extend_from_slice(&diff_hunk.lines);
186-
187-
acc
188-
})
189-
.to_string();
113+
let baseline = baseline.fold_to_unidiff().to_string();
190114

191115
let actual_matches_baseline = actual == baseline;
192116
diffs.push((actual, baseline, actual_matches_baseline, file_name));
@@ -196,6 +120,38 @@ fn baseline_v2() -> gix_testtools::Result {
196120
eprintln!("Slider baseline isn't setup - look at ./gix-diff/tests/README.md for instructions");
197121
}
198122

123+
assert_diffs(&diffs);
124+
Ok(())
125+
}
126+
127+
fn parse_dir_entry(asset_dir: &Path, file_name: &OsStr) -> Option<(String, Algorithm, Vec<u8>, Vec<u8>)> {
128+
let file_name = file_name.to_str().expect("ascii filename").to_owned();
129+
130+
if !file_name.ends_with(".baseline") {
131+
return None;
132+
}
133+
134+
let parts: Vec<_> = file_name.split('.').collect();
135+
let [name, algorithm, ..] = parts[..] else {
136+
unreachable!("BUG: Need file named '<name>.<algorithm>'")
137+
};
138+
let algorithm = match algorithm {
139+
"myers" => Algorithm::Myers,
140+
"histogram" => Algorithm::Histogram,
141+
other => unreachable!("'{other}' is not a supported algorithm"),
142+
};
143+
144+
let parts: Vec<_> = name.split('-').collect();
145+
let [old_blob_id, new_blob_id] = parts[..] else {
146+
unreachable!("BUG: name part of filename must be <old_blob_id>-<new_blob_id>");
147+
};
148+
149+
let old_data = std::fs::read(asset_dir.join(format!("{old_blob_id}.blob"))).unwrap();
150+
let new_data = std::fs::read(asset_dir.join(format!("{new_blob_id}.blob"))).unwrap();
151+
(file_name, algorithm, old_data, new_data).into()
152+
}
153+
154+
fn assert_diffs(diffs: &[(String, String, bool, String)]) {
199155
let total_diffs = diffs.len();
200156
let matching_diffs = diffs
201157
.iter()
@@ -222,12 +178,10 @@ fn baseline_v2() -> gix_testtools::Result {
222178
)
223179
}
224180
);
225-
226-
Ok(())
227181
}
228182

229183
mod baseline {
230-
use gix_object::bstr::ByteSlice;
184+
use gix_object::bstr::{ByteSlice, ByteVec};
231185
use std::iter::Peekable;
232186

233187
use gix_diff::blob::unified_diff::{ConsumeHunk, HunkHeader};
@@ -296,6 +250,20 @@ mod baseline {
296250
}
297251
}
298252

253+
impl Baseline<'_> {
254+
/// Fold all [`DiffHunk`]s we produce into a unified_diff string
255+
pub fn fold_to_unidiff(self) -> BString {
256+
self.fold(BString::default(), |mut acc, diff_hunk| {
257+
acc.push_str(diff_hunk.header.to_string().as_str());
258+
acc.push(b'\n');
259+
260+
acc.extend_from_slice(&diff_hunk.lines);
261+
262+
acc
263+
})
264+
}
265+
}
266+
299267
impl Iterator for Baseline<'_> {
300268
type Item = DiffHunk;
301269

0 commit comments

Comments
 (0)