Skip to content

Commit

Permalink
Add tests for to_chunk
Browse files Browse the repository at this point in the history
  • Loading branch information
LaurenzV committed Apr 1, 2024
1 parent e7372cd commit 4e152f6
Show file tree
Hide file tree
Showing 7 changed files with 1,847 additions and 1,779 deletions.
2 changes: 1 addition & 1 deletion tests/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ fontdb = { workspace = true }
svg2pdf = { workspace = true, default-features = true }
usvg = { workspace = true }
pdfium-render = { workspace = true, features = ["sync"] }
pdf-writer = { workspace = true }
pdf-writer.workspace = true
image = { workspace = true }
oxipng = { workspace = true }
once_cell = { workspace = true }
2 changes: 1 addition & 1 deletion tests/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ that cover certain other edge cases and some integration tests specific to `svg2

# Tests

We use a Python script to generate the `integration.rs` file, which tests all of the svg files
We use a Python script to generate the `render.rs` file, which tests all of the svg files
that are part of the test suites. SVG files which don't have a corresponding reference image
will be skipped. To regenerate this file, you can simply run `./scripts/gen-tests.py` and
it should work out of the box.
Expand Down
Binary file added tests/ref/api/to_chunk.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
20 changes: 17 additions & 3 deletions tests/scripts/gen-tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from common import SVG_DIR, ROOT, TestFile
from pathlib import Path

OUT_PATH = ROOT / "src" / "integration.rs"
OUT_PATH = ROOT / "src" / "render.rs"

NO_RELATIVE_PATHS = "no relative paths supported"
INVESTIGATE = "need to investigate"
Expand Down Expand Up @@ -86,7 +86,21 @@
def main():
test_string = f"// This file was auto-generated by `{Path(__file__).name}`, do not edit manually.\n\n"
test_string += "#![allow(non_snake_case)]\n\n"
test_string += "#[allow(unused_imports)]\nuse crate::run_test;\nuse svg2pdf::Options;\n"
test_string += "#[allow(unused_imports)]\nuse std::path::PathBuf;\nuse crate::{run_test_impl, convert_svg};\nuse svg2pdf::Options;\n"

test_string += """
#[allow(dead_code)]
pub fn get_svg_path(test_name: &str) -> PathBuf {
PathBuf::from("svg").join(String::from(test_name) + ".svg")
}
#[allow(dead_code)]
pub fn run_test(test_name: &str) -> i32 {
let svg_path = get_svg_path(test_name);
let (pdf, actual_image) = convert_svg(&svg_path, Options::default());
run_test_impl(pdf, actual_image, test_name)
}\n
"""

for p in SVG_DIR.rglob("*"):
if p.is_file() and p.suffix == ".svg":
Expand All @@ -107,7 +121,7 @@ def main():

test_string += "#[test] "

test_string += f'fn {function_name}() {{assert_eq!(run_test("{test_file.test_name()}", Options::default()), 0)}}\n'
test_string += f'fn {function_name}() {{assert_eq!(run_test("{test_file.test_name()}"), 0)}}\n'

with open(Path(OUT_PATH), "w") as file:
file.write(test_string)
Expand Down
99 changes: 78 additions & 21 deletions tests/src/api.rs
Original file line number Diff line number Diff line change
@@ -1,27 +1,84 @@
use crate::run_test_impl;
use std::path::Path;
use svg2pdf::Options;

fn run_api_test(svg_path: &Path, test_name: &str, options: Options) {
assert_eq!(
run_test_impl(
Path::new(svg_path),
Path::new(&format!("ref/api/{}.png", test_name)),
Path::new(&format!("diff/api/{}.png", test_name)),
Path::new(&format!("pdf/api/{}.pdf", test_name)),
options
),
0
);
}
use std::collections::HashMap;
#[allow(unused_imports)]
use {
crate::{convert_svg, run_test_impl},
crate::{render_pdf, FONTDB},
pdf_writer::{Content, Finish, Name, Pdf, Rect, Ref, Str},
std::path::Path,
svg2pdf::Options,
};

#[test]
fn text_to_paths() {
let options = Options { embed_text: false, ..Options::default() };

run_api_test(
Path::new("svg/resvg/text/text/simple-case.svg"),
"text_to_paths",
options,
);
let svg_path = "svg/resvg/text/text/simple-case.svg";
let (pdf, actual_image) = convert_svg(Path::new(svg_path), options);
let res = run_test_impl(pdf, actual_image, "api/text_to_paths");
assert_eq!(res, 0);
}

#[test]
fn to_chunk() {
let mut alloc = Ref::new(1);
let catalog_id = alloc.bump();
let page_tree_id = alloc.bump();
let page_id = alloc.bump();
let font_id = alloc.bump();
let content_id = alloc.bump();
let font_name = Name(b"F1");
let svg_name = Name(b"S1");

let path =
"svg/custom/integration/wikimedia/coat_of_the_arms_of_edinburgh_city_council.svg";
let svg = std::fs::read_to_string(path).unwrap();
let db = FONTDB.lock().unwrap();
let tree =
svg2pdf::usvg::Tree::from_str(&svg, &svg2pdf::usvg::Options::default(), &db)
.unwrap();
let (mut svg_chunk, svg_id) =
svg2pdf::to_chunk(&tree, svg2pdf::Options::default(), &db);

let mut map = HashMap::new();
let svg_chunk =
svg_chunk.renumber(|old| *map.entry(old).or_insert_with(|| alloc.bump()));
let svg_id = map.get(&svg_id).unwrap();

let mut pdf = Pdf::new();
pdf.catalog(catalog_id).pages(page_tree_id);
pdf.pages(page_tree_id).kids([page_id]).count(1);

let mut page = pdf.page(page_id);
page.media_box(Rect::new(0.0, 0.0, 595.0, 842.0));
page.parent(page_tree_id);
page.contents(content_id);

let mut resources = page.resources();
resources.x_objects().pair(svg_name, svg_id);
resources.fonts().pair(font_name, font_id);
resources.finish();
page.finish();

pdf.type1_font(font_id).base_font(Name(b"Helvetica"));

let mut content = Content::new();
content
.begin_text()
.set_font(font_name, 16.0)
.next_line(108.0, 734.0)
.show(Str(b"Look at my wonderful (distorted) vector graphic!"))
.end_text();

content
.transform([300.0, 0.0, 0.0, 225.0, 147.5, 385.0])
.x_object(svg_name);

pdf.stream(content_id, &content.finish());
pdf.extend(&svg_chunk);
let pdf = pdf.finish();

let actual_image = render_pdf(pdf.as_slice());
let res = run_test_impl(pdf, actual_image, "api/to_chunk");

assert_eq!(res, 0);
}
21 changes: 2 additions & 19 deletions tests/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#[rustfmt::skip]
mod integration;
mod render;
mod api;

use std::cmp::max;
Expand Down Expand Up @@ -150,10 +150,6 @@ pub fn get_diff(
(diff_image, pixel_diff)
}

pub fn get_svg_path(test_name: &str) -> PathBuf {
PathBuf::from("svg").join(String::from(test_name) + ".svg")
}

pub fn get_ref_path(test_name: &str) -> PathBuf {
PathBuf::from("ref").join(String::from(test_name) + ".png")
}
Expand All @@ -166,24 +162,11 @@ pub fn get_pdf_path(test_name: &str) -> PathBuf {
PathBuf::from("pdf").join(String::from(test_name) + ".pdf")
}

/// Runs a single test instance.
pub fn run_test(test_name: &str, options: Options) -> i32 {
let svg_path = get_svg_path(test_name);
pub fn run_test_impl(pdf: Vec<u8>, actual_image: RgbaImage, test_name: &str) -> i32 {
let ref_path = get_ref_path(test_name);
let diff_path = get_diff_path(test_name);
let pdf_path = get_pdf_path(test_name);

run_test_impl(&svg_path, &ref_path, &diff_path, &pdf_path, options)
}
pub fn run_test_impl(
svg_path: &Path,
ref_path: &Path,
diff_path: &Path,
pdf_path: &Path,
options: Options,
) -> i32 {
let (pdf, actual_image) = convert_svg(&svg_path, options);

// Just as a convenience, if the test is supposed to run but there doesn't exist
// a reference image yet, we create a new one. This allows us to conveniently generate
// new reference images for test cases.
Expand Down
Loading

0 comments on commit 4e152f6

Please sign in to comment.