mirror of
https://github.com/storytold/designcraft.git
synced 2026-11-14 14:22:39 +00:00
Data merge: a file that is not an image does not hide a later image candidate
The image search stopped at the first file that could be read and checked whether it decodes afterwards. A non-image file at an earlier candidate (the drive root, or beside the data file) then hid a valid image beside the data file or the document, and the field was reported missing. The decode check now runs inside the search, so only an image ends it.
This commit is contained in:
1 parent
d490e0fb18
commit
b73c21db37
2 files changed
+28
-5
No files matched your search
@@ -464,7 +464,7 @@ struct LoadedImage {
|
||||
fn load_image(cell: &str, sources: &Sources) -> Option<LoadedImage> {
|
||||
let Sources { data_dir, doc_dir, images, .. } = *sources;
|
||||
let cands = image_candidates(cell, data_dir, doc_dir);
|
||||
let (path, bytes) = cands.iter().find_map(|p| {
|
||||
cands.iter().find_map(|p| {
|
||||
// Read once per merge: many records naming one file is the normal case, and reading it
|
||||
// per record is the amplification (#1595).
|
||||
let bytes = images.get_or_read(p, || {
|
||||
@@ -475,10 +475,11 @@ fn load_image(cell: &str, sources: &Sources) -> Option<LoadedImage> {
|
||||
}
|
||||
crate::io::read_file(p).ok().filter(|b| !b.is_empty())
|
||||
})?;
|
||||
Some((p.clone(), bytes))
|
||||
})?;
|
||||
let (pixels, natural) = designcraft_render::image_size(&bytes).zip(designcraft_render::natural_size(&bytes, 0))?;
|
||||
Some(LoadedImage { path, bytes, pixels, natural })
|
||||
// A file that does not decode leaves the search going, so a valid image at a later
|
||||
// candidate is still found.
|
||||
let (pixels, natural) = designcraft_render::image_size(&bytes).zip(designcraft_render::natural_size(&bytes, 0))?;
|
||||
Some(LoadedImage { path: p.clone(), bytes, pixels, natural })
|
||||
})
|
||||
}
|
||||
|
||||
fn report_missing(report: &mut FillReport, record: u32, field: &str, cell: &str) {
|
||||
|
||||
@@ -914,6 +914,28 @@ fn an_image_path_with_a_leading_separator_is_found_beside_the_data_file() {
|
||||
assert_eq!(r["missingImages"].as_array().map(Vec::len), Some(0), "{r}");
|
||||
}
|
||||
|
||||
/// A file at an earlier candidate that is not an image does not hide a valid image at a later
|
||||
/// one: the search goes on past it.
|
||||
#[test]
|
||||
fn a_non_image_file_beside_the_data_does_not_hide_the_image_beside_the_document() {
|
||||
let dir = scratch("undecodable-image");
|
||||
let (data, docs) = (dir.join("data"), dir.join("docs"));
|
||||
write(&data.join("pics").join("a.png"), "not an image");
|
||||
write_png_sized(&docs.join("pics").join("a.png"), 12, 12);
|
||||
write(&data.join("cards.csv"), "@Photo\npics/a.png\n");
|
||||
let mut s = Session::new();
|
||||
new_doc(&mut s, 1);
|
||||
exec(&mut s, "data.source.select", json!({"path": data.join("cards.csv")}));
|
||||
exec(&mut s, "file.save", json!({"path": docs.join("layout.designcraft")}));
|
||||
let frame = exec(&mut s, "frame.create", json!({"rect": [36.0, 36.0, 80.0, 80.0], "content": "graphic"}));
|
||||
exec(&mut s, "data.placeholder.add", json!({"field": "Photo", "item": frame["id"]}));
|
||||
exec(&mut s, "data.options", json!({"linkImages": true}));
|
||||
let r = exec(&mut s, "data.merge", json!({}));
|
||||
assert_eq!(r["missingImages"].as_array().map(Vec::len), Some(0), "{r}");
|
||||
let link = graphic_link(&s).unwrap_or_default();
|
||||
assert!(link.contains("docs"), "{link}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn single_record_merge_copies_pages_and_leaves_the_template() {
|
||||
let mut s = Session::new();
|
||||
|
||||
Reference in new issue
Block a user