1669 lines
43 KiB
Rust
1669 lines
43 KiB
Rust
//use crate::predicates::ends_with_pkg_version;
|
|
mod internal_predicates;
|
|
use internal_predicates::file;
|
|
|
|
use assert_cmd::Command;
|
|
use assert_cmd::assert::IntoOutputPredicate;
|
|
use assert_cmd::cargo::cargo_bin_cmd;
|
|
#[cfg(system_deps_have_cairo_pdf)]
|
|
use chrono::{TimeZone, Utc};
|
|
use predicates::boolean::*;
|
|
use predicates::prelude::*;
|
|
use predicates::str::*;
|
|
use rsvg::{Length, LengthUnit};
|
|
use std::env;
|
|
use std::io::Write;
|
|
use std::path::{Path, PathBuf};
|
|
use tempfile::{Builder, NamedTempFile};
|
|
use url::Url;
|
|
|
|
// What should be tested here?
|
|
// The goal is to test the code in rsvg-convert, not the entire library.
|
|
//
|
|
// - command-line options that affect size (width, height, zoom, resolution) ✔
|
|
// - pixel dimensions of the output (should be sufficient to do that for PNG) ✔
|
|
// - limit on output size (32767 pixels) ✔
|
|
// - output formats (PNG, PDF, PS, EPS, SVG) ✔
|
|
// - multi-page output (for PDF) ✔
|
|
// - output file option ✔
|
|
// - SOURCE_DATA_EPOCH environment variable for PDF output ✔
|
|
// - background color option ✔
|
|
// - optional CSS stylesheet ✔
|
|
// - error handling for missing SVG dimensions ✔
|
|
// - error handling for export lookup ID ✔
|
|
// - error handling for invalid input ✔
|
|
|
|
struct RsvgConvert {
|
|
command: Command,
|
|
|
|
// This field is never read; it is just to store the temporary file, which will
|
|
// be deleted when the struct is dropped. So, we mark it with dead_code.
|
|
#[allow(dead_code)]
|
|
config_file: NamedTempFile,
|
|
}
|
|
|
|
impl RsvgConvert {
|
|
fn new() -> RsvgConvert {
|
|
let config_file = setup_fontconfig_file();
|
|
let config_file_path: &Path = config_file.as_ref();
|
|
|
|
let path_str = config_file_path.to_str().unwrap();
|
|
eprintln!("FONTCONFIG_FILE={path_str}");
|
|
|
|
let mut command = cargo_bin_cmd!("rsvg-convert");
|
|
command.env("FONTCONFIG_FILE", config_file_path);
|
|
|
|
RsvgConvert {
|
|
command,
|
|
config_file,
|
|
}
|
|
}
|
|
|
|
fn new_with_input<P>(file: P) -> RsvgConvert
|
|
where
|
|
P: AsRef<Path>,
|
|
{
|
|
let mut rsvg_convert = RsvgConvert::new();
|
|
match rsvg_convert.command.pipe_stdin(&file) {
|
|
Ok(_) => (),
|
|
Err(e) => panic!("Error opening file '{}': {}", file.as_ref().display(), e),
|
|
}
|
|
|
|
rsvg_convert
|
|
}
|
|
|
|
fn accepts_arg(option: &str) {
|
|
let mut rsvg_convert = RsvgConvert::new_with_input("tests/fixtures/dpi.svg");
|
|
|
|
rsvg_convert.command.arg(option).assert().success();
|
|
}
|
|
|
|
fn option_yields_output<I, P>(option: &str, output_pred: I)
|
|
where
|
|
I: IntoOutputPredicate<P>,
|
|
P: Predicate<[u8]>,
|
|
{
|
|
let mut rsvg_convert = RsvgConvert::new();
|
|
|
|
rsvg_convert
|
|
.command
|
|
.arg(option)
|
|
.assert()
|
|
.success()
|
|
.stdout(output_pred);
|
|
}
|
|
}
|
|
|
|
/// Creaates a temporary `fonts.conf` for the rsvg-convert tests suite and returns the path
|
|
/// to that file.
|
|
///
|
|
/// Explanation: a few of the tests for rsvg-convert need fonts to be installed, since
|
|
/// otherwise Cairo/fontconfig won't generate the expected output. So, we need to
|
|
///
|
|
/// * Create a fonts.conf.
|
|
/// * Ensure that that fonts.conf has a `<dir>` tag with the location of the font files.
|
|
///
|
|
/// However the location of the font files is rsvg/tests/resources with respect to the
|
|
/// toplevel directory of this librsvg source tree. The librsvg source tree is structured as a Cargo workspace,
|
|
/// with these in the toplevel:
|
|
///
|
|
/// * Cargo.toml
|
|
/// * rsvg/tests/resources
|
|
/// * rsvg_convert/Cargo.toml (manifest path for *this* rsvg_convert project)
|
|
///
|
|
/// So, at this point, `CARGO_MANIFEST_DIR` points to
|
|
/// `librsvg/rsvg_convert`, and we need to find
|
|
/// `../rsvg/tests/resources` and canonicalize it into an absolute
|
|
/// path. Then, we need to make a `fonts.conf` with that absolute
|
|
/// path.
|
|
fn setup_fontconfig_file() -> NamedTempFile {
|
|
let fonts_dir = rsvg_tests_resources_path().into_os_string();
|
|
let fonts_dir_bytes = fonts_dir.as_encoded_bytes();
|
|
|
|
let mut file = NamedTempFile::new().expect("create temporary file for fonts.conf");
|
|
|
|
write!(
|
|
file,
|
|
r#"<?xml version="1.0"?>
|
|
<!DOCTYPE fontconfig SYSTEM "urn:fontconfig:fonts.dtd">
|
|
<fontconfig>
|
|
<cachedir>/tmp/rsvg_tests_fontconfig_cache</cachedir>
|
|
"#
|
|
)
|
|
.unwrap();
|
|
write!(file, "<dir>").unwrap();
|
|
file.write(fonts_dir_bytes).unwrap();
|
|
writeln!(file, "</dir>").unwrap();
|
|
write!(
|
|
file,
|
|
r#"
|
|
<!--
|
|
From openSUSE's fonts.conf:
|
|
Accept deprecated 'sans' alias, replacing it with 'sans-serif'
|
|
-->
|
|
<match target="pattern">
|
|
<test qual="any" name="family">
|
|
<string>sans</string>
|
|
</test>
|
|
<edit name="family" mode="assign" binding="same">
|
|
<string>sans-serif</string>
|
|
</edit>
|
|
</match>
|
|
|
|
<!--
|
|
Map 'serif' to 'sans-serif' since we don't have a serif font in the test resources yet.
|
|
-->
|
|
<match target="pattern">
|
|
<test qual="any" name="family">
|
|
<string>serif</string>
|
|
</test>
|
|
<edit name="family" mode="assign" binding="same">
|
|
<string>sans-serif</string>
|
|
</edit>
|
|
</match>
|
|
|
|
<!--
|
|
Names not including any well known alias are given 'sans-serif'
|
|
-->
|
|
<match target="pattern">
|
|
<test qual="all" name="family" compare="not_eq">
|
|
<string>sans-serif</string>
|
|
</test>
|
|
<test qual="all" name="family" compare="not_eq">
|
|
<string>serif</string>
|
|
</test>
|
|
<test qual="all" name="family" compare="not_eq">
|
|
<string>monospace</string>
|
|
</test>
|
|
<edit name="family" mode="append_last">
|
|
<string>sans-serif</string>
|
|
</edit>
|
|
</match>
|
|
|
|
<!-- Map generic family names to actual fonts -->
|
|
<alias>
|
|
<family>sans-serif</family>
|
|
<prefer><family>Roboto</family></prefer>
|
|
</alias>
|
|
|
|
</fontconfig>
|
|
"#
|
|
)
|
|
.unwrap();
|
|
|
|
file
|
|
}
|
|
|
|
/// Computes the absolute path for the rsvg/tests/resources directory in the source tree
|
|
fn rsvg_tests_resources_path() -> PathBuf {
|
|
let relative_resources_path: PathBuf = [
|
|
env::var("CARGO_MANIFEST_DIR")
|
|
.expect("Manifest directory unknown")
|
|
.as_str(),
|
|
"..",
|
|
"rsvg",
|
|
"tests",
|
|
"resources",
|
|
]
|
|
.iter()
|
|
.collect();
|
|
|
|
let absolute_resources_path = relative_resources_path
|
|
.canonicalize()
|
|
.expect("canonicalizing rsvg/tests/resources path");
|
|
|
|
absolute_resources_path
|
|
}
|
|
|
|
#[test]
|
|
fn converts_svg_from_stdin_to_png() {
|
|
let mut rsvg_convert = RsvgConvert::new_with_input("tests/fixtures/bug521-with-viewbox.svg");
|
|
|
|
rsvg_convert
|
|
.command
|
|
.assert()
|
|
.success()
|
|
.stdout(file::is_png());
|
|
}
|
|
|
|
#[test]
|
|
fn converts_svg_from_stdin_to_png_using_stdin_argument() {
|
|
let mut rsvg_convert = RsvgConvert::new_with_input("tests/fixtures/bug521-with-viewbox.svg");
|
|
|
|
rsvg_convert
|
|
.command
|
|
.arg("-")
|
|
.assert()
|
|
.success()
|
|
.stdout(file::is_png());
|
|
}
|
|
|
|
#[test]
|
|
fn argument_is_input_filename() {
|
|
let input = Path::new("tests/fixtures/bug521-with-viewbox.svg");
|
|
let mut rsvg_convert = RsvgConvert::new();
|
|
|
|
rsvg_convert
|
|
.command
|
|
.arg(input)
|
|
.assert()
|
|
.success()
|
|
.stdout(file::is_png());
|
|
}
|
|
|
|
#[test]
|
|
fn argument_is_url() {
|
|
let path = Path::new("tests/fixtures/bug521-with-viewbox.svg")
|
|
.canonicalize()
|
|
.unwrap();
|
|
let url = Url::from_file_path(path).unwrap();
|
|
let stringified = url.as_str();
|
|
assert!(stringified.starts_with("file://"));
|
|
|
|
let mut rsvg_convert = RsvgConvert::new();
|
|
|
|
rsvg_convert
|
|
.command
|
|
.arg(stringified)
|
|
.assert()
|
|
.success()
|
|
.stdout(file::is_png());
|
|
}
|
|
|
|
#[test]
|
|
fn output_format_png() {
|
|
let mut rsvg_convert = RsvgConvert::new_with_input("tests/fixtures/bug521-with-viewbox.svg");
|
|
|
|
rsvg_convert
|
|
.command
|
|
.arg("--format=png")
|
|
.assert()
|
|
.success()
|
|
.stdout(file::is_png());
|
|
}
|
|
|
|
#[cfg(system_deps_have_cairo_ps)]
|
|
#[test]
|
|
fn output_format_ps() {
|
|
let mut rsvg_convert = RsvgConvert::new_with_input("tests/fixtures/bug521-with-viewbox.svg");
|
|
|
|
rsvg_convert
|
|
.command
|
|
.arg("--format=ps")
|
|
.assert()
|
|
.success()
|
|
.stdout(file::is_ps());
|
|
}
|
|
|
|
#[cfg(system_deps_have_cairo_ps)]
|
|
#[test]
|
|
fn output_format_eps() {
|
|
let mut rsvg_convert = RsvgConvert::new_with_input("tests/fixtures/bug521-with-viewbox.svg");
|
|
|
|
rsvg_convert
|
|
.command
|
|
.arg("--format=eps")
|
|
.assert()
|
|
.success()
|
|
.stdout(file::is_eps());
|
|
}
|
|
|
|
#[cfg(system_deps_have_cairo_pdf)]
|
|
#[test]
|
|
fn output_format_pdf() {
|
|
let mut rsvg_convert = RsvgConvert::new_with_input("tests/fixtures/bug521-with-viewbox.svg");
|
|
|
|
rsvg_convert
|
|
.command
|
|
.arg("--format=pdf")
|
|
.assert()
|
|
.success()
|
|
.stdout(file::is_pdf());
|
|
}
|
|
|
|
#[cfg(system_deps_have_cairo_pdf)]
|
|
#[test]
|
|
fn output_format_pdf_1_7() {
|
|
let mut rsvg_convert = RsvgConvert::new_with_input("tests/fixtures/bug521-with-viewbox.svg");
|
|
|
|
rsvg_convert
|
|
.command
|
|
.arg("--format=pdf1.7")
|
|
.assert()
|
|
.success()
|
|
.stdout(file::is_pdf().with_version("1.7"));
|
|
}
|
|
|
|
#[cfg(system_deps_have_cairo_pdf)]
|
|
#[test]
|
|
fn output_format_pdf_1_6() {
|
|
let mut rsvg_convert = RsvgConvert::new_with_input("tests/fixtures/bug521-with-viewbox.svg");
|
|
|
|
rsvg_convert
|
|
.command
|
|
.arg("--format=pdf1.6")
|
|
.assert()
|
|
.success()
|
|
.stdout(file::is_pdf().with_version("1.6"));
|
|
}
|
|
|
|
#[cfg(system_deps_have_cairo_pdf)]
|
|
#[test]
|
|
fn output_format_pdf_1_5() {
|
|
let mut rsvg_convert = RsvgConvert::new_with_input("tests/fixtures/bug521-with-viewbox.svg");
|
|
|
|
rsvg_convert
|
|
.command
|
|
.arg("--format=pdf1.5")
|
|
.assert()
|
|
.success()
|
|
.stdout(file::is_pdf().with_version("1.5"));
|
|
}
|
|
|
|
#[cfg(system_deps_have_cairo_pdf)]
|
|
#[test]
|
|
fn output_format_pdf_1_4() {
|
|
let mut rsvg_convert = RsvgConvert::new_with_input("tests/fixtures/bug521-with-viewbox.svg");
|
|
|
|
rsvg_convert
|
|
.command
|
|
.arg("--format=pdf1.4")
|
|
.assert()
|
|
.success()
|
|
.stdout(file::is_pdf().with_version("1.4"));
|
|
}
|
|
|
|
#[cfg(system_deps_have_cairo_svg)]
|
|
#[test]
|
|
fn output_format_svg_short_option() {
|
|
let mut rsvg_convert = RsvgConvert::new_with_input("tests/fixtures/bug521-with-viewbox.svg");
|
|
|
|
rsvg_convert
|
|
.command
|
|
.arg("-f")
|
|
.arg("svg")
|
|
.assert()
|
|
.success()
|
|
.stdout(file::is_svg());
|
|
}
|
|
|
|
#[cfg(system_deps_have_cairo_svg)]
|
|
#[test]
|
|
fn user_specified_width_and_height() {
|
|
let mut rsvg_convert = RsvgConvert::new_with_input("tests/fixtures/bug521-with-viewbox.svg");
|
|
|
|
rsvg_convert
|
|
.command
|
|
.arg("--format")
|
|
.arg("svg")
|
|
.arg("--width")
|
|
.arg("42cm")
|
|
.arg("--height")
|
|
.arg("43cm")
|
|
.assert()
|
|
.success()
|
|
.stdout(file::is_svg().with_size(
|
|
Length::new(42.0, LengthUnit::Cm),
|
|
Length::new(43.0, LengthUnit::Cm),
|
|
));
|
|
}
|
|
|
|
#[cfg(system_deps_have_cairo_svg)]
|
|
#[test]
|
|
fn user_specified_width_and_height_px_output() {
|
|
let mut rsvg_convert = RsvgConvert::new_with_input("tests/fixtures/bug521-with-viewbox.svg");
|
|
|
|
rsvg_convert
|
|
.command
|
|
.arg("--format")
|
|
.arg("svg")
|
|
.arg("--width")
|
|
.arg("1920")
|
|
.arg("--height")
|
|
.arg("508mm")
|
|
.assert()
|
|
.success()
|
|
.stdout(file::is_svg().with_size(
|
|
Length::new(1920.0, LengthUnit::Px),
|
|
Length::new(1920.0, LengthUnit::Px),
|
|
));
|
|
}
|
|
|
|
#[cfg(system_deps_have_cairo_svg)]
|
|
#[test]
|
|
fn user_specified_width_and_height_a4() {
|
|
let mut rsvg_convert = RsvgConvert::new_with_input("tests/fixtures/bug521-with-viewbox.svg");
|
|
|
|
rsvg_convert
|
|
.command
|
|
.arg("--format")
|
|
.arg("svg")
|
|
.arg("--page-width")
|
|
.arg("210mm")
|
|
.arg("--page-height")
|
|
.arg("297mm")
|
|
.arg("--left")
|
|
.arg("1cm")
|
|
.arg("--top")
|
|
.arg("1cm")
|
|
.arg("--width")
|
|
.arg("190mm")
|
|
.arg("--height")
|
|
.arg("277mm")
|
|
.assert()
|
|
.success()
|
|
.stdout(file::is_svg().with_size(
|
|
Length::new(210.0, LengthUnit::Mm),
|
|
Length::new(297.0, LengthUnit::Mm),
|
|
));
|
|
}
|
|
|
|
#[test]
|
|
fn output_file_option() {
|
|
let output = {
|
|
let tempfile = Builder::new().suffix(".png").tempfile().unwrap();
|
|
tempfile.path().to_path_buf()
|
|
};
|
|
assert!(predicates::path::is_file().not().eval(&output));
|
|
|
|
let mut rsvg_convert = RsvgConvert::new_with_input("tests/fixtures/bug521-with-viewbox.svg");
|
|
|
|
rsvg_convert
|
|
.command
|
|
.arg(format!("--output={}", output.display()))
|
|
.assert()
|
|
.success()
|
|
.stdout(is_empty());
|
|
|
|
assert!(predicates::path::is_file().eval(&output));
|
|
std::fs::remove_file(&output).unwrap();
|
|
}
|
|
|
|
#[test]
|
|
fn output_file_short_option() {
|
|
let output = {
|
|
let tempfile = Builder::new().suffix(".png").tempfile().unwrap();
|
|
tempfile.path().to_path_buf()
|
|
};
|
|
assert!(predicates::path::is_file().not().eval(&output));
|
|
|
|
let mut rsvg_convert = RsvgConvert::new_with_input("tests/fixtures/bug521-with-viewbox.svg");
|
|
|
|
rsvg_convert
|
|
.command
|
|
.arg("-o")
|
|
.arg(format!("{}", output.display()))
|
|
.assert()
|
|
.success()
|
|
.stdout(is_empty());
|
|
|
|
assert!(predicates::path::is_file().eval(&output));
|
|
std::fs::remove_file(&output).unwrap();
|
|
}
|
|
|
|
#[test]
|
|
fn overwrites_existing_output_file() {
|
|
let output = {
|
|
let tempfile = Builder::new().suffix(".png").tempfile().unwrap();
|
|
tempfile.path().to_path_buf()
|
|
};
|
|
assert!(predicates::path::is_file().not().eval(&output));
|
|
|
|
for _ in 0..2 {
|
|
let mut rsvg_convert =
|
|
RsvgConvert::new_with_input("tests/fixtures/bug521-with-viewbox.svg");
|
|
|
|
rsvg_convert
|
|
.command
|
|
.arg(format!("--output={}", output.display()))
|
|
.assert()
|
|
.success()
|
|
.stdout(is_empty());
|
|
|
|
assert!(predicates::path::is_file().eval(&output));
|
|
}
|
|
|
|
std::fs::remove_file(&output).unwrap();
|
|
}
|
|
|
|
#[test]
|
|
fn empty_input_yields_error() {
|
|
let starts_with = starts_with("Error reading SVG");
|
|
let ends_with = ends_with("Input file is too short").trim();
|
|
let mut rsvg_convert = RsvgConvert::new();
|
|
|
|
rsvg_convert
|
|
.command
|
|
.assert()
|
|
.failure()
|
|
.stderr(starts_with.and(ends_with));
|
|
}
|
|
|
|
#[test]
|
|
fn empty_svg_yields_error() {
|
|
let mut rsvg_convert = RsvgConvert::new_with_input("tests/fixtures/empty.svg");
|
|
|
|
rsvg_convert
|
|
.command
|
|
.assert()
|
|
.failure()
|
|
.stderr("The SVG stdin has no dimensions\n");
|
|
}
|
|
|
|
#[test]
|
|
fn multiple_input_files_not_allowed_for_png_output() {
|
|
let one = Path::new("tests/fixtures/bug521-with-viewbox.svg");
|
|
let two = Path::new("tests/fixtures/sub-rect-no-unit.svg");
|
|
let mut rsvg_convert = RsvgConvert::new();
|
|
|
|
rsvg_convert
|
|
.command
|
|
.arg(one)
|
|
.arg(two)
|
|
.assert()
|
|
.failure()
|
|
.stderr(contains(
|
|
"Multiple SVG files are only allowed for PDF and (E)PS output",
|
|
));
|
|
}
|
|
|
|
#[cfg(system_deps_have_cairo_ps)]
|
|
#[test]
|
|
fn multiple_input_files_accepted_for_eps_output() {
|
|
let one = Path::new("tests/fixtures/bug521-with-viewbox.svg");
|
|
let two = Path::new("tests/fixtures/sub-rect-no-unit.svg");
|
|
let mut rsvg_convert = RsvgConvert::new();
|
|
|
|
rsvg_convert
|
|
.command
|
|
.arg("--format=eps")
|
|
.arg(one)
|
|
.arg(two)
|
|
.assert()
|
|
.success()
|
|
.stdout(file::is_eps());
|
|
}
|
|
|
|
#[cfg(system_deps_have_cairo_ps)]
|
|
#[test]
|
|
fn multiple_input_files_accepted_for_ps_output() {
|
|
let one = Path::new("tests/fixtures/bug521-with-viewbox.svg");
|
|
let two = Path::new("tests/fixtures/sub-rect-no-unit.svg");
|
|
let mut rsvg_convert = RsvgConvert::new();
|
|
|
|
rsvg_convert
|
|
.command
|
|
.arg("--format=ps")
|
|
.arg(one)
|
|
.arg(two)
|
|
.assert()
|
|
.success()
|
|
.stdout(file::is_ps());
|
|
}
|
|
|
|
#[cfg(system_deps_have_cairo_pdf)]
|
|
#[test]
|
|
fn multiple_input_files_create_multi_page_pdf_output() {
|
|
let one = Path::new("tests/fixtures/bug521-with-viewbox.svg");
|
|
let two = Path::new("tests/fixtures/sub-rect-no-unit.svg");
|
|
let three = Path::new("tests/fixtures/example.svg");
|
|
let mut rsvg_convert = RsvgConvert::new();
|
|
|
|
rsvg_convert
|
|
.command
|
|
.arg("--format=pdf")
|
|
.arg(one)
|
|
.arg(two)
|
|
.arg(three)
|
|
.assert()
|
|
.success()
|
|
.stdout(
|
|
file::is_pdf()
|
|
.with_page_count(3)
|
|
.and(file::is_pdf().with_page_size(0, 150.0, 75.0))
|
|
.and(file::is_pdf().with_page_size(1, 123.0, 123.0))
|
|
.and(file::is_pdf().with_page_size(2, 75.0, 300.0)),
|
|
);
|
|
}
|
|
|
|
#[cfg(system_deps_have_cairo_pdf)]
|
|
#[test]
|
|
fn multiple_input_files_create_multi_page_pdf_output_fixed_size() {
|
|
let one = Path::new("tests/fixtures/bug521-with-viewbox.svg");
|
|
let two = Path::new("tests/fixtures/sub-rect-no-unit.svg");
|
|
let three = Path::new("tests/fixtures/example.svg");
|
|
let mut rsvg_convert = RsvgConvert::new();
|
|
|
|
rsvg_convert
|
|
.command
|
|
.arg("--format=pdf")
|
|
.arg("--page-width=8.5in")
|
|
.arg("--page-height=11in")
|
|
.arg("--width=7.5in")
|
|
.arg("--height=10in")
|
|
.arg("--left=0.5in")
|
|
.arg("--top=0.5in")
|
|
.arg("--keep-aspect-ratio")
|
|
.arg(one)
|
|
.arg(two)
|
|
.arg(three)
|
|
.assert()
|
|
.success()
|
|
.stdout(
|
|
file::is_pdf()
|
|
.with_page_count(3)
|
|
// https://www.wolframalpha.com/input/?i=convert+11+inches+to+desktop+publishing+points
|
|
.and(file::is_pdf().with_page_size(0, 612.0, 792.0))
|
|
.and(file::is_pdf().with_page_size(1, 612.0, 792.0))
|
|
.and(file::is_pdf().with_page_size(2, 612.0, 792.0)),
|
|
);
|
|
}
|
|
|
|
#[cfg(system_deps_have_cairo_pdf)]
|
|
#[test]
|
|
fn pdf_has_link() {
|
|
let input = Path::new("tests/fixtures/a-link.svg");
|
|
let mut rsvg_convert = RsvgConvert::new();
|
|
|
|
rsvg_convert
|
|
.command
|
|
.arg("--format=pdf")
|
|
.arg(input)
|
|
.assert()
|
|
.success()
|
|
.stdout(file::is_pdf().with_link("https://example.com"));
|
|
}
|
|
|
|
#[cfg(system_deps_have_cairo_pdf)]
|
|
#[test]
|
|
fn pdf_has_link_inside_text() {
|
|
let input = Path::new("tests/fixtures/text-a-link.svg");
|
|
let mut rsvg_convert = RsvgConvert::new();
|
|
|
|
rsvg_convert
|
|
.command
|
|
.arg("--format=pdf")
|
|
.arg(input)
|
|
.assert()
|
|
.success()
|
|
.stdout(
|
|
file::is_pdf()
|
|
.with_link("https://example.com")
|
|
.and(file::is_pdf().with_link("https://another.example.com")),
|
|
);
|
|
}
|
|
|
|
#[cfg(system_deps_have_cairo_pdf)]
|
|
#[test]
|
|
fn pdf_has_text() {
|
|
let input = Path::new("tests/fixtures/hello-world.svg");
|
|
let mut rsvg_convert = RsvgConvert::new();
|
|
|
|
rsvg_convert
|
|
.command
|
|
.arg("--format=pdf")
|
|
.arg(input)
|
|
.assert()
|
|
.success()
|
|
.stdout(
|
|
file::is_pdf()
|
|
.with_text("Hello world!")
|
|
.and(file::is_pdf().with_text("Hello again!")),
|
|
);
|
|
}
|
|
|
|
#[cfg(system_deps_have_cairo_pdf)]
|
|
#[test]
|
|
fn env_source_data_epoch_controls_pdf_creation_date() {
|
|
let input = Path::new("tests/fixtures/bug521-with-viewbox.svg");
|
|
let date = 1581411039; // seconds since epoch
|
|
let mut rsvg_convert = RsvgConvert::new();
|
|
|
|
rsvg_convert
|
|
.command
|
|
.env("SOURCE_DATE_EPOCH", format!("{}", date))
|
|
.arg("--format=pdf")
|
|
.arg(input)
|
|
.assert()
|
|
.success()
|
|
.stdout(file::is_pdf().with_creation_date(Utc.timestamp_opt(date, 0).unwrap()));
|
|
}
|
|
|
|
#[cfg(system_deps_have_cairo_pdf)]
|
|
#[test]
|
|
fn env_source_data_epoch_no_digits() {
|
|
// intentionally not testing for the full error string here
|
|
let input = Path::new("tests/fixtures/bug521-with-viewbox.svg");
|
|
let mut rsvg_convert = RsvgConvert::new();
|
|
|
|
rsvg_convert
|
|
.command
|
|
.env("SOURCE_DATE_EPOCH", "foobar")
|
|
.arg("--format=pdf")
|
|
.arg(input)
|
|
.assert()
|
|
.failure()
|
|
.stderr(starts_with("Environment variable $SOURCE_DATE_EPOCH"));
|
|
}
|
|
|
|
#[cfg(system_deps_have_cairo_pdf)]
|
|
#[test]
|
|
fn env_source_data_epoch_trailing_garbage() {
|
|
// intentionally not testing for the full error string here
|
|
let input = Path::new("tests/fixtures/bug521-with-viewbox.svg");
|
|
let mut rsvg_convert = RsvgConvert::new();
|
|
|
|
rsvg_convert
|
|
.command
|
|
.arg("--format=pdf")
|
|
.env("SOURCE_DATE_EPOCH", "1234556+")
|
|
.arg(input)
|
|
.assert()
|
|
.failure()
|
|
.stderr(starts_with("Environment variable $SOURCE_DATE_EPOCH"));
|
|
}
|
|
|
|
#[cfg(system_deps_have_cairo_pdf)]
|
|
#[test]
|
|
fn env_source_data_epoch_empty() {
|
|
// intentionally not testing for the full error string here
|
|
let input = Path::new("tests/fixtures/bug521-with-viewbox.svg");
|
|
let mut rsvg_convert = RsvgConvert::new();
|
|
|
|
rsvg_convert
|
|
.command
|
|
.arg("--format=pdf")
|
|
.env("SOURCE_DATE_EPOCH", "")
|
|
.arg(input)
|
|
.assert()
|
|
.failure()
|
|
.stderr(starts_with("Environment variable $SOURCE_DATE_EPOCH"));
|
|
}
|
|
|
|
#[test]
|
|
fn width_option() {
|
|
let mut rsvg_convert = RsvgConvert::new_with_input("tests/fixtures/bug521-with-viewbox.svg");
|
|
|
|
rsvg_convert
|
|
.command
|
|
.arg("--width=300")
|
|
.assert()
|
|
.success()
|
|
.stdout(file::is_png().with_size(300, 150));
|
|
}
|
|
|
|
#[test]
|
|
fn height_option() {
|
|
let mut rsvg_convert = RsvgConvert::new_with_input("tests/fixtures/bug521-with-viewbox.svg");
|
|
|
|
rsvg_convert
|
|
.command
|
|
.arg("--height=200")
|
|
.assert()
|
|
.success()
|
|
.stdout(file::is_png().with_size(400, 200));
|
|
}
|
|
|
|
#[test]
|
|
fn width_and_height_options() {
|
|
let mut rsvg_convert = RsvgConvert::new_with_input("tests/fixtures/bug521-with-viewbox.svg");
|
|
|
|
rsvg_convert
|
|
.command
|
|
.arg("--width=300")
|
|
.arg("--height=200")
|
|
.assert()
|
|
.success()
|
|
.stdout(file::is_png().with_size(300, 200));
|
|
}
|
|
|
|
#[test]
|
|
fn unsupported_unit_in_width_and_height() {
|
|
let mut rsvg_convert = RsvgConvert::new_with_input("tests/fixtures/bug521-with-viewbox.svg");
|
|
|
|
rsvg_convert
|
|
.command
|
|
.arg("--height=200ex")
|
|
.assert()
|
|
.failure()
|
|
.stderr(contains("supported units"));
|
|
}
|
|
|
|
#[test]
|
|
fn invalid_length() {
|
|
let mut rsvg_convert = RsvgConvert::new_with_input("tests/fixtures/bug521-with-viewbox.svg");
|
|
|
|
rsvg_convert
|
|
.command
|
|
.arg("--page-width=foo")
|
|
.assert()
|
|
.failure()
|
|
.stderr(contains("can not be parsed as a length"));
|
|
}
|
|
|
|
#[test]
|
|
fn zoom_factor() {
|
|
let mut rsvg_convert = RsvgConvert::new_with_input("tests/fixtures/bug521-with-viewbox.svg");
|
|
|
|
rsvg_convert
|
|
.command
|
|
.arg("--zoom=0.8")
|
|
.assert()
|
|
.success()
|
|
.stdout(file::is_png().with_size(160, 80));
|
|
}
|
|
|
|
#[test]
|
|
fn zoom_factor_and_larger_size() {
|
|
let mut rsvg_convert = RsvgConvert::new_with_input("tests/fixtures/bug521-with-viewbox.svg");
|
|
|
|
rsvg_convert
|
|
.command
|
|
.arg("--width=400")
|
|
.arg("--height=200")
|
|
.arg("--zoom=1.5")
|
|
.assert()
|
|
.success()
|
|
.stdout(file::is_png().with_size(300, 150));
|
|
}
|
|
|
|
#[test]
|
|
fn zoom_factor_and_smaller_size() {
|
|
let mut rsvg_convert = RsvgConvert::new_with_input("tests/fixtures/bug521-with-viewbox.svg");
|
|
|
|
rsvg_convert
|
|
.command
|
|
.arg("--width=400")
|
|
.arg("--height=200")
|
|
.arg("--zoom=3.5")
|
|
.assert()
|
|
.success()
|
|
.stdout(file::is_png().with_size(400, 200));
|
|
}
|
|
|
|
#[test]
|
|
fn x_zoom_option() {
|
|
let mut rsvg_convert = RsvgConvert::new_with_input("tests/fixtures/bug521-with-viewbox.svg");
|
|
|
|
rsvg_convert
|
|
.command
|
|
.arg("--x-zoom=2")
|
|
.assert()
|
|
.success()
|
|
.stdout(file::is_png().with_size(400, 100));
|
|
}
|
|
|
|
#[test]
|
|
fn x_short_option() {
|
|
let mut rsvg_convert = RsvgConvert::new_with_input("tests/fixtures/bug521-with-viewbox.svg");
|
|
|
|
rsvg_convert
|
|
.command
|
|
.arg("-x")
|
|
.arg("2.0")
|
|
.assert()
|
|
.success()
|
|
.stdout(file::is_png().with_size(400, 100));
|
|
}
|
|
|
|
#[test]
|
|
fn y_zoom_option() {
|
|
let mut rsvg_convert = RsvgConvert::new_with_input("tests/fixtures/bug521-with-viewbox.svg");
|
|
|
|
rsvg_convert
|
|
.command
|
|
.arg("--y-zoom=2.0")
|
|
.assert()
|
|
.success()
|
|
.stdout(file::is_png().with_size(200, 200));
|
|
}
|
|
|
|
#[test]
|
|
fn y_short_option() {
|
|
let mut rsvg_convert = RsvgConvert::new_with_input("tests/fixtures/bug521-with-viewbox.svg");
|
|
|
|
rsvg_convert
|
|
.command
|
|
.arg("-y")
|
|
.arg("2")
|
|
.assert()
|
|
.success()
|
|
.stdout(file::is_png().with_size(200, 200));
|
|
}
|
|
|
|
#[test]
|
|
fn huge_zoom_factor_yields_error() {
|
|
let mut rsvg_convert = RsvgConvert::new_with_input("tests/fixtures/bug521-with-viewbox.svg");
|
|
|
|
rsvg_convert
|
|
.command
|
|
.arg("--zoom=1000")
|
|
.assert()
|
|
.failure()
|
|
.stderr(starts_with(
|
|
"The resulting image would be larger than 32767 pixels",
|
|
));
|
|
}
|
|
|
|
#[test]
|
|
fn negative_zoom_factor_yields_error() {
|
|
let mut rsvg_convert = RsvgConvert::new_with_input("tests/fixtures/bug521-with-viewbox.svg");
|
|
|
|
rsvg_convert
|
|
.command
|
|
.arg("--zoom=-2")
|
|
.assert()
|
|
.failure()
|
|
.stderr(contains("Invalid zoom"));
|
|
}
|
|
|
|
#[test]
|
|
fn invalid_zoom_factor_yields_error() {
|
|
let mut rsvg_convert = RsvgConvert::new_with_input("tests/fixtures/bug521-with-viewbox.svg");
|
|
|
|
rsvg_convert
|
|
.command
|
|
.arg("--zoom=foo")
|
|
.assert()
|
|
.failure()
|
|
.stderr(contains("invalid value"));
|
|
}
|
|
|
|
#[test]
|
|
fn default_resolution_is_96dpi() {
|
|
let mut rsvg_convert = RsvgConvert::new_with_input("tests/fixtures/dpi.svg");
|
|
|
|
rsvg_convert
|
|
.command
|
|
.assert()
|
|
.success()
|
|
.stdout(file::is_png().with_size(96, 384));
|
|
}
|
|
|
|
#[test]
|
|
fn x_resolution() {
|
|
let mut rsvg_convert = RsvgConvert::new_with_input("tests/fixtures/dpi.svg");
|
|
|
|
rsvg_convert
|
|
.command
|
|
.arg("--dpi-x=300")
|
|
.assert()
|
|
.success()
|
|
.stdout(file::is_png().with_size(300, 384));
|
|
}
|
|
|
|
#[test]
|
|
fn x_resolution_short_option() {
|
|
let mut rsvg_convert = RsvgConvert::new_with_input("tests/fixtures/dpi.svg");
|
|
|
|
rsvg_convert
|
|
.command
|
|
.arg("-d")
|
|
.arg("45")
|
|
.assert()
|
|
.success()
|
|
.stdout(file::is_png().with_size(45, 384));
|
|
}
|
|
|
|
#[test]
|
|
fn y_resolution() {
|
|
let mut rsvg_convert = RsvgConvert::new_with_input("tests/fixtures/dpi.svg");
|
|
|
|
rsvg_convert
|
|
.command
|
|
.arg("--dpi-y=300")
|
|
.assert()
|
|
.success()
|
|
.stdout(file::is_png().with_size(96, 1200));
|
|
}
|
|
|
|
#[test]
|
|
fn y_resolution_short_option() {
|
|
let mut rsvg_convert = RsvgConvert::new_with_input("tests/fixtures/dpi.svg");
|
|
|
|
rsvg_convert
|
|
.command
|
|
.arg("-p")
|
|
.arg("45")
|
|
.assert()
|
|
.success()
|
|
.stdout(file::is_png().with_size(96, 180));
|
|
}
|
|
|
|
#[test]
|
|
fn x_and_y_resolution() {
|
|
let mut rsvg_convert = RsvgConvert::new_with_input("tests/fixtures/dpi.svg");
|
|
|
|
rsvg_convert
|
|
.command
|
|
.arg("--dpi-x=300")
|
|
.arg("--dpi-y=150")
|
|
.assert()
|
|
.success()
|
|
.stdout(file::is_png().with_size(300, 600));
|
|
}
|
|
|
|
#[test]
|
|
fn zero_resolution_is_invalid() {
|
|
let mut rsvg_convert = RsvgConvert::new_with_input("tests/fixtures/dpi.svg");
|
|
|
|
rsvg_convert
|
|
.command
|
|
.arg("--dpi-x=0")
|
|
.arg("--dpi-y=0")
|
|
.assert()
|
|
.failure()
|
|
.stderr(contains("Invalid resolution"));
|
|
}
|
|
|
|
#[test]
|
|
fn negative_resolution_is_invalid() {
|
|
let mut rsvg_convert = RsvgConvert::new_with_input("tests/fixtures/dpi.svg");
|
|
|
|
rsvg_convert
|
|
.command
|
|
.arg("--dpi-x=-100")
|
|
.arg("--dpi-y=-100")
|
|
.assert()
|
|
.failure()
|
|
.stderr(contains("Invalid resolution"));
|
|
}
|
|
|
|
#[test]
|
|
fn unparsable_resolution_is_invalid() {
|
|
let mut rsvg_convert = RsvgConvert::new_with_input("tests/fixtures/dpi.svg");
|
|
|
|
rsvg_convert
|
|
.command
|
|
.arg("--dpi-x=blah")
|
|
.arg("--dpi-y=blah")
|
|
.assert()
|
|
.failure()
|
|
.stderr(contains("invalid value")); // this comes from clap
|
|
}
|
|
|
|
#[test]
|
|
fn zero_offset_png() {
|
|
let mut rsvg_convert = RsvgConvert::new_with_input("tests/fixtures/dimensions-in.svg");
|
|
|
|
rsvg_convert
|
|
.command
|
|
.arg("--page-width=640")
|
|
.arg("--page-height=480")
|
|
.arg("--width=200")
|
|
.arg("--height=100")
|
|
.assert()
|
|
.success()
|
|
.stdout(file::is_png().with_contents("tests/fixtures/zero-offset-png.png"));
|
|
}
|
|
|
|
#[test]
|
|
fn offset_png() {
|
|
let mut rsvg_convert = RsvgConvert::new_with_input("tests/fixtures/dimensions-in.svg");
|
|
|
|
rsvg_convert
|
|
.command
|
|
.arg("--page-width=640")
|
|
.arg("--page-height=480")
|
|
.arg("--width=200")
|
|
.arg("--height=100")
|
|
.arg("--left=100")
|
|
.arg("--top=50")
|
|
.assert()
|
|
.success()
|
|
.stdout(file::is_png().with_contents("tests/fixtures/offset-png.png"));
|
|
}
|
|
|
|
#[cfg(system_deps_have_cairo_pdf)]
|
|
#[test]
|
|
fn unscaled_pdf_size() {
|
|
let mut rsvg_convert = RsvgConvert::new_with_input("tests/fixtures/dimensions-in.svg");
|
|
|
|
rsvg_convert
|
|
.command
|
|
.arg("--format=pdf")
|
|
.assert()
|
|
.success()
|
|
.stdout(file::is_pdf().with_page_size(0, 72.0, 72.0));
|
|
}
|
|
|
|
#[cfg(system_deps_have_cairo_pdf)]
|
|
#[test]
|
|
fn pdf_size_width_height() {
|
|
let mut rsvg_convert = RsvgConvert::new_with_input("tests/fixtures/dimensions-in.svg");
|
|
|
|
rsvg_convert
|
|
.command
|
|
.arg("--format=pdf")
|
|
.arg("--width=2in")
|
|
.arg("--height=3in")
|
|
.assert()
|
|
.success()
|
|
.stdout(file::is_pdf().with_page_size(0, 144.0, 216.0));
|
|
}
|
|
|
|
#[cfg(system_deps_have_cairo_pdf)]
|
|
#[test]
|
|
fn pdf_size_width_height_proportional() {
|
|
let mut rsvg_convert = RsvgConvert::new_with_input("tests/fixtures/dimensions-in.svg");
|
|
|
|
rsvg_convert
|
|
.command
|
|
.arg("--format=pdf")
|
|
.arg("--width=2in")
|
|
.arg("--height=3in")
|
|
.arg("--keep-aspect-ratio")
|
|
.assert()
|
|
.success()
|
|
.stdout(file::is_pdf().with_page_size(0, 144.0, 144.0));
|
|
}
|
|
|
|
#[cfg(system_deps_have_cairo_pdf)]
|
|
#[test]
|
|
fn pdf_page_size() {
|
|
let mut rsvg_convert = RsvgConvert::new_with_input("tests/fixtures/dimensions-in.svg");
|
|
|
|
rsvg_convert
|
|
.command
|
|
.arg("--format=pdf")
|
|
.arg("--page-width=210mm")
|
|
.arg("--page-height=297mm")
|
|
.assert()
|
|
.success()
|
|
.stdout(file::is_pdf().with_page_size(0, 210.0 / 25.4 * 72.0, 297.0 / 25.4 * 72.0));
|
|
}
|
|
|
|
#[cfg(system_deps_have_cairo_pdf)]
|
|
#[test]
|
|
fn multiple_input_files_create_multi_page_pdf_size_override() {
|
|
let one = Path::new("tests/fixtures/bug521-with-viewbox.svg");
|
|
let two = Path::new("tests/fixtures/sub-rect-no-unit.svg");
|
|
let three = Path::new("tests/fixtures/example.svg");
|
|
let mut rsvg_convert = RsvgConvert::new();
|
|
|
|
rsvg_convert
|
|
.command
|
|
.arg("--format=pdf")
|
|
.arg("--width=300pt")
|
|
.arg("--height=200pt")
|
|
.arg(one)
|
|
.arg(two)
|
|
.arg(three)
|
|
.assert()
|
|
.success()
|
|
.stdout(
|
|
file::is_pdf()
|
|
.with_page_count(3)
|
|
.and(file::is_pdf().with_page_size(0, 300.0, 200.0))
|
|
.and(file::is_pdf().with_page_size(1, 300.0, 200.0))
|
|
.and(file::is_pdf().with_page_size(2, 300.0, 200.0)),
|
|
);
|
|
}
|
|
|
|
#[cfg(system_deps_have_cairo_pdf)]
|
|
#[test]
|
|
fn missing_page_size_yields_error() {
|
|
let mut rsvg_convert = RsvgConvert::new_with_input("tests/fixtures/dimensions-in.svg");
|
|
|
|
rsvg_convert
|
|
.command
|
|
.arg("--format=pdf")
|
|
.arg("--page-width=210mm")
|
|
.assert()
|
|
.failure()
|
|
.stderr(contains("both").and(contains("options")));
|
|
|
|
let mut rsvg_convert = RsvgConvert::new_with_input("tests/fixtures/dimensions-in.svg");
|
|
|
|
rsvg_convert
|
|
.command
|
|
.arg("--format=pdf")
|
|
.arg("--page-height=297mm")
|
|
.assert()
|
|
.failure()
|
|
.stderr(contains("both").and(contains("options")));
|
|
}
|
|
|
|
#[test]
|
|
fn does_not_clip_partial_coverage_pixels() {
|
|
let mut rsvg_convert = RsvgConvert::new_with_input("tests/fixtures/bug677-partial-pixel.svg");
|
|
|
|
rsvg_convert
|
|
.command
|
|
.assert()
|
|
.success()
|
|
.stdout(file::is_png().with_size(2, 2));
|
|
}
|
|
|
|
#[test]
|
|
fn background_color_option_with_valid_color() {
|
|
RsvgConvert::accepts_arg("--background-color=LimeGreen");
|
|
}
|
|
|
|
#[test]
|
|
fn background_color_option_none() {
|
|
RsvgConvert::accepts_arg("--background-color=None");
|
|
}
|
|
|
|
#[test]
|
|
fn background_color_short_option() {
|
|
let mut rsvg_convert = RsvgConvert::new_with_input("tests/fixtures/dpi.svg");
|
|
|
|
rsvg_convert
|
|
.command
|
|
.arg("-b")
|
|
.arg("#aabbcc")
|
|
.assert()
|
|
.success();
|
|
}
|
|
|
|
#[test]
|
|
fn background_color_option_invalid_color_yields_error() {
|
|
let mut rsvg_convert = RsvgConvert::new_with_input("tests/fixtures/dpi.svg");
|
|
|
|
rsvg_convert
|
|
.command
|
|
.arg("--background-color=foobar")
|
|
.assert()
|
|
.failure()
|
|
.stderr(contains("Invalid").and(contains("color")));
|
|
}
|
|
|
|
#[test]
|
|
fn background_color_is_rendered() {
|
|
let mut rsvg_convert = RsvgConvert::new_with_input("tests/fixtures/gimp-wilber.svg");
|
|
|
|
rsvg_convert
|
|
.command
|
|
.arg("--background-color=purple")
|
|
.assert()
|
|
.success()
|
|
.stdout(file::is_png().with_contents("tests/fixtures/gimp-wilber-ref.png"));
|
|
}
|
|
|
|
#[test]
|
|
fn background_color_rgb() {
|
|
let mut rsvg_convert = RsvgConvert::new_with_input("tests/fixtures/empty-10x10.svg");
|
|
|
|
rsvg_convert
|
|
.command
|
|
.arg("--width=10")
|
|
.arg("--height=10")
|
|
.arg("--background-color=rgb(0, 255, 0)")
|
|
.assert()
|
|
.success()
|
|
.stdout(file::is_png().with_contents("tests/fixtures/lime-ref.png"));
|
|
}
|
|
|
|
#[test]
|
|
fn background_color_rgba() {
|
|
let mut rsvg_convert = RsvgConvert::new_with_input("tests/fixtures/empty-10x10.svg");
|
|
|
|
rsvg_convert
|
|
.command
|
|
.arg("--width=10")
|
|
.arg("--height=10")
|
|
.arg("--background-color=rgba(0, 255, 0, 0.5)")
|
|
.assert()
|
|
.success()
|
|
.stdout(file::is_png().with_contents("tests/fixtures/lime-transparent-ref.png"));
|
|
}
|
|
|
|
#[test]
|
|
fn background_color_hsl() {
|
|
let mut rsvg_convert = RsvgConvert::new_with_input("tests/fixtures/empty-10x10.svg");
|
|
|
|
rsvg_convert
|
|
.command
|
|
.arg("--width=10")
|
|
.arg("--height=10")
|
|
.arg("--background-color=hsl(120, 100%, 50%)")
|
|
.assert()
|
|
.success()
|
|
.stdout(file::is_png().with_contents("tests/fixtures/lime-ref.png"));
|
|
}
|
|
|
|
#[test]
|
|
fn background_color_hsla() {
|
|
let mut rsvg_convert = RsvgConvert::new_with_input("tests/fixtures/empty-10x10.svg");
|
|
|
|
rsvg_convert
|
|
.command
|
|
.arg("--width=10")
|
|
.arg("--height=10")
|
|
.arg("--background-color=hsla(120, 100%, 50%, 0.5)")
|
|
.assert()
|
|
.success()
|
|
.stdout(file::is_png().with_contents("tests/fixtures/lime-transparent-ref.png"));
|
|
}
|
|
|
|
#[test]
|
|
fn background_color_hwb() {
|
|
let mut rsvg_convert = RsvgConvert::new_with_input("tests/fixtures/empty-10x10.svg");
|
|
|
|
rsvg_convert
|
|
.command
|
|
.arg("--width=10")
|
|
.arg("--height=10")
|
|
.arg("--background-color=hwb(120 0% 0%)")
|
|
.assert()
|
|
.success()
|
|
.stdout(file::is_png().with_contents("tests/fixtures/lime-ref.png"));
|
|
}
|
|
|
|
#[test]
|
|
fn background_color_hwba() {
|
|
let mut rsvg_convert = RsvgConvert::new_with_input("tests/fixtures/empty-10x10.svg");
|
|
|
|
rsvg_convert
|
|
.command
|
|
.arg("--width=10")
|
|
.arg("--height=10")
|
|
.arg("--background-color=hwb(120 0% 0% / 0.5)")
|
|
.assert()
|
|
.success()
|
|
.stdout(file::is_png().with_contents("tests/fixtures/lime-transparent-ref.png"));
|
|
}
|
|
|
|
fn test_unsupported_background_color(color: &str) {
|
|
let color_arg = format!("--background-color={color}");
|
|
let mut rsvg_convert = RsvgConvert::new_with_input("tests/fixtures/empty-10x10.svg");
|
|
|
|
rsvg_convert
|
|
.command
|
|
.arg("--width=10")
|
|
.arg("--height=10")
|
|
.arg(&color_arg)
|
|
.assert()
|
|
.failure()
|
|
.stderr(contains("Invalid value").and(contains("unsupported color syntax")));
|
|
}
|
|
|
|
#[test]
|
|
fn unsupported_background_color() {
|
|
let colors = [
|
|
"lab(62.2345% -34.9638 47.7721)",
|
|
"lch(62.2345% 59.2 126.2)",
|
|
"oklab(66.016% -0.1084 0.1114)",
|
|
"oklch(0.66016 0.15546 134.231)",
|
|
"color(display-p3 -0.6112 1.0079 -0.2192)",
|
|
];
|
|
|
|
for c in &colors {
|
|
test_unsupported_background_color(c);
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn stylesheet_option() {
|
|
let mut rsvg_convert = RsvgConvert::new_with_input("tests/fixtures/dpi.svg");
|
|
|
|
rsvg_convert
|
|
.command
|
|
.arg("--stylesheet=tests/fixtures/empty.css")
|
|
.assert()
|
|
.success();
|
|
}
|
|
|
|
#[test]
|
|
fn stylesheet_short_option() {
|
|
let mut rsvg_convert = RsvgConvert::new_with_input("tests/fixtures/dpi.svg");
|
|
|
|
rsvg_convert
|
|
.command
|
|
.arg("-s")
|
|
.arg("tests/fixtures/empty.css")
|
|
.assert()
|
|
.success();
|
|
}
|
|
|
|
#[test]
|
|
fn stylesheet_option_error() {
|
|
let mut rsvg_convert = RsvgConvert::new_with_input("tests/fixtures/dpi.svg");
|
|
|
|
rsvg_convert
|
|
.command
|
|
.arg("--stylesheet=foobar")
|
|
.assert()
|
|
.failure()
|
|
.stderr(starts_with("Error reading stylesheet"));
|
|
}
|
|
|
|
#[test]
|
|
fn export_id_option() {
|
|
let mut rsvg_convert = RsvgConvert::new_with_input("tests/fixtures/geometry-element.svg");
|
|
|
|
rsvg_convert
|
|
.command
|
|
.arg("--export-id=foo")
|
|
.assert()
|
|
.success()
|
|
.stdout(file::is_png().with_size(40, 50));
|
|
}
|
|
|
|
#[test]
|
|
fn export_id_with_zero_stroke_width() {
|
|
// https://gitlab.gnome.org/GNOME/librsvg/-/issues/601
|
|
//
|
|
// This tests a bug that manifested itself easily with the --export-id option, but it
|
|
// is not a bug with the option itself. An object with stroke_width=0 was causing
|
|
// an extra point at the origin to be put in the bounding box, so the final image
|
|
// spanned the origin to the actual visible bounds of the rendered object.
|
|
//
|
|
// We can probably test this more cleanly once we have a render tree.
|
|
let mut rsvg_convert =
|
|
RsvgConvert::new_with_input("tests/fixtures/bug601-zero-stroke-width.svg");
|
|
|
|
rsvg_convert
|
|
.command
|
|
.arg("--export-id=foo")
|
|
.assert()
|
|
.success()
|
|
.stdout(
|
|
file::is_png()
|
|
.with_contents("tests/fixtures/bug601-zero-stroke-width-render-only-foo.png"),
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn export_id_short_option() {
|
|
let mut rsvg_convert = RsvgConvert::new_with_input("tests/fixtures/dpi.svg");
|
|
|
|
rsvg_convert
|
|
.command
|
|
.arg("-i")
|
|
.arg("two")
|
|
.assert()
|
|
.success()
|
|
.stdout(file::is_png().with_size(100, 200));
|
|
}
|
|
|
|
#[test]
|
|
fn export_id_with_hash_prefix() {
|
|
let mut rsvg_convert = RsvgConvert::new_with_input("tests/fixtures/dpi.svg");
|
|
|
|
rsvg_convert
|
|
.command
|
|
.arg("-i")
|
|
.arg("#two")
|
|
.assert()
|
|
.success()
|
|
.stdout(file::is_png().with_size(100, 200));
|
|
}
|
|
|
|
#[test]
|
|
fn export_id_option_error() {
|
|
let mut rsvg_convert = RsvgConvert::new_with_input("tests/fixtures/dpi.svg");
|
|
|
|
rsvg_convert
|
|
.command
|
|
.arg("--export-id=foobar")
|
|
.assert()
|
|
.failure()
|
|
.stderr(starts_with("File stdin does not have an object with id \""));
|
|
}
|
|
|
|
#[test]
|
|
fn unlimited_option() {
|
|
RsvgConvert::accepts_arg("--unlimited");
|
|
}
|
|
|
|
#[test]
|
|
fn unlimited_short_option() {
|
|
RsvgConvert::accepts_arg("-u");
|
|
}
|
|
|
|
#[test]
|
|
fn keep_aspect_ratio_option() {
|
|
let input = Path::new("tests/fixtures/dpi.svg");
|
|
let mut rsvg_convert = RsvgConvert::new_with_input(input);
|
|
|
|
rsvg_convert
|
|
.command
|
|
.arg("--width=500")
|
|
.arg("--height=1000")
|
|
.assert()
|
|
.success()
|
|
.stdout(file::is_png().with_size(500, 1000));
|
|
let mut rsvg_convert = RsvgConvert::new_with_input(input);
|
|
|
|
rsvg_convert
|
|
.command
|
|
.arg("--width=500")
|
|
.arg("--height=1000")
|
|
.arg("--keep-aspect-ratio")
|
|
.assert()
|
|
.success()
|
|
.stdout(file::is_png().with_size(250, 1000));
|
|
}
|
|
|
|
#[test]
|
|
fn keep_aspect_ratio_short_option() {
|
|
let input = Path::new("tests/fixtures/dpi.svg");
|
|
let mut rsvg_convert = RsvgConvert::new_with_input(input);
|
|
|
|
rsvg_convert
|
|
.command
|
|
.arg("--width=1000")
|
|
.arg("--height=500")
|
|
.assert()
|
|
.success()
|
|
.stdout(file::is_png().with_size(1000, 500));
|
|
let mut rsvg_convert = RsvgConvert::new_with_input(input);
|
|
|
|
rsvg_convert
|
|
.command
|
|
.arg("--width=1000")
|
|
.arg("--height=500")
|
|
.arg("-a")
|
|
.assert()
|
|
.success()
|
|
.stdout(file::is_png().with_size(125, 500));
|
|
}
|
|
|
|
#[test]
|
|
fn overflowing_size_is_detected() {
|
|
let mut rsvg_convert = RsvgConvert::new_with_input("tests/fixtures/bug591-vbox-overflow.svg");
|
|
|
|
rsvg_convert.command.assert().failure().stderr(starts_with(
|
|
"The resulting image would be larger than 32767 pixels",
|
|
));
|
|
}
|
|
|
|
#[test]
|
|
fn accept_language_given() {
|
|
let mut rsvg_convert = RsvgConvert::new_with_input("tests/fixtures/accept-language.svg");
|
|
|
|
rsvg_convert
|
|
.command
|
|
.arg("--accept-language=es-MX")
|
|
.assert()
|
|
.success()
|
|
.stdout(file::is_png().with_contents("tests/fixtures/accept-language-es.png"));
|
|
|
|
let mut rsvg_convert = RsvgConvert::new_with_input("tests/fixtures/accept-language.svg");
|
|
|
|
rsvg_convert
|
|
.command
|
|
.arg("--accept-language=de")
|
|
.assert()
|
|
.success()
|
|
.stdout(file::is_png().with_contents("tests/fixtures/accept-language-de.png"));
|
|
}
|
|
|
|
#[test]
|
|
fn accept_language_fallback() {
|
|
let mut rsvg_convert = RsvgConvert::new_with_input("tests/fixtures/accept-language.svg");
|
|
|
|
rsvg_convert
|
|
.command
|
|
.arg("--accept-language=fr")
|
|
.assert()
|
|
.success()
|
|
.stdout(file::is_png().with_contents("tests/fixtures/accept-language-fallback.png"));
|
|
}
|
|
|
|
#[test]
|
|
fn accept_language_invalid_tag() {
|
|
// underscores are not valid in BCP47 language tags
|
|
let mut rsvg_convert = RsvgConvert::new_with_input("tests/fixtures/accept-language.svg");
|
|
|
|
rsvg_convert
|
|
.command
|
|
.arg("--accept-language=foo_bar")
|
|
.assert()
|
|
.failure()
|
|
.stderr(contains("invalid language tag"));
|
|
}
|
|
|
|
#[test]
|
|
fn keep_image_data_option() {
|
|
RsvgConvert::accepts_arg("--keep-image-data");
|
|
}
|
|
|
|
#[test]
|
|
fn no_keep_image_data_option() {
|
|
RsvgConvert::accepts_arg("--no-keep-image-data");
|
|
}
|
|
|
|
fn is_version_output() -> RegexPredicate {
|
|
predicates::str::is_match(r"rsvg-convert version \d+\.\d+\.\d+").unwrap()
|
|
}
|
|
|
|
#[test]
|
|
fn version_option() {
|
|
RsvgConvert::option_yields_output("--version", is_version_output())
|
|
}
|
|
|
|
#[test]
|
|
fn version_short_option() {
|
|
RsvgConvert::option_yields_output("-v", is_version_output())
|
|
}
|
|
|
|
fn is_usage_output() -> OrPredicate<ContainsPredicate, ContainsPredicate, str> {
|
|
contains("Usage:").or(contains("USAGE:"))
|
|
}
|
|
|
|
#[test]
|
|
fn help_option() {
|
|
RsvgConvert::option_yields_output("--help", is_usage_output())
|
|
}
|
|
|
|
#[test]
|
|
fn help_short_option() {
|
|
RsvgConvert::option_yields_output("-?", is_usage_output())
|
|
}
|
|
|
|
#[test]
|
|
fn multiple_stdin_arguments_not_allowed() {
|
|
let mut rsvg_convert = RsvgConvert::new_with_input("tests/fixtures/accept-language.svg");
|
|
|
|
rsvg_convert
|
|
.command
|
|
.arg("-")
|
|
.arg("-")
|
|
.assert()
|
|
.failure()
|
|
.stderr(contains("Only one input file can be read from stdin"));
|
|
}
|