summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/README.md7
-rw-r--r--tests/cmp/coma.pngbin79107 -> 0 bytes
-rw-r--r--tests/cmp/image.pngbin281515 -> 0 bytes
-rw-r--r--tests/ref/empty.pngbin0 -> 120 bytes
-rw-r--r--tests/ref/example-coma.pngbin0 -> 27418 bytes
-rw-r--r--tests/ref/image-error.pngbin0 -> 120 bytes
-rw-r--r--tests/ref/image-fit.pngbin0 -> 190100 bytes
-rw-r--r--tests/ref/image-jpeg.pngbin0 -> 69754 bytes
-rw-r--r--tests/ref/image-png.pngbin0 -> 37986 bytes
-rw-r--r--tests/typ/empty.typ0
-rw-r--r--tests/typ/example-coma.typ (renamed from tests/typ/coma.typ)2
-rw-r--r--tests/typ/image-error.typ8
-rw-r--r--tests/typ/image-fit.typ21
-rw-r--r--tests/typ/image-jpeg.typ2
-rw-r--r--tests/typ/image-png.typ2
-rw-r--r--tests/typ/image.typ15
-rw-r--r--tests/typeset.rs193
17 files changed, 159 insertions, 91 deletions
diff --git a/tests/README.md b/tests/README.md
index 89c31c89..7d9c3eda 100644
--- a/tests/README.md
+++ b/tests/README.md
@@ -1,8 +1,7 @@
# Tests
- `typ`: Input files
-- `pdf`: PDF files produced by tests
-- `png`: PNG files produced by tests
-- `cmp`: Reference images which the PNGs are compared to byte-wise to determine
- whether the test passed or failed
+- `ref`: Reference images which the output is compared with to determine
+ whether a test passed or failed
- `res`: Resource files used by tests
+- `out`: PNG and PDF files produced by tests
diff --git a/tests/cmp/coma.png b/tests/cmp/coma.png
deleted file mode 100644
index d0c524ec..00000000
--- a/tests/cmp/coma.png
+++ /dev/null
Binary files differ
diff --git a/tests/cmp/image.png b/tests/cmp/image.png
deleted file mode 100644
index 5bf744e9..00000000
--- a/tests/cmp/image.png
+++ /dev/null
Binary files differ
diff --git a/tests/ref/empty.png b/tests/ref/empty.png
new file mode 100644
index 00000000..812a3758
--- /dev/null
+++ b/tests/ref/empty.png
Binary files differ
diff --git a/tests/ref/example-coma.png b/tests/ref/example-coma.png
new file mode 100644
index 00000000..0c18b810
--- /dev/null
+++ b/tests/ref/example-coma.png
Binary files differ
diff --git a/tests/ref/image-error.png b/tests/ref/image-error.png
new file mode 100644
index 00000000..812a3758
--- /dev/null
+++ b/tests/ref/image-error.png
Binary files differ
diff --git a/tests/ref/image-fit.png b/tests/ref/image-fit.png
new file mode 100644
index 00000000..b89e78fd
--- /dev/null
+++ b/tests/ref/image-fit.png
Binary files differ
diff --git a/tests/ref/image-jpeg.png b/tests/ref/image-jpeg.png
new file mode 100644
index 00000000..ef9e74cb
--- /dev/null
+++ b/tests/ref/image-jpeg.png
Binary files differ
diff --git a/tests/ref/image-png.png b/tests/ref/image-png.png
new file mode 100644
index 00000000..4e0818d2
--- /dev/null
+++ b/tests/ref/image-png.png
Binary files differ
diff --git a/tests/typ/empty.typ b/tests/typ/empty.typ
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/tests/typ/empty.typ
diff --git a/tests/typ/coma.typ b/tests/typ/example-coma.typ
index 839335b7..f841a122 100644
--- a/tests/typ/coma.typ
+++ b/tests/typ/example-coma.typ
@@ -1,3 +1,5 @@
+// Small integration test of syntax, page setup, box layout and alignment.
+
[page: width=450pt, height=300pt, margins=1cm]
[box][
diff --git a/tests/typ/image-error.typ b/tests/typ/image-error.typ
new file mode 100644
index 00000000..4fde4ab2
--- /dev/null
+++ b/tests/typ/image-error.typ
@@ -0,0 +1,8 @@
+// error: 5:9-5:30 failed to load image
+// error: 8:9-8:30 failed to load image
+
+// File does not exist.
+[image: "path/does/not/exist"]
+
+// File exists, but is no image.
+[image: "typ/image-error.typ"]
diff --git a/tests/typ/image-fit.typ b/tests/typ/image-fit.typ
new file mode 100644
index 00000000..b735f058
--- /dev/null
+++ b/tests/typ/image-fit.typ
@@ -0,0 +1,21 @@
+// Fit to width of page.
+[image: "res/rhino.png"]
+
+// Fit to height of page.
+[page: width=270pt][
+ [image: "res/rhino.png"]
+]
+
+// Set width explicitly.
+[image: "res/rhino.png", width=50pt]
+
+// Set height explicitly.
+[image: "res/rhino.png", height=50pt]
+
+// Set width and height explicitly and force stretching.
+[image: "res/rhino.png", width=25pt, height=50pt]
+
+// Make sure the bounding-box of the image is correct.
+[align: bottom, right][
+ [image: "res/tiger.jpg"]
+]
diff --git a/tests/typ/image-jpeg.typ b/tests/typ/image-jpeg.typ
new file mode 100644
index 00000000..48cf1a0d
--- /dev/null
+++ b/tests/typ/image-jpeg.typ
@@ -0,0 +1,2 @@
+// Load an RGB JPEG image.
+[image: "res/tiger.jpg"]
diff --git a/tests/typ/image-png.typ b/tests/typ/image-png.typ
new file mode 100644
index 00000000..482591e9
--- /dev/null
+++ b/tests/typ/image-png.typ
@@ -0,0 +1,2 @@
+// Load an RGBA PNG image.
+[image: "res/rhino.png"]
diff --git a/tests/typ/image.typ b/tests/typ/image.typ
deleted file mode 100644
index 6ae349a1..00000000
--- a/tests/typ/image.typ
+++ /dev/null
@@ -1,15 +0,0 @@
-[page: width=5cm, height=5cm, margins=0.25cm]
-
-[image: "res/tiger.jpg"]
-
-[pagebreak]
-
-# Tiger
-[image: "res/tiger.jpg", width=2cm]
-[image: "res/rhino.png", width=1cm]
-[image: "res/rhino.png", height=2cm]
-
-[pagebreak]
-
-[align: center, bottom]
-[image: "res/tiger.jpg", width=2cm, height=3.5cm]
diff --git a/tests/typeset.rs b/tests/typeset.rs
index 807215ed..037bd7ef 100644
--- a/tests/typeset.rs
+++ b/tests/typeset.rs
@@ -1,35 +1,35 @@
use std::cell::RefCell;
use std::env;
use std::ffi::OsStr;
-use std::fs::{self, File};
+use std::fs;
use std::path::Path;
use std::rc::Rc;
use fontdock::fs::{FsIndex, FsSource};
use image::{GenericImageView, Rgba};
-use memmap::Mmap;
use tiny_skia::{
Canvas, Color, ColorU8, FillRule, FilterQuality, Paint, PathBuilder, Pattern, Pixmap,
Rect, SpreadMode, Transform,
};
use ttf_parser::OutlineBuilder;
-use typst::diag::{Feedback, Pass};
+use typst::diag::{Diag, Feedback, Level, Pass};
use typst::env::{Env, ImageResource, ResourceLoader, SharedEnv};
use typst::eval::State;
use typst::export::pdf;
use typst::font::FontLoader;
-use typst::geom::{Length, Point};
+use typst::geom::{Length, Point, Sides, Size};
use typst::layout::{BoxLayout, ImageElement, LayoutElement};
-use typst::parse::LineMap;
+use typst::parse::{LineMap, Scanner};
use typst::shaping::Shaped;
+use typst::syntax::{Location, Pos, SpanVec, SpanWith, Spanned};
use typst::typeset;
-const FONT_DIR: &str = "../fonts";
const TYP_DIR: &str = "typ";
-const PDF_DIR: &str = "pdf";
-const PNG_DIR: &str = "png";
-const CMP_DIR: &str = "cmp";
+const REF_DIR: &str = "ref";
+const PNG_DIR: &str = "out/png";
+const PDF_DIR: &str = "out/pdf";
+const FONT_DIR: &str = "../fonts";
fn main() {
env::set_current_dir(env::current_dir().unwrap().join("tests")).unwrap();
@@ -44,12 +44,8 @@ fn main() {
}
let name = src_path.file_stem().unwrap().to_string_lossy().to_string();
- let pdf_path = Path::new(PDF_DIR).join(&name).with_extension("pdf");
- let png_path = Path::new(PNG_DIR).join(&name).with_extension("png");
- let ref_path = Path::new(CMP_DIR).join(&name).with_extension("png");
-
if filter.matches(&name) {
- filtered.push((name, src_path, pdf_path, png_path, ref_path));
+ filtered.push((name, src_path));
}
}
@@ -62,8 +58,8 @@ fn main() {
println!("Running {} tests", len);
}
- fs::create_dir_all(PDF_DIR).unwrap();
fs::create_dir_all(PNG_DIR).unwrap();
+ fs::create_dir_all(PDF_DIR).unwrap();
let mut index = FsIndex::new();
index.search_dir(FONT_DIR);
@@ -76,29 +72,12 @@ fn main() {
let mut ok = true;
- for (name, src_path, pdf_path, png_path, ref_path) in filtered {
- print!("Testing {}.", name);
- test(&src_path, &pdf_path, &png_path, &env);
-
- let png_file = File::open(&png_path).unwrap();
- let ref_file = match File::open(&ref_path) {
- Ok(file) => file,
- Err(_) => {
- println!(" Failed to open reference image. ❌");
- ok = false;
- continue;
- }
- };
-
- let a = unsafe { Mmap::map(&png_file).unwrap() };
- let b = unsafe { Mmap::map(&ref_file).unwrap() };
+ for (name, src_path) in filtered {
+ let png_path = Path::new(PNG_DIR).join(&name).with_extension("png");
+ let pdf_path = Path::new(PDF_DIR).join(&name).with_extension("pdf");
+ let ref_path = Path::new(REF_DIR).join(&name).with_extension("png");
- if *a != *b {
- println!(" Does not match reference image. ❌");
- ok = false;
- } else {
- println!(" Okay. ✔");
- }
+ ok &= test(&name, &src_path, &pdf_path, &png_path, &ref_path, &env);
}
if !ok {
@@ -106,41 +85,6 @@ fn main() {
}
}
-fn test(src_path: &Path, pdf_path: &Path, png_path: &Path, env: &SharedEnv) {
- let src = fs::read_to_string(src_path).unwrap();
- let state = State::default();
- let Pass {
- output: layouts,
- feedback: Feedback { mut diags, .. },
- } = typeset(&src, Rc::clone(env), state);
-
- if !diags.is_empty() {
- diags.sort();
-
- let map = LineMap::new(&src);
- for diag in diags {
- let span = diag.span;
- let start = map.location(span.start);
- let end = map.location(span.end);
- println!(
- " {}: {}:{}-{}: {}",
- diag.v.level,
- src_path.display(),
- start,
- end,
- diag.v.message,
- );
- }
- }
-
- let env = env.borrow();
- let canvas = draw(&layouts, &env, 2.0);
- canvas.pixmap.save_png(png_path).unwrap();
-
- let pdf_data = pdf::export(&layouts, &env);
- fs::write(pdf_path, pdf_data).unwrap();
-}
-
struct TestFilter {
filter: Vec<String>,
perfect: bool,
@@ -171,6 +115,111 @@ impl TestFilter {
}
}
+fn test(
+ name: &str,
+ src_path: &Path,
+ pdf_path: &Path,
+ png_path: &Path,
+ ref_path: &Path,
+ env: &SharedEnv,
+) -> bool {
+ println!("Testing {}.", name);
+
+ let src = fs::read_to_string(src_path).unwrap();
+ let map = LineMap::new(&src);
+ let ref_diags = parse_diags(&src, &map);
+
+ let mut state = State::default();
+ state.page.size = Size::uniform(Length::pt(120.0));
+ state.page.margins = Sides::uniform(Some(Length::pt(10.0).into()));
+
+ let Pass {
+ output: layouts,
+ feedback: Feedback { mut diags, .. },
+ } = typeset(&src, Rc::clone(env), state);
+ diags.sort();
+
+ let env = env.borrow();
+ let canvas = draw(&layouts, &env, 2.0);
+ canvas.pixmap.save_png(png_path).unwrap();
+
+ let pdf_data = pdf::export(&layouts, &env);
+ fs::write(pdf_path, pdf_data).unwrap();
+
+ let mut ok = true;
+
+ if diags != ref_diags {
+ println!(" Does not match expected diagnostics. ❌");
+ ok = false;
+
+ for diag in &diags {
+ if ref_diags.binary_search(diag).is_err() {
+ print!(" Unexpected | ");
+ print_diag(diag, &map);
+ }
+ }
+
+ for diag in &ref_diags {
+ if diags.binary_search(diag).is_err() {
+ print!(" Missing | ");
+ print_diag(diag, &map);
+ }
+ }
+ }
+
+ if let Ok(ref_pixmap) = Pixmap::load_png(&ref_path) {
+ if canvas.pixmap != ref_pixmap {
+ println!(" Does not match reference image. ❌");
+ ok = false;
+ }
+ } else {
+ println!(" Failed to open reference image. ❌");
+ ok = false;
+ }
+
+ if ok {
+ println!("\x1b[1ATesting {}. ✔", name);
+ }
+
+ ok
+}
+
+fn parse_diags(src: &str, map: &LineMap) -> SpanVec<Diag> {
+ let mut diags = vec![];
+
+ for line in src.lines() {
+ let (level, rest) = if let Some(rest) = line.strip_prefix("// error: ") {
+ (Level::Error, rest)
+ } else if let Some(rest) = line.strip_prefix("// warning: ") {
+ (Level::Warning, rest)
+ } else {
+ continue;
+ };
+
+ fn pos(s: &mut Scanner, map: &LineMap) -> Pos {
+ let (line, _, column) = (num(s), s.eat_assert(':'), num(s));
+ map.pos(Location { line, column }).unwrap()
+ }
+
+ fn num(s: &mut Scanner) -> u32 {
+ s.eat_while(|c| c.is_numeric()).parse().unwrap()
+ }
+
+ let mut s = Scanner::new(rest);
+ let (start, _, end) = (pos(&mut s, map), s.eat_assert('-'), pos(&mut s, map));
+ diags.push(Diag::new(level, s.rest().trim()).span_with(start .. end));
+ }
+
+ diags.sort();
+ diags
+}
+
+fn print_diag(diag: &Spanned<Diag>, map: &LineMap) {
+ let start = map.location(diag.span.start).unwrap();
+ let end = map.location(diag.span.end).unwrap();
+ println!("{}: {}-{}: {}", diag.v.level, start, end, diag.v.message,);
+}
+
fn draw(layouts: &[BoxLayout], env: &Env, pixel_per_pt: f32) -> Canvas {
let pad = Length::pt(5.0);