diff --git a/.gitignore b/.gitignore index c17c6399c..a1915f4a3 100644 --- a/.gitignore +++ b/.gitignore @@ -6,11 +6,8 @@ desktop.ini .DS_Store # Tests and benchmarks -tests/png -tests/pdf -tests/svg -tests/target -tests/typ/**/*.pdf +tests/store +tests/suite/**/*.pdf tests/fuzz/target tests/fuzz/corpus tests/fuzz/artifacts @@ -23,6 +20,7 @@ tarpaulin-report.html # Node node_modules +tools/test-helper/dist package-lock.json # Nix diff --git a/Cargo.lock b/Cargo.lock index 8215e9e48..066f2381a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2675,8 +2675,11 @@ dependencies = [ "ecow", "if_chain", "log", + "once_cell", "serde", "typst", + "typst-assets", + "typst-dev-assets", "unscanny", ] @@ -2773,13 +2776,13 @@ dependencies = [ "ecow", "once_cell", "oxipng", + "parking_lot", "rayon", "tiny-skia", "ttf-parser", "typst", "typst-assets", "typst-dev-assets", - "typst-ide", "typst-pdf", "typst-render", "typst-svg", diff --git a/crates/typst-cli/src/world.rs b/crates/typst-cli/src/world.rs index 99da838cf..5b4259f49 100644 --- a/crates/typst-cli/src/world.rs +++ b/crates/typst-cli/src/world.rs @@ -241,7 +241,7 @@ struct FileSlot { } impl FileSlot { - /// Create a new path slot. + /// Create a new file slot. fn new(id: FileId) -> Self { Self { id, file: SlotCell::new(), source: SlotCell::new() } } diff --git a/crates/typst-ide/Cargo.toml b/crates/typst-ide/Cargo.toml index 45a83d556..01f7a1062 100644 --- a/crates/typst-ide/Cargo.toml +++ b/crates/typst-ide/Cargo.toml @@ -21,5 +21,10 @@ log = { workspace = true } serde = { workspace = true } unscanny = { workspace = true } +[dev-dependencies] +typst-assets = { workspace = true } +typst-dev-assets = { workspace = true } +once_cell = { workspace = true } + [lints] workspace = true diff --git a/crates/typst-ide/src/complete.rs b/crates/typst-ide/src/complete.rs index be28a4314..c758dd1c0 100644 --- a/crates/typst-ide/src/complete.rs +++ b/crates/typst-ide/src/complete.rs @@ -1403,3 +1403,34 @@ impl<'a> CompletionContext<'a> { } } } + +#[cfg(test)] +mod tests { + use typst::eval::Tracer; + + use super::autocomplete; + use crate::tests::TestWorld; + + #[track_caller] + fn test(text: &str, cursor: usize, contains: &[&str], excludes: &[&str]) { + let world = TestWorld::new(text); + let doc = typst::compile(&world, &mut Tracer::new()).ok(); + let (_, completions) = + autocomplete(&world, doc.as_ref(), &world.main, cursor, true) + .unwrap_or_default(); + + let labels: Vec<_> = completions.iter().map(|c| c.label.as_str()).collect(); + for item in contains { + assert!(labels.contains(item), "{item:?} was not contained in {labels:?}"); + } + for item in excludes { + assert!(!labels.contains(item), "{item:?} was not excluded in {labels:?}"); + } + } + + #[test] + fn test_autocomplete() { + test("#i", 2, &["int", "if conditional"], &["foo"]); + test("#().", 4, &["insert", "remove", "len", "all"], &["foo"]); + } +} diff --git a/crates/typst-ide/src/lib.rs b/crates/typst-ide/src/lib.rs index bbfd56d95..3967aaad4 100644 --- a/crates/typst-ide/src/lib.rs +++ b/crates/typst-ide/src/lib.rs @@ -90,3 +90,88 @@ fn summarize_font_family<'a>(variants: impl Iterator) -> Ec detail } + +#[cfg(test)] +mod tests { + use comemo::Prehashed; + use once_cell::sync::Lazy; + use typst::diag::{FileError, FileResult}; + use typst::foundations::{Bytes, Datetime}; + use typst::syntax::{FileId, Source}; + use typst::text::{Font, FontBook}; + use typst::{Library, World}; + + /// A world for IDE testing. + pub struct TestWorld { + pub main: Source, + base: &'static TestBase, + } + + impl TestWorld { + /// Create a new world for a single test. + /// + /// This is cheap because the shared base for all test runs is lazily + /// initialized just once. + pub fn new(text: &str) -> Self { + static BASE: Lazy = Lazy::new(TestBase::default); + let main = Source::detached(text); + Self { main, base: &*BASE } + } + } + + impl World for TestWorld { + fn library(&self) -> &Prehashed { + &self.base.library + } + + fn book(&self) -> &Prehashed { + &self.base.book + } + + fn main(&self) -> Source { + self.main.clone() + } + + fn source(&self, id: FileId) -> FileResult { + if id == self.main.id() { + Ok(self.main.clone()) + } else { + Err(FileError::NotFound(id.vpath().as_rootless_path().into())) + } + } + + fn file(&self, id: FileId) -> FileResult { + Err(FileError::NotFound(id.vpath().as_rootless_path().into())) + } + + fn font(&self, index: usize) -> Option { + Some(self.base.fonts[index].clone()) + } + + fn today(&self, _: Option) -> Option { + None + } + } + + /// Shared foundation of all test worlds. + struct TestBase { + library: Prehashed, + book: Prehashed, + fonts: Vec, + } + + impl Default for TestBase { + fn default() -> Self { + let fonts: Vec<_> = typst_assets::fonts() + .chain(typst_dev_assets::fonts()) + .flat_map(|data| Font::iter(Bytes::from_static(data))) + .collect(); + + Self { + library: Prehashed::new(Library::default()), + book: Prehashed::new(FontBook::from_fonts(&fonts)), + fonts, + } + } + } +} diff --git a/crates/typst-pdf/src/page.rs b/crates/typst-pdf/src/page.rs index c31d12040..42358db51 100644 --- a/crates/typst-pdf/src/page.rs +++ b/crates/typst-pdf/src/page.rs @@ -377,7 +377,7 @@ pub struct EncodedPage { } /// Represents a resource being used in a PDF page by its name. -#[derive(Debug, Clone, PartialEq, Eq, Hash)] +#[derive(Debug, Clone, PartialEq, Eq, Hash, Ord, PartialOrd)] pub struct PageResource { kind: ResourceKind, name: EcoString, @@ -390,7 +390,7 @@ impl PageResource { } /// A kind of resource being used in a PDF page. -#[derive(Debug, Clone, PartialEq, Eq, Hash)] +#[derive(Debug, Clone, PartialEq, Eq, Hash, Ord, PartialOrd)] pub enum ResourceKind { XObject, Font, diff --git a/crates/typst-pdf/src/pattern.rs b/crates/typst-pdf/src/pattern.rs index 6dfb0f666..5d5942bc9 100644 --- a/crates/typst-pdf/src/pattern.rs +++ b/crates/typst-pdf/src/pattern.rs @@ -118,13 +118,15 @@ fn register_pattern( // Render the body. let (_, content) = construct_page(ctx.parent, pattern.frame()); - let pdf_pattern = PdfPattern { + let mut pdf_pattern = PdfPattern { transform, pattern: pattern.clone(), content: content.content.wait().clone(), resources: content.resources.into_iter().collect(), }; + pdf_pattern.resources.sort(); + ctx.parent.pattern_map.insert(pdf_pattern) } diff --git a/crates/typst-render/src/lib.rs b/crates/typst-render/src/lib.rs index fdacb5976..28302180a 100644 --- a/crates/typst-render/src/lib.rs +++ b/crates/typst-render/src/lib.rs @@ -42,13 +42,13 @@ pub fn render(frame: &Frame, pixel_per_pt: f32, fill: Color) -> sk::Pixmap { /// Export a document with potentially multiple pages into a single raster image. /// -/// The padding will be added around and between the individual frames. +/// The gap will be added between the individual frames. pub fn render_merged( document: &Document, pixel_per_pt: f32, frame_fill: Color, - padding: Abs, - padding_fill: Color, + gap: Abs, + gap_fill: Color, ) -> sk::Pixmap { let pixmaps: Vec<_> = document .pages @@ -56,19 +56,18 @@ pub fn render_merged( .map(|page| render(&page.frame, pixel_per_pt, frame_fill)) .collect(); - let padding = (pixel_per_pt * padding.to_f32()).round() as u32; - let pxw = - 2 * padding + pixmaps.iter().map(sk::Pixmap::width).max().unwrap_or_default(); - let pxh = - padding + pixmaps.iter().map(|pixmap| pixmap.height() + padding).sum::(); + let gap = (pixel_per_pt * gap.to_f32()).round() as u32; + let pxw = pixmaps.iter().map(sk::Pixmap::width).max().unwrap_or_default(); + let pxh = pixmaps.iter().map(|pixmap| pixmap.height()).sum::() + + gap * pixmaps.len().saturating_sub(1) as u32; let mut canvas = sk::Pixmap::new(pxw, pxh).unwrap(); - canvas.fill(to_sk_color(padding_fill)); + canvas.fill(to_sk_color(gap_fill)); - let [x, mut y] = [padding; 2]; + let mut y = 0; for pixmap in pixmaps { canvas.draw_pixmap( - x as i32, + 0, y as i32, pixmap.as_ref(), &sk::PixmapPaint::default(), @@ -76,7 +75,7 @@ pub fn render_merged( None, ); - y += pixmap.height() + padding; + y += pixmap.height() + gap; } canvas diff --git a/crates/typst/src/model/footnote.rs b/crates/typst/src/model/footnote.rs index 44942341b..4945ebb18 100644 --- a/crates/typst/src/model/footnote.rs +++ b/crates/typst/src/model/footnote.rs @@ -167,11 +167,6 @@ cast! { /// This function is not intended to be called directly. Instead, it is used /// in set and show rules to customize footnote listings. /// -/// _Note:_ Set and show rules for `footnote.entry` must be defined at the -/// beginning of the document in order to work correctly. -/// See [here](https://github.com/typst/typst/issues/1348#issuecomment-1566316463) -/// for more information. -/// /// ```example /// #show footnote.entry: set text(red) /// @@ -179,6 +174,12 @@ cast! { /// #footnote[It's down here] /// has red text! /// ``` +/// +/// _Note:_ Set and show rules for `footnote.entry` must be defined at the +/// beginning of the document in order to work correctly. See [here][issue] for +/// more information. +/// +/// [issue]: https://github.com/typst/typst/issues/1467#issuecomment-1588799440 #[elem(name = "entry", title = "Footnote Entry", Show, ShowSet)] pub struct FootnoteEntry { /// The footnote for this entry. It's location can be used to determine diff --git a/tests/Cargo.toml b/tests/Cargo.toml index 1f650c976..62e7a493a 100644 --- a/tests/Cargo.toml +++ b/tests/Cargo.toml @@ -6,29 +6,29 @@ authors = { workspace = true } edition = { workspace = true } publish = false -[dev-dependencies] +[[test]] +name = "tests" +path = "src/tests.rs" +harness = false + +[dependencies] typst = { workspace = true } typst-assets = { workspace = true, features = ["fonts"] } typst-dev-assets = { workspace = true } typst-pdf = { workspace = true } typst-render = { workspace = true } typst-svg = { workspace = true } -typst-ide = { workspace = true } clap = { workspace = true } comemo = { workspace = true } ecow = { workspace = true } once_cell = { workspace = true } oxipng = { workspace = true } +parking_lot = { workspace = true } rayon = { workspace = true } tiny-skia = { workspace = true } ttf-parser = { workspace = true } unscanny = { workspace = true } walkdir = { workspace = true } -[[test]] -name = "tests" -path = "src/tests.rs" -harness = false - [lints] workspace = true diff --git a/tests/README.md b/tests/README.md index 68b72f2df..6cc79217a 100644 --- a/tests/README.md +++ b/tests/README.md @@ -3,13 +3,10 @@ ## Directory structure Top level directory structure: - `src`: Testing code. -- `typ`: Input files. The tests in `compiler` specifically test the compiler - while the others test the standard library (but also the compiler - indirectly). +- `suite`: Input files. Mostly organize in parallel to the code. - `ref`: Reference images which the output is compared with to determine whether a test passed or failed. -- `png`: PNG files produced by tests. -- `pdf`: PDF files produced by tests. +- `store`: Store for PNG, PDF, and SVG output files produced by the tests. ## Running the tests Running all tests (including unit tests): @@ -37,11 +34,6 @@ Running a test with the exact filename `page.typ`. testit --exact page.typ ``` -Debug-printing the layout trees for all executed tests. -```bash -testit --debug empty.typ -``` - To make the integration tests go faster they don't generate PDFs by default. Pass the `--pdf` flag to generate those. Mind that PDFs are not tested automatically at the moment, so you should always check the output manually when @@ -50,18 +42,48 @@ making changes. testit --pdf ``` -## Update expected images +## Writing tests +The syntax for an individual test is `--- {name} ---` followed by some Typst +code that should be tested. The name must be globally unique in the test suite, +so that tests can be easily migrated across files. + +There are, broadly speaking, three kinds of tests: + +- Tests that just ensure that the code runs successfully: Those typically make + use of `test` or `assert.eq` (both are very similar, `test` is just shorter) + to ensure certain properties hold when executing the Typst code. + +- Tests that ensure the code fails with a particular error: Those have inline + annotations like `// Error: 2-7 thing was wrong`. An annotation can be + either an "Error", a "Warning", or a "Hint". The range designates where + in the next non-comment line the error is and after it follows the message. + If you the error is in a line further below, you can also write ranges like + `3:2-3:7` to indicate the 2-7 column in the 3rd non-comment line. + +- Tests that ensure certain visual output is produced: Those render the result + of the test with the `typst-render` crate and compare against a reference + image stored in the repository. The test runner automatically detects whether + a test has visual output and requires a reference image in this case. + + To prevent bloat, it is important that the test images are kept as small as + possible. To that effect, the test runner enforces a maximum size of 20 KiB. + If truly necessary, this limit can however be lifted by adding `// LARGE` as + the first line of a test. + +If you have the choice between writing a test using assertions or using +reference images, prefer assertions. This makes the test easier to understand +in isolation and prevents bloat due to images. + +## Updating reference images If you created a new test or fixed a bug in an existing test, you need to update -the reference image used for comparison. For this, you can use the -`UPDATE_EXPECT` environment variable or the `--update` flag: +the reference image used for comparison. For this, you can use the `--update` +flag: ```bash testit mytest --update ``` If you use the VS Code test helper extension (see the `tools` folder), you can -alternatively use the checkmark button to update the reference image. In that -case you should also install `oxipng` on your system so that the test helper -can optimize the reference images. +alternatively use the save button to update the reference image. ## Making an alias If you want to have a quicker way to run the tests, consider adding a shortcut diff --git a/tests/ref/align-center-in-flow.png b/tests/ref/align-center-in-flow.png new file mode 100644 index 000000000..ecfe49dc5 Binary files /dev/null and b/tests/ref/align-center-in-flow.png differ diff --git a/tests/ref/align-in-stack.png b/tests/ref/align-in-stack.png new file mode 100644 index 000000000..556721ab0 Binary files /dev/null and b/tests/ref/align-in-stack.png differ diff --git a/tests/ref/align-right.png b/tests/ref/align-right.png new file mode 100644 index 000000000..edab88510 Binary files /dev/null and b/tests/ref/align-right.png differ diff --git a/tests/ref/align-start-and-end.png b/tests/ref/align-start-and-end.png new file mode 100644 index 000000000..cf3faeae6 Binary files /dev/null and b/tests/ref/align-start-and-end.png differ diff --git a/tests/ref/array-basic-syntax.png b/tests/ref/array-basic-syntax.png new file mode 100644 index 000000000..6eb95305c Binary files /dev/null and b/tests/ref/array-basic-syntax.png differ diff --git a/tests/ref/array-insert-and-remove.png b/tests/ref/array-insert-and-remove.png new file mode 100644 index 000000000..ea4b8cf2a Binary files /dev/null and b/tests/ref/array-insert-and-remove.png differ diff --git a/tests/ref/array-join-content.png b/tests/ref/array-join-content.png new file mode 100644 index 000000000..4d08142eb Binary files /dev/null and b/tests/ref/array-join-content.png differ diff --git a/tests/ref/baseline-box.png b/tests/ref/baseline-box.png new file mode 100644 index 000000000..8d7627c60 Binary files /dev/null and b/tests/ref/baseline-box.png differ diff --git a/tests/ref/baseline-text.png b/tests/ref/baseline-text.png new file mode 100644 index 000000000..72beac795 Binary files /dev/null and b/tests/ref/baseline-text.png differ diff --git a/tests/ref/bibliography-basic.png b/tests/ref/bibliography-basic.png new file mode 100644 index 000000000..eeb773bfe Binary files /dev/null and b/tests/ref/bibliography-basic.png differ diff --git a/tests/ref/bibliography-before-content.png b/tests/ref/bibliography-before-content.png new file mode 100644 index 000000000..806daa089 Binary files /dev/null and b/tests/ref/bibliography-before-content.png differ diff --git a/tests/ref/bibliography-full.png b/tests/ref/bibliography-full.png new file mode 100644 index 000000000..1da15d166 Binary files /dev/null and b/tests/ref/bibliography-full.png differ diff --git a/tests/ref/bibliography-math.png b/tests/ref/bibliography-math.png new file mode 100644 index 000000000..3fc36efca Binary files /dev/null and b/tests/ref/bibliography-math.png differ diff --git a/tests/ref/bibliography-multiple-files.png b/tests/ref/bibliography-multiple-files.png new file mode 100644 index 000000000..1293ba22b Binary files /dev/null and b/tests/ref/bibliography-multiple-files.png differ diff --git a/tests/ref/bibliography-ordering.png b/tests/ref/bibliography-ordering.png new file mode 100644 index 000000000..b1e14c9ad Binary files /dev/null and b/tests/ref/bibliography-ordering.png differ diff --git a/tests/ref/bidi-consecutive-embedded-ltr-runs.png b/tests/ref/bidi-consecutive-embedded-ltr-runs.png new file mode 100644 index 000000000..dbaaff07d Binary files /dev/null and b/tests/ref/bidi-consecutive-embedded-ltr-runs.png differ diff --git a/tests/ref/bidi-consecutive-embedded-rtl-runs.png b/tests/ref/bidi-consecutive-embedded-rtl-runs.png new file mode 100644 index 000000000..4cf62d3e0 Binary files /dev/null and b/tests/ref/bidi-consecutive-embedded-rtl-runs.png differ diff --git a/tests/ref/bidi-en-he-top-level.png b/tests/ref/bidi-en-he-top-level.png new file mode 100644 index 000000000..abab54f4b Binary files /dev/null and b/tests/ref/bidi-en-he-top-level.png differ diff --git a/tests/ref/bidi-explicit-dir.png b/tests/ref/bidi-explicit-dir.png new file mode 100644 index 000000000..8b813be0c Binary files /dev/null and b/tests/ref/bidi-explicit-dir.png differ diff --git a/tests/ref/bidi-manual-linebreak.png b/tests/ref/bidi-manual-linebreak.png new file mode 100644 index 000000000..4d0eb6f89 Binary files /dev/null and b/tests/ref/bidi-manual-linebreak.png differ diff --git a/tests/ref/bidi-nesting.png b/tests/ref/bidi-nesting.png new file mode 100644 index 000000000..e18d6c0a0 Binary files /dev/null and b/tests/ref/bidi-nesting.png differ diff --git a/tests/ref/bidi-obj.png b/tests/ref/bidi-obj.png new file mode 100644 index 000000000..8cc41528a Binary files /dev/null and b/tests/ref/bidi-obj.png differ diff --git a/tests/ref/bidi-raw.png b/tests/ref/bidi-raw.png new file mode 100644 index 000000000..24503ee93 Binary files /dev/null and b/tests/ref/bidi-raw.png differ diff --git a/tests/ref/bidi-spacing.png b/tests/ref/bidi-spacing.png new file mode 100644 index 000000000..44ede76f1 Binary files /dev/null and b/tests/ref/bidi-spacing.png differ diff --git a/tests/ref/bidi-whitespace-reset.png b/tests/ref/bidi-whitespace-reset.png new file mode 100644 index 000000000..7d64012f9 Binary files /dev/null and b/tests/ref/bidi-whitespace-reset.png differ diff --git a/tests/ref/block-box-fill.png b/tests/ref/block-box-fill.png new file mode 100644 index 000000000..fe4f72580 Binary files /dev/null and b/tests/ref/block-box-fill.png differ diff --git a/tests/ref/block-clip-svg-glyphs.png b/tests/ref/block-clip-svg-glyphs.png new file mode 100644 index 000000000..d8db5b61e Binary files /dev/null and b/tests/ref/block-clip-svg-glyphs.png differ diff --git a/tests/ref/block-clip-text.png b/tests/ref/block-clip-text.png new file mode 100644 index 000000000..7cd86ddbe Binary files /dev/null and b/tests/ref/block-clip-text.png differ diff --git a/tests/ref/block-clipping-multiple-pages.png b/tests/ref/block-clipping-multiple-pages.png new file mode 100644 index 000000000..9c9aa89b4 Binary files /dev/null and b/tests/ref/block-clipping-multiple-pages.png differ diff --git a/tests/ref/block-fixed-height.png b/tests/ref/block-fixed-height.png new file mode 100644 index 000000000..95c3be1e5 Binary files /dev/null and b/tests/ref/block-fixed-height.png differ diff --git a/tests/ref/block-multiple-pages.png b/tests/ref/block-multiple-pages.png new file mode 100644 index 000000000..c2f192bd6 Binary files /dev/null and b/tests/ref/block-multiple-pages.png differ diff --git a/tests/ref/block-sizing.png b/tests/ref/block-sizing.png new file mode 100644 index 000000000..76cb04dfa Binary files /dev/null and b/tests/ref/block-sizing.png differ diff --git a/tests/ref/block-spacing-basic.png b/tests/ref/block-spacing-basic.png new file mode 100644 index 000000000..875410acb Binary files /dev/null and b/tests/ref/block-spacing-basic.png differ diff --git a/tests/ref/block-spacing-collapse-text-style.png b/tests/ref/block-spacing-collapse-text-style.png new file mode 100644 index 000000000..6c631457b Binary files /dev/null and b/tests/ref/block-spacing-collapse-text-style.png differ diff --git a/tests/ref/block-spacing-maximum.png b/tests/ref/block-spacing-maximum.png new file mode 100644 index 000000000..755b1cc30 Binary files /dev/null and b/tests/ref/block-spacing-maximum.png differ diff --git a/tests/ref/block-spacing-table.png b/tests/ref/block-spacing-table.png new file mode 100644 index 000000000..1591acb7c Binary files /dev/null and b/tests/ref/block-spacing-table.png differ diff --git a/tests/ref/box-clip-radius-without-stroke.png b/tests/ref/box-clip-radius-without-stroke.png new file mode 100644 index 000000000..121373582 Binary files /dev/null and b/tests/ref/box-clip-radius-without-stroke.png differ diff --git a/tests/ref/box-clip-radius.png b/tests/ref/box-clip-radius.png new file mode 100644 index 000000000..da20fa5bf Binary files /dev/null and b/tests/ref/box-clip-radius.png differ diff --git a/tests/ref/box-clip-rect.png b/tests/ref/box-clip-rect.png new file mode 100644 index 000000000..49a4e4abc Binary files /dev/null and b/tests/ref/box-clip-rect.png differ diff --git a/tests/ref/box-layoutable-child.png b/tests/ref/box-layoutable-child.png new file mode 100644 index 000000000..a1960a249 Binary files /dev/null and b/tests/ref/box-layoutable-child.png differ diff --git a/tests/ref/box-width-fr.png b/tests/ref/box-width-fr.png new file mode 100644 index 000000000..30d481631 Binary files /dev/null and b/tests/ref/box-width-fr.png differ diff --git a/tests/ref/box.png b/tests/ref/box.png new file mode 100644 index 000000000..fde288a80 Binary files /dev/null and b/tests/ref/box.png differ diff --git a/tests/ref/bugs/1050-terms-indent.png b/tests/ref/bugs/1050-terms-indent.png deleted file mode 100644 index 58a7feae8..000000000 Binary files a/tests/ref/bugs/1050-terms-indent.png and /dev/null differ diff --git a/tests/ref/bugs/1240-stack-fr.png b/tests/ref/bugs/1240-stack-fr.png deleted file mode 100644 index 29df5d44a..000000000 Binary files a/tests/ref/bugs/1240-stack-fr.png and /dev/null differ diff --git a/tests/ref/bugs/1597-cite-footnote.png b/tests/ref/bugs/1597-cite-footnote.png deleted file mode 100644 index c2e219f27..000000000 Binary files a/tests/ref/bugs/1597-cite-footnote.png and /dev/null differ diff --git a/tests/ref/bugs/2044-invalid-parsed-ident.png b/tests/ref/bugs/2044-invalid-parsed-ident.png deleted file mode 100644 index 327150e78..000000000 Binary files a/tests/ref/bugs/2044-invalid-parsed-ident.png and /dev/null differ diff --git a/tests/ref/bugs/2105-linebreak-tofu.png b/tests/ref/bugs/2105-linebreak-tofu.png deleted file mode 100644 index 78f937eb2..000000000 Binary files a/tests/ref/bugs/2105-linebreak-tofu.png and /dev/null differ diff --git a/tests/ref/bugs/2595-float-overlap.png b/tests/ref/bugs/2595-float-overlap.png deleted file mode 100644 index 6d8eaf941..000000000 Binary files a/tests/ref/bugs/2595-float-overlap.png and /dev/null differ diff --git a/tests/ref/bugs/2650-cjk-latin-spacing-meta.png b/tests/ref/bugs/2650-cjk-latin-spacing-meta.png deleted file mode 100644 index 35ff0e62d..000000000 Binary files a/tests/ref/bugs/2650-cjk-latin-spacing-meta.png and /dev/null differ diff --git a/tests/ref/bugs/2715-float-order.png b/tests/ref/bugs/2715-float-order.png deleted file mode 100644 index 0a4f8812e..000000000 Binary files a/tests/ref/bugs/2715-float-order.png and /dev/null differ diff --git a/tests/ref/bugs/3082-chinese-punctuation.png b/tests/ref/bugs/3082-chinese-punctuation.png deleted file mode 100644 index c187d4955..000000000 Binary files a/tests/ref/bugs/3082-chinese-punctuation.png and /dev/null differ diff --git a/tests/ref/bugs/3641-float-loop.png b/tests/ref/bugs/3641-float-loop.png deleted file mode 100644 index 092b2ff51..000000000 Binary files a/tests/ref/bugs/3641-float-loop.png and /dev/null differ diff --git a/tests/ref/bugs/3650-italic-equation.png b/tests/ref/bugs/3650-italic-equation.png deleted file mode 100644 index 41f071ab8..000000000 Binary files a/tests/ref/bugs/3650-italic-equation.png and /dev/null differ diff --git a/tests/ref/bugs/3658-math-size.png b/tests/ref/bugs/3658-math-size.png deleted file mode 100644 index 94c8d3881..000000000 Binary files a/tests/ref/bugs/3658-math-size.png and /dev/null differ diff --git a/tests/ref/bugs/3662-pdf-smartquotes.png b/tests/ref/bugs/3662-pdf-smartquotes.png deleted file mode 100644 index c272a8ffd..000000000 Binary files a/tests/ref/bugs/3662-pdf-smartquotes.png and /dev/null differ diff --git a/tests/ref/bugs/3700-deformed-stroke.png b/tests/ref/bugs/3700-deformed-stroke.png deleted file mode 100644 index f1db28366..000000000 Binary files a/tests/ref/bugs/3700-deformed-stroke.png and /dev/null differ diff --git a/tests/ref/bugs/3841-tabs-in-raw-typ-code.png b/tests/ref/bugs/3841-tabs-in-raw-typ-code.png deleted file mode 100644 index 37dab1368..000000000 Binary files a/tests/ref/bugs/3841-tabs-in-raw-typ-code.png and /dev/null differ diff --git a/tests/ref/bugs/870-image-rotation.png b/tests/ref/bugs/870-image-rotation.png deleted file mode 100644 index 83d9267d1..000000000 Binary files a/tests/ref/bugs/870-image-rotation.png and /dev/null differ diff --git a/tests/ref/bugs/args-sink.png b/tests/ref/bugs/args-sink.png deleted file mode 100644 index 564c59a2b..000000000 Binary files a/tests/ref/bugs/args-sink.png and /dev/null differ diff --git a/tests/ref/bugs/bibliography-math.png b/tests/ref/bugs/bibliography-math.png deleted file mode 100644 index 0ab308dc9..000000000 Binary files a/tests/ref/bugs/bibliography-math.png and /dev/null differ diff --git a/tests/ref/bugs/bidi-tofus.png b/tests/ref/bugs/bidi-tofus.png deleted file mode 100644 index 1b7a7d8b4..000000000 Binary files a/tests/ref/bugs/bidi-tofus.png and /dev/null differ diff --git a/tests/ref/bugs/block-width-box.png b/tests/ref/bugs/block-width-box.png deleted file mode 100644 index 9cb27a5de..000000000 Binary files a/tests/ref/bugs/block-width-box.png and /dev/null differ diff --git a/tests/ref/bugs/cite-locate.png b/tests/ref/bugs/cite-locate.png deleted file mode 100644 index bd31df7db..000000000 Binary files a/tests/ref/bugs/cite-locate.png and /dev/null differ diff --git a/tests/ref/bugs/cite-show-set.png b/tests/ref/bugs/cite-show-set.png deleted file mode 100644 index 566186a4c..000000000 Binary files a/tests/ref/bugs/cite-show-set.png and /dev/null differ diff --git a/tests/ref/bugs/clamp-panic.png b/tests/ref/bugs/clamp-panic.png deleted file mode 100644 index c0c4912e3..000000000 Binary files a/tests/ref/bugs/clamp-panic.png and /dev/null differ diff --git a/tests/ref/bugs/columns-1.png b/tests/ref/bugs/columns-1.png deleted file mode 100644 index 4b462b60a..000000000 Binary files a/tests/ref/bugs/columns-1.png and /dev/null differ diff --git a/tests/ref/bugs/emoji-linebreak.png b/tests/ref/bugs/emoji-linebreak.png deleted file mode 100644 index 6944233d8..000000000 Binary files a/tests/ref/bugs/emoji-linebreak.png and /dev/null differ diff --git a/tests/ref/bugs/flow-1.png b/tests/ref/bugs/flow-1.png deleted file mode 100644 index 662a7b147..000000000 Binary files a/tests/ref/bugs/flow-1.png and /dev/null differ diff --git a/tests/ref/bugs/flow-2.png b/tests/ref/bugs/flow-2.png deleted file mode 100644 index c7ece3083..000000000 Binary files a/tests/ref/bugs/flow-2.png and /dev/null differ diff --git a/tests/ref/bugs/flow-3.png b/tests/ref/bugs/flow-3.png deleted file mode 100644 index 25acc06df..000000000 Binary files a/tests/ref/bugs/flow-3.png and /dev/null differ diff --git a/tests/ref/bugs/flow-4.png b/tests/ref/bugs/flow-4.png deleted file mode 100644 index 2adcbe157..000000000 Binary files a/tests/ref/bugs/flow-4.png and /dev/null differ diff --git a/tests/ref/bugs/flow-5.png b/tests/ref/bugs/flow-5.png deleted file mode 100644 index 648c8c44f..000000000 Binary files a/tests/ref/bugs/flow-5.png and /dev/null differ diff --git a/tests/ref/bugs/fold-vector.png b/tests/ref/bugs/fold-vector.png deleted file mode 100644 index d8503a8eb..000000000 Binary files a/tests/ref/bugs/fold-vector.png and /dev/null differ diff --git a/tests/ref/bugs/footnote-keep-multiple.png b/tests/ref/bugs/footnote-keep-multiple.png deleted file mode 100644 index f3b67a745..000000000 Binary files a/tests/ref/bugs/footnote-keep-multiple.png and /dev/null differ diff --git a/tests/ref/bugs/footnote-list.png b/tests/ref/bugs/footnote-list.png deleted file mode 100644 index 1b56f2274..000000000 Binary files a/tests/ref/bugs/footnote-list.png and /dev/null differ diff --git a/tests/ref/bugs/gradient-cmyk-encode.png b/tests/ref/bugs/gradient-cmyk-encode.png deleted file mode 100644 index 5002442f7..000000000 Binary files a/tests/ref/bugs/gradient-cmyk-encode.png and /dev/null differ diff --git a/tests/ref/bugs/grid-1.png b/tests/ref/bugs/grid-1.png deleted file mode 100644 index f60ad7f47..000000000 Binary files a/tests/ref/bugs/grid-1.png and /dev/null differ diff --git a/tests/ref/bugs/grid-2.png b/tests/ref/bugs/grid-2.png deleted file mode 100644 index 882e0d6ad..000000000 Binary files a/tests/ref/bugs/grid-2.png and /dev/null differ diff --git a/tests/ref/bugs/grid-3.png b/tests/ref/bugs/grid-3.png deleted file mode 100644 index 6b5ae649e..000000000 Binary files a/tests/ref/bugs/grid-3.png and /dev/null differ diff --git a/tests/ref/bugs/grid-4.png b/tests/ref/bugs/grid-4.png deleted file mode 100644 index 475f561ea..000000000 Binary files a/tests/ref/bugs/grid-4.png and /dev/null differ diff --git a/tests/ref/bugs/hide-meta.png b/tests/ref/bugs/hide-meta.png deleted file mode 100644 index 76b4671a0..000000000 Binary files a/tests/ref/bugs/hide-meta.png and /dev/null differ diff --git a/tests/ref/bugs/justify-hanging-indent.png b/tests/ref/bugs/justify-hanging-indent.png deleted file mode 100644 index 015cc44e6..000000000 Binary files a/tests/ref/bugs/justify-hanging-indent.png and /dev/null differ diff --git a/tests/ref/bugs/line-align.png b/tests/ref/bugs/line-align.png deleted file mode 100644 index 1117ed6bf..000000000 Binary files a/tests/ref/bugs/line-align.png and /dev/null differ diff --git a/tests/ref/bugs/linebreak-no-justifiables.png b/tests/ref/bugs/linebreak-no-justifiables.png deleted file mode 100644 index 3f934592a..000000000 Binary files a/tests/ref/bugs/linebreak-no-justifiables.png and /dev/null differ diff --git a/tests/ref/bugs/mat-aug-color.png b/tests/ref/bugs/mat-aug-color.png deleted file mode 100644 index 472c19686..000000000 Binary files a/tests/ref/bugs/mat-aug-color.png and /dev/null differ diff --git a/tests/ref/bugs/math-eval.png b/tests/ref/bugs/math-eval.png deleted file mode 100644 index b673e5039..000000000 Binary files a/tests/ref/bugs/math-eval.png and /dev/null differ diff --git a/tests/ref/bugs/math-hide.png b/tests/ref/bugs/math-hide.png deleted file mode 100644 index 7ac5d2f10..000000000 Binary files a/tests/ref/bugs/math-hide.png and /dev/null differ diff --git a/tests/ref/bugs/math-number-spacing.png b/tests/ref/bugs/math-number-spacing.png deleted file mode 100644 index 5ec65df30..000000000 Binary files a/tests/ref/bugs/math-number-spacing.png and /dev/null differ diff --git a/tests/ref/bugs/math-realize.png b/tests/ref/bugs/math-realize.png deleted file mode 100644 index e972e099c..000000000 Binary files a/tests/ref/bugs/math-realize.png and /dev/null differ diff --git a/tests/ref/bugs/math-shift.png b/tests/ref/bugs/math-shift.png deleted file mode 100644 index d6a2ef3b1..000000000 Binary files a/tests/ref/bugs/math-shift.png and /dev/null differ diff --git a/tests/ref/bugs/math-text-break.png b/tests/ref/bugs/math-text-break.png deleted file mode 100644 index 768ca65f6..000000000 Binary files a/tests/ref/bugs/math-text-break.png and /dev/null differ diff --git a/tests/ref/bugs/new-cm-svg.png b/tests/ref/bugs/new-cm-svg.png deleted file mode 100644 index d75a6dbb0..000000000 Binary files a/tests/ref/bugs/new-cm-svg.png and /dev/null differ diff --git a/tests/ref/bugs/newline-mode.png b/tests/ref/bugs/newline-mode.png deleted file mode 100644 index d4b6c6d85..000000000 Binary files a/tests/ref/bugs/newline-mode.png and /dev/null differ diff --git a/tests/ref/bugs/pagebreak-bibliography.png b/tests/ref/bugs/pagebreak-bibliography.png deleted file mode 100644 index 43de15744..000000000 Binary files a/tests/ref/bugs/pagebreak-bibliography.png and /dev/null differ diff --git a/tests/ref/bugs/pagebreak-numbering.png b/tests/ref/bugs/pagebreak-numbering.png deleted file mode 100644 index 96f047a88..000000000 Binary files a/tests/ref/bugs/pagebreak-numbering.png and /dev/null differ diff --git a/tests/ref/bugs/pagebreak-set-style.png b/tests/ref/bugs/pagebreak-set-style.png deleted file mode 100644 index f81b8c2f2..000000000 Binary files a/tests/ref/bugs/pagebreak-set-style.png and /dev/null differ diff --git a/tests/ref/bugs/place-base.png b/tests/ref/bugs/place-base.png deleted file mode 100644 index 4442b173c..000000000 Binary files a/tests/ref/bugs/place-base.png and /dev/null differ diff --git a/tests/ref/bugs/place-nested.png b/tests/ref/bugs/place-nested.png deleted file mode 100644 index b59dc5d3d..000000000 Binary files a/tests/ref/bugs/place-nested.png and /dev/null differ diff --git a/tests/ref/bugs/place-pagebreak.png b/tests/ref/bugs/place-pagebreak.png deleted file mode 100644 index 2aa3d6b00..000000000 Binary files a/tests/ref/bugs/place-pagebreak.png and /dev/null differ diff --git a/tests/ref/bugs/place-spacing.png b/tests/ref/bugs/place-spacing.png deleted file mode 100644 index d14ce6ec1..000000000 Binary files a/tests/ref/bugs/place-spacing.png and /dev/null differ diff --git a/tests/ref/bugs/raw-color-overwrite.png b/tests/ref/bugs/raw-color-overwrite.png deleted file mode 100644 index b01d86a49..000000000 Binary files a/tests/ref/bugs/raw-color-overwrite.png and /dev/null differ diff --git a/tests/ref/bugs/smartquotes-in-outline.png b/tests/ref/bugs/smartquotes-in-outline.png deleted file mode 100644 index 8a2cbc6ae..000000000 Binary files a/tests/ref/bugs/smartquotes-in-outline.png and /dev/null differ diff --git a/tests/ref/bugs/smartquotes-on-newline.png b/tests/ref/bugs/smartquotes-on-newline.png deleted file mode 100644 index fdf4623ad..000000000 Binary files a/tests/ref/bugs/smartquotes-on-newline.png and /dev/null differ diff --git a/tests/ref/bugs/spacing-behaviour.png b/tests/ref/bugs/spacing-behaviour.png deleted file mode 100644 index 08fcfa739..000000000 Binary files a/tests/ref/bugs/spacing-behaviour.png and /dev/null differ diff --git a/tests/ref/bugs/square-base.png b/tests/ref/bugs/square-base.png deleted file mode 100644 index 290ee54e5..000000000 Binary files a/tests/ref/bugs/square-base.png and /dev/null differ diff --git a/tests/ref/bugs/table-lines.png b/tests/ref/bugs/table-lines.png deleted file mode 100644 index 600391cb5..000000000 Binary files a/tests/ref/bugs/table-lines.png and /dev/null differ diff --git a/tests/ref/bugs/table-row-missing.png b/tests/ref/bugs/table-row-missing.png deleted file mode 100644 index 90c46d323..000000000 Binary files a/tests/ref/bugs/table-row-missing.png and /dev/null differ diff --git a/tests/ref/call-basic.png b/tests/ref/call-basic.png new file mode 100644 index 000000000..9016e9e8d Binary files /dev/null and b/tests/ref/call-basic.png differ diff --git a/tests/ref/circle-auto-sizing.png b/tests/ref/circle-auto-sizing.png new file mode 100644 index 000000000..377dbe1dd Binary files /dev/null and b/tests/ref/circle-auto-sizing.png differ diff --git a/tests/ref/circle-directly-in-rect.png b/tests/ref/circle-directly-in-rect.png new file mode 100644 index 000000000..cb74496d7 Binary files /dev/null and b/tests/ref/circle-directly-in-rect.png differ diff --git a/tests/ref/circle-relative-sizing.png b/tests/ref/circle-relative-sizing.png new file mode 100644 index 000000000..efff34cf9 Binary files /dev/null and b/tests/ref/circle-relative-sizing.png differ diff --git a/tests/ref/circle-sizing-options.png b/tests/ref/circle-sizing-options.png new file mode 100644 index 000000000..778a82495 Binary files /dev/null and b/tests/ref/circle-sizing-options.png differ diff --git a/tests/ref/circle.png b/tests/ref/circle.png new file mode 100644 index 000000000..8a86e1948 Binary files /dev/null and b/tests/ref/circle.png differ diff --git a/tests/ref/cite-footnote.png b/tests/ref/cite-footnote.png new file mode 100644 index 000000000..5bc6433e0 Binary files /dev/null and b/tests/ref/cite-footnote.png differ diff --git a/tests/ref/cite-form.png b/tests/ref/cite-form.png new file mode 100644 index 000000000..c35a35735 Binary files /dev/null and b/tests/ref/cite-form.png differ diff --git a/tests/ref/cite-group.png b/tests/ref/cite-group.png new file mode 100644 index 000000000..70feb4e1e Binary files /dev/null and b/tests/ref/cite-group.png differ diff --git a/tests/ref/cite-grouping-and-ordering.png b/tests/ref/cite-grouping-and-ordering.png new file mode 100644 index 000000000..6a70539db Binary files /dev/null and b/tests/ref/cite-grouping-and-ordering.png differ diff --git a/tests/ref/cjk-punctuation-adjustment-1.png b/tests/ref/cjk-punctuation-adjustment-1.png new file mode 100644 index 000000000..a68274cf3 Binary files /dev/null and b/tests/ref/cjk-punctuation-adjustment-1.png differ diff --git a/tests/ref/cjk-punctuation-adjustment-2.png b/tests/ref/cjk-punctuation-adjustment-2.png new file mode 100644 index 000000000..925c0f3c5 Binary files /dev/null and b/tests/ref/cjk-punctuation-adjustment-2.png differ diff --git a/tests/ref/cjk-punctuation-adjustment-3.png b/tests/ref/cjk-punctuation-adjustment-3.png new file mode 100644 index 000000000..e5eb70a94 Binary files /dev/null and b/tests/ref/cjk-punctuation-adjustment-3.png differ diff --git a/tests/ref/closure-capture-in-lvalue.png b/tests/ref/closure-capture-in-lvalue.png new file mode 100644 index 000000000..5f3ab0356 Binary files /dev/null and b/tests/ref/closure-capture-in-lvalue.png differ diff --git a/tests/ref/closure-path-resolve-in-layout-phase.png b/tests/ref/closure-path-resolve-in-layout-phase.png new file mode 100644 index 000000000..e56e23a02 Binary files /dev/null and b/tests/ref/closure-path-resolve-in-layout-phase.png differ diff --git a/tests/ref/closure-without-params-non-atomic.png b/tests/ref/closure-without-params-non-atomic.png new file mode 100644 index 000000000..7d01ea3cd Binary files /dev/null and b/tests/ref/closure-without-params-non-atomic.png differ diff --git a/tests/ref/code-block-basic-syntax.png b/tests/ref/code-block-basic-syntax.png new file mode 100644 index 000000000..7b2e6045e Binary files /dev/null and b/tests/ref/code-block-basic-syntax.png differ diff --git a/tests/ref/color-cmyk-ops.png b/tests/ref/color-cmyk-ops.png new file mode 100644 index 000000000..4f799efa1 Binary files /dev/null and b/tests/ref/color-cmyk-ops.png differ diff --git a/tests/ref/color-luma.png b/tests/ref/color-luma.png new file mode 100644 index 000000000..7bacc7443 Binary files /dev/null and b/tests/ref/color-luma.png differ diff --git a/tests/ref/color-outside-srgb-gamut.png b/tests/ref/color-outside-srgb-gamut.png new file mode 100644 index 000000000..3a2806c5d Binary files /dev/null and b/tests/ref/color-outside-srgb-gamut.png differ diff --git a/tests/ref/color-rotate-hue.png b/tests/ref/color-rotate-hue.png new file mode 100644 index 000000000..a21397141 Binary files /dev/null and b/tests/ref/color-rotate-hue.png differ diff --git a/tests/ref/color-saturation.png b/tests/ref/color-saturation.png new file mode 100644 index 000000000..ccac48287 Binary files /dev/null and b/tests/ref/color-saturation.png differ diff --git a/tests/ref/color-spaces.png b/tests/ref/color-spaces.png new file mode 100644 index 000000000..ade861ccb Binary files /dev/null and b/tests/ref/color-spaces.png differ diff --git a/tests/ref/columns-colbreak-after-place.png b/tests/ref/columns-colbreak-after-place.png new file mode 100644 index 000000000..f6a8a63dc Binary files /dev/null and b/tests/ref/columns-colbreak-after-place.png differ diff --git a/tests/ref/columns-empty-second-column.png b/tests/ref/columns-empty-second-column.png new file mode 100644 index 000000000..a00d5fb2a Binary files /dev/null and b/tests/ref/columns-empty-second-column.png differ diff --git a/tests/ref/columns-in-auto-sized-rect.png b/tests/ref/columns-in-auto-sized-rect.png new file mode 100644 index 000000000..00088b7eb Binary files /dev/null and b/tests/ref/columns-in-auto-sized-rect.png differ diff --git a/tests/ref/columns-in-fixed-size-rect.png b/tests/ref/columns-in-fixed-size-rect.png new file mode 100644 index 000000000..28cb97cb2 Binary files /dev/null and b/tests/ref/columns-in-fixed-size-rect.png differ diff --git a/tests/ref/columns-more-with-gutter.png b/tests/ref/columns-more-with-gutter.png new file mode 100644 index 000000000..e89c6a0b2 Binary files /dev/null and b/tests/ref/columns-more-with-gutter.png differ diff --git a/tests/ref/columns-one.png b/tests/ref/columns-one.png new file mode 100644 index 000000000..02abf6590 Binary files /dev/null and b/tests/ref/columns-one.png differ diff --git a/tests/ref/columns-page-height-auto.png b/tests/ref/columns-page-height-auto.png new file mode 100644 index 000000000..9b3f1f855 Binary files /dev/null and b/tests/ref/columns-page-height-auto.png differ diff --git a/tests/ref/columns-page-width-auto.png b/tests/ref/columns-page-width-auto.png new file mode 100644 index 000000000..04d88bc10 Binary files /dev/null and b/tests/ref/columns-page-width-auto.png differ diff --git a/tests/ref/columns-rtl.png b/tests/ref/columns-rtl.png new file mode 100644 index 000000000..7efa57f57 Binary files /dev/null and b/tests/ref/columns-rtl.png differ diff --git a/tests/ref/columns-set-page-colbreak-pagebreak.png b/tests/ref/columns-set-page-colbreak-pagebreak.png new file mode 100644 index 000000000..48d2fd7b1 Binary files /dev/null and b/tests/ref/columns-set-page-colbreak-pagebreak.png differ diff --git a/tests/ref/columns-set-page.png b/tests/ref/columns-set-page.png new file mode 100644 index 000000000..42b5bea70 Binary files /dev/null and b/tests/ref/columns-set-page.png differ diff --git a/tests/ref/coma.png b/tests/ref/coma.png index fc0f6ba1d..96f9e4d9b 100644 Binary files a/tests/ref/coma.png and b/tests/ref/coma.png differ diff --git a/tests/ref/comment-end-of-line.png b/tests/ref/comment-end-of-line.png new file mode 100644 index 000000000..94da23cb1 Binary files /dev/null and b/tests/ref/comment-end-of-line.png differ diff --git a/tests/ref/comments.png b/tests/ref/comments.png new file mode 100644 index 000000000..892ff5e47 Binary files /dev/null and b/tests/ref/comments.png differ diff --git a/tests/ref/compiler/array.png b/tests/ref/compiler/array.png deleted file mode 100644 index 9b6bf8b30..000000000 Binary files a/tests/ref/compiler/array.png and /dev/null differ diff --git a/tests/ref/compiler/block.png b/tests/ref/compiler/block.png deleted file mode 100644 index 21a38de2c..000000000 Binary files a/tests/ref/compiler/block.png and /dev/null differ diff --git a/tests/ref/compiler/break-continue.png b/tests/ref/compiler/break-continue.png deleted file mode 100644 index 9751d3951..000000000 Binary files a/tests/ref/compiler/break-continue.png and /dev/null differ diff --git a/tests/ref/compiler/call.png b/tests/ref/compiler/call.png deleted file mode 100644 index 2c5d1e78f..000000000 Binary files a/tests/ref/compiler/call.png and /dev/null differ diff --git a/tests/ref/compiler/closure.png b/tests/ref/compiler/closure.png deleted file mode 100644 index 07c171c58..000000000 Binary files a/tests/ref/compiler/closure.png and /dev/null differ diff --git a/tests/ref/compiler/color.png b/tests/ref/compiler/color.png deleted file mode 100644 index 2b416f641..000000000 Binary files a/tests/ref/compiler/color.png and /dev/null differ diff --git a/tests/ref/compiler/comment.png b/tests/ref/compiler/comment.png deleted file mode 100644 index 608df6eae..000000000 Binary files a/tests/ref/compiler/comment.png and /dev/null differ diff --git a/tests/ref/compiler/construct.png b/tests/ref/compiler/construct.png deleted file mode 100644 index f1acf6654..000000000 Binary files a/tests/ref/compiler/construct.png and /dev/null differ diff --git a/tests/ref/compiler/content-field.png b/tests/ref/compiler/content-field.png deleted file mode 100644 index d582cfa19..000000000 Binary files a/tests/ref/compiler/content-field.png and /dev/null differ diff --git a/tests/ref/compiler/dict.png b/tests/ref/compiler/dict.png deleted file mode 100644 index c97b2dbf3..000000000 Binary files a/tests/ref/compiler/dict.png and /dev/null differ diff --git a/tests/ref/compiler/for.png b/tests/ref/compiler/for.png deleted file mode 100644 index 5608248f8..000000000 Binary files a/tests/ref/compiler/for.png and /dev/null differ diff --git a/tests/ref/compiler/highlight.png b/tests/ref/compiler/highlight.png deleted file mode 100644 index ccbbc0560..000000000 Binary files a/tests/ref/compiler/highlight.png and /dev/null differ diff --git a/tests/ref/compiler/if.png b/tests/ref/compiler/if.png deleted file mode 100644 index bd3adc88b..000000000 Binary files a/tests/ref/compiler/if.png and /dev/null differ diff --git a/tests/ref/compiler/import.png b/tests/ref/compiler/import.png deleted file mode 100644 index 5c6132d2f..000000000 Binary files a/tests/ref/compiler/import.png and /dev/null differ diff --git a/tests/ref/compiler/include.png b/tests/ref/compiler/include.png deleted file mode 100644 index 7fdb0310b..000000000 Binary files a/tests/ref/compiler/include.png and /dev/null differ diff --git a/tests/ref/compiler/label.png b/tests/ref/compiler/label.png deleted file mode 100644 index 21764f978..000000000 Binary files a/tests/ref/compiler/label.png and /dev/null differ diff --git a/tests/ref/compiler/let.png b/tests/ref/compiler/let.png deleted file mode 100644 index 4423fe0a3..000000000 Binary files a/tests/ref/compiler/let.png and /dev/null differ diff --git a/tests/ref/compiler/ops.png b/tests/ref/compiler/ops.png deleted file mode 100644 index 51fb9d1a5..000000000 Binary files a/tests/ref/compiler/ops.png and /dev/null differ diff --git a/tests/ref/compiler/repr-color-gradient.png b/tests/ref/compiler/repr-color-gradient.png deleted file mode 100644 index 11bde774e..000000000 Binary files a/tests/ref/compiler/repr-color-gradient.png and /dev/null differ diff --git a/tests/ref/compiler/repr.png b/tests/ref/compiler/repr.png deleted file mode 100644 index 105b6c80b..000000000 Binary files a/tests/ref/compiler/repr.png and /dev/null differ diff --git a/tests/ref/compiler/return.png b/tests/ref/compiler/return.png deleted file mode 100644 index e8fa3ab2b..000000000 Binary files a/tests/ref/compiler/return.png and /dev/null differ diff --git a/tests/ref/compiler/select-where-styles.png b/tests/ref/compiler/select-where-styles.png deleted file mode 100644 index ffdc4babf..000000000 Binary files a/tests/ref/compiler/select-where-styles.png and /dev/null differ diff --git a/tests/ref/compiler/selector-logical.png b/tests/ref/compiler/selector-logical.png deleted file mode 100644 index eafa93c81..000000000 Binary files a/tests/ref/compiler/selector-logical.png and /dev/null differ diff --git a/tests/ref/compiler/set.png b/tests/ref/compiler/set.png deleted file mode 100644 index 264093968..000000000 Binary files a/tests/ref/compiler/set.png and /dev/null differ diff --git a/tests/ref/compiler/shorthand.png b/tests/ref/compiler/shorthand.png deleted file mode 100644 index 4507177bc..000000000 Binary files a/tests/ref/compiler/shorthand.png and /dev/null differ diff --git a/tests/ref/compiler/show-bare.png b/tests/ref/compiler/show-bare.png deleted file mode 100644 index c6a1e1013..000000000 Binary files a/tests/ref/compiler/show-bare.png and /dev/null differ diff --git a/tests/ref/compiler/show-node.png b/tests/ref/compiler/show-node.png deleted file mode 100644 index 396e5429e..000000000 Binary files a/tests/ref/compiler/show-node.png and /dev/null differ diff --git a/tests/ref/compiler/show-recursive.png b/tests/ref/compiler/show-recursive.png deleted file mode 100644 index a5a153c07..000000000 Binary files a/tests/ref/compiler/show-recursive.png and /dev/null differ diff --git a/tests/ref/compiler/show-selector-logical.png b/tests/ref/compiler/show-selector-logical.png deleted file mode 100644 index a7a800530..000000000 Binary files a/tests/ref/compiler/show-selector-logical.png and /dev/null differ diff --git a/tests/ref/compiler/show-selector.png b/tests/ref/compiler/show-selector.png deleted file mode 100644 index 52e99c9ac..000000000 Binary files a/tests/ref/compiler/show-selector.png and /dev/null differ diff --git a/tests/ref/compiler/show-set-func.png b/tests/ref/compiler/show-set-func.png deleted file mode 100644 index c5ff24893..000000000 Binary files a/tests/ref/compiler/show-set-func.png and /dev/null differ diff --git a/tests/ref/compiler/show-set-text.png b/tests/ref/compiler/show-set-text.png deleted file mode 100644 index 27803e8a4..000000000 Binary files a/tests/ref/compiler/show-set-text.png and /dev/null differ diff --git a/tests/ref/compiler/show-set.png b/tests/ref/compiler/show-set.png deleted file mode 100644 index e87fc6002..000000000 Binary files a/tests/ref/compiler/show-set.png and /dev/null differ diff --git a/tests/ref/compiler/show-text.png b/tests/ref/compiler/show-text.png deleted file mode 100644 index 2026cc35c..000000000 Binary files a/tests/ref/compiler/show-text.png and /dev/null differ diff --git a/tests/ref/compiler/while.png b/tests/ref/compiler/while.png deleted file mode 100644 index d0f864736..000000000 Binary files a/tests/ref/compiler/while.png and /dev/null differ diff --git a/tests/ref/compute/construct.png b/tests/ref/compute/construct.png deleted file mode 100644 index e17174733..000000000 Binary files a/tests/ref/compute/construct.png and /dev/null differ diff --git a/tests/ref/compute/data.png b/tests/ref/compute/data.png deleted file mode 100644 index 2dab6875b..000000000 Binary files a/tests/ref/compute/data.png and /dev/null differ diff --git a/tests/ref/compute/eval-path.png b/tests/ref/compute/eval-path.png deleted file mode 100644 index c59dd2aa4..000000000 Binary files a/tests/ref/compute/eval-path.png and /dev/null differ diff --git a/tests/ref/compute/foundations.png b/tests/ref/compute/foundations.png deleted file mode 100644 index 5d6ba7441..000000000 Binary files a/tests/ref/compute/foundations.png and /dev/null differ diff --git a/tests/ref/content-field-materialized-heading.png b/tests/ref/content-field-materialized-heading.png new file mode 100644 index 000000000..722016278 Binary files /dev/null and b/tests/ref/content-field-materialized-heading.png differ diff --git a/tests/ref/content-field-materialized-query.png b/tests/ref/content-field-materialized-query.png new file mode 100644 index 000000000..2d2a14806 Binary files /dev/null and b/tests/ref/content-field-materialized-query.png differ diff --git a/tests/ref/content-field-materialized-table.png b/tests/ref/content-field-materialized-table.png new file mode 100644 index 000000000..9eceec8f6 Binary files /dev/null and b/tests/ref/content-field-materialized-table.png differ diff --git a/tests/ref/content-fields-complex.png b/tests/ref/content-fields-complex.png new file mode 100644 index 000000000..624a8b332 Binary files /dev/null and b/tests/ref/content-fields-complex.png differ diff --git a/tests/ref/content-label-field-access.png b/tests/ref/content-label-field-access.png new file mode 100644 index 000000000..bdb7c0f2f Binary files /dev/null and b/tests/ref/content-label-field-access.png differ diff --git a/tests/ref/content-label-fields-method.png b/tests/ref/content-label-fields-method.png new file mode 100644 index 000000000..bdb7c0f2f Binary files /dev/null and b/tests/ref/content-label-fields-method.png differ diff --git a/tests/ref/content-label-has-method.png b/tests/ref/content-label-has-method.png new file mode 100644 index 000000000..bdb7c0f2f Binary files /dev/null and b/tests/ref/content-label-has-method.png differ diff --git a/tests/ref/context-compatibility-locate.png b/tests/ref/context-compatibility-locate.png new file mode 100644 index 000000000..4c8944ab4 Binary files /dev/null and b/tests/ref/context-compatibility-locate.png differ diff --git a/tests/ref/context-compatibility-styling.png b/tests/ref/context-compatibility-styling.png new file mode 100644 index 000000000..aee16c3ab Binary files /dev/null and b/tests/ref/context-compatibility-styling.png differ diff --git a/tests/ref/counter-basic-1.png b/tests/ref/counter-basic-1.png new file mode 100644 index 000000000..922825948 Binary files /dev/null and b/tests/ref/counter-basic-1.png differ diff --git a/tests/ref/counter-figure.png b/tests/ref/counter-figure.png new file mode 100644 index 000000000..5e4a4a5f3 Binary files /dev/null and b/tests/ref/counter-figure.png differ diff --git a/tests/ref/counter-heading.png b/tests/ref/counter-heading.png new file mode 100644 index 000000000..96dafd6ad Binary files /dev/null and b/tests/ref/counter-heading.png differ diff --git a/tests/ref/counter-label.png b/tests/ref/counter-label.png new file mode 100644 index 000000000..6fea90df7 Binary files /dev/null and b/tests/ref/counter-label.png differ diff --git a/tests/ref/counter-page.png b/tests/ref/counter-page.png new file mode 100644 index 000000000..be1653ebd Binary files /dev/null and b/tests/ref/counter-page.png differ diff --git a/tests/ref/csv.png b/tests/ref/csv.png new file mode 100644 index 000000000..fd0c9a1cd Binary files /dev/null and b/tests/ref/csv.png differ diff --git a/tests/ref/destructuring-during-loop-continue.png b/tests/ref/destructuring-during-loop-continue.png new file mode 100644 index 000000000..9ea8e3c1f Binary files /dev/null and b/tests/ref/destructuring-during-loop-continue.png differ diff --git a/tests/ref/dict-basic-methods.png b/tests/ref/dict-basic-methods.png new file mode 100644 index 000000000..20410cc3b Binary files /dev/null and b/tests/ref/dict-basic-methods.png differ diff --git a/tests/ref/dict-basic-syntax.png b/tests/ref/dict-basic-syntax.png new file mode 100644 index 000000000..02effef67 Binary files /dev/null and b/tests/ref/dict-basic-syntax.png differ diff --git a/tests/ref/dict-from-module.png b/tests/ref/dict-from-module.png new file mode 100644 index 000000000..7fd6eec36 Binary files /dev/null and b/tests/ref/dict-from-module.png differ diff --git a/tests/ref/dict-remove-order.png b/tests/ref/dict-remove-order.png new file mode 100644 index 000000000..20410cc3b Binary files /dev/null and b/tests/ref/dict-remove-order.png differ diff --git a/tests/ref/document-set-title.png b/tests/ref/document-set-title.png new file mode 100644 index 000000000..74bcfe191 Binary files /dev/null and b/tests/ref/document-set-title.png differ diff --git a/tests/ref/ellipse-auto-sizing.png b/tests/ref/ellipse-auto-sizing.png new file mode 100644 index 000000000..ed2015215 Binary files /dev/null and b/tests/ref/ellipse-auto-sizing.png differ diff --git a/tests/ref/ellipse.png b/tests/ref/ellipse.png new file mode 100644 index 000000000..0f4e92cac Binary files /dev/null and b/tests/ref/ellipse.png differ diff --git a/tests/ref/emph-and-strong-call-in-word.png b/tests/ref/emph-and-strong-call-in-word.png new file mode 100644 index 000000000..4720f9949 Binary files /dev/null and b/tests/ref/emph-and-strong-call-in-word.png differ diff --git a/tests/ref/emph-double-underscore-empty-hint.png b/tests/ref/emph-double-underscore-empty-hint.png new file mode 100644 index 000000000..a940dfb6a Binary files /dev/null and b/tests/ref/emph-double-underscore-empty-hint.png differ diff --git a/tests/ref/emph-syntax.png b/tests/ref/emph-syntax.png new file mode 100644 index 000000000..66f117a8e Binary files /dev/null and b/tests/ref/emph-syntax.png differ diff --git a/tests/ref/empty.png b/tests/ref/empty.png deleted file mode 100644 index db3a66950..000000000 Binary files a/tests/ref/empty.png and /dev/null differ diff --git a/tests/ref/enum-built-in-loop.png b/tests/ref/enum-built-in-loop.png new file mode 100644 index 000000000..298518da3 Binary files /dev/null and b/tests/ref/enum-built-in-loop.png differ diff --git a/tests/ref/enum-function-call.png b/tests/ref/enum-function-call.png new file mode 100644 index 000000000..a451f27c7 Binary files /dev/null and b/tests/ref/enum-function-call.png differ diff --git a/tests/ref/enum-number-align-2d.png b/tests/ref/enum-number-align-2d.png new file mode 100644 index 000000000..e205844ff Binary files /dev/null and b/tests/ref/enum-number-align-2d.png differ diff --git a/tests/ref/enum-number-align-default.png b/tests/ref/enum-number-align-default.png new file mode 100644 index 000000000..c47f9001a Binary files /dev/null and b/tests/ref/enum-number-align-default.png differ diff --git a/tests/ref/enum-number-align-specified.png b/tests/ref/enum-number-align-specified.png new file mode 100644 index 000000000..b2f2d619a Binary files /dev/null and b/tests/ref/enum-number-align-specified.png differ diff --git a/tests/ref/enum-number-align-unaffected.png b/tests/ref/enum-number-align-unaffected.png new file mode 100644 index 000000000..3abcaaab7 Binary files /dev/null and b/tests/ref/enum-number-align-unaffected.png differ diff --git a/tests/ref/enum-number-align-unfolded.png b/tests/ref/enum-number-align-unfolded.png new file mode 100644 index 000000000..8c4f29433 Binary files /dev/null and b/tests/ref/enum-number-align-unfolded.png differ diff --git a/tests/ref/enum-number-override-nested.png b/tests/ref/enum-number-override-nested.png new file mode 100644 index 000000000..22bb7611e Binary files /dev/null and b/tests/ref/enum-number-override-nested.png differ diff --git a/tests/ref/enum-number-override.png b/tests/ref/enum-number-override.png new file mode 100644 index 000000000..65c0f9d84 Binary files /dev/null and b/tests/ref/enum-number-override.png differ diff --git a/tests/ref/enum-numbering-closure-nested-complex.png b/tests/ref/enum-numbering-closure-nested-complex.png new file mode 100644 index 000000000..a756f37cd Binary files /dev/null and b/tests/ref/enum-numbering-closure-nested-complex.png differ diff --git a/tests/ref/enum-numbering-closure-nested.png b/tests/ref/enum-numbering-closure-nested.png new file mode 100644 index 000000000..25a5c42d5 Binary files /dev/null and b/tests/ref/enum-numbering-closure-nested.png differ diff --git a/tests/ref/enum-numbering-closure.png b/tests/ref/enum-numbering-closure.png new file mode 100644 index 000000000..bf86f5541 Binary files /dev/null and b/tests/ref/enum-numbering-closure.png differ diff --git a/tests/ref/enum-numbering-full.png b/tests/ref/enum-numbering-full.png new file mode 100644 index 000000000..46449e573 Binary files /dev/null and b/tests/ref/enum-numbering-full.png differ diff --git a/tests/ref/enum-numbering-pattern.png b/tests/ref/enum-numbering-pattern.png new file mode 100644 index 000000000..4ecb9e4a2 Binary files /dev/null and b/tests/ref/enum-numbering-pattern.png differ diff --git a/tests/ref/enum-syntax-at-start.png b/tests/ref/enum-syntax-at-start.png new file mode 100644 index 000000000..ce9f3967e Binary files /dev/null and b/tests/ref/enum-syntax-at-start.png differ diff --git a/tests/ref/enum-syntax-edge-cases.png b/tests/ref/enum-syntax-edge-cases.png new file mode 100644 index 000000000..496dc8e3d Binary files /dev/null and b/tests/ref/enum-syntax-edge-cases.png differ diff --git a/tests/ref/escape.png b/tests/ref/escape.png new file mode 100644 index 000000000..0b49606ca Binary files /dev/null and b/tests/ref/escape.png differ diff --git a/tests/ref/eval-in-show-rule.png b/tests/ref/eval-in-show-rule.png new file mode 100644 index 000000000..91a038683 Binary files /dev/null and b/tests/ref/eval-in-show-rule.png differ diff --git a/tests/ref/eval-mode.png b/tests/ref/eval-mode.png new file mode 100644 index 000000000..94357ff4f Binary files /dev/null and b/tests/ref/eval-mode.png differ diff --git a/tests/ref/eval-path-resolve-in-show-rule.png b/tests/ref/eval-path-resolve-in-show-rule.png new file mode 100644 index 000000000..cf5c183ad Binary files /dev/null and b/tests/ref/eval-path-resolve-in-show-rule.png differ diff --git a/tests/ref/eval-path-resolve.png b/tests/ref/eval-path-resolve.png new file mode 100644 index 000000000..cf5c183ad Binary files /dev/null and b/tests/ref/eval-path-resolve.png differ diff --git a/tests/ref/field-function.png b/tests/ref/field-function.png new file mode 100644 index 000000000..261fb3957 Binary files /dev/null and b/tests/ref/field-function.png differ diff --git a/tests/ref/figure-and-caption-show.png b/tests/ref/figure-and-caption-show.png new file mode 100644 index 000000000..daf8f2b62 Binary files /dev/null and b/tests/ref/figure-and-caption-show.png differ diff --git a/tests/ref/figure-basic.png b/tests/ref/figure-basic.png new file mode 100644 index 000000000..22a841db5 Binary files /dev/null and b/tests/ref/figure-basic.png differ diff --git a/tests/ref/figure-breakable.png b/tests/ref/figure-breakable.png new file mode 100644 index 000000000..40cb3ec57 Binary files /dev/null and b/tests/ref/figure-breakable.png differ diff --git a/tests/ref/figure-caption-separator.png b/tests/ref/figure-caption-separator.png new file mode 100644 index 000000000..e645f01fe Binary files /dev/null and b/tests/ref/figure-caption-separator.png differ diff --git a/tests/ref/figure-caption-show.png b/tests/ref/figure-caption-show.png new file mode 100644 index 000000000..4ed6443ac Binary files /dev/null and b/tests/ref/figure-caption-show.png differ diff --git a/tests/ref/figure-caption-where-selector.png b/tests/ref/figure-caption-where-selector.png new file mode 100644 index 000000000..08eb46f60 Binary files /dev/null and b/tests/ref/figure-caption-where-selector.png differ diff --git a/tests/ref/figure-localization-fr.png b/tests/ref/figure-localization-fr.png new file mode 100644 index 000000000..665b35522 Binary files /dev/null and b/tests/ref/figure-localization-fr.png differ diff --git a/tests/ref/figure-localization-gr.png b/tests/ref/figure-localization-gr.png new file mode 100644 index 000000000..46b52b051 Binary files /dev/null and b/tests/ref/figure-localization-gr.png differ diff --git a/tests/ref/figure-localization-ru.png b/tests/ref/figure-localization-ru.png new file mode 100644 index 000000000..102df5971 Binary files /dev/null and b/tests/ref/figure-localization-ru.png differ diff --git a/tests/ref/figure-localization-zh.png b/tests/ref/figure-localization-zh.png new file mode 100644 index 000000000..f7625b1b4 Binary files /dev/null and b/tests/ref/figure-localization-zh.png differ diff --git a/tests/ref/figure-table.png b/tests/ref/figure-table.png new file mode 100644 index 000000000..9a09f6590 Binary files /dev/null and b/tests/ref/figure-table.png differ diff --git a/tests/ref/figure-theorem.png b/tests/ref/figure-theorem.png new file mode 100644 index 000000000..10d6eeacb Binary files /dev/null and b/tests/ref/figure-theorem.png differ diff --git a/tests/ref/float-display.png b/tests/ref/float-display.png new file mode 100644 index 000000000..6c33b372f Binary files /dev/null and b/tests/ref/float-display.png differ diff --git a/tests/ref/float-repr.png b/tests/ref/float-repr.png new file mode 100644 index 000000000..8b5109697 Binary files /dev/null and b/tests/ref/float-repr.png differ diff --git a/tests/ref/flow-first-region-counter-update-and-placed.png b/tests/ref/flow-first-region-counter-update-and-placed.png new file mode 100644 index 000000000..213167199 Binary files /dev/null and b/tests/ref/flow-first-region-counter-update-and-placed.png differ diff --git a/tests/ref/flow-first-region-counter-update-placed-and-line.png b/tests/ref/flow-first-region-counter-update-placed-and-line.png new file mode 100644 index 000000000..95ca518e4 Binary files /dev/null and b/tests/ref/flow-first-region-counter-update-placed-and-line.png differ diff --git a/tests/ref/flow-first-region-counter-update.png b/tests/ref/flow-first-region-counter-update.png new file mode 100644 index 000000000..8e883335a Binary files /dev/null and b/tests/ref/flow-first-region-counter-update.png differ diff --git a/tests/ref/flow-first-region-no-item.png b/tests/ref/flow-first-region-no-item.png new file mode 100644 index 000000000..e888898c0 Binary files /dev/null and b/tests/ref/flow-first-region-no-item.png differ diff --git a/tests/ref/flow-first-region-placed.png b/tests/ref/flow-first-region-placed.png new file mode 100644 index 000000000..cae4aa32f Binary files /dev/null and b/tests/ref/flow-first-region-placed.png differ diff --git a/tests/ref/flow-first-region-zero-sized-item.png b/tests/ref/flow-first-region-zero-sized-item.png new file mode 100644 index 000000000..2e75fcfe7 Binary files /dev/null and b/tests/ref/flow-first-region-zero-sized-item.png differ diff --git a/tests/ref/flow-fr.png b/tests/ref/flow-fr.png new file mode 100644 index 000000000..b09a96042 Binary files /dev/null and b/tests/ref/flow-fr.png differ diff --git a/tests/ref/flow-heading-no-orphan.png b/tests/ref/flow-heading-no-orphan.png new file mode 100644 index 000000000..87789ea11 Binary files /dev/null and b/tests/ref/flow-heading-no-orphan.png differ diff --git a/tests/ref/flow-par-no-orphan-and-widow-lines.png b/tests/ref/flow-par-no-orphan-and-widow-lines.png new file mode 100644 index 000000000..cace5d448 Binary files /dev/null and b/tests/ref/flow-par-no-orphan-and-widow-lines.png differ diff --git a/tests/ref/fold-vec-order-meta.png b/tests/ref/fold-vec-order-meta.png new file mode 100644 index 000000000..36e3cd515 Binary files /dev/null and b/tests/ref/fold-vec-order-meta.png differ diff --git a/tests/ref/fold-vec-order-text-decos.png b/tests/ref/fold-vec-order-text-decos.png new file mode 100644 index 000000000..62c9e1af9 Binary files /dev/null and b/tests/ref/fold-vec-order-text-decos.png differ diff --git a/tests/ref/fold-vec-order-text-features.png b/tests/ref/fold-vec-order-text-features.png new file mode 100644 index 000000000..f2ff6f25a Binary files /dev/null and b/tests/ref/fold-vec-order-text-features.png differ diff --git a/tests/ref/footnote-basic.png b/tests/ref/footnote-basic.png new file mode 100644 index 000000000..3562438bd Binary files /dev/null and b/tests/ref/footnote-basic.png differ diff --git a/tests/ref/footnote-break-across-pages.png b/tests/ref/footnote-break-across-pages.png new file mode 100644 index 000000000..8ec55418c Binary files /dev/null and b/tests/ref/footnote-break-across-pages.png differ diff --git a/tests/ref/footnote-duplicate.png b/tests/ref/footnote-duplicate.png new file mode 100644 index 000000000..7c83b8de6 Binary files /dev/null and b/tests/ref/footnote-duplicate.png differ diff --git a/tests/ref/footnote-entry.png b/tests/ref/footnote-entry.png new file mode 100644 index 000000000..e62315c46 Binary files /dev/null and b/tests/ref/footnote-entry.png differ diff --git a/tests/ref/footnote-in-caption.png b/tests/ref/footnote-in-caption.png new file mode 100644 index 000000000..8d548c596 Binary files /dev/null and b/tests/ref/footnote-in-caption.png differ diff --git a/tests/ref/footnote-in-columns.png b/tests/ref/footnote-in-columns.png new file mode 100644 index 000000000..e16b4ebcf Binary files /dev/null and b/tests/ref/footnote-in-columns.png differ diff --git a/tests/ref/footnote-in-table.png b/tests/ref/footnote-in-table.png new file mode 100644 index 000000000..0fd0acc7f Binary files /dev/null and b/tests/ref/footnote-in-table.png differ diff --git a/tests/ref/footnote-invariant.png b/tests/ref/footnote-invariant.png new file mode 100644 index 000000000..c49c268d4 Binary files /dev/null and b/tests/ref/footnote-invariant.png differ diff --git a/tests/ref/footnote-nested-same-frame.png b/tests/ref/footnote-nested-same-frame.png new file mode 100644 index 000000000..b22276d5c Binary files /dev/null and b/tests/ref/footnote-nested-same-frame.png differ diff --git a/tests/ref/footnote-nested.png b/tests/ref/footnote-nested.png new file mode 100644 index 000000000..fecf2e8de Binary files /dev/null and b/tests/ref/footnote-nested.png differ diff --git a/tests/ref/footnote-ref-call.png b/tests/ref/footnote-ref-call.png new file mode 100644 index 000000000..3c795302e Binary files /dev/null and b/tests/ref/footnote-ref-call.png differ diff --git a/tests/ref/footnote-ref-forward.png b/tests/ref/footnote-ref-forward.png new file mode 100644 index 000000000..e67671bec Binary files /dev/null and b/tests/ref/footnote-ref-forward.png differ diff --git a/tests/ref/footnote-ref-in-footnote.png b/tests/ref/footnote-ref-in-footnote.png new file mode 100644 index 000000000..4718a0887 Binary files /dev/null and b/tests/ref/footnote-ref-in-footnote.png differ diff --git a/tests/ref/footnote-ref-multiple.png b/tests/ref/footnote-ref-multiple.png new file mode 100644 index 000000000..fc6f11cf5 Binary files /dev/null and b/tests/ref/footnote-ref-multiple.png differ diff --git a/tests/ref/footnote-ref.png b/tests/ref/footnote-ref.png new file mode 100644 index 000000000..517d997aa Binary files /dev/null and b/tests/ref/footnote-ref.png differ diff --git a/tests/ref/footnote-space-collapsing.png b/tests/ref/footnote-space-collapsing.png new file mode 100644 index 000000000..d7d02704d Binary files /dev/null and b/tests/ref/footnote-space-collapsing.png differ diff --git a/tests/ref/footnote-styling.png b/tests/ref/footnote-styling.png new file mode 100644 index 000000000..fd7684af7 Binary files /dev/null and b/tests/ref/footnote-styling.png differ diff --git a/tests/ref/for-loop-basic.png b/tests/ref/for-loop-basic.png new file mode 100644 index 000000000..42d611eff Binary files /dev/null and b/tests/ref/for-loop-basic.png differ diff --git a/tests/ref/gradient-conic-angled.png b/tests/ref/gradient-conic-angled.png new file mode 100644 index 000000000..163366e6c Binary files /dev/null and b/tests/ref/gradient-conic-angled.png differ diff --git a/tests/ref/gradient-conic-center-shifted-1.png b/tests/ref/gradient-conic-center-shifted-1.png new file mode 100644 index 000000000..5964b124a Binary files /dev/null and b/tests/ref/gradient-conic-center-shifted-1.png differ diff --git a/tests/ref/gradient-conic-center-shifted-2.png b/tests/ref/gradient-conic-center-shifted-2.png new file mode 100644 index 000000000..53e5da982 Binary files /dev/null and b/tests/ref/gradient-conic-center-shifted-2.png differ diff --git a/tests/ref/gradient-conic-hsl.png b/tests/ref/gradient-conic-hsl.png new file mode 100644 index 000000000..321a3b07c Binary files /dev/null and b/tests/ref/gradient-conic-hsl.png differ diff --git a/tests/ref/gradient-conic-hsv.png b/tests/ref/gradient-conic-hsv.png new file mode 100644 index 000000000..648e1fb50 Binary files /dev/null and b/tests/ref/gradient-conic-hsv.png differ diff --git a/tests/ref/gradient-conic-oklab.png b/tests/ref/gradient-conic-oklab.png new file mode 100644 index 000000000..e567eacc1 Binary files /dev/null and b/tests/ref/gradient-conic-oklab.png differ diff --git a/tests/ref/gradient-conic-oklch.png b/tests/ref/gradient-conic-oklch.png new file mode 100644 index 000000000..f712defab Binary files /dev/null and b/tests/ref/gradient-conic-oklch.png differ diff --git a/tests/ref/gradient-conic-relative-parent.png b/tests/ref/gradient-conic-relative-parent.png new file mode 100644 index 000000000..1685ca446 Binary files /dev/null and b/tests/ref/gradient-conic-relative-parent.png differ diff --git a/tests/ref/gradient-conic-relative-self.png b/tests/ref/gradient-conic-relative-self.png new file mode 100644 index 000000000..108fe43a6 Binary files /dev/null and b/tests/ref/gradient-conic-relative-self.png differ diff --git a/tests/ref/gradient-conic-stroke.png b/tests/ref/gradient-conic-stroke.png new file mode 100644 index 000000000..ae631fd4f Binary files /dev/null and b/tests/ref/gradient-conic-stroke.png differ diff --git a/tests/ref/gradient-conic-text.png b/tests/ref/gradient-conic-text.png new file mode 100644 index 000000000..1abef3cb8 Binary files /dev/null and b/tests/ref/gradient-conic-text.png differ diff --git a/tests/ref/gradient-conic.png b/tests/ref/gradient-conic.png new file mode 100644 index 000000000..0f5f5bada Binary files /dev/null and b/tests/ref/gradient-conic.png differ diff --git a/tests/ref/gradient-fill-and-stroke.png b/tests/ref/gradient-fill-and-stroke.png new file mode 100644 index 000000000..785635171 Binary files /dev/null and b/tests/ref/gradient-fill-and-stroke.png differ diff --git a/tests/ref/gradient-linear-angled.png b/tests/ref/gradient-linear-angled.png new file mode 100644 index 000000000..b195b1281 Binary files /dev/null and b/tests/ref/gradient-linear-angled.png differ diff --git a/tests/ref/gradient-linear-hsl.png b/tests/ref/gradient-linear-hsl.png new file mode 100644 index 000000000..7bfe958bf Binary files /dev/null and b/tests/ref/gradient-linear-hsl.png differ diff --git a/tests/ref/gradient-linear-hsv.png b/tests/ref/gradient-linear-hsv.png new file mode 100644 index 000000000..56b446f28 Binary files /dev/null and b/tests/ref/gradient-linear-hsv.png differ diff --git a/tests/ref/gradient-linear-line.png b/tests/ref/gradient-linear-line.png new file mode 100644 index 000000000..d32aba892 Binary files /dev/null and b/tests/ref/gradient-linear-line.png differ diff --git a/tests/ref/gradient-linear-oklab.png b/tests/ref/gradient-linear-oklab.png new file mode 100644 index 000000000..6f963c772 Binary files /dev/null and b/tests/ref/gradient-linear-oklab.png differ diff --git a/tests/ref/gradient-linear-oklch.png b/tests/ref/gradient-linear-oklch.png new file mode 100644 index 000000000..394d0935e Binary files /dev/null and b/tests/ref/gradient-linear-oklch.png differ diff --git a/tests/ref/gradient-linear-relative-parent.png b/tests/ref/gradient-linear-relative-parent.png new file mode 100644 index 000000000..2ad1286e8 Binary files /dev/null and b/tests/ref/gradient-linear-relative-parent.png differ diff --git a/tests/ref/gradient-linear-relative-self.png b/tests/ref/gradient-linear-relative-self.png new file mode 100644 index 000000000..d573a892f Binary files /dev/null and b/tests/ref/gradient-linear-relative-self.png differ diff --git a/tests/ref/gradient-linear-repeat-and-mirror-1.png b/tests/ref/gradient-linear-repeat-and-mirror-1.png new file mode 100644 index 000000000..9640d5e20 Binary files /dev/null and b/tests/ref/gradient-linear-repeat-and-mirror-1.png differ diff --git a/tests/ref/gradient-linear-repeat-and-mirror-2.png b/tests/ref/gradient-linear-repeat-and-mirror-2.png new file mode 100644 index 000000000..98cf25434 Binary files /dev/null and b/tests/ref/gradient-linear-repeat-and-mirror-2.png differ diff --git a/tests/ref/gradient-linear-repeat-and-mirror-3.png b/tests/ref/gradient-linear-repeat-and-mirror-3.png new file mode 100644 index 000000000..641e54c9c Binary files /dev/null and b/tests/ref/gradient-linear-repeat-and-mirror-3.png differ diff --git a/tests/ref/gradient-linear-sharp-and-repeat.png b/tests/ref/gradient-linear-sharp-and-repeat.png new file mode 100644 index 000000000..e46af7a05 Binary files /dev/null and b/tests/ref/gradient-linear-sharp-and-repeat.png differ diff --git a/tests/ref/gradient-linear-sharp-and-smooth.png b/tests/ref/gradient-linear-sharp-and-smooth.png new file mode 100644 index 000000000..5bd74d247 Binary files /dev/null and b/tests/ref/gradient-linear-sharp-and-smooth.png differ diff --git a/tests/ref/gradient-linear-sharp-repeat-and-mirror.png b/tests/ref/gradient-linear-sharp-repeat-and-mirror.png new file mode 100644 index 000000000..5b4b9817b Binary files /dev/null and b/tests/ref/gradient-linear-sharp-repeat-and-mirror.png differ diff --git a/tests/ref/gradient-linear-sharp.png b/tests/ref/gradient-linear-sharp.png new file mode 100644 index 000000000..4d63884f7 Binary files /dev/null and b/tests/ref/gradient-linear-sharp.png differ diff --git a/tests/ref/gradient-linear-stroke.png b/tests/ref/gradient-linear-stroke.png new file mode 100644 index 000000000..490ffec26 Binary files /dev/null and b/tests/ref/gradient-linear-stroke.png differ diff --git a/tests/ref/gradient-math-cancel.png b/tests/ref/gradient-math-cancel.png new file mode 100644 index 000000000..0769d6d36 Binary files /dev/null and b/tests/ref/gradient-math-cancel.png differ diff --git a/tests/ref/gradient-math-conic.png b/tests/ref/gradient-math-conic.png new file mode 100644 index 000000000..88ff7a85c Binary files /dev/null and b/tests/ref/gradient-math-conic.png differ diff --git a/tests/ref/gradient-math-dir.png b/tests/ref/gradient-math-dir.png new file mode 100644 index 000000000..5ed191821 Binary files /dev/null and b/tests/ref/gradient-math-dir.png differ diff --git a/tests/ref/gradient-math-frac.png b/tests/ref/gradient-math-frac.png new file mode 100644 index 000000000..1316dc47a Binary files /dev/null and b/tests/ref/gradient-math-frac.png differ diff --git a/tests/ref/gradient-math-mat.png b/tests/ref/gradient-math-mat.png new file mode 100644 index 000000000..aa3332b96 Binary files /dev/null and b/tests/ref/gradient-math-mat.png differ diff --git a/tests/ref/gradient-math-misc.png b/tests/ref/gradient-math-misc.png new file mode 100644 index 000000000..b8fbdd745 Binary files /dev/null and b/tests/ref/gradient-math-misc.png differ diff --git a/tests/ref/gradient-math-radial.png b/tests/ref/gradient-math-radial.png new file mode 100644 index 000000000..c9b966b29 Binary files /dev/null and b/tests/ref/gradient-math-radial.png differ diff --git a/tests/ref/gradient-math-root.png b/tests/ref/gradient-math-root.png new file mode 100644 index 000000000..4c2e4272e Binary files /dev/null and b/tests/ref/gradient-math-root.png differ diff --git a/tests/ref/gradient-math-underover.png b/tests/ref/gradient-math-underover.png new file mode 100644 index 000000000..890980511 Binary files /dev/null and b/tests/ref/gradient-math-underover.png differ diff --git a/tests/ref/gradient-presets.png b/tests/ref/gradient-presets.png new file mode 100644 index 000000000..0c7fabdd7 Binary files /dev/null and b/tests/ref/gradient-presets.png differ diff --git a/tests/ref/gradient-radial-center.png b/tests/ref/gradient-radial-center.png new file mode 100644 index 000000000..e89e1f30b Binary files /dev/null and b/tests/ref/gradient-radial-center.png differ diff --git a/tests/ref/gradient-radial-focal-center-and-radius.png b/tests/ref/gradient-radial-focal-center-and-radius.png new file mode 100644 index 000000000..4bc8a5d6d Binary files /dev/null and b/tests/ref/gradient-radial-focal-center-and-radius.png differ diff --git a/tests/ref/gradient-radial-hsl.png b/tests/ref/gradient-radial-hsl.png new file mode 100644 index 000000000..4a2ded186 Binary files /dev/null and b/tests/ref/gradient-radial-hsl.png differ diff --git a/tests/ref/gradient-radial-radius.png b/tests/ref/gradient-radial-radius.png new file mode 100644 index 000000000..1037e63f2 Binary files /dev/null and b/tests/ref/gradient-radial-radius.png differ diff --git a/tests/ref/gradient-radial-relative-parent.png b/tests/ref/gradient-radial-relative-parent.png new file mode 100644 index 000000000..f8addbe01 Binary files /dev/null and b/tests/ref/gradient-radial-relative-parent.png differ diff --git a/tests/ref/gradient-radial-relative-self.png b/tests/ref/gradient-radial-relative-self.png new file mode 100644 index 000000000..f5fc68364 Binary files /dev/null and b/tests/ref/gradient-radial-relative-self.png differ diff --git a/tests/ref/gradient-radial-text.png b/tests/ref/gradient-radial-text.png new file mode 100644 index 000000000..6da098780 Binary files /dev/null and b/tests/ref/gradient-radial-text.png differ diff --git a/tests/ref/gradient-repr.png b/tests/ref/gradient-repr.png new file mode 100644 index 000000000..04908e594 Binary files /dev/null and b/tests/ref/gradient-repr.png differ diff --git a/tests/ref/gradient-text-decoration.png b/tests/ref/gradient-text-decoration.png new file mode 100644 index 000000000..d1713c99d Binary files /dev/null and b/tests/ref/gradient-text-decoration.png differ diff --git a/tests/ref/gradient-text-dir.png b/tests/ref/gradient-text-dir.png new file mode 100644 index 000000000..eab56d66e Binary files /dev/null and b/tests/ref/gradient-text-dir.png differ diff --git a/tests/ref/gradient-text-global.png b/tests/ref/gradient-text-global.png new file mode 100644 index 000000000..7892fbb2c Binary files /dev/null and b/tests/ref/gradient-text-global.png differ diff --git a/tests/ref/gradient-text-in-container.png b/tests/ref/gradient-text-in-container.png new file mode 100644 index 000000000..9122a556d Binary files /dev/null and b/tests/ref/gradient-text-in-container.png differ diff --git a/tests/ref/gradient-text-rotate.png b/tests/ref/gradient-text-rotate.png new file mode 100644 index 000000000..a32cacf85 Binary files /dev/null and b/tests/ref/gradient-text-rotate.png differ diff --git a/tests/ref/gradient-transformed.png b/tests/ref/gradient-transformed.png new file mode 100644 index 000000000..2ad1286e8 Binary files /dev/null and b/tests/ref/gradient-transformed.png differ diff --git a/tests/ref/grid-align.png b/tests/ref/grid-align.png new file mode 100644 index 000000000..f85abf694 Binary files /dev/null and b/tests/ref/grid-align.png differ diff --git a/tests/ref/grid-auto-shrink.png b/tests/ref/grid-auto-shrink.png new file mode 100644 index 000000000..27813e261 Binary files /dev/null and b/tests/ref/grid-auto-shrink.png differ diff --git a/tests/ref/grid-breaking-expand-vertically.png b/tests/ref/grid-breaking-expand-vertically.png new file mode 100644 index 000000000..14434d7c4 Binary files /dev/null and b/tests/ref/grid-breaking-expand-vertically.png differ diff --git a/tests/ref/grid-calendar.png b/tests/ref/grid-calendar.png new file mode 100644 index 000000000..0609b84f0 Binary files /dev/null and b/tests/ref/grid-calendar.png differ diff --git a/tests/ref/grid-cell-align-override.png b/tests/ref/grid-cell-align-override.png new file mode 100644 index 000000000..8ffde97f5 Binary files /dev/null and b/tests/ref/grid-cell-align-override.png differ diff --git a/tests/ref/grid-cell-breaking.png b/tests/ref/grid-cell-breaking.png new file mode 100644 index 000000000..c91a39932 Binary files /dev/null and b/tests/ref/grid-cell-breaking.png differ diff --git a/tests/ref/grid-cell-folding.png b/tests/ref/grid-cell-folding.png new file mode 100644 index 000000000..ce1108c69 Binary files /dev/null and b/tests/ref/grid-cell-folding.png differ diff --git a/tests/ref/grid-cell-override-in-header-and-footer-with-gutter.png b/tests/ref/grid-cell-override-in-header-and-footer-with-gutter.png new file mode 100644 index 000000000..a475bf90d Binary files /dev/null and b/tests/ref/grid-cell-override-in-header-and-footer-with-gutter.png differ diff --git a/tests/ref/grid-cell-override-in-header-and-footer.png b/tests/ref/grid-cell-override-in-header-and-footer.png new file mode 100644 index 000000000..4d31e3796 Binary files /dev/null and b/tests/ref/grid-cell-override-in-header-and-footer.png differ diff --git a/tests/ref/grid-cell-override.png b/tests/ref/grid-cell-override.png new file mode 100644 index 000000000..d6f37d632 Binary files /dev/null and b/tests/ref/grid-cell-override.png differ diff --git a/tests/ref/grid-cell-position-automatic-skip-manual.png b/tests/ref/grid-cell-position-automatic-skip-manual.png new file mode 100644 index 000000000..ec615c977 Binary files /dev/null and b/tests/ref/grid-cell-position-automatic-skip-manual.png differ diff --git a/tests/ref/grid-cell-position-extra-rows.png b/tests/ref/grid-cell-position-extra-rows.png new file mode 100644 index 000000000..4d73c3f7c Binary files /dev/null and b/tests/ref/grid-cell-position-extra-rows.png differ diff --git a/tests/ref/grid-cell-position-out-of-order.png b/tests/ref/grid-cell-position-out-of-order.png new file mode 100644 index 000000000..d6bdad462 Binary files /dev/null and b/tests/ref/grid-cell-position-out-of-order.png differ diff --git a/tests/ref/grid-cell-position-partial.png b/tests/ref/grid-cell-position-partial.png new file mode 100644 index 000000000..3012c5b5e Binary files /dev/null and b/tests/ref/grid-cell-position-partial.png differ diff --git a/tests/ref/grid-cell-set.png b/tests/ref/grid-cell-set.png new file mode 100644 index 000000000..5dc3fdf61 Binary files /dev/null and b/tests/ref/grid-cell-set.png differ diff --git a/tests/ref/grid-cell-show-and-override.png b/tests/ref/grid-cell-show-and-override.png new file mode 100644 index 000000000..6af555964 Binary files /dev/null and b/tests/ref/grid-cell-show-and-override.png differ diff --git a/tests/ref/grid-cell-show-based-on-position.png b/tests/ref/grid-cell-show-based-on-position.png new file mode 100644 index 000000000..26ad62849 Binary files /dev/null and b/tests/ref/grid-cell-show-based-on-position.png differ diff --git a/tests/ref/grid-cell-show-emph.png b/tests/ref/grid-cell-show-emph.png new file mode 100644 index 000000000..bfc03d6d3 Binary files /dev/null and b/tests/ref/grid-cell-show-emph.png differ diff --git a/tests/ref/grid-cell-show-x-y.png b/tests/ref/grid-cell-show-x-y.png new file mode 100644 index 000000000..0fb4c2c55 Binary files /dev/null and b/tests/ref/grid-cell-show-x-y.png differ diff --git a/tests/ref/grid-cell-show.png b/tests/ref/grid-cell-show.png new file mode 100644 index 000000000..9ac6d2695 Binary files /dev/null and b/tests/ref/grid-cell-show.png differ diff --git a/tests/ref/grid-cell-various-overrides.png b/tests/ref/grid-cell-various-overrides.png new file mode 100644 index 000000000..74490e846 Binary files /dev/null and b/tests/ref/grid-cell-various-overrides.png differ diff --git a/tests/ref/grid-colspan-gutter.png b/tests/ref/grid-colspan-gutter.png new file mode 100644 index 000000000..2ba9c217a Binary files /dev/null and b/tests/ref/grid-colspan-gutter.png differ diff --git a/tests/ref/grid-colspan-multiple-regions.png b/tests/ref/grid-colspan-multiple-regions.png new file mode 100644 index 000000000..22811acae Binary files /dev/null and b/tests/ref/grid-colspan-multiple-regions.png differ diff --git a/tests/ref/grid-colspan-over-all-fr-columns-page-width-auto.png b/tests/ref/grid-colspan-over-all-fr-columns-page-width-auto.png new file mode 100644 index 000000000..b5cf6cacf Binary files /dev/null and b/tests/ref/grid-colspan-over-all-fr-columns-page-width-auto.png differ diff --git a/tests/ref/grid-colspan-over-all-fr-columns.png b/tests/ref/grid-colspan-over-all-fr-columns.png new file mode 100644 index 000000000..c152f3cc7 Binary files /dev/null and b/tests/ref/grid-colspan-over-all-fr-columns.png differ diff --git a/tests/ref/grid-colspan-over-some-fr-columns.png b/tests/ref/grid-colspan-over-some-fr-columns.png new file mode 100644 index 000000000..5d8157c20 Binary files /dev/null and b/tests/ref/grid-colspan-over-some-fr-columns.png differ diff --git a/tests/ref/grid-colspan-thick-stroke.png b/tests/ref/grid-colspan-thick-stroke.png new file mode 100644 index 000000000..7348551e0 Binary files /dev/null and b/tests/ref/grid-colspan-thick-stroke.png differ diff --git a/tests/ref/grid-colspan.png b/tests/ref/grid-colspan.png new file mode 100644 index 000000000..419d23b2f Binary files /dev/null and b/tests/ref/grid-colspan.png differ diff --git a/tests/ref/grid-column-sizing-auto-base.png b/tests/ref/grid-column-sizing-auto-base.png new file mode 100644 index 000000000..75664027d Binary files /dev/null and b/tests/ref/grid-column-sizing-auto-base.png differ diff --git a/tests/ref/grid-column-sizing-fr-base.png b/tests/ref/grid-column-sizing-fr-base.png new file mode 100644 index 000000000..d4a44be70 Binary files /dev/null and b/tests/ref/grid-column-sizing-fr-base.png differ diff --git a/tests/ref/grid-column-sizing-mixed-base.png b/tests/ref/grid-column-sizing-mixed-base.png new file mode 100644 index 000000000..dc92564d3 Binary files /dev/null and b/tests/ref/grid-column-sizing-mixed-base.png differ diff --git a/tests/ref/grid-columns-sizings-rect.png b/tests/ref/grid-columns-sizings-rect.png new file mode 100644 index 000000000..9381103d7 Binary files /dev/null and b/tests/ref/grid-columns-sizings-rect.png differ diff --git a/tests/ref/grid-complete-rows.png b/tests/ref/grid-complete-rows.png new file mode 100644 index 000000000..192aa911b Binary files /dev/null and b/tests/ref/grid-complete-rows.png differ diff --git a/tests/ref/grid-consecutive-rows-breaking.png b/tests/ref/grid-consecutive-rows-breaking.png new file mode 100644 index 000000000..6000271d8 Binary files /dev/null and b/tests/ref/grid-consecutive-rows-breaking.png differ diff --git a/tests/ref/grid-exam.png b/tests/ref/grid-exam.png new file mode 100644 index 000000000..97edd52eb Binary files /dev/null and b/tests/ref/grid-exam.png differ diff --git a/tests/ref/grid-fill-func.png b/tests/ref/grid-fill-func.png new file mode 100644 index 000000000..388a52df4 Binary files /dev/null and b/tests/ref/grid-fill-func.png differ diff --git a/tests/ref/grid-finance.png b/tests/ref/grid-finance.png new file mode 100644 index 000000000..2ea485945 Binary files /dev/null and b/tests/ref/grid-finance.png differ diff --git a/tests/ref/grid-footer-bare-1.png b/tests/ref/grid-footer-bare-1.png new file mode 100644 index 000000000..e8c8b21a3 Binary files /dev/null and b/tests/ref/grid-footer-bare-1.png differ diff --git a/tests/ref/grid-footer-bare-2.png b/tests/ref/grid-footer-bare-2.png new file mode 100644 index 000000000..bad6a3dd8 Binary files /dev/null and b/tests/ref/grid-footer-bare-2.png differ diff --git a/tests/ref/grid-footer-below-rowspans.png b/tests/ref/grid-footer-below-rowspans.png new file mode 100644 index 000000000..5c3a2b26d Binary files /dev/null and b/tests/ref/grid-footer-below-rowspans.png differ diff --git a/tests/ref/grid-footer-cell-with-y.png b/tests/ref/grid-footer-cell-with-y.png new file mode 100644 index 000000000..3237ea69d Binary files /dev/null and b/tests/ref/grid-footer-cell-with-y.png differ diff --git a/tests/ref/grid-footer-expand.png b/tests/ref/grid-footer-expand.png new file mode 100644 index 000000000..118765d5c Binary files /dev/null and b/tests/ref/grid-footer-expand.png differ diff --git a/tests/ref/grid-footer-gutter-and-no-repeat.png b/tests/ref/grid-footer-gutter-and-no-repeat.png new file mode 100644 index 000000000..ea36ae034 Binary files /dev/null and b/tests/ref/grid-footer-gutter-and-no-repeat.png differ diff --git a/tests/ref/grid-footer-hline-and-vline-1.png b/tests/ref/grid-footer-hline-and-vline-1.png new file mode 100644 index 000000000..a4d9a6812 Binary files /dev/null and b/tests/ref/grid-footer-hline-and-vline-1.png differ diff --git a/tests/ref/grid-footer-hline-and-vline-2.png b/tests/ref/grid-footer-hline-and-vline-2.png new file mode 100644 index 000000000..0ad2bacc5 Binary files /dev/null and b/tests/ref/grid-footer-hline-and-vline-2.png differ diff --git a/tests/ref/grid-footer-relative-row-sizes.png b/tests/ref/grid-footer-relative-row-sizes.png new file mode 100644 index 000000000..b533f13f3 Binary files /dev/null and b/tests/ref/grid-footer-relative-row-sizes.png differ diff --git a/tests/ref/grid-footer-rowspan.png b/tests/ref/grid-footer-rowspan.png new file mode 100644 index 000000000..369e4d079 Binary files /dev/null and b/tests/ref/grid-footer-rowspan.png differ diff --git a/tests/ref/grid-footer-stroke-edge-cases.png b/tests/ref/grid-footer-stroke-edge-cases.png new file mode 100644 index 000000000..c3db98e78 Binary files /dev/null and b/tests/ref/grid-footer-stroke-edge-cases.png differ diff --git a/tests/ref/grid-footer-top-stroke.png b/tests/ref/grid-footer-top-stroke.png new file mode 100644 index 000000000..ff9aa9f01 Binary files /dev/null and b/tests/ref/grid-footer-top-stroke.png differ diff --git a/tests/ref/grid-footer.png b/tests/ref/grid-footer.png new file mode 100644 index 000000000..196563c7f Binary files /dev/null and b/tests/ref/grid-footer.png differ diff --git a/tests/ref/grid-funcs-gutter.png b/tests/ref/grid-funcs-gutter.png new file mode 100644 index 000000000..ee6723ef9 Binary files /dev/null and b/tests/ref/grid-funcs-gutter.png differ diff --git a/tests/ref/grid-gutter-fr.png b/tests/ref/grid-gutter-fr.png new file mode 100644 index 000000000..2fce69492 Binary files /dev/null and b/tests/ref/grid-gutter-fr.png differ diff --git a/tests/ref/grid-header-and-footer-containing-rowspan.png b/tests/ref/grid-header-and-footer-containing-rowspan.png new file mode 100644 index 000000000..705d72a47 Binary files /dev/null and b/tests/ref/grid-header-and-footer-containing-rowspan.png differ diff --git a/tests/ref/grid-header-and-footer-empty.png b/tests/ref/grid-header-and-footer-empty.png new file mode 100644 index 000000000..c4e7bb0e4 Binary files /dev/null and b/tests/ref/grid-header-and-footer-empty.png differ diff --git a/tests/ref/grid-header-and-footer-lack-of-space.png b/tests/ref/grid-header-and-footer-lack-of-space.png new file mode 100644 index 000000000..78705776d Binary files /dev/null and b/tests/ref/grid-header-and-footer-lack-of-space.png differ diff --git a/tests/ref/grid-header-and-footer-orphan-prevention.png b/tests/ref/grid-header-and-footer-orphan-prevention.png new file mode 100644 index 000000000..8253b6572 Binary files /dev/null and b/tests/ref/grid-header-and-footer-orphan-prevention.png differ diff --git a/tests/ref/grid-header-and-rowspan-non-contiguous-1.png b/tests/ref/grid-header-and-rowspan-non-contiguous-1.png new file mode 100644 index 000000000..d5088a12f Binary files /dev/null and b/tests/ref/grid-header-and-rowspan-non-contiguous-1.png differ diff --git a/tests/ref/grid-header-and-rowspan-non-contiguous-2.png b/tests/ref/grid-header-and-rowspan-non-contiguous-2.png new file mode 100644 index 000000000..4894d1418 Binary files /dev/null and b/tests/ref/grid-header-and-rowspan-non-contiguous-2.png differ diff --git a/tests/ref/grid-header-and-rowspan-non-contiguous-3.png b/tests/ref/grid-header-and-rowspan-non-contiguous-3.png new file mode 100644 index 000000000..36e9a3c31 Binary files /dev/null and b/tests/ref/grid-header-and-rowspan-non-contiguous-3.png differ diff --git a/tests/ref/grid-header-block-with-fixed-height.png b/tests/ref/grid-header-block-with-fixed-height.png new file mode 100644 index 000000000..b7f2eedb3 Binary files /dev/null and b/tests/ref/grid-header-block-with-fixed-height.png differ diff --git a/tests/ref/grid-header-cell-with-y.png b/tests/ref/grid-header-cell-with-y.png new file mode 100644 index 000000000..e54e35fa2 Binary files /dev/null and b/tests/ref/grid-header-cell-with-y.png differ diff --git a/tests/ref/grid-header-containing-rowspan.png b/tests/ref/grid-header-containing-rowspan.png new file mode 100644 index 000000000..3cabff9e2 Binary files /dev/null and b/tests/ref/grid-header-containing-rowspan.png differ diff --git a/tests/ref/grid-header-empty.png b/tests/ref/grid-header-empty.png new file mode 100644 index 000000000..20e4d92ca Binary files /dev/null and b/tests/ref/grid-header-empty.png differ diff --git a/tests/ref/grid-header-expand.png b/tests/ref/grid-header-expand.png new file mode 100644 index 000000000..465724417 Binary files /dev/null and b/tests/ref/grid-header-expand.png differ diff --git a/tests/ref/grid-header-footer-and-rowspan-non-contiguous-1.png b/tests/ref/grid-header-footer-and-rowspan-non-contiguous-1.png new file mode 100644 index 000000000..e7b153c82 Binary files /dev/null and b/tests/ref/grid-header-footer-and-rowspan-non-contiguous-1.png differ diff --git a/tests/ref/grid-header-footer-and-rowspan-non-contiguous-2.png b/tests/ref/grid-header-footer-and-rowspan-non-contiguous-2.png new file mode 100644 index 000000000..525475ac5 Binary files /dev/null and b/tests/ref/grid-header-footer-and-rowspan-non-contiguous-2.png differ diff --git a/tests/ref/grid-header-footer-block-with-fixed-height.png b/tests/ref/grid-header-footer-block-with-fixed-height.png new file mode 100644 index 000000000..1f2e7c204 Binary files /dev/null and b/tests/ref/grid-header-footer-block-with-fixed-height.png differ diff --git a/tests/ref/grid-header-hline-and-vline.png b/tests/ref/grid-header-hline-and-vline.png new file mode 100644 index 000000000..a01fc00b3 Binary files /dev/null and b/tests/ref/grid-header-hline-and-vline.png differ diff --git a/tests/ref/grid-header-hline-bottom-manually.png b/tests/ref/grid-header-hline-bottom-manually.png new file mode 100644 index 000000000..d944f7b5e Binary files /dev/null and b/tests/ref/grid-header-hline-bottom-manually.png differ diff --git a/tests/ref/grid-header-hline-bottom.png b/tests/ref/grid-header-hline-bottom.png new file mode 100644 index 000000000..f13612420 Binary files /dev/null and b/tests/ref/grid-header-hline-bottom.png differ diff --git a/tests/ref/grid-header-lack-of-space.png b/tests/ref/grid-header-lack-of-space.png new file mode 100644 index 000000000..4d2b483f1 Binary files /dev/null and b/tests/ref/grid-header-lack-of-space.png differ diff --git a/tests/ref/grid-header-last-child.png b/tests/ref/grid-header-last-child.png new file mode 100644 index 000000000..4fa1ff7c7 Binary files /dev/null and b/tests/ref/grid-header-last-child.png differ diff --git a/tests/ref/grid-header-nested.png b/tests/ref/grid-header-nested.png new file mode 100644 index 000000000..9078090f5 Binary files /dev/null and b/tests/ref/grid-header-nested.png differ diff --git a/tests/ref/grid-header-orphan-prevention.png b/tests/ref/grid-header-orphan-prevention.png new file mode 100644 index 000000000..fa903e42d Binary files /dev/null and b/tests/ref/grid-header-orphan-prevention.png differ diff --git a/tests/ref/grid-header-relative-row-sizes.png b/tests/ref/grid-header-relative-row-sizes.png new file mode 100644 index 000000000..69ed1d1e0 Binary files /dev/null and b/tests/ref/grid-header-relative-row-sizes.png differ diff --git a/tests/ref/grid-header-rowspan-base.png b/tests/ref/grid-header-rowspan-base.png new file mode 100644 index 000000000..1ab83591e Binary files /dev/null and b/tests/ref/grid-header-rowspan-base.png differ diff --git a/tests/ref/grid-header-stroke-edge-cases.png b/tests/ref/grid-header-stroke-edge-cases.png new file mode 100644 index 000000000..b86eb6326 Binary files /dev/null and b/tests/ref/grid-header-stroke-edge-cases.png differ diff --git a/tests/ref/grid-headers-gutter.png b/tests/ref/grid-headers-gutter.png new file mode 100644 index 000000000..c2a48a66e Binary files /dev/null and b/tests/ref/grid-headers-gutter.png differ diff --git a/tests/ref/grid-headers-no-repeat.png b/tests/ref/grid-headers-no-repeat.png new file mode 100644 index 000000000..32d281a1c Binary files /dev/null and b/tests/ref/grid-headers-no-repeat.png differ diff --git a/tests/ref/grid-headers.png b/tests/ref/grid-headers.png new file mode 100644 index 000000000..13e88dbec Binary files /dev/null and b/tests/ref/grid-headers.png differ diff --git a/tests/ref/grid-inset-folding.png b/tests/ref/grid-inset-folding.png new file mode 100644 index 000000000..7f9942646 Binary files /dev/null and b/tests/ref/grid-inset-folding.png differ diff --git a/tests/ref/grid-inset.png b/tests/ref/grid-inset.png new file mode 100644 index 000000000..d31197d03 Binary files /dev/null and b/tests/ref/grid-inset.png differ diff --git a/tests/ref/grid-nested-breaking.png b/tests/ref/grid-nested-breaking.png new file mode 100644 index 000000000..b203c2300 Binary files /dev/null and b/tests/ref/grid-nested-breaking.png differ diff --git a/tests/ref/grid-nested-footers.png b/tests/ref/grid-nested-footers.png new file mode 100644 index 000000000..1af85a00f Binary files /dev/null and b/tests/ref/grid-nested-footers.png differ diff --git a/tests/ref/grid-nested-headers.png b/tests/ref/grid-nested-headers.png new file mode 100644 index 000000000..e714dcc45 Binary files /dev/null and b/tests/ref/grid-nested-headers.png differ diff --git a/tests/ref/grid-nested-with-footers.png b/tests/ref/grid-nested-with-footers.png new file mode 100644 index 000000000..5ceae8770 Binary files /dev/null and b/tests/ref/grid-nested-with-footers.png differ diff --git a/tests/ref/grid-nested-with-headers.png b/tests/ref/grid-nested-with-headers.png new file mode 100644 index 000000000..6b7ef14bb Binary files /dev/null and b/tests/ref/grid-nested-with-headers.png differ diff --git a/tests/ref/grid-row-sizing-manual-align.png b/tests/ref/grid-row-sizing-manual-align.png new file mode 100644 index 000000000..68b0911ed Binary files /dev/null and b/tests/ref/grid-row-sizing-manual-align.png differ diff --git a/tests/ref/grid-rowspan-block-full-height.png b/tests/ref/grid-rowspan-block-full-height.png new file mode 100644 index 000000000..078cbda42 Binary files /dev/null and b/tests/ref/grid-rowspan-block-full-height.png differ diff --git a/tests/ref/grid-rowspan-block-overflow.png b/tests/ref/grid-rowspan-block-overflow.png new file mode 100644 index 000000000..78e26d720 Binary files /dev/null and b/tests/ref/grid-rowspan-block-overflow.png differ diff --git a/tests/ref/grid-rowspan-cell-coordinates.png b/tests/ref/grid-rowspan-cell-coordinates.png new file mode 100644 index 000000000..ebe19fd49 Binary files /dev/null and b/tests/ref/grid-rowspan-cell-coordinates.png differ diff --git a/tests/ref/grid-rowspan-cell-order.png b/tests/ref/grid-rowspan-cell-order.png new file mode 100644 index 000000000..c9b1f5546 Binary files /dev/null and b/tests/ref/grid-rowspan-cell-order.png differ diff --git a/tests/ref/grid-rowspan-excessive-gutter.png b/tests/ref/grid-rowspan-excessive-gutter.png new file mode 100644 index 000000000..8688364c9 Binary files /dev/null and b/tests/ref/grid-rowspan-excessive-gutter.png differ diff --git a/tests/ref/grid-rowspan-excessive.png b/tests/ref/grid-rowspan-excessive.png new file mode 100644 index 000000000..1e6b41282 Binary files /dev/null and b/tests/ref/grid-rowspan-excessive.png differ diff --git a/tests/ref/grid-rowspan-fixed-size.png b/tests/ref/grid-rowspan-fixed-size.png new file mode 100644 index 000000000..c9ae3fa12 Binary files /dev/null and b/tests/ref/grid-rowspan-fixed-size.png differ diff --git a/tests/ref/grid-rowspan-gutter.png b/tests/ref/grid-rowspan-gutter.png new file mode 100644 index 000000000..b37a1cab2 Binary files /dev/null and b/tests/ref/grid-rowspan-gutter.png differ diff --git a/tests/ref/grid-rowspan-in-all-columns-stroke-gutter.png b/tests/ref/grid-rowspan-in-all-columns-stroke-gutter.png new file mode 100644 index 000000000..edad2f01f Binary files /dev/null and b/tests/ref/grid-rowspan-in-all-columns-stroke-gutter.png differ diff --git a/tests/ref/grid-rowspan-in-all-columns-stroke.png b/tests/ref/grid-rowspan-in-all-columns-stroke.png new file mode 100644 index 000000000..135d1911a Binary files /dev/null and b/tests/ref/grid-rowspan-in-all-columns-stroke.png differ diff --git a/tests/ref/grid-rowspan-over-auto-row.png b/tests/ref/grid-rowspan-over-auto-row.png new file mode 100644 index 000000000..450373824 Binary files /dev/null and b/tests/ref/grid-rowspan-over-auto-row.png differ diff --git a/tests/ref/grid-rowspan-over-fr-row-at-end.png b/tests/ref/grid-rowspan-over-fr-row-at-end.png new file mode 100644 index 000000000..1cf8b9fc8 Binary files /dev/null and b/tests/ref/grid-rowspan-over-fr-row-at-end.png differ diff --git a/tests/ref/grid-rowspan-over-fr-row-at-start.png b/tests/ref/grid-rowspan-over-fr-row-at-start.png new file mode 100644 index 000000000..577db9165 Binary files /dev/null and b/tests/ref/grid-rowspan-over-fr-row-at-start.png differ diff --git a/tests/ref/grid-rowspan-split-1.png b/tests/ref/grid-rowspan-split-1.png new file mode 100644 index 000000000..e99b105f9 Binary files /dev/null and b/tests/ref/grid-rowspan-split-1.png differ diff --git a/tests/ref/grid-rowspan-split-10.png b/tests/ref/grid-rowspan-split-10.png new file mode 100644 index 000000000..0b907e7df Binary files /dev/null and b/tests/ref/grid-rowspan-split-10.png differ diff --git a/tests/ref/grid-rowspan-split-11.png b/tests/ref/grid-rowspan-split-11.png new file mode 100644 index 000000000..202665d6d Binary files /dev/null and b/tests/ref/grid-rowspan-split-11.png differ diff --git a/tests/ref/grid-rowspan-split-12.png b/tests/ref/grid-rowspan-split-12.png new file mode 100644 index 000000000..3d8985f2d Binary files /dev/null and b/tests/ref/grid-rowspan-split-12.png differ diff --git a/tests/ref/grid-rowspan-split-13.png b/tests/ref/grid-rowspan-split-13.png new file mode 100644 index 000000000..f4e9d694e Binary files /dev/null and b/tests/ref/grid-rowspan-split-13.png differ diff --git a/tests/ref/grid-rowspan-split-14.png b/tests/ref/grid-rowspan-split-14.png new file mode 100644 index 000000000..1500a89b0 Binary files /dev/null and b/tests/ref/grid-rowspan-split-14.png differ diff --git a/tests/ref/grid-rowspan-split-15.png b/tests/ref/grid-rowspan-split-15.png new file mode 100644 index 000000000..445f0a959 Binary files /dev/null and b/tests/ref/grid-rowspan-split-15.png differ diff --git a/tests/ref/grid-rowspan-split-16.png b/tests/ref/grid-rowspan-split-16.png new file mode 100644 index 000000000..fff83aebe Binary files /dev/null and b/tests/ref/grid-rowspan-split-16.png differ diff --git a/tests/ref/grid-rowspan-split-17.png b/tests/ref/grid-rowspan-split-17.png new file mode 100644 index 000000000..2224c194c Binary files /dev/null and b/tests/ref/grid-rowspan-split-17.png differ diff --git a/tests/ref/grid-rowspan-split-2.png b/tests/ref/grid-rowspan-split-2.png new file mode 100644 index 000000000..43a5eed7c Binary files /dev/null and b/tests/ref/grid-rowspan-split-2.png differ diff --git a/tests/ref/grid-rowspan-split-3.png b/tests/ref/grid-rowspan-split-3.png new file mode 100644 index 000000000..0d7c3359c Binary files /dev/null and b/tests/ref/grid-rowspan-split-3.png differ diff --git a/tests/ref/grid-rowspan-split-4.png b/tests/ref/grid-rowspan-split-4.png new file mode 100644 index 000000000..2af887bba Binary files /dev/null and b/tests/ref/grid-rowspan-split-4.png differ diff --git a/tests/ref/grid-rowspan-split-5.png b/tests/ref/grid-rowspan-split-5.png new file mode 100644 index 000000000..3aa79cda3 Binary files /dev/null and b/tests/ref/grid-rowspan-split-5.png differ diff --git a/tests/ref/grid-rowspan-split-6.png b/tests/ref/grid-rowspan-split-6.png new file mode 100644 index 000000000..fbf5bf28c Binary files /dev/null and b/tests/ref/grid-rowspan-split-6.png differ diff --git a/tests/ref/grid-rowspan-split-7.png b/tests/ref/grid-rowspan-split-7.png new file mode 100644 index 000000000..00e03f025 Binary files /dev/null and b/tests/ref/grid-rowspan-split-7.png differ diff --git a/tests/ref/grid-rowspan-split-8.png b/tests/ref/grid-rowspan-split-8.png new file mode 100644 index 000000000..405b54235 Binary files /dev/null and b/tests/ref/grid-rowspan-split-8.png differ diff --git a/tests/ref/grid-rowspan-split-9.png b/tests/ref/grid-rowspan-split-9.png new file mode 100644 index 000000000..5346be718 Binary files /dev/null and b/tests/ref/grid-rowspan-split-9.png differ diff --git a/tests/ref/grid-rowspan-unbreakable-1.png b/tests/ref/grid-rowspan-unbreakable-1.png new file mode 100644 index 000000000..6112c0692 Binary files /dev/null and b/tests/ref/grid-rowspan-unbreakable-1.png differ diff --git a/tests/ref/grid-rowspan-unbreakable-2.png b/tests/ref/grid-rowspan-unbreakable-2.png new file mode 100644 index 000000000..8e4a222aa Binary files /dev/null and b/tests/ref/grid-rowspan-unbreakable-2.png differ diff --git a/tests/ref/grid-rowspan.png b/tests/ref/grid-rowspan.png new file mode 100644 index 000000000..87ad41807 Binary files /dev/null and b/tests/ref/grid-rowspan.png differ diff --git a/tests/ref/grid-rtl-colspan-stroke.png b/tests/ref/grid-rtl-colspan-stroke.png new file mode 100644 index 000000000..248a575cb Binary files /dev/null and b/tests/ref/grid-rtl-colspan-stroke.png differ diff --git a/tests/ref/grid-rtl-colspan.png b/tests/ref/grid-rtl-colspan.png new file mode 100644 index 000000000..886e276df Binary files /dev/null and b/tests/ref/grid-rtl-colspan.png differ diff --git a/tests/ref/grid-rtl-complex.png b/tests/ref/grid-rtl-complex.png new file mode 100644 index 000000000..a4177548d Binary files /dev/null and b/tests/ref/grid-rtl-complex.png differ diff --git a/tests/ref/grid-rtl-header.png b/tests/ref/grid-rtl-header.png new file mode 100644 index 000000000..1ed532c38 Binary files /dev/null and b/tests/ref/grid-rtl-header.png differ diff --git a/tests/ref/grid-rtl-multiple-regions.png b/tests/ref/grid-rtl-multiple-regions.png new file mode 100644 index 000000000..a9ec7340e Binary files /dev/null and b/tests/ref/grid-rtl-multiple-regions.png differ diff --git a/tests/ref/grid-rtl-rowspan.png b/tests/ref/grid-rtl-rowspan.png new file mode 100644 index 000000000..2465164b1 Binary files /dev/null and b/tests/ref/grid-rtl-rowspan.png differ diff --git a/tests/ref/grid-rtl-vline-position.png b/tests/ref/grid-rtl-vline-position.png new file mode 100644 index 000000000..3612fc9fe Binary files /dev/null and b/tests/ref/grid-rtl-vline-position.png differ diff --git a/tests/ref/grid-rtl.png b/tests/ref/grid-rtl.png new file mode 100644 index 000000000..c40fc5885 Binary files /dev/null and b/tests/ref/grid-rtl.png differ diff --git a/tests/ref/grid-same-row-multiple-columns-breaking.png b/tests/ref/grid-same-row-multiple-columns-breaking.png new file mode 100644 index 000000000..b440f3368 Binary files /dev/null and b/tests/ref/grid-same-row-multiple-columns-breaking.png differ diff --git a/tests/ref/grid-stroke-array.png b/tests/ref/grid-stroke-array.png new file mode 100644 index 000000000..6f8e28b09 Binary files /dev/null and b/tests/ref/grid-stroke-array.png differ diff --git a/tests/ref/grid-stroke-automatically-positioned-lines.png b/tests/ref/grid-stroke-automatically-positioned-lines.png new file mode 100644 index 000000000..2118112c0 Binary files /dev/null and b/tests/ref/grid-stroke-automatically-positioned-lines.png differ diff --git a/tests/ref/grid-stroke-border-partial.png b/tests/ref/grid-stroke-border-partial.png new file mode 100644 index 000000000..ffd8835f1 Binary files /dev/null and b/tests/ref/grid-stroke-border-partial.png differ diff --git a/tests/ref/grid-stroke-complex.png b/tests/ref/grid-stroke-complex.png new file mode 100644 index 000000000..e68fd5f3b Binary files /dev/null and b/tests/ref/grid-stroke-complex.png differ diff --git a/tests/ref/grid-stroke-field-in-show.png b/tests/ref/grid-stroke-field-in-show.png new file mode 100644 index 000000000..695868c04 Binary files /dev/null and b/tests/ref/grid-stroke-field-in-show.png differ diff --git a/tests/ref/grid-stroke-folding.png b/tests/ref/grid-stroke-folding.png new file mode 100644 index 000000000..0f2d59602 Binary files /dev/null and b/tests/ref/grid-stroke-folding.png differ diff --git a/tests/ref/grid-stroke-func.png b/tests/ref/grid-stroke-func.png new file mode 100644 index 000000000..954e90df5 Binary files /dev/null and b/tests/ref/grid-stroke-func.png differ diff --git a/tests/ref/grid-stroke-hline-position-bottom-gutter.png b/tests/ref/grid-stroke-hline-position-bottom-gutter.png new file mode 100644 index 000000000..23c7def41 Binary files /dev/null and b/tests/ref/grid-stroke-hline-position-bottom-gutter.png differ diff --git a/tests/ref/grid-stroke-hline-position-bottom.png b/tests/ref/grid-stroke-hline-position-bottom.png new file mode 100644 index 000000000..25c003c81 Binary files /dev/null and b/tests/ref/grid-stroke-hline-position-bottom.png differ diff --git a/tests/ref/grid-stroke-hline-rowspan.png b/tests/ref/grid-stroke-hline-rowspan.png new file mode 100644 index 000000000..2faf70791 Binary files /dev/null and b/tests/ref/grid-stroke-hline-rowspan.png differ diff --git a/tests/ref/grid-stroke-manually-positioned-lines.png b/tests/ref/grid-stroke-manually-positioned-lines.png new file mode 100644 index 000000000..a8a75ee07 Binary files /dev/null and b/tests/ref/grid-stroke-manually-positioned-lines.png differ diff --git a/tests/ref/grid-stroke-none.png b/tests/ref/grid-stroke-none.png new file mode 100644 index 000000000..3f978bd3a Binary files /dev/null and b/tests/ref/grid-stroke-none.png differ diff --git a/tests/ref/grid-stroke-pattern.png b/tests/ref/grid-stroke-pattern.png new file mode 100644 index 000000000..15e846eaf Binary files /dev/null and b/tests/ref/grid-stroke-pattern.png differ diff --git a/tests/ref/grid-stroke-priority-cell.png b/tests/ref/grid-stroke-priority-cell.png new file mode 100644 index 000000000..2c28e9e81 Binary files /dev/null and b/tests/ref/grid-stroke-priority-cell.png differ diff --git a/tests/ref/grid-stroke-priority-line-cell.png b/tests/ref/grid-stroke-priority-line-cell.png new file mode 100644 index 000000000..064dc1c98 Binary files /dev/null and b/tests/ref/grid-stroke-priority-line-cell.png differ diff --git a/tests/ref/grid-stroke-priority-line.png b/tests/ref/grid-stroke-priority-line.png new file mode 100644 index 000000000..1bcaa2ee8 Binary files /dev/null and b/tests/ref/grid-stroke-priority-line.png differ diff --git a/tests/ref/grid-stroke-set-on-cell-and-line.png b/tests/ref/grid-stroke-set-on-cell-and-line.png new file mode 100644 index 000000000..d43752f05 Binary files /dev/null and b/tests/ref/grid-stroke-set-on-cell-and-line.png differ diff --git a/tests/ref/grid-stroke-vline-colspan.png b/tests/ref/grid-stroke-vline-colspan.png new file mode 100644 index 000000000..7b3814372 Binary files /dev/null and b/tests/ref/grid-stroke-vline-colspan.png differ diff --git a/tests/ref/grid-stroke-vline-position-left-and-right.png b/tests/ref/grid-stroke-vline-position-left-and-right.png new file mode 100644 index 000000000..852fcf297 Binary files /dev/null and b/tests/ref/grid-stroke-vline-position-left-and-right.png differ diff --git a/tests/ref/grid-trailing-linebreak-region-overflow.png b/tests/ref/grid-trailing-linebreak-region-overflow.png new file mode 100644 index 000000000..4f7bc852f Binary files /dev/null and b/tests/ref/grid-trailing-linebreak-region-overflow.png differ diff --git a/tests/ref/heading-basic.png b/tests/ref/heading-basic.png new file mode 100644 index 000000000..74a8f2cea Binary files /dev/null and b/tests/ref/heading-basic.png differ diff --git a/tests/ref/heading-block.png b/tests/ref/heading-block.png new file mode 100644 index 000000000..595f18f5d Binary files /dev/null and b/tests/ref/heading-block.png differ diff --git a/tests/ref/heading-offset-and-level.png b/tests/ref/heading-offset-and-level.png new file mode 100644 index 000000000..9277e770a Binary files /dev/null and b/tests/ref/heading-offset-and-level.png differ diff --git a/tests/ref/heading-offset.png b/tests/ref/heading-offset.png new file mode 100644 index 000000000..3a3670cc3 Binary files /dev/null and b/tests/ref/heading-offset.png differ diff --git a/tests/ref/heading-show-where.png b/tests/ref/heading-show-where.png new file mode 100644 index 000000000..609e6ec9a Binary files /dev/null and b/tests/ref/heading-show-where.png differ diff --git a/tests/ref/heading-syntax-at-start.png b/tests/ref/heading-syntax-at-start.png new file mode 100644 index 000000000..29b824e09 Binary files /dev/null and b/tests/ref/heading-syntax-at-start.png differ diff --git a/tests/ref/heading-syntax-edge-cases.png b/tests/ref/heading-syntax-edge-cases.png new file mode 100644 index 000000000..372e1a65d Binary files /dev/null and b/tests/ref/heading-syntax-edge-cases.png differ diff --git a/tests/ref/hide-image.png b/tests/ref/hide-image.png new file mode 100644 index 000000000..78bc690c8 Binary files /dev/null and b/tests/ref/hide-image.png differ diff --git a/tests/ref/hide-line.png b/tests/ref/hide-line.png new file mode 100644 index 000000000..7d8fa6cd2 Binary files /dev/null and b/tests/ref/hide-line.png differ diff --git a/tests/ref/hide-list.png b/tests/ref/hide-list.png new file mode 100644 index 000000000..055f7b66f Binary files /dev/null and b/tests/ref/hide-list.png differ diff --git a/tests/ref/hide-polygon.png b/tests/ref/hide-polygon.png new file mode 100644 index 000000000..5c74eb41a Binary files /dev/null and b/tests/ref/hide-polygon.png differ diff --git a/tests/ref/hide-rect.png b/tests/ref/hide-rect.png new file mode 100644 index 000000000..62372c21f Binary files /dev/null and b/tests/ref/hide-rect.png differ diff --git a/tests/ref/hide-table.png b/tests/ref/hide-table.png new file mode 100644 index 000000000..e3d890d7b Binary files /dev/null and b/tests/ref/hide-table.png differ diff --git a/tests/ref/hide-text.png b/tests/ref/hide-text.png new file mode 100644 index 000000000..1136038cc Binary files /dev/null and b/tests/ref/hide-text.png differ diff --git a/tests/ref/highlight-bounds.png b/tests/ref/highlight-bounds.png new file mode 100644 index 000000000..ed868c29b Binary files /dev/null and b/tests/ref/highlight-bounds.png differ diff --git a/tests/ref/highlight-edges-bounds.png b/tests/ref/highlight-edges-bounds.png new file mode 100644 index 000000000..f78f3cc39 Binary files /dev/null and b/tests/ref/highlight-edges-bounds.png differ diff --git a/tests/ref/highlight-edges.png b/tests/ref/highlight-edges.png new file mode 100644 index 000000000..ca48707f0 Binary files /dev/null and b/tests/ref/highlight-edges.png differ diff --git a/tests/ref/highlight-radius.png b/tests/ref/highlight-radius.png new file mode 100644 index 000000000..3baa3e6d9 Binary files /dev/null and b/tests/ref/highlight-radius.png differ diff --git a/tests/ref/highlight-stroke.png b/tests/ref/highlight-stroke.png new file mode 100644 index 000000000..5a8ad3b59 Binary files /dev/null and b/tests/ref/highlight-stroke.png differ diff --git a/tests/ref/highlight.png b/tests/ref/highlight.png new file mode 100644 index 000000000..0047b7f49 Binary files /dev/null and b/tests/ref/highlight.png differ diff --git a/tests/ref/hyphenate-between-shape-runs.png b/tests/ref/hyphenate-between-shape-runs.png new file mode 100644 index 000000000..a365af24d Binary files /dev/null and b/tests/ref/hyphenate-between-shape-runs.png differ diff --git a/tests/ref/hyphenate-off-temporarily.png b/tests/ref/hyphenate-off-temporarily.png new file mode 100644 index 000000000..48e3caa96 Binary files /dev/null and b/tests/ref/hyphenate-off-temporarily.png differ diff --git a/tests/ref/hyphenate-punctuation.png b/tests/ref/hyphenate-punctuation.png new file mode 100644 index 000000000..897a15a04 Binary files /dev/null and b/tests/ref/hyphenate-punctuation.png differ diff --git a/tests/ref/hyphenate-shy.png b/tests/ref/hyphenate-shy.png new file mode 100644 index 000000000..a548c711a Binary files /dev/null and b/tests/ref/hyphenate-shy.png differ diff --git a/tests/ref/hyphenate.png b/tests/ref/hyphenate.png new file mode 100644 index 000000000..c01c90211 Binary files /dev/null and b/tests/ref/hyphenate.png differ diff --git a/tests/ref/if-condition-complex.png b/tests/ref/if-condition-complex.png new file mode 100644 index 000000000..4cbebc5e0 Binary files /dev/null and b/tests/ref/if-condition-complex.png differ diff --git a/tests/ref/if-markup.png b/tests/ref/if-markup.png new file mode 100644 index 000000000..57eb47da1 Binary files /dev/null and b/tests/ref/if-markup.png differ diff --git a/tests/ref/image-baseline-with-box.png b/tests/ref/image-baseline-with-box.png new file mode 100644 index 000000000..411280698 Binary files /dev/null and b/tests/ref/image-baseline-with-box.png differ diff --git a/tests/ref/image-decode-detect-format.png b/tests/ref/image-decode-detect-format.png new file mode 100644 index 000000000..6f12e8b47 Binary files /dev/null and b/tests/ref/image-decode-detect-format.png differ diff --git a/tests/ref/image-decode-specify-format.png b/tests/ref/image-decode-specify-format.png new file mode 100644 index 000000000..6f12e8b47 Binary files /dev/null and b/tests/ref/image-decode-specify-format.png differ diff --git a/tests/ref/image-decode-svg.png b/tests/ref/image-decode-svg.png new file mode 100644 index 000000000..b7cfcb17c Binary files /dev/null and b/tests/ref/image-decode-svg.png differ diff --git a/tests/ref/image-fit.png b/tests/ref/image-fit.png new file mode 100644 index 000000000..5a3bdec18 Binary files /dev/null and b/tests/ref/image-fit.png differ diff --git a/tests/ref/image-jump-to-next-page.png b/tests/ref/image-jump-to-next-page.png new file mode 100644 index 000000000..d8f03b3f4 Binary files /dev/null and b/tests/ref/image-jump-to-next-page.png differ diff --git a/tests/ref/image-natural-dpi-sizing.png b/tests/ref/image-natural-dpi-sizing.png new file mode 100644 index 000000000..3b9f3fa5d Binary files /dev/null and b/tests/ref/image-natural-dpi-sizing.png differ diff --git a/tests/ref/image-rgba-png-and-jpeg.png b/tests/ref/image-rgba-png-and-jpeg.png new file mode 100644 index 000000000..601271705 Binary files /dev/null and b/tests/ref/image-rgba-png-and-jpeg.png differ diff --git a/tests/ref/image-sizing.png b/tests/ref/image-sizing.png new file mode 100644 index 000000000..7419de141 Binary files /dev/null and b/tests/ref/image-sizing.png differ diff --git a/tests/ref/image-svg-complex.png b/tests/ref/image-svg-complex.png new file mode 100644 index 000000000..1ac454774 Binary files /dev/null and b/tests/ref/image-svg-complex.png differ diff --git a/tests/ref/image-svg-text-font.png b/tests/ref/image-svg-text-font.png new file mode 100644 index 000000000..2e3b0a0f5 Binary files /dev/null and b/tests/ref/image-svg-text-font.png differ diff --git a/tests/ref/image-svg-text.png b/tests/ref/image-svg-text.png new file mode 100644 index 000000000..2e41f905e Binary files /dev/null and b/tests/ref/image-svg-text.png differ diff --git a/tests/ref/import-basic.png b/tests/ref/import-basic.png new file mode 100644 index 000000000..674c4ecf9 Binary files /dev/null and b/tests/ref/import-basic.png differ diff --git a/tests/ref/import-from-function-scope.png b/tests/ref/import-from-function-scope.png new file mode 100644 index 000000000..f6169d8c2 Binary files /dev/null and b/tests/ref/import-from-function-scope.png differ diff --git a/tests/ref/import-source-field-access.png b/tests/ref/import-source-field-access.png new file mode 100644 index 000000000..e42bf2091 Binary files /dev/null and b/tests/ref/import-source-field-access.png differ diff --git a/tests/ref/include-file.png b/tests/ref/include-file.png new file mode 100644 index 000000000..57c3aca1e Binary files /dev/null and b/tests/ref/include-file.png differ diff --git a/tests/ref/int-display.png b/tests/ref/int-display.png new file mode 100644 index 000000000..bfb046480 Binary files /dev/null and b/tests/ref/int-display.png differ diff --git a/tests/ref/int-repr.png b/tests/ref/int-repr.png new file mode 100644 index 000000000..a2ee4ee08 Binary files /dev/null and b/tests/ref/int-repr.png differ diff --git a/tests/ref/issue-1041-smartquotes-in-outline.png b/tests/ref/issue-1041-smartquotes-in-outline.png new file mode 100644 index 000000000..29ba4065a Binary files /dev/null and b/tests/ref/issue-1041-smartquotes-in-outline.png differ diff --git a/tests/ref/issue-1050-terms-indent.png b/tests/ref/issue-1050-terms-indent.png new file mode 100644 index 000000000..ca0521c76 Binary files /dev/null and b/tests/ref/issue-1050-terms-indent.png differ diff --git a/tests/ref/issue-1052-math-number-spacing.png b/tests/ref/issue-1052-math-number-spacing.png new file mode 100644 index 000000000..79df2c9f9 Binary files /dev/null and b/tests/ref/issue-1052-math-number-spacing.png differ diff --git a/tests/ref/issue-1216-clamp-panic.png b/tests/ref/issue-1216-clamp-panic.png new file mode 100644 index 000000000..d51f134c2 Binary files /dev/null and b/tests/ref/issue-1216-clamp-panic.png differ diff --git a/tests/ref/issue-1240-stack-h-fr.png b/tests/ref/issue-1240-stack-h-fr.png new file mode 100644 index 000000000..ae1ba41e0 Binary files /dev/null and b/tests/ref/issue-1240-stack-h-fr.png differ diff --git a/tests/ref/issue-1240-stack-v-fr.png b/tests/ref/issue-1240-stack-v-fr.png new file mode 100644 index 000000000..a9ac36e8b Binary files /dev/null and b/tests/ref/issue-1240-stack-v-fr.png differ diff --git a/tests/ref/issue-1368-place-pagebreak.png b/tests/ref/issue-1368-place-pagebreak.png new file mode 100644 index 000000000..920cd2030 Binary files /dev/null and b/tests/ref/issue-1368-place-pagebreak.png differ diff --git a/tests/ref/issue-1373-bidi-tofus.png b/tests/ref/issue-1373-bidi-tofus.png new file mode 100644 index 000000000..783eb473d Binary files /dev/null and b/tests/ref/issue-1373-bidi-tofus.png differ diff --git a/tests/ref/issue-1388-table-row-missing.png b/tests/ref/issue-1388-table-row-missing.png new file mode 100644 index 000000000..dd08eb464 Binary files /dev/null and b/tests/ref/issue-1388-table-row-missing.png differ diff --git a/tests/ref/issue-1398-line-align.png b/tests/ref/issue-1398-line-align.png new file mode 100644 index 000000000..778aa72c9 Binary files /dev/null and b/tests/ref/issue-1398-line-align.png differ diff --git a/tests/ref/issue-1433-footnote-in-list.png b/tests/ref/issue-1433-footnote-in-list.png new file mode 100644 index 000000000..28a6e77ff Binary files /dev/null and b/tests/ref/issue-1433-footnote-in-list.png differ diff --git a/tests/ref/issue-1540-smartquotes-across-newlines.png b/tests/ref/issue-1540-smartquotes-across-newlines.png new file mode 100644 index 000000000..10fe73379 Binary files /dev/null and b/tests/ref/issue-1540-smartquotes-across-newlines.png differ diff --git a/tests/ref/issue-1597-cite-footnote.png b/tests/ref/issue-1597-cite-footnote.png new file mode 100644 index 000000000..bdd9f2257 Binary files /dev/null and b/tests/ref/issue-1597-cite-footnote.png differ diff --git a/tests/ref/issue-1825-rect-overflow.png b/tests/ref/issue-1825-rect-overflow.png new file mode 100644 index 000000000..70f09e120 Binary files /dev/null and b/tests/ref/issue-1825-rect-overflow.png differ diff --git a/tests/ref/issue-183-table-lines.png b/tests/ref/issue-183-table-lines.png new file mode 100644 index 000000000..e43692624 Binary files /dev/null and b/tests/ref/issue-183-table-lines.png differ diff --git a/tests/ref/issue-1948-math-text-break.png b/tests/ref/issue-1948-math-text-break.png new file mode 100644 index 000000000..6e3e9e85b Binary files /dev/null and b/tests/ref/issue-1948-math-text-break.png differ diff --git a/tests/ref/issue-2044-invalid-parsed-ident.png b/tests/ref/issue-2044-invalid-parsed-ident.png new file mode 100644 index 000000000..7e37ce2c6 Binary files /dev/null and b/tests/ref/issue-2044-invalid-parsed-ident.png differ diff --git a/tests/ref/issue-2051-new-cm-svg.png b/tests/ref/issue-2051-new-cm-svg.png new file mode 100644 index 000000000..653528602 Binary files /dev/null and b/tests/ref/issue-2051-new-cm-svg.png differ diff --git a/tests/ref/issue-2055-math-eval.png b/tests/ref/issue-2055-math-eval.png new file mode 100644 index 000000000..168b89139 Binary files /dev/null and b/tests/ref/issue-2055-math-eval.png differ diff --git a/tests/ref/issue-2095-pagebreak-numbering.png b/tests/ref/issue-2095-pagebreak-numbering.png new file mode 100644 index 000000000..e3a515b76 Binary files /dev/null and b/tests/ref/issue-2095-pagebreak-numbering.png differ diff --git a/tests/ref/issue-2105-linebreak-tofu.png b/tests/ref/issue-2105-linebreak-tofu.png new file mode 100644 index 000000000..197412b97 Binary files /dev/null and b/tests/ref/issue-2105-linebreak-tofu.png differ diff --git a/tests/ref/issue-2128-block-width-box.png b/tests/ref/issue-2128-block-width-box.png new file mode 100644 index 000000000..40fe6b4f8 Binary files /dev/null and b/tests/ref/issue-2128-block-width-box.png differ diff --git a/tests/ref/issue-2134-pagebreak-bibliography.png b/tests/ref/issue-2134-pagebreak-bibliography.png new file mode 100644 index 000000000..ad0fb1653 Binary files /dev/null and b/tests/ref/issue-2134-pagebreak-bibliography.png differ diff --git a/tests/ref/issue-2162-pagebreak-set-style.png b/tests/ref/issue-2162-pagebreak-set-style.png new file mode 100644 index 000000000..4ea6f56ff Binary files /dev/null and b/tests/ref/issue-2162-pagebreak-set-style.png differ diff --git a/tests/ref/issue-2199-place-spacing-bottom.png b/tests/ref/issue-2199-place-spacing-bottom.png new file mode 100644 index 000000000..1f27559bc Binary files /dev/null and b/tests/ref/issue-2199-place-spacing-bottom.png differ diff --git a/tests/ref/issue-2199-place-spacing-default.png b/tests/ref/issue-2199-place-spacing-default.png new file mode 100644 index 000000000..565a83028 Binary files /dev/null and b/tests/ref/issue-2199-place-spacing-default.png differ diff --git a/tests/ref/issue-2214-baseline-math.png b/tests/ref/issue-2214-baseline-math.png new file mode 100644 index 000000000..9a3e6f3c6 Binary files /dev/null and b/tests/ref/issue-2214-baseline-math.png differ diff --git a/tests/ref/issue-2259-raw-color-overwrite.png b/tests/ref/issue-2259-raw-color-overwrite.png new file mode 100644 index 000000000..9cf42c437 Binary files /dev/null and b/tests/ref/issue-2259-raw-color-overwrite.png differ diff --git a/tests/ref/issue-2268-mat-augment-color.png b/tests/ref/issue-2268-mat-augment-color.png new file mode 100644 index 000000000..5aca29cae Binary files /dev/null and b/tests/ref/issue-2268-mat-augment-color.png differ diff --git a/tests/ref/issue-2419-justify-hanging-indent.png b/tests/ref/issue-2419-justify-hanging-indent.png new file mode 100644 index 000000000..bb478ba45 Binary files /dev/null and b/tests/ref/issue-2419-justify-hanging-indent.png differ diff --git a/tests/ref/issue-2530-enum-item-panic.png b/tests/ref/issue-2530-enum-item-panic.png new file mode 100644 index 000000000..4f6130bad Binary files /dev/null and b/tests/ref/issue-2530-enum-item-panic.png differ diff --git a/tests/ref/issue-2530-figure-caption-panic.png b/tests/ref/issue-2530-figure-caption-panic.png new file mode 100644 index 000000000..025449efe Binary files /dev/null and b/tests/ref/issue-2530-figure-caption-panic.png differ diff --git a/tests/ref/issue-2530-list-item-panic.png b/tests/ref/issue-2530-list-item-panic.png new file mode 100644 index 000000000..14d2f5700 Binary files /dev/null and b/tests/ref/issue-2530-list-item-panic.png differ diff --git a/tests/ref/issue-2530-term-item-panic.png b/tests/ref/issue-2530-term-item-panic.png new file mode 100644 index 000000000..85b3e92f6 Binary files /dev/null and b/tests/ref/issue-2530-term-item-panic.png differ diff --git a/tests/ref/issue-2531-cite-show-set.png b/tests/ref/issue-2531-cite-show-set.png new file mode 100644 index 000000000..25723f4de Binary files /dev/null and b/tests/ref/issue-2531-cite-show-set.png differ diff --git a/tests/ref/issue-2538-cjk-latin-spacing-before-linebreak.png b/tests/ref/issue-2538-cjk-latin-spacing-before-linebreak.png new file mode 100644 index 000000000..595716426 Binary files /dev/null and b/tests/ref/issue-2538-cjk-latin-spacing-before-linebreak.png differ diff --git a/tests/ref/issue-2595-float-overlap.png b/tests/ref/issue-2595-float-overlap.png new file mode 100644 index 000000000..4b460579d Binary files /dev/null and b/tests/ref/issue-2595-float-overlap.png differ diff --git a/tests/ref/issue-2650-cjk-latin-spacing-meta.png b/tests/ref/issue-2650-cjk-latin-spacing-meta.png new file mode 100644 index 000000000..d346b73f9 Binary files /dev/null and b/tests/ref/issue-2650-cjk-latin-spacing-meta.png differ diff --git a/tests/ref/issue-2715-float-order.png b/tests/ref/issue-2715-float-order.png new file mode 100644 index 000000000..01599d250 Binary files /dev/null and b/tests/ref/issue-2715-float-order.png differ diff --git a/tests/ref/issue-2902-gradient-oklab-panic.png b/tests/ref/issue-2902-gradient-oklab-panic.png new file mode 100644 index 000000000..f8e18f7ce Binary files /dev/null and b/tests/ref/issue-2902-gradient-oklab-panic.png differ diff --git a/tests/ref/issue-2902-gradient-oklch-panic.png b/tests/ref/issue-2902-gradient-oklch-panic.png new file mode 100644 index 000000000..1af7200e6 Binary files /dev/null and b/tests/ref/issue-2902-gradient-oklch-panic.png differ diff --git a/tests/ref/issue-3082-chinese-punctuation.png b/tests/ref/issue-3082-chinese-punctuation.png new file mode 100644 index 000000000..642013d09 Binary files /dev/null and b/tests/ref/issue-3082-chinese-punctuation.png differ diff --git a/tests/ref/issue-3191-raw-indent-shrink.png b/tests/ref/issue-3191-raw-indent-shrink.png new file mode 100644 index 000000000..e7ac73b73 Binary files /dev/null and b/tests/ref/issue-3191-raw-indent-shrink.png differ diff --git a/tests/ref/issue-3191-raw-normal-paragraphs-still-shrink.png b/tests/ref/issue-3191-raw-normal-paragraphs-still-shrink.png new file mode 100644 index 000000000..1eb499959 Binary files /dev/null and b/tests/ref/issue-3191-raw-normal-paragraphs-still-shrink.png differ diff --git a/tests/ref/issue-3232-dict-empty.png b/tests/ref/issue-3232-dict-empty.png new file mode 100644 index 000000000..f8d3f324f Binary files /dev/null and b/tests/ref/issue-3232-dict-empty.png differ diff --git a/tests/ref/issue-3264-rect-negative-dimensions.png b/tests/ref/issue-3264-rect-negative-dimensions.png new file mode 100644 index 000000000..44a046811 Binary files /dev/null and b/tests/ref/issue-3264-rect-negative-dimensions.png differ diff --git a/tests/ref/issue-3363-json-large-number.png b/tests/ref/issue-3363-json-large-number.png new file mode 100644 index 000000000..3e13dea16 Binary files /dev/null and b/tests/ref/issue-3363-json-large-number.png differ diff --git a/tests/ref/issue-3586-figure-caption-separator.png b/tests/ref/issue-3586-figure-caption-separator.png new file mode 100644 index 000000000..1d038fe3f Binary files /dev/null and b/tests/ref/issue-3586-figure-caption-separator.png differ diff --git a/tests/ref/issue-3624-spacing-behaviour.png b/tests/ref/issue-3624-spacing-behaviour.png new file mode 100644 index 000000000..c7db67538 Binary files /dev/null and b/tests/ref/issue-3624-spacing-behaviour.png differ diff --git a/tests/ref/issue-3641-float-loop.png b/tests/ref/issue-3641-float-loop.png new file mode 100644 index 000000000..4490d30a5 Binary files /dev/null and b/tests/ref/issue-3641-float-loop.png differ diff --git a/tests/ref/issue-3650-italic-equation.png b/tests/ref/issue-3650-italic-equation.png new file mode 100644 index 000000000..484457e82 Binary files /dev/null and b/tests/ref/issue-3650-italic-equation.png differ diff --git a/tests/ref/issue-3658-math-size.png b/tests/ref/issue-3658-math-size.png new file mode 100644 index 000000000..db8fccf9a Binary files /dev/null and b/tests/ref/issue-3658-math-size.png differ diff --git a/tests/ref/issue-3662-pdf-smartquotes.png b/tests/ref/issue-3662-pdf-smartquotes.png new file mode 100644 index 000000000..ff73cbc80 Binary files /dev/null and b/tests/ref/issue-3662-pdf-smartquotes.png differ diff --git a/tests/ref/issue-3700-deformed-stroke.png b/tests/ref/issue-3700-deformed-stroke.png new file mode 100644 index 000000000..9578a675d Binary files /dev/null and b/tests/ref/issue-3700-deformed-stroke.png differ diff --git a/tests/ref/issue-3841-tabs-in-raw-type-code.png b/tests/ref/issue-3841-tabs-in-raw-type-code.png new file mode 100644 index 000000000..b7a7b1bae Binary files /dev/null and b/tests/ref/issue-3841-tabs-in-raw-type-code.png differ diff --git a/tests/ref/issue-622-hide-meta-cite.png b/tests/ref/issue-622-hide-meta-cite.png new file mode 100644 index 000000000..8918f668a Binary files /dev/null and b/tests/ref/issue-622-hide-meta-cite.png differ diff --git a/tests/ref/issue-622-hide-meta-outline.png b/tests/ref/issue-622-hide-meta-outline.png new file mode 100644 index 000000000..72a82e4d8 Binary files /dev/null and b/tests/ref/issue-622-hide-meta-outline.png differ diff --git a/tests/ref/issue-785-cite-locate.png b/tests/ref/issue-785-cite-locate.png new file mode 100644 index 000000000..7c2a650a4 Binary files /dev/null and b/tests/ref/issue-785-cite-locate.png differ diff --git a/tests/ref/issue-80-emoji-linebreak.png b/tests/ref/issue-80-emoji-linebreak.png new file mode 100644 index 000000000..d35a62b3c Binary files /dev/null and b/tests/ref/issue-80-emoji-linebreak.png differ diff --git a/tests/ref/issue-852-mat-type.png b/tests/ref/issue-852-mat-type.png new file mode 100644 index 000000000..81af3bb5b Binary files /dev/null and b/tests/ref/issue-852-mat-type.png differ diff --git a/tests/ref/issue-870-image-rotation.png b/tests/ref/issue-870-image-rotation.png new file mode 100644 index 000000000..c321a1a93 Binary files /dev/null and b/tests/ref/issue-870-image-rotation.png differ diff --git a/tests/ref/issue-886-args-sink.png b/tests/ref/issue-886-args-sink.png new file mode 100644 index 000000000..2ef08adf9 Binary files /dev/null and b/tests/ref/issue-886-args-sink.png differ diff --git a/tests/ref/issue-columns-heading.png b/tests/ref/issue-columns-heading.png new file mode 100644 index 000000000..700972bc0 Binary files /dev/null and b/tests/ref/issue-columns-heading.png differ diff --git a/tests/ref/issue-flow-frame-placement.png b/tests/ref/issue-flow-frame-placement.png new file mode 100644 index 000000000..27469c279 Binary files /dev/null and b/tests/ref/issue-flow-frame-placement.png differ diff --git a/tests/ref/issue-flow-layout-index-out-of-bounds.png b/tests/ref/issue-flow-layout-index-out-of-bounds.png new file mode 100644 index 000000000..8746cbfc9 Binary files /dev/null and b/tests/ref/issue-flow-layout-index-out-of-bounds.png differ diff --git a/tests/ref/issue-flow-overlarge-frames.png b/tests/ref/issue-flow-overlarge-frames.png new file mode 100644 index 000000000..016af525d Binary files /dev/null and b/tests/ref/issue-flow-overlarge-frames.png differ diff --git a/tests/ref/issue-flow-trailing-leading.png b/tests/ref/issue-flow-trailing-leading.png new file mode 100644 index 000000000..4245d42fb Binary files /dev/null and b/tests/ref/issue-flow-trailing-leading.png differ diff --git a/tests/ref/issue-flow-weak-spacing.png b/tests/ref/issue-flow-weak-spacing.png new file mode 100644 index 000000000..e37a5ae33 Binary files /dev/null and b/tests/ref/issue-flow-weak-spacing.png differ diff --git a/tests/ref/issue-gradient-cmyk-encode.png b/tests/ref/issue-gradient-cmyk-encode.png new file mode 100644 index 000000000..065d1a3b4 Binary files /dev/null and b/tests/ref/issue-gradient-cmyk-encode.png differ diff --git a/tests/ref/issue-grid-base-auto-row-list.png b/tests/ref/issue-grid-base-auto-row-list.png new file mode 100644 index 000000000..8da3adf5d Binary files /dev/null and b/tests/ref/issue-grid-base-auto-row-list.png differ diff --git a/tests/ref/issue-grid-base-auto-row.png b/tests/ref/issue-grid-base-auto-row.png new file mode 100644 index 000000000..0e05577de Binary files /dev/null and b/tests/ref/issue-grid-base-auto-row.png differ diff --git a/tests/ref/issue-grid-double-skip.png b/tests/ref/issue-grid-double-skip.png new file mode 100644 index 000000000..2901f29ae Binary files /dev/null and b/tests/ref/issue-grid-double-skip.png differ diff --git a/tests/ref/issue-grid-gutter-skip.png b/tests/ref/issue-grid-gutter-skip.png new file mode 100644 index 000000000..3404fd101 Binary files /dev/null and b/tests/ref/issue-grid-gutter-skip.png differ diff --git a/tests/ref/issue-grid-skip-list.png b/tests/ref/issue-grid-skip-list.png new file mode 100644 index 000000000..bd6743376 Binary files /dev/null and b/tests/ref/issue-grid-skip-list.png differ diff --git a/tests/ref/issue-grid-skip.png b/tests/ref/issue-grid-skip.png new file mode 100644 index 000000000..1b46fd1a3 Binary files /dev/null and b/tests/ref/issue-grid-skip.png differ diff --git a/tests/ref/issue-math-realize-hide.png b/tests/ref/issue-math-realize-hide.png new file mode 100644 index 000000000..729e9f00c Binary files /dev/null and b/tests/ref/issue-math-realize-hide.png differ diff --git a/tests/ref/issue-math-realize-scripting.png b/tests/ref/issue-math-realize-scripting.png new file mode 100644 index 000000000..a29b0364d Binary files /dev/null and b/tests/ref/issue-math-realize-scripting.png differ diff --git a/tests/ref/issue-math-realize-show.png b/tests/ref/issue-math-realize-show.png new file mode 100644 index 000000000..d6b727c1d Binary files /dev/null and b/tests/ref/issue-math-realize-show.png differ diff --git a/tests/ref/issue-multiple-footnote-in-one-line.png b/tests/ref/issue-multiple-footnote-in-one-line.png new file mode 100644 index 000000000..1d8c017d4 Binary files /dev/null and b/tests/ref/issue-multiple-footnote-in-one-line.png differ diff --git a/tests/ref/issue-non-atomic-closure.png b/tests/ref/issue-non-atomic-closure.png new file mode 100644 index 000000000..f60b46548 Binary files /dev/null and b/tests/ref/issue-non-atomic-closure.png differ diff --git a/tests/ref/issue-place-base.png b/tests/ref/issue-place-base.png new file mode 100644 index 000000000..45517fe94 Binary files /dev/null and b/tests/ref/issue-place-base.png differ diff --git a/tests/ref/issue-rtl-safe-to-break-panic.png b/tests/ref/issue-rtl-safe-to-break-panic.png new file mode 100644 index 000000000..5cd9920cc Binary files /dev/null and b/tests/ref/issue-rtl-safe-to-break-panic.png differ diff --git a/tests/ref/justify-avoid-runts.png b/tests/ref/justify-avoid-runts.png new file mode 100644 index 000000000..70513939c Binary files /dev/null and b/tests/ref/justify-avoid-runts.png differ diff --git a/tests/ref/justify-chinese.png b/tests/ref/justify-chinese.png new file mode 100644 index 000000000..0284e8b9d Binary files /dev/null and b/tests/ref/justify-chinese.png differ diff --git a/tests/ref/justify-code-blocks.png b/tests/ref/justify-code-blocks.png new file mode 100644 index 000000000..088e8b636 Binary files /dev/null and b/tests/ref/justify-code-blocks.png differ diff --git a/tests/ref/justify-japanese.png b/tests/ref/justify-japanese.png new file mode 100644 index 000000000..addeba548 Binary files /dev/null and b/tests/ref/justify-japanese.png differ diff --git a/tests/ref/justify-justified-linebreak.png b/tests/ref/justify-justified-linebreak.png new file mode 100644 index 000000000..8792e9e2e Binary files /dev/null and b/tests/ref/justify-justified-linebreak.png differ diff --git a/tests/ref/justify-knuth-story.png b/tests/ref/justify-knuth-story.png new file mode 100644 index 000000000..9fbcc3c3e Binary files /dev/null and b/tests/ref/justify-knuth-story.png differ diff --git a/tests/ref/justify-manual-linebreak.png b/tests/ref/justify-manual-linebreak.png new file mode 100644 index 000000000..144a62c73 Binary files /dev/null and b/tests/ref/justify-manual-linebreak.png differ diff --git a/tests/ref/justify-no-leading-spaces.png b/tests/ref/justify-no-leading-spaces.png new file mode 100644 index 000000000..9d2557b5c Binary files /dev/null and b/tests/ref/justify-no-leading-spaces.png differ diff --git a/tests/ref/justify-punctuation-adjustment.png b/tests/ref/justify-punctuation-adjustment.png new file mode 100644 index 000000000..28d4ef047 Binary files /dev/null and b/tests/ref/justify-punctuation-adjustment.png differ diff --git a/tests/ref/justify-shrink-last-line.png b/tests/ref/justify-shrink-last-line.png new file mode 100644 index 000000000..f839e92ed Binary files /dev/null and b/tests/ref/justify-shrink-last-line.png differ diff --git a/tests/ref/justify-variants.png b/tests/ref/justify-variants.png new file mode 100644 index 000000000..81fcc700e Binary files /dev/null and b/tests/ref/justify-variants.png differ diff --git a/tests/ref/justify-whitespace-adjustment.png b/tests/ref/justify-whitespace-adjustment.png new file mode 100644 index 000000000..4ea6829ca Binary files /dev/null and b/tests/ref/justify-whitespace-adjustment.png differ diff --git a/tests/ref/justify-without-justifiables.png b/tests/ref/justify-without-justifiables.png new file mode 100644 index 000000000..77e5bf1b3 Binary files /dev/null and b/tests/ref/justify-without-justifiables.png differ diff --git a/tests/ref/justify.png b/tests/ref/justify.png new file mode 100644 index 000000000..4e4fdbf54 Binary files /dev/null and b/tests/ref/justify.png differ diff --git a/tests/ref/label-after-expression.png b/tests/ref/label-after-expression.png new file mode 100644 index 000000000..5ceaf3420 Binary files /dev/null and b/tests/ref/label-after-expression.png differ diff --git a/tests/ref/label-after-parbreak.png b/tests/ref/label-after-parbreak.png new file mode 100644 index 000000000..9339c65c2 Binary files /dev/null and b/tests/ref/label-after-parbreak.png differ diff --git a/tests/ref/label-dynamic-show-set.png b/tests/ref/label-dynamic-show-set.png new file mode 100644 index 000000000..25681b929 Binary files /dev/null and b/tests/ref/label-dynamic-show-set.png differ diff --git a/tests/ref/label-in-block.png b/tests/ref/label-in-block.png new file mode 100644 index 000000000..e97bd7257 Binary files /dev/null and b/tests/ref/label-in-block.png differ diff --git a/tests/ref/label-on-text.png b/tests/ref/label-on-text.png new file mode 100644 index 000000000..67fb1aa81 Binary files /dev/null and b/tests/ref/label-on-text.png differ diff --git a/tests/ref/label-show-where-selector.png b/tests/ref/label-show-where-selector.png new file mode 100644 index 000000000..61e90a9ad Binary files /dev/null and b/tests/ref/label-show-where-selector.png differ diff --git a/tests/ref/label-unclosed-is-text.png b/tests/ref/label-unclosed-is-text.png new file mode 100644 index 000000000..051db0cf9 Binary files /dev/null and b/tests/ref/label-unclosed-is-text.png differ diff --git a/tests/ref/layout-in-fixed-size-block.png b/tests/ref/layout-in-fixed-size-block.png new file mode 100644 index 000000000..6cc321b36 Binary files /dev/null and b/tests/ref/layout-in-fixed-size-block.png differ diff --git a/tests/ref/layout-in-page-call.png b/tests/ref/layout-in-page-call.png new file mode 100644 index 000000000..9bc75ae79 Binary files /dev/null and b/tests/ref/layout-in-page-call.png differ diff --git a/tests/ref/layout/align.png b/tests/ref/layout/align.png deleted file mode 100644 index a01135976..000000000 Binary files a/tests/ref/layout/align.png and /dev/null differ diff --git a/tests/ref/layout/block-sizing.png b/tests/ref/layout/block-sizing.png deleted file mode 100644 index 7d57a0d83..000000000 Binary files a/tests/ref/layout/block-sizing.png and /dev/null differ diff --git a/tests/ref/layout/block-spacing.png b/tests/ref/layout/block-spacing.png deleted file mode 100644 index d73abac02..000000000 Binary files a/tests/ref/layout/block-spacing.png and /dev/null differ diff --git a/tests/ref/layout/cjk-latin-spacing.png b/tests/ref/layout/cjk-latin-spacing.png deleted file mode 100644 index 629145e46..000000000 Binary files a/tests/ref/layout/cjk-latin-spacing.png and /dev/null differ diff --git a/tests/ref/layout/cjk-punctuation-adjustment.png b/tests/ref/layout/cjk-punctuation-adjustment.png deleted file mode 100644 index 1da08f23f..000000000 Binary files a/tests/ref/layout/cjk-punctuation-adjustment.png and /dev/null differ diff --git a/tests/ref/layout/clip.png b/tests/ref/layout/clip.png deleted file mode 100644 index f37bf9ad1..000000000 Binary files a/tests/ref/layout/clip.png and /dev/null differ diff --git a/tests/ref/layout/code-indent-shrink.png b/tests/ref/layout/code-indent-shrink.png deleted file mode 100644 index 26f6ec404..000000000 Binary files a/tests/ref/layout/code-indent-shrink.png and /dev/null differ diff --git a/tests/ref/layout/columns.png b/tests/ref/layout/columns.png deleted file mode 100644 index 38912f1bf..000000000 Binary files a/tests/ref/layout/columns.png and /dev/null differ diff --git a/tests/ref/layout/container-fill.png b/tests/ref/layout/container-fill.png deleted file mode 100644 index 74fdc73df..000000000 Binary files a/tests/ref/layout/container-fill.png and /dev/null differ diff --git a/tests/ref/layout/container.png b/tests/ref/layout/container.png deleted file mode 100644 index 0cd56b2df..000000000 Binary files a/tests/ref/layout/container.png and /dev/null differ diff --git a/tests/ref/layout/enum-align.png b/tests/ref/layout/enum-align.png deleted file mode 100644 index 18e392f2f..000000000 Binary files a/tests/ref/layout/enum-align.png and /dev/null differ diff --git a/tests/ref/layout/enum-numbering.png b/tests/ref/layout/enum-numbering.png deleted file mode 100644 index e1b2103bb..000000000 Binary files a/tests/ref/layout/enum-numbering.png and /dev/null differ diff --git a/tests/ref/layout/enum.png b/tests/ref/layout/enum.png deleted file mode 100644 index 62f1e4abf..000000000 Binary files a/tests/ref/layout/enum.png and /dev/null differ diff --git a/tests/ref/layout/flow-orphan.png b/tests/ref/layout/flow-orphan.png deleted file mode 100644 index 434636c45..000000000 Binary files a/tests/ref/layout/flow-orphan.png and /dev/null differ diff --git a/tests/ref/layout/grid-1.png b/tests/ref/layout/grid-1.png deleted file mode 100644 index 9e33772c8..000000000 Binary files a/tests/ref/layout/grid-1.png and /dev/null differ diff --git a/tests/ref/layout/grid-2.png b/tests/ref/layout/grid-2.png deleted file mode 100644 index ac1f7014b..000000000 Binary files a/tests/ref/layout/grid-2.png and /dev/null differ diff --git a/tests/ref/layout/grid-3.png b/tests/ref/layout/grid-3.png deleted file mode 100644 index 0f54f2ccd..000000000 Binary files a/tests/ref/layout/grid-3.png and /dev/null differ diff --git a/tests/ref/layout/grid-4.png b/tests/ref/layout/grid-4.png deleted file mode 100644 index 35a05ab52..000000000 Binary files a/tests/ref/layout/grid-4.png and /dev/null differ diff --git a/tests/ref/layout/grid-5.png b/tests/ref/layout/grid-5.png deleted file mode 100644 index 233ebb00c..000000000 Binary files a/tests/ref/layout/grid-5.png and /dev/null differ diff --git a/tests/ref/layout/grid-auto-shrink.png b/tests/ref/layout/grid-auto-shrink.png deleted file mode 100644 index 34995215b..000000000 Binary files a/tests/ref/layout/grid-auto-shrink.png and /dev/null differ diff --git a/tests/ref/layout/grid-cell.png b/tests/ref/layout/grid-cell.png deleted file mode 100644 index 563d6721e..000000000 Binary files a/tests/ref/layout/grid-cell.png and /dev/null differ diff --git a/tests/ref/layout/grid-colspan.png b/tests/ref/layout/grid-colspan.png deleted file mode 100644 index e16ca347e..000000000 Binary files a/tests/ref/layout/grid-colspan.png and /dev/null differ diff --git a/tests/ref/layout/grid-footers-1.png b/tests/ref/layout/grid-footers-1.png deleted file mode 100644 index 331cf7ad5..000000000 Binary files a/tests/ref/layout/grid-footers-1.png and /dev/null differ diff --git a/tests/ref/layout/grid-footers-2.png b/tests/ref/layout/grid-footers-2.png deleted file mode 100644 index 60e9689c6..000000000 Binary files a/tests/ref/layout/grid-footers-2.png and /dev/null differ diff --git a/tests/ref/layout/grid-footers-3.png b/tests/ref/layout/grid-footers-3.png deleted file mode 100644 index cc4948b80..000000000 Binary files a/tests/ref/layout/grid-footers-3.png and /dev/null differ diff --git a/tests/ref/layout/grid-footers-4.png b/tests/ref/layout/grid-footers-4.png deleted file mode 100644 index 29a6430bd..000000000 Binary files a/tests/ref/layout/grid-footers-4.png and /dev/null differ diff --git a/tests/ref/layout/grid-footers-5.png b/tests/ref/layout/grid-footers-5.png deleted file mode 100644 index 6cae5592c..000000000 Binary files a/tests/ref/layout/grid-footers-5.png and /dev/null differ diff --git a/tests/ref/layout/grid-headers-1.png b/tests/ref/layout/grid-headers-1.png deleted file mode 100644 index 7ae2d8d34..000000000 Binary files a/tests/ref/layout/grid-headers-1.png and /dev/null differ diff --git a/tests/ref/layout/grid-headers-2.png b/tests/ref/layout/grid-headers-2.png deleted file mode 100644 index 3dbc07c88..000000000 Binary files a/tests/ref/layout/grid-headers-2.png and /dev/null differ diff --git a/tests/ref/layout/grid-headers-3.png b/tests/ref/layout/grid-headers-3.png deleted file mode 100644 index 9ee77d50b..000000000 Binary files a/tests/ref/layout/grid-headers-3.png and /dev/null differ diff --git a/tests/ref/layout/grid-headers-4.png b/tests/ref/layout/grid-headers-4.png deleted file mode 100644 index 1f3e4b10f..000000000 Binary files a/tests/ref/layout/grid-headers-4.png and /dev/null differ diff --git a/tests/ref/layout/grid-positioning.png b/tests/ref/layout/grid-positioning.png deleted file mode 100644 index cac93f403..000000000 Binary files a/tests/ref/layout/grid-positioning.png and /dev/null differ diff --git a/tests/ref/layout/grid-rowspan-basic.png b/tests/ref/layout/grid-rowspan-basic.png deleted file mode 100644 index b464d8b40..000000000 Binary files a/tests/ref/layout/grid-rowspan-basic.png and /dev/null differ diff --git a/tests/ref/layout/grid-rowspan-split-1.png b/tests/ref/layout/grid-rowspan-split-1.png deleted file mode 100644 index 12cd5fc6f..000000000 Binary files a/tests/ref/layout/grid-rowspan-split-1.png and /dev/null differ diff --git a/tests/ref/layout/grid-rowspan-split-2.png b/tests/ref/layout/grid-rowspan-split-2.png deleted file mode 100644 index e55c5e230..000000000 Binary files a/tests/ref/layout/grid-rowspan-split-2.png and /dev/null differ diff --git a/tests/ref/layout/grid-rowspan-split-3.png b/tests/ref/layout/grid-rowspan-split-3.png deleted file mode 100644 index c3ff4bd15..000000000 Binary files a/tests/ref/layout/grid-rowspan-split-3.png and /dev/null differ diff --git a/tests/ref/layout/grid-rtl.png b/tests/ref/layout/grid-rtl.png deleted file mode 100644 index d628ee8ae..000000000 Binary files a/tests/ref/layout/grid-rtl.png and /dev/null differ diff --git a/tests/ref/layout/grid-stroke.png b/tests/ref/layout/grid-stroke.png deleted file mode 100644 index fbba379e8..000000000 Binary files a/tests/ref/layout/grid-stroke.png and /dev/null differ diff --git a/tests/ref/layout/grid-styling.png b/tests/ref/layout/grid-styling.png deleted file mode 100644 index dc50dd901..000000000 Binary files a/tests/ref/layout/grid-styling.png and /dev/null differ diff --git a/tests/ref/layout/hide.png b/tests/ref/layout/hide.png deleted file mode 100644 index d89800494..000000000 Binary files a/tests/ref/layout/hide.png and /dev/null differ diff --git a/tests/ref/layout/list-attach.png b/tests/ref/layout/list-attach.png deleted file mode 100644 index 4a6a45737..000000000 Binary files a/tests/ref/layout/list-attach.png and /dev/null differ diff --git a/tests/ref/layout/list-marker.png b/tests/ref/layout/list-marker.png deleted file mode 100644 index 19d6ed5fa..000000000 Binary files a/tests/ref/layout/list-marker.png and /dev/null differ diff --git a/tests/ref/layout/list.png b/tests/ref/layout/list.png deleted file mode 100644 index 269243eb9..000000000 Binary files a/tests/ref/layout/list.png and /dev/null differ diff --git a/tests/ref/layout/out-of-flow-in-block.png b/tests/ref/layout/out-of-flow-in-block.png deleted file mode 100644 index 97637145f..000000000 Binary files a/tests/ref/layout/out-of-flow-in-block.png and /dev/null differ diff --git a/tests/ref/layout/pad.png b/tests/ref/layout/pad.png deleted file mode 100644 index d228f07fb..000000000 Binary files a/tests/ref/layout/pad.png and /dev/null differ diff --git a/tests/ref/layout/page-binding.png b/tests/ref/layout/page-binding.png deleted file mode 100644 index 5b6d06576..000000000 Binary files a/tests/ref/layout/page-binding.png and /dev/null differ diff --git a/tests/ref/layout/page-margin.png b/tests/ref/layout/page-margin.png deleted file mode 100644 index f690724b2..000000000 Binary files a/tests/ref/layout/page-margin.png and /dev/null differ diff --git a/tests/ref/layout/page-marginals.png b/tests/ref/layout/page-marginals.png deleted file mode 100644 index bbe6358ed..000000000 Binary files a/tests/ref/layout/page-marginals.png and /dev/null differ diff --git a/tests/ref/layout/page-number-align.png b/tests/ref/layout/page-number-align.png deleted file mode 100644 index b05ca4545..000000000 Binary files a/tests/ref/layout/page-number-align.png and /dev/null differ diff --git a/tests/ref/layout/page-style.png b/tests/ref/layout/page-style.png deleted file mode 100644 index ac6b602c1..000000000 Binary files a/tests/ref/layout/page-style.png and /dev/null differ diff --git a/tests/ref/layout/page.png b/tests/ref/layout/page.png deleted file mode 100644 index bcf325261..000000000 Binary files a/tests/ref/layout/page.png and /dev/null differ diff --git a/tests/ref/layout/pagebreak-parity.png b/tests/ref/layout/pagebreak-parity.png deleted file mode 100644 index 0dbabe7ae..000000000 Binary files a/tests/ref/layout/pagebreak-parity.png and /dev/null differ diff --git a/tests/ref/layout/pagebreak-weak.png b/tests/ref/layout/pagebreak-weak.png deleted file mode 100644 index 412c4e8d6..000000000 Binary files a/tests/ref/layout/pagebreak-weak.png and /dev/null differ diff --git a/tests/ref/layout/pagebreak.png b/tests/ref/layout/pagebreak.png deleted file mode 100644 index ab0556433..000000000 Binary files a/tests/ref/layout/pagebreak.png and /dev/null differ diff --git a/tests/ref/layout/par-bidi.png b/tests/ref/layout/par-bidi.png deleted file mode 100644 index af66a719f..000000000 Binary files a/tests/ref/layout/par-bidi.png and /dev/null differ diff --git a/tests/ref/layout/par-indent.png b/tests/ref/layout/par-indent.png deleted file mode 100644 index cceaa3b91..000000000 Binary files a/tests/ref/layout/par-indent.png and /dev/null differ diff --git a/tests/ref/layout/par-justify-cjk.png b/tests/ref/layout/par-justify-cjk.png deleted file mode 100644 index 25adfcb25..000000000 Binary files a/tests/ref/layout/par-justify-cjk.png and /dev/null differ diff --git a/tests/ref/layout/par-justify.png b/tests/ref/layout/par-justify.png deleted file mode 100644 index 0cd9cbcdc..000000000 Binary files a/tests/ref/layout/par-justify.png and /dev/null differ diff --git a/tests/ref/layout/par-knuth.png b/tests/ref/layout/par-knuth.png deleted file mode 100644 index f3da17531..000000000 Binary files a/tests/ref/layout/par-knuth.png and /dev/null differ diff --git a/tests/ref/layout/par-simple.png b/tests/ref/layout/par-simple.png deleted file mode 100644 index a645bfd89..000000000 Binary files a/tests/ref/layout/par-simple.png and /dev/null differ diff --git a/tests/ref/layout/par.png b/tests/ref/layout/par.png deleted file mode 100644 index f25f56d2b..000000000 Binary files a/tests/ref/layout/par.png and /dev/null differ diff --git a/tests/ref/layout/place-background.png b/tests/ref/layout/place-background.png deleted file mode 100644 index d9c1c42f3..000000000 Binary files a/tests/ref/layout/place-background.png and /dev/null differ diff --git a/tests/ref/layout/place-float-auto.png b/tests/ref/layout/place-float-auto.png deleted file mode 100644 index f2e4ee92e..000000000 Binary files a/tests/ref/layout/place-float-auto.png and /dev/null differ diff --git a/tests/ref/layout/place-float-columns.png b/tests/ref/layout/place-float-columns.png deleted file mode 100644 index 186b79d14..000000000 Binary files a/tests/ref/layout/place-float-columns.png and /dev/null differ diff --git a/tests/ref/layout/place-float-figure.png b/tests/ref/layout/place-float-figure.png deleted file mode 100644 index bf9d21b4f..000000000 Binary files a/tests/ref/layout/place-float-figure.png and /dev/null differ diff --git a/tests/ref/layout/place-nested.png b/tests/ref/layout/place-nested.png deleted file mode 100644 index 864830d85..000000000 Binary files a/tests/ref/layout/place-nested.png and /dev/null differ diff --git a/tests/ref/layout/place.png b/tests/ref/layout/place.png deleted file mode 100644 index 2ef85a4de..000000000 Binary files a/tests/ref/layout/place.png and /dev/null differ diff --git a/tests/ref/layout/repeat.png b/tests/ref/layout/repeat.png deleted file mode 100644 index 8e21f1022..000000000 Binary files a/tests/ref/layout/repeat.png and /dev/null differ diff --git a/tests/ref/layout/spacing.png b/tests/ref/layout/spacing.png deleted file mode 100644 index 9bab536a2..000000000 Binary files a/tests/ref/layout/spacing.png and /dev/null differ diff --git a/tests/ref/layout/stack-1.png b/tests/ref/layout/stack-1.png deleted file mode 100644 index 1a3133b82..000000000 Binary files a/tests/ref/layout/stack-1.png and /dev/null differ diff --git a/tests/ref/layout/stack-2.png b/tests/ref/layout/stack-2.png deleted file mode 100644 index 6cb0aad2f..000000000 Binary files a/tests/ref/layout/stack-2.png and /dev/null differ diff --git a/tests/ref/layout/table-cell.png b/tests/ref/layout/table-cell.png deleted file mode 100644 index d0c393636..000000000 Binary files a/tests/ref/layout/table-cell.png and /dev/null differ diff --git a/tests/ref/layout/table.png b/tests/ref/layout/table.png deleted file mode 100644 index ddd0e0434..000000000 Binary files a/tests/ref/layout/table.png and /dev/null differ diff --git a/tests/ref/layout/terms.png b/tests/ref/layout/terms.png deleted file mode 100644 index e0cd013ab..000000000 Binary files a/tests/ref/layout/terms.png and /dev/null differ diff --git a/tests/ref/layout/transform-layout.png b/tests/ref/layout/transform-layout.png deleted file mode 100644 index 576824f06..000000000 Binary files a/tests/ref/layout/transform-layout.png and /dev/null differ diff --git a/tests/ref/layout/transform.png b/tests/ref/layout/transform.png deleted file mode 100644 index 83b7d13ab..000000000 Binary files a/tests/ref/layout/transform.png and /dev/null differ diff --git a/tests/ref/let-basic.png b/tests/ref/let-basic.png new file mode 100644 index 000000000..ded47a5a9 Binary files /dev/null and b/tests/ref/let-basic.png differ diff --git a/tests/ref/let-termination.png b/tests/ref/let-termination.png new file mode 100644 index 000000000..552bb4ce4 Binary files /dev/null and b/tests/ref/let-termination.png differ diff --git a/tests/ref/line-basic.png b/tests/ref/line-basic.png new file mode 100644 index 000000000..007672e12 Binary files /dev/null and b/tests/ref/line-basic.png differ diff --git a/tests/ref/line-positioning.png b/tests/ref/line-positioning.png new file mode 100644 index 000000000..65678caa6 Binary files /dev/null and b/tests/ref/line-positioning.png differ diff --git a/tests/ref/line-stroke-dash.png b/tests/ref/line-stroke-dash.png new file mode 100644 index 000000000..f245e32fd Binary files /dev/null and b/tests/ref/line-stroke-dash.png differ diff --git a/tests/ref/line-stroke-set.png b/tests/ref/line-stroke-set.png new file mode 100644 index 000000000..f82f899eb Binary files /dev/null and b/tests/ref/line-stroke-set.png differ diff --git a/tests/ref/line-stroke.png b/tests/ref/line-stroke.png new file mode 100644 index 000000000..d0213002e Binary files /dev/null and b/tests/ref/line-stroke.png differ diff --git a/tests/ref/linebreak-cite-punctuation.png b/tests/ref/linebreak-cite-punctuation.png new file mode 100644 index 000000000..64d930c6d Binary files /dev/null and b/tests/ref/linebreak-cite-punctuation.png differ diff --git a/tests/ref/linebreak-hyphen-nbsp.png b/tests/ref/linebreak-hyphen-nbsp.png new file mode 100644 index 000000000..ee88ae586 Binary files /dev/null and b/tests/ref/linebreak-hyphen-nbsp.png differ diff --git a/tests/ref/linebreak-link-end.png b/tests/ref/linebreak-link-end.png new file mode 100644 index 000000000..f11e91d60 Binary files /dev/null and b/tests/ref/linebreak-link-end.png differ diff --git a/tests/ref/linebreak-link-justify.png b/tests/ref/linebreak-link-justify.png new file mode 100644 index 000000000..8007cf3e2 Binary files /dev/null and b/tests/ref/linebreak-link-justify.png differ diff --git a/tests/ref/linebreak-link.png b/tests/ref/linebreak-link.png new file mode 100644 index 000000000..d5ba8c9e3 Binary files /dev/null and b/tests/ref/linebreak-link.png differ diff --git a/tests/ref/linebreak-manual-consecutive.png b/tests/ref/linebreak-manual-consecutive.png new file mode 100644 index 000000000..0dbef35b9 Binary files /dev/null and b/tests/ref/linebreak-manual-consecutive.png differ diff --git a/tests/ref/linebreak-manual-directly-after-automatic.png b/tests/ref/linebreak-manual-directly-after-automatic.png new file mode 100644 index 000000000..006e3ef26 Binary files /dev/null and b/tests/ref/linebreak-manual-directly-after-automatic.png differ diff --git a/tests/ref/linebreak-manual-justified.png b/tests/ref/linebreak-manual-justified.png new file mode 100644 index 000000000..f74ea3fd0 Binary files /dev/null and b/tests/ref/linebreak-manual-justified.png differ diff --git a/tests/ref/linebreak-manual-trailing-multiple.png b/tests/ref/linebreak-manual-trailing-multiple.png new file mode 100644 index 000000000..edf3a9499 Binary files /dev/null and b/tests/ref/linebreak-manual-trailing-multiple.png differ diff --git a/tests/ref/linebreak-manual.png b/tests/ref/linebreak-manual.png new file mode 100644 index 000000000..37aca398a Binary files /dev/null and b/tests/ref/linebreak-manual.png differ diff --git a/tests/ref/linebreak-math-punctuation.png b/tests/ref/linebreak-math-punctuation.png new file mode 100644 index 000000000..93b77d2af Binary files /dev/null and b/tests/ref/linebreak-math-punctuation.png differ diff --git a/tests/ref/linebreak-narrow-nbsp.png b/tests/ref/linebreak-narrow-nbsp.png new file mode 100644 index 000000000..81cf82f86 Binary files /dev/null and b/tests/ref/linebreak-narrow-nbsp.png differ diff --git a/tests/ref/linebreak-overflow-double.png b/tests/ref/linebreak-overflow-double.png new file mode 100644 index 000000000..04a5bbaaa Binary files /dev/null and b/tests/ref/linebreak-overflow-double.png differ diff --git a/tests/ref/linebreak-overflow.png b/tests/ref/linebreak-overflow.png new file mode 100644 index 000000000..1dfcbc27e Binary files /dev/null and b/tests/ref/linebreak-overflow.png differ diff --git a/tests/ref/linebreak-shape-run.png b/tests/ref/linebreak-shape-run.png new file mode 100644 index 000000000..ebfb87f06 Binary files /dev/null and b/tests/ref/linebreak-shape-run.png differ diff --git a/tests/ref/linebreak-thai.png b/tests/ref/linebreak-thai.png new file mode 100644 index 000000000..8053a2128 Binary files /dev/null and b/tests/ref/linebreak-thai.png differ diff --git a/tests/ref/link-basic.png b/tests/ref/link-basic.png new file mode 100644 index 000000000..d16c7ef15 Binary files /dev/null and b/tests/ref/link-basic.png differ diff --git a/tests/ref/link-bracket-balanced.png b/tests/ref/link-bracket-balanced.png new file mode 100644 index 000000000..048a7c52b Binary files /dev/null and b/tests/ref/link-bracket-balanced.png differ diff --git a/tests/ref/link-bracket-unbalanced-closing.png b/tests/ref/link-bracket-unbalanced-closing.png new file mode 100644 index 000000000..e1c1341ce Binary files /dev/null and b/tests/ref/link-bracket-unbalanced-closing.png differ diff --git a/tests/ref/link-on-block.png b/tests/ref/link-on-block.png new file mode 100644 index 000000000..9076983de Binary files /dev/null and b/tests/ref/link-on-block.png differ diff --git a/tests/ref/link-show.png b/tests/ref/link-show.png new file mode 100644 index 000000000..59542bad8 Binary files /dev/null and b/tests/ref/link-show.png differ diff --git a/tests/ref/link-to-label.png b/tests/ref/link-to-label.png new file mode 100644 index 000000000..f60755261 Binary files /dev/null and b/tests/ref/link-to-label.png differ diff --git a/tests/ref/link-to-page.png b/tests/ref/link-to-page.png new file mode 100644 index 000000000..bbd2f1035 Binary files /dev/null and b/tests/ref/link-to-page.png differ diff --git a/tests/ref/link-trailing-period.png b/tests/ref/link-trailing-period.png new file mode 100644 index 000000000..4dd11f340 Binary files /dev/null and b/tests/ref/link-trailing-period.png differ diff --git a/tests/ref/link-transformed.png b/tests/ref/link-transformed.png new file mode 100644 index 000000000..6b94b5cb3 Binary files /dev/null and b/tests/ref/link-transformed.png differ diff --git a/tests/ref/list-attached-above-spacing.png b/tests/ref/list-attached-above-spacing.png new file mode 100644 index 000000000..0f499769b Binary files /dev/null and b/tests/ref/list-attached-above-spacing.png differ diff --git a/tests/ref/list-attached.png b/tests/ref/list-attached.png new file mode 100644 index 000000000..c1735fd01 Binary files /dev/null and b/tests/ref/list-attached.png differ diff --git a/tests/ref/list-basic.png b/tests/ref/list-basic.png new file mode 100644 index 000000000..edf69cac7 Binary files /dev/null and b/tests/ref/list-basic.png differ diff --git a/tests/ref/list-content-block.png b/tests/ref/list-content-block.png new file mode 100644 index 000000000..18b003e57 Binary files /dev/null and b/tests/ref/list-content-block.png differ diff --git a/tests/ref/list-indent-specifics.png b/tests/ref/list-indent-specifics.png new file mode 100644 index 000000000..212e45ed0 Binary files /dev/null and b/tests/ref/list-indent-specifics.png differ diff --git a/tests/ref/list-marker-align-unaffected.png b/tests/ref/list-marker-align-unaffected.png new file mode 100644 index 000000000..90f9ad45b Binary files /dev/null and b/tests/ref/list-marker-align-unaffected.png differ diff --git a/tests/ref/list-marker-bare-hyphen.png b/tests/ref/list-marker-bare-hyphen.png new file mode 100644 index 000000000..37830fd67 Binary files /dev/null and b/tests/ref/list-marker-bare-hyphen.png differ diff --git a/tests/ref/list-marker-closure.png b/tests/ref/list-marker-closure.png new file mode 100644 index 000000000..4dba3b9d8 Binary files /dev/null and b/tests/ref/list-marker-closure.png differ diff --git a/tests/ref/list-marker-cycle.png b/tests/ref/list-marker-cycle.png new file mode 100644 index 000000000..ef219f074 Binary files /dev/null and b/tests/ref/list-marker-cycle.png differ diff --git a/tests/ref/list-marker-dash.png b/tests/ref/list-marker-dash.png new file mode 100644 index 000000000..10abc8a67 Binary files /dev/null and b/tests/ref/list-marker-dash.png differ diff --git a/tests/ref/list-mix.png b/tests/ref/list-mix.png new file mode 100644 index 000000000..0f2b03cf9 Binary files /dev/null and b/tests/ref/list-mix.png differ diff --git a/tests/ref/list-mixed-tabs-and-spaces.png b/tests/ref/list-mixed-tabs-and-spaces.png new file mode 100644 index 000000000..fcddff42b Binary files /dev/null and b/tests/ref/list-mixed-tabs-and-spaces.png differ diff --git a/tests/ref/list-nested.png b/tests/ref/list-nested.png new file mode 100644 index 000000000..22f73ecb3 Binary files /dev/null and b/tests/ref/list-nested.png differ diff --git a/tests/ref/list-non-attached-followed-by-attached.png b/tests/ref/list-non-attached-followed-by-attached.png new file mode 100644 index 000000000..22db4e388 Binary files /dev/null and b/tests/ref/list-non-attached-followed-by-attached.png differ diff --git a/tests/ref/list-rtl.png b/tests/ref/list-rtl.png new file mode 100644 index 000000000..db1e75463 Binary files /dev/null and b/tests/ref/list-rtl.png differ diff --git a/tests/ref/list-syntax-edge-cases.png b/tests/ref/list-syntax-edge-cases.png new file mode 100644 index 000000000..460462e3c Binary files /dev/null and b/tests/ref/list-syntax-edge-cases.png differ diff --git a/tests/ref/list-tabs.png b/tests/ref/list-tabs.png new file mode 100644 index 000000000..1fce74c35 Binary files /dev/null and b/tests/ref/list-tabs.png differ diff --git a/tests/ref/list-tight-non-attached-tight.png b/tests/ref/list-tight-non-attached-tight.png new file mode 100644 index 000000000..96d518133 Binary files /dev/null and b/tests/ref/list-tight-non-attached-tight.png differ diff --git a/tests/ref/list-top-level-indent.png b/tests/ref/list-top-level-indent.png new file mode 100644 index 000000000..beb17ede9 Binary files /dev/null and b/tests/ref/list-top-level-indent.png differ diff --git a/tests/ref/list-wide-cannot-attach.png b/tests/ref/list-wide-cannot-attach.png new file mode 100644 index 000000000..600041a77 Binary files /dev/null and b/tests/ref/list-wide-cannot-attach.png differ diff --git a/tests/ref/list-wide-really-cannot-attach.png b/tests/ref/list-wide-really-cannot-attach.png new file mode 100644 index 000000000..89680c092 Binary files /dev/null and b/tests/ref/list-wide-really-cannot-attach.png differ diff --git a/tests/ref/locate-element-selector.png b/tests/ref/locate-element-selector.png new file mode 100644 index 000000000..fc36ddff6 Binary files /dev/null and b/tests/ref/locate-element-selector.png differ diff --git a/tests/ref/locate-position.png b/tests/ref/locate-position.png new file mode 100644 index 000000000..fc36ddff6 Binary files /dev/null and b/tests/ref/locate-position.png differ diff --git a/tests/ref/loop-break-join-in-first-arg.png b/tests/ref/loop-break-join-in-first-arg.png new file mode 100644 index 000000000..fbad2125e Binary files /dev/null and b/tests/ref/loop-break-join-in-first-arg.png differ diff --git a/tests/ref/loop-break-join-in-nested-blocks.png b/tests/ref/loop-break-join-in-nested-blocks.png new file mode 100644 index 000000000..6e2af47a6 Binary files /dev/null and b/tests/ref/loop-break-join-in-nested-blocks.png differ diff --git a/tests/ref/loop-break-join-in-set-rule-args.png b/tests/ref/loop-break-join-in-set-rule-args.png new file mode 100644 index 000000000..37e137732 Binary files /dev/null and b/tests/ref/loop-break-join-in-set-rule-args.png differ diff --git a/tests/ref/loop-break-join-set-and-show.png b/tests/ref/loop-break-join-set-and-show.png new file mode 100644 index 000000000..8c81c1472 Binary files /dev/null and b/tests/ref/loop-break-join-set-and-show.png differ diff --git a/tests/ref/lorem-pars.png b/tests/ref/lorem-pars.png new file mode 100644 index 000000000..5ff0a3451 Binary files /dev/null and b/tests/ref/lorem-pars.png differ diff --git a/tests/ref/lorem.png b/tests/ref/lorem.png new file mode 100644 index 000000000..197acb1ce Binary files /dev/null and b/tests/ref/lorem.png differ diff --git a/tests/ref/math-accent-align.png b/tests/ref/math-accent-align.png new file mode 100644 index 000000000..84e8dc8cc Binary files /dev/null and b/tests/ref/math-accent-align.png differ diff --git a/tests/ref/math-accent-bounds.png b/tests/ref/math-accent-bounds.png new file mode 100644 index 000000000..d98761828 Binary files /dev/null and b/tests/ref/math-accent-bounds.png differ diff --git a/tests/ref/math-accent-func.png b/tests/ref/math-accent-func.png new file mode 100644 index 000000000..00821f70d Binary files /dev/null and b/tests/ref/math-accent-func.png differ diff --git a/tests/ref/math-accent-high-base.png b/tests/ref/math-accent-high-base.png new file mode 100644 index 000000000..f4d7580f1 Binary files /dev/null and b/tests/ref/math-accent-high-base.png differ diff --git a/tests/ref/math-accent-sized.png b/tests/ref/math-accent-sized.png new file mode 100644 index 000000000..76783b254 Binary files /dev/null and b/tests/ref/math-accent-sized.png differ diff --git a/tests/ref/math-accent-superscript.png b/tests/ref/math-accent-superscript.png new file mode 100644 index 000000000..8ddf113d5 Binary files /dev/null and b/tests/ref/math-accent-superscript.png differ diff --git a/tests/ref/math-accent-sym-call.png b/tests/ref/math-accent-sym-call.png new file mode 100644 index 000000000..0837a86c9 Binary files /dev/null and b/tests/ref/math-accent-sym-call.png differ diff --git a/tests/ref/math-accent-wide-base.png b/tests/ref/math-accent-wide-base.png new file mode 100644 index 000000000..af716bf45 Binary files /dev/null and b/tests/ref/math-accent-wide-base.png differ diff --git a/tests/ref/math-align-aligned-in-source.png b/tests/ref/math-align-aligned-in-source.png new file mode 100644 index 000000000..958a42c5d Binary files /dev/null and b/tests/ref/math-align-aligned-in-source.png differ diff --git a/tests/ref/math-align-basic.png b/tests/ref/math-align-basic.png new file mode 100644 index 000000000..cf4a8d6ae Binary files /dev/null and b/tests/ref/math-align-basic.png differ diff --git a/tests/ref/math-align-cases.png b/tests/ref/math-align-cases.png new file mode 100644 index 000000000..4ea9a264c Binary files /dev/null and b/tests/ref/math-align-cases.png differ diff --git a/tests/ref/math-align-implicit.png b/tests/ref/math-align-implicit.png new file mode 100644 index 000000000..05a0d98d8 Binary files /dev/null and b/tests/ref/math-align-implicit.png differ diff --git a/tests/ref/math-align-lines-mixed.png b/tests/ref/math-align-lines-mixed.png new file mode 100644 index 000000000..d50af28c5 Binary files /dev/null and b/tests/ref/math-align-lines-mixed.png differ diff --git a/tests/ref/math-align-post-fix.png b/tests/ref/math-align-post-fix.png new file mode 100644 index 000000000..33bc3da7f Binary files /dev/null and b/tests/ref/math-align-post-fix.png differ diff --git a/tests/ref/math-align-toggle.png b/tests/ref/math-align-toggle.png new file mode 100644 index 000000000..24448ab5f Binary files /dev/null and b/tests/ref/math-align-toggle.png differ diff --git a/tests/ref/math-align-weird.png b/tests/ref/math-align-weird.png new file mode 100644 index 000000000..672742ec1 Binary files /dev/null and b/tests/ref/math-align-weird.png differ diff --git a/tests/ref/math-align-wider-first-column.png b/tests/ref/math-align-wider-first-column.png new file mode 100644 index 000000000..46c9c3ff1 Binary files /dev/null and b/tests/ref/math-align-wider-first-column.png differ diff --git a/tests/ref/math-attach-default-placement.png b/tests/ref/math-attach-default-placement.png new file mode 100644 index 000000000..685fb550a Binary files /dev/null and b/tests/ref/math-attach-default-placement.png differ diff --git a/tests/ref/math-attach-descender-collision.png b/tests/ref/math-attach-descender-collision.png new file mode 100644 index 000000000..71654916b Binary files /dev/null and b/tests/ref/math-attach-descender-collision.png differ diff --git a/tests/ref/math-attach-followed-by-func-call.png b/tests/ref/math-attach-followed-by-func-call.png new file mode 100644 index 000000000..71d78c16e Binary files /dev/null and b/tests/ref/math-attach-followed-by-func-call.png differ diff --git a/tests/ref/math-attach-force-scripts-and-limits.png b/tests/ref/math-attach-force-scripts-and-limits.png new file mode 100644 index 000000000..21a1050f2 Binary files /dev/null and b/tests/ref/math-attach-force-scripts-and-limits.png differ diff --git a/tests/ref/math-attach-high.png b/tests/ref/math-attach-high.png new file mode 100644 index 000000000..4bb6cb29f Binary files /dev/null and b/tests/ref/math-attach-high.png differ diff --git a/tests/ref/math-attach-horizontal-align.png b/tests/ref/math-attach-horizontal-align.png new file mode 100644 index 000000000..507cb0ffd Binary files /dev/null and b/tests/ref/math-attach-horizontal-align.png differ diff --git a/tests/ref/math-attach-integral.png b/tests/ref/math-attach-integral.png new file mode 100644 index 000000000..baebf44c6 Binary files /dev/null and b/tests/ref/math-attach-integral.png differ diff --git a/tests/ref/math-attach-large-operator.png b/tests/ref/math-attach-large-operator.png new file mode 100644 index 000000000..774b603c0 Binary files /dev/null and b/tests/ref/math-attach-large-operator.png differ diff --git a/tests/ref/math-attach-limit.png b/tests/ref/math-attach-limit.png new file mode 100644 index 000000000..5f9f24d7c Binary files /dev/null and b/tests/ref/math-attach-limit.png differ diff --git a/tests/ref/math-attach-mixed.png b/tests/ref/math-attach-mixed.png new file mode 100644 index 000000000..4be327e3e Binary files /dev/null and b/tests/ref/math-attach-mixed.png differ diff --git a/tests/ref/math-attach-nested.png b/tests/ref/math-attach-nested.png new file mode 100644 index 000000000..8b4309cf8 Binary files /dev/null and b/tests/ref/math-attach-nested.png differ diff --git a/tests/ref/math-attach-postscripts.png b/tests/ref/math-attach-postscripts.png new file mode 100644 index 000000000..bd94e4bd7 Binary files /dev/null and b/tests/ref/math-attach-postscripts.png differ diff --git a/tests/ref/math-attach-prescripts.png b/tests/ref/math-attach-prescripts.png new file mode 100644 index 000000000..cd105e9df Binary files /dev/null and b/tests/ref/math-attach-prescripts.png differ diff --git a/tests/ref/math-attach-show-limit.png b/tests/ref/math-attach-show-limit.png new file mode 100644 index 000000000..4ce2b3fbc Binary files /dev/null and b/tests/ref/math-attach-show-limit.png differ diff --git a/tests/ref/math-attach-subscript-multiline.png b/tests/ref/math-attach-subscript-multiline.png new file mode 100644 index 000000000..7f9aec2e4 Binary files /dev/null and b/tests/ref/math-attach-subscript-multiline.png differ diff --git a/tests/ref/math-attach-to-group.png b/tests/ref/math-attach-to-group.png new file mode 100644 index 000000000..a3d1923eb Binary files /dev/null and b/tests/ref/math-attach-to-group.png differ diff --git a/tests/ref/math-binom-multiple.png b/tests/ref/math-binom-multiple.png new file mode 100644 index 000000000..7eb60be01 Binary files /dev/null and b/tests/ref/math-binom-multiple.png differ diff --git a/tests/ref/math-binom.png b/tests/ref/math-binom.png new file mode 100644 index 000000000..85ab08f92 Binary files /dev/null and b/tests/ref/math-binom.png differ diff --git a/tests/ref/math-box-with-baseline.png b/tests/ref/math-box-with-baseline.png new file mode 100644 index 000000000..e38e6442f Binary files /dev/null and b/tests/ref/math-box-with-baseline.png differ diff --git a/tests/ref/math-box-without-baseline.png b/tests/ref/math-box-without-baseline.png new file mode 100644 index 000000000..275495878 Binary files /dev/null and b/tests/ref/math-box-without-baseline.png differ diff --git a/tests/ref/math-call-non-func.png b/tests/ref/math-call-non-func.png new file mode 100644 index 000000000..da46efc96 Binary files /dev/null and b/tests/ref/math-call-non-func.png differ diff --git a/tests/ref/math-cancel-angle-absolute.png b/tests/ref/math-cancel-angle-absolute.png new file mode 100644 index 000000000..125e59fb1 Binary files /dev/null and b/tests/ref/math-cancel-angle-absolute.png differ diff --git a/tests/ref/math-cancel-angle-func.png b/tests/ref/math-cancel-angle-func.png new file mode 100644 index 000000000..54f6e7595 Binary files /dev/null and b/tests/ref/math-cancel-angle-func.png differ diff --git a/tests/ref/math-cancel-cross.png b/tests/ref/math-cancel-cross.png new file mode 100644 index 000000000..49fba664e Binary files /dev/null and b/tests/ref/math-cancel-cross.png differ diff --git a/tests/ref/math-cancel-customized.png b/tests/ref/math-cancel-customized.png new file mode 100644 index 000000000..9fa5045d7 Binary files /dev/null and b/tests/ref/math-cancel-customized.png differ diff --git a/tests/ref/math-cancel-display.png b/tests/ref/math-cancel-display.png new file mode 100644 index 000000000..30d30a596 Binary files /dev/null and b/tests/ref/math-cancel-display.png differ diff --git a/tests/ref/math-cancel-inline.png b/tests/ref/math-cancel-inline.png new file mode 100644 index 000000000..4d92bc5e3 Binary files /dev/null and b/tests/ref/math-cancel-inline.png differ diff --git a/tests/ref/math-cancel-inverted.png b/tests/ref/math-cancel-inverted.png new file mode 100644 index 000000000..129d53a05 Binary files /dev/null and b/tests/ref/math-cancel-inverted.png differ diff --git a/tests/ref/math-cases-gap.png b/tests/ref/math-cases-gap.png new file mode 100644 index 000000000..e35791307 Binary files /dev/null and b/tests/ref/math-cases-gap.png differ diff --git a/tests/ref/math-cases.png b/tests/ref/math-cases.png new file mode 100644 index 000000000..2e8c260a3 Binary files /dev/null and b/tests/ref/math-cases.png differ diff --git a/tests/ref/math-class-chars.png b/tests/ref/math-class-chars.png new file mode 100644 index 000000000..a4f7d29b1 Binary files /dev/null and b/tests/ref/math-class-chars.png differ diff --git a/tests/ref/math-class-content.png b/tests/ref/math-class-content.png new file mode 100644 index 000000000..47603fb4b Binary files /dev/null and b/tests/ref/math-class-content.png differ diff --git a/tests/ref/math-class-exceptions.png b/tests/ref/math-class-exceptions.png new file mode 100644 index 000000000..8b3ecc816 Binary files /dev/null and b/tests/ref/math-class-exceptions.png differ diff --git a/tests/ref/math-class-limits.png b/tests/ref/math-class-limits.png new file mode 100644 index 000000000..140acf956 Binary files /dev/null and b/tests/ref/math-class-limits.png differ diff --git a/tests/ref/math-class-nested.png b/tests/ref/math-class-nested.png new file mode 100644 index 000000000..5847868ea Binary files /dev/null and b/tests/ref/math-class-nested.png differ diff --git a/tests/ref/math-common-symbols.png b/tests/ref/math-common-symbols.png new file mode 100644 index 000000000..22da84b52 Binary files /dev/null and b/tests/ref/math-common-symbols.png differ diff --git a/tests/ref/math-dif.png b/tests/ref/math-dif.png new file mode 100644 index 000000000..dfe88b3c3 Binary files /dev/null and b/tests/ref/math-dif.png differ diff --git a/tests/ref/math-equation-align-numbered.png b/tests/ref/math-equation-align-numbered.png new file mode 100644 index 000000000..e43054c8c Binary files /dev/null and b/tests/ref/math-equation-align-numbered.png differ diff --git a/tests/ref/math-equation-align-unnumbered.png b/tests/ref/math-equation-align-unnumbered.png new file mode 100644 index 000000000..413da1200 Binary files /dev/null and b/tests/ref/math-equation-align-unnumbered.png differ diff --git a/tests/ref/math-equation-auto-wrapping.png b/tests/ref/math-equation-auto-wrapping.png new file mode 100644 index 000000000..9c600172e Binary files /dev/null and b/tests/ref/math-equation-auto-wrapping.png differ diff --git a/tests/ref/math-equation-font.png b/tests/ref/math-equation-font.png new file mode 100644 index 000000000..b105d9e35 Binary files /dev/null and b/tests/ref/math-equation-font.png differ diff --git a/tests/ref/math-equation-number-align-end.png b/tests/ref/math-equation-number-align-end.png new file mode 100644 index 000000000..f60a15ec1 Binary files /dev/null and b/tests/ref/math-equation-number-align-end.png differ diff --git a/tests/ref/math-equation-number-align-left.png b/tests/ref/math-equation-number-align-left.png new file mode 100644 index 000000000..a8ed40a5e Binary files /dev/null and b/tests/ref/math-equation-number-align-left.png differ diff --git a/tests/ref/math-equation-number-align-multiline-bottom.png b/tests/ref/math-equation-number-align-multiline-bottom.png new file mode 100644 index 000000000..cb0e5daa9 Binary files /dev/null and b/tests/ref/math-equation-number-align-multiline-bottom.png differ diff --git a/tests/ref/math-equation-number-align-multiline-expand.png b/tests/ref/math-equation-number-align-multiline-expand.png new file mode 100644 index 000000000..3c3cdc051 Binary files /dev/null and b/tests/ref/math-equation-number-align-multiline-expand.png differ diff --git a/tests/ref/math-equation-number-align-multiline-top-start.png b/tests/ref/math-equation-number-align-multiline-top-start.png new file mode 100644 index 000000000..43346de95 Binary files /dev/null and b/tests/ref/math-equation-number-align-multiline-top-start.png differ diff --git a/tests/ref/math-equation-number-align-multiline.png b/tests/ref/math-equation-number-align-multiline.png new file mode 100644 index 000000000..a46bc1e98 Binary files /dev/null and b/tests/ref/math-equation-number-align-multiline.png differ diff --git a/tests/ref/math-equation-number-align-right.png b/tests/ref/math-equation-number-align-right.png new file mode 100644 index 000000000..e3d588c4e Binary files /dev/null and b/tests/ref/math-equation-number-align-right.png differ diff --git a/tests/ref/math-equation-number-align-start.png b/tests/ref/math-equation-number-align-start.png new file mode 100644 index 000000000..67ed3c4c2 Binary files /dev/null and b/tests/ref/math-equation-number-align-start.png differ diff --git a/tests/ref/math-equation-number-align.png b/tests/ref/math-equation-number-align.png new file mode 100644 index 000000000..f60a15ec1 Binary files /dev/null and b/tests/ref/math-equation-number-align.png differ diff --git a/tests/ref/math-equation-numbering.png b/tests/ref/math-equation-numbering.png new file mode 100644 index 000000000..b1e6b10e3 Binary files /dev/null and b/tests/ref/math-equation-numbering.png differ diff --git a/tests/ref/math-equation-show-rule.png b/tests/ref/math-equation-show-rule.png new file mode 100644 index 000000000..26da7cd19 Binary files /dev/null and b/tests/ref/math-equation-show-rule.png differ diff --git a/tests/ref/math-font-fallback.png b/tests/ref/math-font-fallback.png new file mode 100644 index 000000000..50fa85c7e Binary files /dev/null and b/tests/ref/math-font-fallback.png differ diff --git a/tests/ref/math-font-features.png b/tests/ref/math-font-features.png new file mode 100644 index 000000000..0fd5e6e13 Binary files /dev/null and b/tests/ref/math-font-features.png differ diff --git a/tests/ref/math-font-switch.png b/tests/ref/math-font-switch.png new file mode 100644 index 000000000..4c572ea54 Binary files /dev/null and b/tests/ref/math-font-switch.png differ diff --git a/tests/ref/math-frac-associativity.png b/tests/ref/math-frac-associativity.png new file mode 100644 index 000000000..a5daca596 Binary files /dev/null and b/tests/ref/math-frac-associativity.png differ diff --git a/tests/ref/math-frac-baseline.png b/tests/ref/math-frac-baseline.png new file mode 100644 index 000000000..d65e2c337 Binary files /dev/null and b/tests/ref/math-frac-baseline.png differ diff --git a/tests/ref/math-frac-large.png b/tests/ref/math-frac-large.png new file mode 100644 index 000000000..ff9520f37 Binary files /dev/null and b/tests/ref/math-frac-large.png differ diff --git a/tests/ref/math-frac-paren-removal.png b/tests/ref/math-frac-paren-removal.png new file mode 100644 index 000000000..4f58f1d39 Binary files /dev/null and b/tests/ref/math-frac-paren-removal.png differ diff --git a/tests/ref/math-frac-precedence.png b/tests/ref/math-frac-precedence.png new file mode 100644 index 000000000..236b9989e Binary files /dev/null and b/tests/ref/math-frac-precedence.png differ diff --git a/tests/ref/math-linebreaking-after-binop-and-rel.png b/tests/ref/math-linebreaking-after-binop-and-rel.png new file mode 100644 index 000000000..1cdd73c4f Binary files /dev/null and b/tests/ref/math-linebreaking-after-binop-and-rel.png differ diff --git a/tests/ref/math-linebreaking-after-relation-without-space.png b/tests/ref/math-linebreaking-after-relation-without-space.png new file mode 100644 index 000000000..7c569ad1f Binary files /dev/null and b/tests/ref/math-linebreaking-after-relation-without-space.png differ diff --git a/tests/ref/math-linebreaking-between-consecutive-relations.png b/tests/ref/math-linebreaking-between-consecutive-relations.png new file mode 100644 index 000000000..ba222c573 Binary files /dev/null and b/tests/ref/math-linebreaking-between-consecutive-relations.png differ diff --git a/tests/ref/math-linebreaking-empty.png b/tests/ref/math-linebreaking-empty.png new file mode 100644 index 000000000..8fd4dbb9e Binary files /dev/null and b/tests/ref/math-linebreaking-empty.png differ diff --git a/tests/ref/math-linebreaking-in-box.png b/tests/ref/math-linebreaking-in-box.png new file mode 100644 index 000000000..e026f1a22 Binary files /dev/null and b/tests/ref/math-linebreaking-in-box.png differ diff --git a/tests/ref/math-linebreaking-lr.png b/tests/ref/math-linebreaking-lr.png new file mode 100644 index 000000000..69f08e7ea Binary files /dev/null and b/tests/ref/math-linebreaking-lr.png differ diff --git a/tests/ref/math-linebreaking-multiline.png b/tests/ref/math-linebreaking-multiline.png new file mode 100644 index 000000000..cd5f2fcea Binary files /dev/null and b/tests/ref/math-linebreaking-multiline.png differ diff --git a/tests/ref/math-linebreaking-trailing-linebreak.png b/tests/ref/math-linebreaking-trailing-linebreak.png new file mode 100644 index 000000000..4a50832ba Binary files /dev/null and b/tests/ref/math-linebreaking-trailing-linebreak.png differ diff --git a/tests/ref/math-lr-call.png b/tests/ref/math-lr-call.png new file mode 100644 index 000000000..baf668d4d Binary files /dev/null and b/tests/ref/math-lr-call.png differ diff --git a/tests/ref/math-lr-color.png b/tests/ref/math-lr-color.png new file mode 100644 index 000000000..668768192 Binary files /dev/null and b/tests/ref/math-lr-color.png differ diff --git a/tests/ref/math-lr-fences.png b/tests/ref/math-lr-fences.png new file mode 100644 index 000000000..32314cb4b Binary files /dev/null and b/tests/ref/math-lr-fences.png differ diff --git a/tests/ref/math-lr-half.png b/tests/ref/math-lr-half.png new file mode 100644 index 000000000..311188b4c Binary files /dev/null and b/tests/ref/math-lr-half.png differ diff --git a/tests/ref/math-lr-matching.png b/tests/ref/math-lr-matching.png new file mode 100644 index 000000000..e5fd4c7b5 Binary files /dev/null and b/tests/ref/math-lr-matching.png differ diff --git a/tests/ref/math-lr-mid.png b/tests/ref/math-lr-mid.png new file mode 100644 index 000000000..e4f1e6716 Binary files /dev/null and b/tests/ref/math-lr-mid.png differ diff --git a/tests/ref/math-lr-shorthands.png b/tests/ref/math-lr-shorthands.png new file mode 100644 index 000000000..d8961672e Binary files /dev/null and b/tests/ref/math-lr-shorthands.png differ diff --git a/tests/ref/math-lr-size.png b/tests/ref/math-lr-size.png new file mode 100644 index 000000000..09d244215 Binary files /dev/null and b/tests/ref/math-lr-size.png differ diff --git a/tests/ref/math-lr-symbol-unmatched.png b/tests/ref/math-lr-symbol-unmatched.png new file mode 100644 index 000000000..38d0a988a Binary files /dev/null and b/tests/ref/math-lr-symbol-unmatched.png differ diff --git a/tests/ref/math-lr-unbalanced.png b/tests/ref/math-lr-unbalanced.png new file mode 100644 index 000000000..eff579ba4 Binary files /dev/null and b/tests/ref/math-lr-unbalanced.png differ diff --git a/tests/ref/math-lr-unmatched.png b/tests/ref/math-lr-unmatched.png new file mode 100644 index 000000000..9a0f3275e Binary files /dev/null and b/tests/ref/math-lr-unmatched.png differ diff --git a/tests/ref/math-lr-weak-spacing.png b/tests/ref/math-lr-weak-spacing.png new file mode 100644 index 000000000..871aaa2eb Binary files /dev/null and b/tests/ref/math-lr-weak-spacing.png differ diff --git a/tests/ref/math-mat-align-complex.png b/tests/ref/math-mat-align-complex.png new file mode 100644 index 000000000..682fed228 Binary files /dev/null and b/tests/ref/math-mat-align-complex.png differ diff --git a/tests/ref/math-mat-align-explicit--alternating.png b/tests/ref/math-mat-align-explicit--alternating.png new file mode 100644 index 000000000..cb29eb067 Binary files /dev/null and b/tests/ref/math-mat-align-explicit--alternating.png differ diff --git a/tests/ref/math-mat-align-explicit-left.png b/tests/ref/math-mat-align-explicit-left.png new file mode 100644 index 000000000..97fe0a1f4 Binary files /dev/null and b/tests/ref/math-mat-align-explicit-left.png differ diff --git a/tests/ref/math-mat-align-explicit-right.png b/tests/ref/math-mat-align-explicit-right.png new file mode 100644 index 000000000..80966e524 Binary files /dev/null and b/tests/ref/math-mat-align-explicit-right.png differ diff --git a/tests/ref/math-mat-align-implicit.png b/tests/ref/math-mat-align-implicit.png new file mode 100644 index 000000000..0c14f1a79 Binary files /dev/null and b/tests/ref/math-mat-align-implicit.png differ diff --git a/tests/ref/math-mat-align-signed-numbers.png b/tests/ref/math-mat-align-signed-numbers.png new file mode 100644 index 000000000..02a3c5820 Binary files /dev/null and b/tests/ref/math-mat-align-signed-numbers.png differ diff --git a/tests/ref/math-mat-augment-set.png b/tests/ref/math-mat-augment-set.png new file mode 100644 index 000000000..f3827c41f Binary files /dev/null and b/tests/ref/math-mat-augment-set.png differ diff --git a/tests/ref/math-mat-augment.png b/tests/ref/math-mat-augment.png new file mode 100644 index 000000000..3a272ce90 Binary files /dev/null and b/tests/ref/math-mat-augment.png differ diff --git a/tests/ref/math-mat-baseline.png b/tests/ref/math-mat-baseline.png new file mode 100644 index 000000000..51e90a1f3 Binary files /dev/null and b/tests/ref/math-mat-baseline.png differ diff --git a/tests/ref/math-mat-delim-direct.png b/tests/ref/math-mat-delim-direct.png new file mode 100644 index 000000000..b40fd36cf Binary files /dev/null and b/tests/ref/math-mat-delim-direct.png differ diff --git a/tests/ref/math-mat-delim-set.png b/tests/ref/math-mat-delim-set.png new file mode 100644 index 000000000..fc92fd4b3 Binary files /dev/null and b/tests/ref/math-mat-delim-set.png differ diff --git a/tests/ref/math-mat-gap.png b/tests/ref/math-mat-gap.png new file mode 100644 index 000000000..5eb8460d7 Binary files /dev/null and b/tests/ref/math-mat-gap.png differ diff --git a/tests/ref/math-mat-gaps.png b/tests/ref/math-mat-gaps.png new file mode 100644 index 000000000..38cf52475 Binary files /dev/null and b/tests/ref/math-mat-gaps.png differ diff --git a/tests/ref/math-mat-semicolon.png b/tests/ref/math-mat-semicolon.png new file mode 100644 index 000000000..abb5d1df8 Binary files /dev/null and b/tests/ref/math-mat-semicolon.png differ diff --git a/tests/ref/math-mat-sparse.png b/tests/ref/math-mat-sparse.png new file mode 100644 index 000000000..4d077931b Binary files /dev/null and b/tests/ref/math-mat-sparse.png differ diff --git a/tests/ref/math-multiline-multiple-trailing-linebreaks.png b/tests/ref/math-multiline-multiple-trailing-linebreaks.png new file mode 100644 index 000000000..2c6484c7a Binary files /dev/null and b/tests/ref/math-multiline-multiple-trailing-linebreaks.png differ diff --git a/tests/ref/math-multiline-no-trailing-linebreak.png b/tests/ref/math-multiline-no-trailing-linebreak.png new file mode 100644 index 000000000..8ad6204d4 Binary files /dev/null and b/tests/ref/math-multiline-no-trailing-linebreak.png differ diff --git a/tests/ref/math-multiline-trailing-linebreak.png b/tests/ref/math-multiline-trailing-linebreak.png new file mode 100644 index 000000000..364d8624d Binary files /dev/null and b/tests/ref/math-multiline-trailing-linebreak.png differ diff --git a/tests/ref/math-nested-normal-layout.png b/tests/ref/math-nested-normal-layout.png new file mode 100644 index 000000000..4ec7d46eb Binary files /dev/null and b/tests/ref/math-nested-normal-layout.png differ diff --git a/tests/ref/math-non-math-content.png b/tests/ref/math-non-math-content.png new file mode 100644 index 000000000..66896d186 Binary files /dev/null and b/tests/ref/math-non-math-content.png differ diff --git a/tests/ref/math-op-call.png b/tests/ref/math-op-call.png new file mode 100644 index 000000000..2fcdf2cb3 Binary files /dev/null and b/tests/ref/math-op-call.png differ diff --git a/tests/ref/math-op-custom.png b/tests/ref/math-op-custom.png new file mode 100644 index 000000000..fbba241d5 Binary files /dev/null and b/tests/ref/math-op-custom.png differ diff --git a/tests/ref/math-op-predefined.png b/tests/ref/math-op-predefined.png new file mode 100644 index 000000000..bfede9e73 Binary files /dev/null and b/tests/ref/math-op-predefined.png differ diff --git a/tests/ref/math-op-scripts-vs-limits.png b/tests/ref/math-op-scripts-vs-limits.png new file mode 100644 index 000000000..418974169 Binary files /dev/null and b/tests/ref/math-op-scripts-vs-limits.png differ diff --git a/tests/ref/math-op-styled.png b/tests/ref/math-op-styled.png new file mode 100644 index 000000000..c6890d74e Binary files /dev/null and b/tests/ref/math-op-styled.png differ diff --git a/tests/ref/math-optical-size-frac-script-script.png b/tests/ref/math-optical-size-frac-script-script.png new file mode 100644 index 000000000..893b34349 Binary files /dev/null and b/tests/ref/math-optical-size-frac-script-script.png differ diff --git a/tests/ref/math-optical-size-nested-scripts.png b/tests/ref/math-optical-size-nested-scripts.png new file mode 100644 index 000000000..8ca35c6e4 Binary files /dev/null and b/tests/ref/math-optical-size-nested-scripts.png differ diff --git a/tests/ref/math-optical-size-prime-large-operator.png b/tests/ref/math-optical-size-prime-large-operator.png new file mode 100644 index 000000000..b38a934ed Binary files /dev/null and b/tests/ref/math-optical-size-prime-large-operator.png differ diff --git a/tests/ref/math-optical-size-primes.png b/tests/ref/math-optical-size-primes.png new file mode 100644 index 000000000..8fc199aa8 Binary files /dev/null and b/tests/ref/math-optical-size-primes.png differ diff --git a/tests/ref/math-primes-after-code-expr.png b/tests/ref/math-primes-after-code-expr.png new file mode 100644 index 000000000..5ec3bc8cf Binary files /dev/null and b/tests/ref/math-primes-after-code-expr.png differ diff --git a/tests/ref/math-primes-attach.png b/tests/ref/math-primes-attach.png new file mode 100644 index 000000000..95b77882e Binary files /dev/null and b/tests/ref/math-primes-attach.png differ diff --git a/tests/ref/math-primes-complex.png b/tests/ref/math-primes-complex.png new file mode 100644 index 000000000..5f5558eb2 Binary files /dev/null and b/tests/ref/math-primes-complex.png differ diff --git a/tests/ref/math-primes-limits.png b/tests/ref/math-primes-limits.png new file mode 100644 index 000000000..f2c5cec26 Binary files /dev/null and b/tests/ref/math-primes-limits.png differ diff --git a/tests/ref/math-primes-scripts.png b/tests/ref/math-primes-scripts.png new file mode 100644 index 000000000..2a9121809 Binary files /dev/null and b/tests/ref/math-primes-scripts.png differ diff --git a/tests/ref/math-primes-spaces.png b/tests/ref/math-primes-spaces.png new file mode 100644 index 000000000..890cc3484 Binary files /dev/null and b/tests/ref/math-primes-spaces.png differ diff --git a/tests/ref/math-primes.png b/tests/ref/math-primes.png new file mode 100644 index 000000000..f3323197b Binary files /dev/null and b/tests/ref/math-primes.png differ diff --git a/tests/ref/math-root-basic.png b/tests/ref/math-root-basic.png new file mode 100644 index 000000000..b8b891eb0 Binary files /dev/null and b/tests/ref/math-root-basic.png differ diff --git a/tests/ref/math-root-large-body.png b/tests/ref/math-root-large-body.png new file mode 100644 index 000000000..3dd4d848e Binary files /dev/null and b/tests/ref/math-root-large-body.png differ diff --git a/tests/ref/math-root-large-index.png b/tests/ref/math-root-large-index.png new file mode 100644 index 000000000..8037222cb Binary files /dev/null and b/tests/ref/math-root-large-index.png differ diff --git a/tests/ref/math-root-precomposed.png b/tests/ref/math-root-precomposed.png new file mode 100644 index 000000000..e09f18781 Binary files /dev/null and b/tests/ref/math-root-precomposed.png differ diff --git a/tests/ref/math-root-radical-attachment.png b/tests/ref/math-root-radical-attachment.png new file mode 100644 index 000000000..4cb447ec0 Binary files /dev/null and b/tests/ref/math-root-radical-attachment.png differ diff --git a/tests/ref/math-root-syntax.png b/tests/ref/math-root-syntax.png new file mode 100644 index 000000000..492554934 Binary files /dev/null and b/tests/ref/math-root-syntax.png differ diff --git a/tests/ref/math-shorthandes.png b/tests/ref/math-shorthandes.png new file mode 100644 index 000000000..ff26ce96f Binary files /dev/null and b/tests/ref/math-shorthandes.png differ diff --git a/tests/ref/math-size.png b/tests/ref/math-size.png new file mode 100644 index 000000000..b44e4c745 Binary files /dev/null and b/tests/ref/math-size.png differ diff --git a/tests/ref/math-spacing-basic.png b/tests/ref/math-spacing-basic.png new file mode 100644 index 000000000..5567b0875 Binary files /dev/null and b/tests/ref/math-spacing-basic.png differ diff --git a/tests/ref/math-spacing-decorated.png b/tests/ref/math-spacing-decorated.png new file mode 100644 index 000000000..e34066ea2 Binary files /dev/null and b/tests/ref/math-spacing-decorated.png differ diff --git a/tests/ref/math-spacing-kept-spaces.png b/tests/ref/math-spacing-kept-spaces.png new file mode 100644 index 000000000..bb433d4fc Binary files /dev/null and b/tests/ref/math-spacing-kept-spaces.png differ diff --git a/tests/ref/math-spacing-predefined.png b/tests/ref/math-spacing-predefined.png new file mode 100644 index 000000000..244e76428 Binary files /dev/null and b/tests/ref/math-spacing-predefined.png differ diff --git a/tests/ref/math-spacing-set-comprehension.png b/tests/ref/math-spacing-set-comprehension.png new file mode 100644 index 000000000..63ef46ca9 Binary files /dev/null and b/tests/ref/math-spacing-set-comprehension.png differ diff --git a/tests/ref/math-spacing-weak.png b/tests/ref/math-spacing-weak.png new file mode 100644 index 000000000..71af32221 Binary files /dev/null and b/tests/ref/math-spacing-weak.png differ diff --git a/tests/ref/math-style-exceptions.png b/tests/ref/math-style-exceptions.png new file mode 100644 index 000000000..bdeabb673 Binary files /dev/null and b/tests/ref/math-style-exceptions.png differ diff --git a/tests/ref/math-style-greek-exceptions.png b/tests/ref/math-style-greek-exceptions.png new file mode 100644 index 000000000..93ae6309b Binary files /dev/null and b/tests/ref/math-style-greek-exceptions.png differ diff --git a/tests/ref/math-style-hebrew-exceptions.png b/tests/ref/math-style-hebrew-exceptions.png new file mode 100644 index 000000000..723466e8a Binary files /dev/null and b/tests/ref/math-style-hebrew-exceptions.png differ diff --git a/tests/ref/math-style-italic-default.png b/tests/ref/math-style-italic-default.png new file mode 100644 index 000000000..0a25f6fac Binary files /dev/null and b/tests/ref/math-style-italic-default.png differ diff --git a/tests/ref/math-style.png b/tests/ref/math-style.png new file mode 100644 index 000000000..f514bd18d Binary files /dev/null and b/tests/ref/math-style.png differ diff --git a/tests/ref/math-symbol-show-rule.png b/tests/ref/math-symbol-show-rule.png new file mode 100644 index 000000000..68faf937a Binary files /dev/null and b/tests/ref/math-symbol-show-rule.png differ diff --git a/tests/ref/math-table.png b/tests/ref/math-table.png new file mode 100644 index 000000000..5eb932181 Binary files /dev/null and b/tests/ref/math-table.png differ diff --git a/tests/ref/math-text-color.png b/tests/ref/math-text-color.png new file mode 100644 index 000000000..33ff00f37 Binary files /dev/null and b/tests/ref/math-text-color.png differ diff --git a/tests/ref/math-underover-brace.png b/tests/ref/math-underover-brace.png new file mode 100644 index 000000000..d4a3f4a1c Binary files /dev/null and b/tests/ref/math-underover-brace.png differ diff --git a/tests/ref/math-underover-brackets.png b/tests/ref/math-underover-brackets.png new file mode 100644 index 000000000..03419bc3b Binary files /dev/null and b/tests/ref/math-underover-brackets.png differ diff --git a/tests/ref/math-underover-line-bracket.png b/tests/ref/math-underover-line-bracket.png new file mode 100644 index 000000000..08d8df202 Binary files /dev/null and b/tests/ref/math-underover-line-bracket.png differ diff --git a/tests/ref/math-unicode.png b/tests/ref/math-unicode.png new file mode 100644 index 000000000..e74429ebf Binary files /dev/null and b/tests/ref/math-unicode.png differ diff --git a/tests/ref/math-vec-align-explicit-alternating.png b/tests/ref/math-vec-align-explicit-alternating.png new file mode 100644 index 000000000..cb29eb067 Binary files /dev/null and b/tests/ref/math-vec-align-explicit-alternating.png differ diff --git a/tests/ref/math-vec-delim-set.png b/tests/ref/math-vec-delim-set.png new file mode 100644 index 000000000..8024d594c Binary files /dev/null and b/tests/ref/math-vec-delim-set.png differ diff --git a/tests/ref/math-vec-gap.png b/tests/ref/math-vec-gap.png new file mode 100644 index 000000000..06f8cf7de Binary files /dev/null and b/tests/ref/math-vec-gap.png differ diff --git a/tests/ref/math-vec-wide.png b/tests/ref/math-vec-wide.png new file mode 100644 index 000000000..30853a001 Binary files /dev/null and b/tests/ref/math-vec-wide.png differ diff --git a/tests/ref/math/accent.png b/tests/ref/math/accent.png deleted file mode 100644 index 52a7037e3..000000000 Binary files a/tests/ref/math/accent.png and /dev/null differ diff --git a/tests/ref/math/alignment.png b/tests/ref/math/alignment.png deleted file mode 100644 index 4bf739a4f..000000000 Binary files a/tests/ref/math/alignment.png and /dev/null differ diff --git a/tests/ref/math/attach-p1.png b/tests/ref/math/attach-p1.png deleted file mode 100644 index 45c465ce5..000000000 Binary files a/tests/ref/math/attach-p1.png and /dev/null differ diff --git a/tests/ref/math/attach-p2.png b/tests/ref/math/attach-p2.png deleted file mode 100644 index 3820f33e9..000000000 Binary files a/tests/ref/math/attach-p2.png and /dev/null differ diff --git a/tests/ref/math/attach-p3.png b/tests/ref/math/attach-p3.png deleted file mode 100644 index 69e0a7dd7..000000000 Binary files a/tests/ref/math/attach-p3.png and /dev/null differ diff --git a/tests/ref/math/call.png b/tests/ref/math/call.png deleted file mode 100644 index 907a1a2be..000000000 Binary files a/tests/ref/math/call.png and /dev/null differ diff --git a/tests/ref/math/cancel.png b/tests/ref/math/cancel.png deleted file mode 100644 index 4f0de1360..000000000 Binary files a/tests/ref/math/cancel.png and /dev/null differ diff --git a/tests/ref/math/cases.png b/tests/ref/math/cases.png deleted file mode 100644 index e222ae17a..000000000 Binary files a/tests/ref/math/cases.png and /dev/null differ diff --git a/tests/ref/math/class.png b/tests/ref/math/class.png deleted file mode 100644 index a4d6e86c1..000000000 Binary files a/tests/ref/math/class.png and /dev/null differ diff --git a/tests/ref/math/content.png b/tests/ref/math/content.png deleted file mode 100644 index c27a17ea6..000000000 Binary files a/tests/ref/math/content.png and /dev/null differ diff --git a/tests/ref/math/delimited.png b/tests/ref/math/delimited.png deleted file mode 100644 index 6126f58ad..000000000 Binary files a/tests/ref/math/delimited.png and /dev/null differ diff --git a/tests/ref/math/equation-block-align.png b/tests/ref/math/equation-block-align.png deleted file mode 100644 index 8736312a7..000000000 Binary files a/tests/ref/math/equation-block-align.png and /dev/null differ diff --git a/tests/ref/math/equation-number.png b/tests/ref/math/equation-number.png deleted file mode 100644 index 8ba915902..000000000 Binary files a/tests/ref/math/equation-number.png and /dev/null differ diff --git a/tests/ref/math/equation-show.png b/tests/ref/math/equation-show.png deleted file mode 100644 index 79a70dc02..000000000 Binary files a/tests/ref/math/equation-show.png and /dev/null differ diff --git a/tests/ref/math/font-features.png b/tests/ref/math/font-features.png deleted file mode 100644 index 0ab2c06d0..000000000 Binary files a/tests/ref/math/font-features.png and /dev/null differ diff --git a/tests/ref/math/frac.png b/tests/ref/math/frac.png deleted file mode 100644 index 3e08f7e5b..000000000 Binary files a/tests/ref/math/frac.png and /dev/null differ diff --git a/tests/ref/math/linebreak.png b/tests/ref/math/linebreak.png deleted file mode 100644 index f3212a4a1..000000000 Binary files a/tests/ref/math/linebreak.png and /dev/null differ diff --git a/tests/ref/math/matrix-alignment.png b/tests/ref/math/matrix-alignment.png deleted file mode 100644 index cdf174639..000000000 Binary files a/tests/ref/math/matrix-alignment.png and /dev/null differ diff --git a/tests/ref/math/matrix-gaps.png b/tests/ref/math/matrix-gaps.png deleted file mode 100644 index 16788969f..000000000 Binary files a/tests/ref/math/matrix-gaps.png and /dev/null differ diff --git a/tests/ref/math/matrix.png b/tests/ref/math/matrix.png deleted file mode 100644 index b8ea19e20..000000000 Binary files a/tests/ref/math/matrix.png and /dev/null differ diff --git a/tests/ref/math/multiline.png b/tests/ref/math/multiline.png deleted file mode 100644 index 185724af9..000000000 Binary files a/tests/ref/math/multiline.png and /dev/null differ diff --git a/tests/ref/math/numbering.png b/tests/ref/math/numbering.png deleted file mode 100644 index 813f5f8c3..000000000 Binary files a/tests/ref/math/numbering.png and /dev/null differ diff --git a/tests/ref/math/op.png b/tests/ref/math/op.png deleted file mode 100644 index ab3f35f6e..000000000 Binary files a/tests/ref/math/op.png and /dev/null differ diff --git a/tests/ref/math/opticalsize.png b/tests/ref/math/opticalsize.png deleted file mode 100644 index 303f7bee7..000000000 Binary files a/tests/ref/math/opticalsize.png and /dev/null differ diff --git a/tests/ref/math/prime.png b/tests/ref/math/prime.png deleted file mode 100644 index 81a476436..000000000 Binary files a/tests/ref/math/prime.png and /dev/null differ diff --git a/tests/ref/math/root.png b/tests/ref/math/root.png deleted file mode 100644 index 51fdf2e8f..000000000 Binary files a/tests/ref/math/root.png and /dev/null differ diff --git a/tests/ref/math/spacing.png b/tests/ref/math/spacing.png deleted file mode 100644 index d8198bbfb..000000000 Binary files a/tests/ref/math/spacing.png and /dev/null differ diff --git a/tests/ref/math/style.png b/tests/ref/math/style.png deleted file mode 100644 index a52136dc9..000000000 Binary files a/tests/ref/math/style.png and /dev/null differ diff --git a/tests/ref/math/syntax.png b/tests/ref/math/syntax.png deleted file mode 100644 index 3855fa9b8..000000000 Binary files a/tests/ref/math/syntax.png and /dev/null differ diff --git a/tests/ref/math/unbalanced.png b/tests/ref/math/unbalanced.png deleted file mode 100644 index 84f51837c..000000000 Binary files a/tests/ref/math/unbalanced.png and /dev/null differ diff --git a/tests/ref/math/underover.png b/tests/ref/math/underover.png deleted file mode 100644 index e974302f4..000000000 Binary files a/tests/ref/math/underover.png and /dev/null differ diff --git a/tests/ref/math/vec.png b/tests/ref/math/vec.png deleted file mode 100644 index f2371e5b3..000000000 Binary files a/tests/ref/math/vec.png and /dev/null differ diff --git a/tests/ref/meta/bibliography-full.png b/tests/ref/meta/bibliography-full.png deleted file mode 100644 index d8778c09e..000000000 Binary files a/tests/ref/meta/bibliography-full.png and /dev/null differ diff --git a/tests/ref/meta/bibliography-ordering.png b/tests/ref/meta/bibliography-ordering.png deleted file mode 100644 index 116c561d0..000000000 Binary files a/tests/ref/meta/bibliography-ordering.png and /dev/null differ diff --git a/tests/ref/meta/bibliography.png b/tests/ref/meta/bibliography.png deleted file mode 100644 index 8fbd09bc8..000000000 Binary files a/tests/ref/meta/bibliography.png and /dev/null differ diff --git a/tests/ref/meta/cite-footnote.png b/tests/ref/meta/cite-footnote.png deleted file mode 100644 index 3a7a0094d..000000000 Binary files a/tests/ref/meta/cite-footnote.png and /dev/null differ diff --git a/tests/ref/meta/cite-form.png b/tests/ref/meta/cite-form.png deleted file mode 100644 index 8adeac92f..000000000 Binary files a/tests/ref/meta/cite-form.png and /dev/null differ diff --git a/tests/ref/meta/cite-group.png b/tests/ref/meta/cite-group.png deleted file mode 100644 index 8d02a9036..000000000 Binary files a/tests/ref/meta/cite-group.png and /dev/null differ diff --git a/tests/ref/meta/counter-page.png b/tests/ref/meta/counter-page.png deleted file mode 100644 index 869718bca..000000000 Binary files a/tests/ref/meta/counter-page.png and /dev/null differ diff --git a/tests/ref/meta/counter.png b/tests/ref/meta/counter.png deleted file mode 100644 index 6c29ac17f..000000000 Binary files a/tests/ref/meta/counter.png and /dev/null differ diff --git a/tests/ref/meta/document.png b/tests/ref/meta/document.png deleted file mode 100644 index 6db265112..000000000 Binary files a/tests/ref/meta/document.png and /dev/null differ diff --git a/tests/ref/meta/figure-caption.png b/tests/ref/meta/figure-caption.png deleted file mode 100644 index 8a1d4a599..000000000 Binary files a/tests/ref/meta/figure-caption.png and /dev/null differ diff --git a/tests/ref/meta/figure-localization.png b/tests/ref/meta/figure-localization.png deleted file mode 100644 index 5fcbd2b7c..000000000 Binary files a/tests/ref/meta/figure-localization.png and /dev/null differ diff --git a/tests/ref/meta/figure.png b/tests/ref/meta/figure.png deleted file mode 100644 index bcdd0d2fa..000000000 Binary files a/tests/ref/meta/figure.png and /dev/null differ diff --git a/tests/ref/meta/footnote-break.png b/tests/ref/meta/footnote-break.png deleted file mode 100644 index 625305c88..000000000 Binary files a/tests/ref/meta/footnote-break.png and /dev/null differ diff --git a/tests/ref/meta/footnote-columns.png b/tests/ref/meta/footnote-columns.png deleted file mode 100644 index 528ec6641..000000000 Binary files a/tests/ref/meta/footnote-columns.png and /dev/null differ diff --git a/tests/ref/meta/footnote-container.png b/tests/ref/meta/footnote-container.png deleted file mode 100644 index 9327e7eec..000000000 Binary files a/tests/ref/meta/footnote-container.png and /dev/null differ diff --git a/tests/ref/meta/footnote-invariant.png b/tests/ref/meta/footnote-invariant.png deleted file mode 100644 index 66b411825..000000000 Binary files a/tests/ref/meta/footnote-invariant.png and /dev/null differ diff --git a/tests/ref/meta/footnote-refs.png b/tests/ref/meta/footnote-refs.png deleted file mode 100644 index 3fab7bd5d..000000000 Binary files a/tests/ref/meta/footnote-refs.png and /dev/null differ diff --git a/tests/ref/meta/footnote-table.png b/tests/ref/meta/footnote-table.png deleted file mode 100644 index 023f8008b..000000000 Binary files a/tests/ref/meta/footnote-table.png and /dev/null differ diff --git a/tests/ref/meta/footnote.png b/tests/ref/meta/footnote.png deleted file mode 100644 index 4c67bbd78..000000000 Binary files a/tests/ref/meta/footnote.png and /dev/null differ diff --git a/tests/ref/meta/heading.png b/tests/ref/meta/heading.png deleted file mode 100644 index 8467ea538..000000000 Binary files a/tests/ref/meta/heading.png and /dev/null differ diff --git a/tests/ref/meta/link.png b/tests/ref/meta/link.png deleted file mode 100644 index 3c3ecd2c0..000000000 Binary files a/tests/ref/meta/link.png and /dev/null differ diff --git a/tests/ref/meta/numbering.png b/tests/ref/meta/numbering.png deleted file mode 100644 index fa5b520fa..000000000 Binary files a/tests/ref/meta/numbering.png and /dev/null differ diff --git a/tests/ref/meta/outline-entry.png b/tests/ref/meta/outline-entry.png deleted file mode 100644 index f8f5412f0..000000000 Binary files a/tests/ref/meta/outline-entry.png and /dev/null differ diff --git a/tests/ref/meta/outline-first-par-indent.png b/tests/ref/meta/outline-first-par-indent.png deleted file mode 100644 index f6e4ffe80..000000000 Binary files a/tests/ref/meta/outline-first-par-indent.png and /dev/null differ diff --git a/tests/ref/meta/outline-indent.png b/tests/ref/meta/outline-indent.png deleted file mode 100644 index 816d86a5e..000000000 Binary files a/tests/ref/meta/outline-indent.png and /dev/null differ diff --git a/tests/ref/meta/outline.png b/tests/ref/meta/outline.png deleted file mode 100644 index 047bcc801..000000000 Binary files a/tests/ref/meta/outline.png and /dev/null differ diff --git a/tests/ref/meta/page-label.png b/tests/ref/meta/page-label.png deleted file mode 100644 index 301d626ab..000000000 Binary files a/tests/ref/meta/page-label.png and /dev/null differ diff --git a/tests/ref/meta/query-before-after.png b/tests/ref/meta/query-before-after.png deleted file mode 100644 index 80f8fe1f7..000000000 Binary files a/tests/ref/meta/query-before-after.png and /dev/null differ diff --git a/tests/ref/meta/query-figure.png b/tests/ref/meta/query-figure.png deleted file mode 100644 index 2537ebf00..000000000 Binary files a/tests/ref/meta/query-figure.png and /dev/null differ diff --git a/tests/ref/meta/query-header.png b/tests/ref/meta/query-header.png deleted file mode 100644 index c2dc46892..000000000 Binary files a/tests/ref/meta/query-header.png and /dev/null differ diff --git a/tests/ref/meta/ref.png b/tests/ref/meta/ref.png deleted file mode 100644 index 51563f54b..000000000 Binary files a/tests/ref/meta/ref.png and /dev/null differ diff --git a/tests/ref/meta/state.png b/tests/ref/meta/state.png deleted file mode 100644 index 25faa0d99..000000000 Binary files a/tests/ref/meta/state.png and /dev/null differ diff --git a/tests/ref/newline-continuation-code.png b/tests/ref/newline-continuation-code.png new file mode 100644 index 000000000..46a6afd56 Binary files /dev/null and b/tests/ref/newline-continuation-code.png differ diff --git a/tests/ref/newline-continuation-markup.png b/tests/ref/newline-continuation-markup.png new file mode 100644 index 000000000..268e5f840 Binary files /dev/null and b/tests/ref/newline-continuation-markup.png differ diff --git a/tests/ref/numbering-chinese.png b/tests/ref/numbering-chinese.png new file mode 100644 index 000000000..06b313342 Binary files /dev/null and b/tests/ref/numbering-chinese.png differ diff --git a/tests/ref/numbering-hebrew.png b/tests/ref/numbering-hebrew.png new file mode 100644 index 000000000..d76142259 Binary files /dev/null and b/tests/ref/numbering-hebrew.png differ diff --git a/tests/ref/numbering-japanese-aiueo.png b/tests/ref/numbering-japanese-aiueo.png new file mode 100644 index 000000000..b06d5c69f Binary files /dev/null and b/tests/ref/numbering-japanese-aiueo.png differ diff --git a/tests/ref/numbering-japanese-iroha.png b/tests/ref/numbering-japanese-iroha.png new file mode 100644 index 000000000..2018802f2 Binary files /dev/null and b/tests/ref/numbering-japanese-iroha.png differ diff --git a/tests/ref/numbering-korean.png b/tests/ref/numbering-korean.png new file mode 100644 index 000000000..281f2ec28 Binary files /dev/null and b/tests/ref/numbering-korean.png differ diff --git a/tests/ref/numbering-latin.png b/tests/ref/numbering-latin.png new file mode 100644 index 000000000..e154735a1 Binary files /dev/null and b/tests/ref/numbering-latin.png differ diff --git a/tests/ref/numbering-symbol-and-roman.png b/tests/ref/numbering-symbol-and-roman.png new file mode 100644 index 000000000..979f3b90b Binary files /dev/null and b/tests/ref/numbering-symbol-and-roman.png differ diff --git a/tests/ref/numbers.png b/tests/ref/numbers.png new file mode 100644 index 000000000..e6e7215b5 Binary files /dev/null and b/tests/ref/numbers.png differ diff --git a/tests/ref/ops-add-content.png b/tests/ref/ops-add-content.png new file mode 100644 index 000000000..bdb8cb5ea Binary files /dev/null and b/tests/ref/ops-add-content.png differ diff --git a/tests/ref/ops-multiply-inf-with-length.png b/tests/ref/ops-multiply-inf-with-length.png new file mode 100644 index 000000000..749be0564 Binary files /dev/null and b/tests/ref/ops-multiply-inf-with-length.png differ diff --git a/tests/ref/outline-entry-complex.png b/tests/ref/outline-entry-complex.png new file mode 100644 index 000000000..c885cacc0 Binary files /dev/null and b/tests/ref/outline-entry-complex.png differ diff --git a/tests/ref/outline-entry.png b/tests/ref/outline-entry.png new file mode 100644 index 000000000..94e7a5a74 Binary files /dev/null and b/tests/ref/outline-entry.png differ diff --git a/tests/ref/outline-first-line-indent.png b/tests/ref/outline-first-line-indent.png new file mode 100644 index 000000000..dd995f319 Binary files /dev/null and b/tests/ref/outline-first-line-indent.png differ diff --git a/tests/ref/outline-indent-no-numbering.png b/tests/ref/outline-indent-no-numbering.png new file mode 100644 index 000000000..62bd80a3c Binary files /dev/null and b/tests/ref/outline-indent-no-numbering.png differ diff --git a/tests/ref/outline-indent-numbering.png b/tests/ref/outline-indent-numbering.png new file mode 100644 index 000000000..6c9368271 Binary files /dev/null and b/tests/ref/outline-indent-numbering.png differ diff --git a/tests/ref/outline.png b/tests/ref/outline.png new file mode 100644 index 000000000..e5c24a980 Binary files /dev/null and b/tests/ref/outline.png differ diff --git a/tests/ref/overhang-lone.png b/tests/ref/overhang-lone.png new file mode 100644 index 000000000..b48618fb2 Binary files /dev/null and b/tests/ref/overhang-lone.png differ diff --git a/tests/ref/overhang.png b/tests/ref/overhang.png new file mode 100644 index 000000000..b97ef30ce Binary files /dev/null and b/tests/ref/overhang.png differ diff --git a/tests/ref/overline-background.png b/tests/ref/overline-background.png new file mode 100644 index 000000000..8efd147ea Binary files /dev/null and b/tests/ref/overline-background.png differ diff --git a/tests/ref/pad-basic.png b/tests/ref/pad-basic.png new file mode 100644 index 000000000..f8c40088f Binary files /dev/null and b/tests/ref/pad-basic.png differ diff --git a/tests/ref/pad-expanding-contents.png b/tests/ref/pad-expanding-contents.png new file mode 100644 index 000000000..1bef4a81b Binary files /dev/null and b/tests/ref/pad-expanding-contents.png differ diff --git a/tests/ref/pad-followed-by-content.png b/tests/ref/pad-followed-by-content.png new file mode 100644 index 000000000..f0f06a6ce Binary files /dev/null and b/tests/ref/pad-followed-by-content.png differ diff --git a/tests/ref/page-call-followed-by-pagebreak.png b/tests/ref/page-call-followed-by-pagebreak.png new file mode 100644 index 000000000..87cd9735e Binary files /dev/null and b/tests/ref/page-call-followed-by-pagebreak.png differ diff --git a/tests/ref/page-call-styled-empty.png b/tests/ref/page-call-styled-empty.png new file mode 100644 index 000000000..6a24b1bc1 Binary files /dev/null and b/tests/ref/page-call-styled-empty.png differ diff --git a/tests/ref/page-fill.png b/tests/ref/page-fill.png new file mode 100644 index 000000000..0c7ab2778 Binary files /dev/null and b/tests/ref/page-fill.png differ diff --git a/tests/ref/page-large.png b/tests/ref/page-large.png new file mode 100644 index 000000000..a57dceec7 Binary files /dev/null and b/tests/ref/page-large.png differ diff --git a/tests/ref/page-margin-binding-from-text-lang.png b/tests/ref/page-margin-binding-from-text-lang.png new file mode 100644 index 000000000..8d12ff2f4 Binary files /dev/null and b/tests/ref/page-margin-binding-from-text-lang.png differ diff --git a/tests/ref/page-margin-individual.png b/tests/ref/page-margin-individual.png new file mode 100644 index 000000000..0bc0f51bc Binary files /dev/null and b/tests/ref/page-margin-individual.png differ diff --git a/tests/ref/page-margin-inside-outside-override.png b/tests/ref/page-margin-inside-outside-override.png new file mode 100644 index 000000000..5aa8bf12a Binary files /dev/null and b/tests/ref/page-margin-inside-outside-override.png differ diff --git a/tests/ref/page-margin-inside-with-binding.png b/tests/ref/page-margin-inside-with-binding.png new file mode 100644 index 000000000..5b9ec04fd Binary files /dev/null and b/tests/ref/page-margin-inside-with-binding.png differ diff --git a/tests/ref/page-margin-inside.png b/tests/ref/page-margin-inside.png new file mode 100644 index 000000000..d70b86047 Binary files /dev/null and b/tests/ref/page-margin-inside.png differ diff --git a/tests/ref/page-margin-uniform.png b/tests/ref/page-margin-uniform.png new file mode 100644 index 000000000..8a06fb749 Binary files /dev/null and b/tests/ref/page-margin-uniform.png differ diff --git a/tests/ref/page-marginals.png b/tests/ref/page-marginals.png new file mode 100644 index 000000000..cab886b38 Binary files /dev/null and b/tests/ref/page-marginals.png differ diff --git a/tests/ref/page-number-align-bottom-left.png b/tests/ref/page-number-align-bottom-left.png new file mode 100644 index 000000000..396f6e98f Binary files /dev/null and b/tests/ref/page-number-align-bottom-left.png differ diff --git a/tests/ref/page-number-align-top-right.png b/tests/ref/page-number-align-top-right.png new file mode 100644 index 000000000..3c7e5579a Binary files /dev/null and b/tests/ref/page-number-align-top-right.png differ diff --git a/tests/ref/page-numbering-pdf-label.png b/tests/ref/page-numbering-pdf-label.png new file mode 100644 index 000000000..a1cae7207 Binary files /dev/null and b/tests/ref/page-numbering-pdf-label.png differ diff --git a/tests/ref/page-set-empty.png b/tests/ref/page-set-empty.png new file mode 100644 index 000000000..6a24b1bc1 Binary files /dev/null and b/tests/ref/page-set-empty.png differ diff --git a/tests/ref/page-set-forces-break.png b/tests/ref/page-set-forces-break.png new file mode 100644 index 000000000..4654ef6c0 Binary files /dev/null and b/tests/ref/page-set-forces-break.png differ diff --git a/tests/ref/page-set-only-pagebreak.png b/tests/ref/page-set-only-pagebreak.png new file mode 100644 index 000000000..9bf379d6e Binary files /dev/null and b/tests/ref/page-set-only-pagebreak.png differ diff --git a/tests/ref/page-set-override-and-mix.png b/tests/ref/page-set-override-and-mix.png new file mode 100644 index 000000000..d9df6acd0 Binary files /dev/null and b/tests/ref/page-set-override-and-mix.png differ diff --git a/tests/ref/page-set-override-thrice.png b/tests/ref/page-set-override-thrice.png new file mode 100644 index 000000000..99173ced3 Binary files /dev/null and b/tests/ref/page-set-override-thrice.png differ diff --git a/tests/ref/pagebreak-around-set-page.png b/tests/ref/pagebreak-around-set-page.png new file mode 100644 index 000000000..2c1ce508a Binary files /dev/null and b/tests/ref/pagebreak-around-set-page.png differ diff --git a/tests/ref/pagebreak-followed-by-page-call.png b/tests/ref/pagebreak-followed-by-page-call.png new file mode 100644 index 000000000..ee435cdca Binary files /dev/null and b/tests/ref/pagebreak-followed-by-page-call.png differ diff --git a/tests/ref/pagebreak-meta.png b/tests/ref/pagebreak-meta.png new file mode 100644 index 000000000..7953dc51a Binary files /dev/null and b/tests/ref/pagebreak-meta.png differ diff --git a/tests/ref/pagebreak-set-page-mixed.png b/tests/ref/pagebreak-set-page-mixed.png new file mode 100644 index 000000000..3502ee42b Binary files /dev/null and b/tests/ref/pagebreak-set-page-mixed.png differ diff --git a/tests/ref/pagebreak-to-auto-sized.png b/tests/ref/pagebreak-to-auto-sized.png new file mode 100644 index 000000000..f3e2df45e Binary files /dev/null and b/tests/ref/pagebreak-to-auto-sized.png differ diff --git a/tests/ref/pagebreak-to-multiple-pages.png b/tests/ref/pagebreak-to-multiple-pages.png new file mode 100644 index 000000000..a7af0a9a8 Binary files /dev/null and b/tests/ref/pagebreak-to-multiple-pages.png differ diff --git a/tests/ref/pagebreak-to.png b/tests/ref/pagebreak-to.png new file mode 100644 index 000000000..62a4ee20a Binary files /dev/null and b/tests/ref/pagebreak-to.png differ diff --git a/tests/ref/pagebreak-weak-after-set-page.png b/tests/ref/pagebreak-weak-after-set-page.png new file mode 100644 index 000000000..c8014df17 Binary files /dev/null and b/tests/ref/pagebreak-weak-after-set-page.png differ diff --git a/tests/ref/pagebreak-weak-meta.png b/tests/ref/pagebreak-weak-meta.png new file mode 100644 index 000000000..aa69e606f Binary files /dev/null and b/tests/ref/pagebreak-weak-meta.png differ diff --git a/tests/ref/pagebreak-weak-place.png b/tests/ref/pagebreak-weak-place.png new file mode 100644 index 000000000..f85bdf02b Binary files /dev/null and b/tests/ref/pagebreak-weak-place.png differ diff --git a/tests/ref/pagebreak.png b/tests/ref/pagebreak.png new file mode 100644 index 000000000..d07473d90 Binary files /dev/null and b/tests/ref/pagebreak.png differ diff --git a/tests/ref/par-basic.png b/tests/ref/par-basic.png new file mode 100644 index 000000000..ffd9de9a3 Binary files /dev/null and b/tests/ref/par-basic.png differ diff --git a/tests/ref/par-first-line-indent.png b/tests/ref/par-first-line-indent.png new file mode 100644 index 000000000..e6d7ed761 Binary files /dev/null and b/tests/ref/par-first-line-indent.png differ diff --git a/tests/ref/par-hanging-indent-manual-linebreak.png b/tests/ref/par-hanging-indent-manual-linebreak.png new file mode 100644 index 000000000..e9c666cd7 Binary files /dev/null and b/tests/ref/par-hanging-indent-manual-linebreak.png differ diff --git a/tests/ref/par-hanging-indent-rtl.png b/tests/ref/par-hanging-indent-rtl.png new file mode 100644 index 000000000..849e0a012 Binary files /dev/null and b/tests/ref/par-hanging-indent-rtl.png differ diff --git a/tests/ref/par-hanging-indent.png b/tests/ref/par-hanging-indent.png new file mode 100644 index 000000000..49455a78d Binary files /dev/null and b/tests/ref/par-hanging-indent.png differ diff --git a/tests/ref/par-leading-and-block-spacing.png b/tests/ref/par-leading-and-block-spacing.png new file mode 100644 index 000000000..faaa31164 Binary files /dev/null and b/tests/ref/par-leading-and-block-spacing.png differ diff --git a/tests/ref/par-spacing-and-first-line-indent.png b/tests/ref/par-spacing-and-first-line-indent.png new file mode 100644 index 000000000..c322f6309 Binary files /dev/null and b/tests/ref/par-spacing-and-first-line-indent.png differ diff --git a/tests/ref/parser-backtracking-destructuring-whitespace.png b/tests/ref/parser-backtracking-destructuring-whitespace.png new file mode 100644 index 000000000..d5d72888e Binary files /dev/null and b/tests/ref/parser-backtracking-destructuring-whitespace.png differ diff --git a/tests/ref/path.png b/tests/ref/path.png new file mode 100644 index 000000000..9643a476c Binary files /dev/null and b/tests/ref/path.png differ diff --git a/tests/ref/pattern-line.png b/tests/ref/pattern-line.png new file mode 100644 index 000000000..b891b6d7c Binary files /dev/null and b/tests/ref/pattern-line.png differ diff --git a/tests/ref/pattern-lines.png b/tests/ref/pattern-lines.png new file mode 100644 index 000000000..008d357e7 Binary files /dev/null and b/tests/ref/pattern-lines.png differ diff --git a/tests/ref/pattern-relative-parent.png b/tests/ref/pattern-relative-parent.png new file mode 100644 index 000000000..786057ef3 Binary files /dev/null and b/tests/ref/pattern-relative-parent.png differ diff --git a/tests/ref/pattern-relative-self.png b/tests/ref/pattern-relative-self.png new file mode 100644 index 000000000..284080811 Binary files /dev/null and b/tests/ref/pattern-relative-self.png differ diff --git a/tests/ref/pattern-small.png b/tests/ref/pattern-small.png new file mode 100644 index 000000000..0406252d8 Binary files /dev/null and b/tests/ref/pattern-small.png differ diff --git a/tests/ref/pattern-spacing-negative.png b/tests/ref/pattern-spacing-negative.png new file mode 100644 index 000000000..659c22837 Binary files /dev/null and b/tests/ref/pattern-spacing-negative.png differ diff --git a/tests/ref/pattern-spacing-positive.png b/tests/ref/pattern-spacing-positive.png new file mode 100644 index 000000000..3e475eeea Binary files /dev/null and b/tests/ref/pattern-spacing-positive.png differ diff --git a/tests/ref/pattern-spacing-zero.png b/tests/ref/pattern-spacing-zero.png new file mode 100644 index 000000000..5118471ab Binary files /dev/null and b/tests/ref/pattern-spacing-zero.png differ diff --git a/tests/ref/pattern-stroke.png b/tests/ref/pattern-stroke.png new file mode 100644 index 000000000..8b03783b5 Binary files /dev/null and b/tests/ref/pattern-stroke.png differ diff --git a/tests/ref/pattern-text.png b/tests/ref/pattern-text.png new file mode 100644 index 000000000..de9bfc2ec Binary files /dev/null and b/tests/ref/pattern-text.png differ diff --git a/tests/ref/place-background.png b/tests/ref/place-background.png new file mode 100644 index 000000000..7d732717b Binary files /dev/null and b/tests/ref/place-background.png differ diff --git a/tests/ref/place-basic.png b/tests/ref/place-basic.png new file mode 100644 index 000000000..07642c347 Binary files /dev/null and b/tests/ref/place-basic.png differ diff --git a/tests/ref/place-block-spacing.png b/tests/ref/place-block-spacing.png new file mode 100644 index 000000000..fb01d1b69 Binary files /dev/null and b/tests/ref/place-block-spacing.png differ diff --git a/tests/ref/place-bottom-in-box.png b/tests/ref/place-bottom-in-box.png new file mode 100644 index 000000000..fdd8c010e Binary files /dev/null and b/tests/ref/place-bottom-in-box.png differ diff --git a/tests/ref/place-bottom-right-in-box.png b/tests/ref/place-bottom-right-in-box.png new file mode 100644 index 000000000..49c408862 Binary files /dev/null and b/tests/ref/place-bottom-right-in-box.png differ diff --git a/tests/ref/place-float-columns.png b/tests/ref/place-float-columns.png new file mode 100644 index 000000000..97065b68f Binary files /dev/null and b/tests/ref/place-float-columns.png differ diff --git a/tests/ref/place-float-figure.png b/tests/ref/place-float-figure.png new file mode 100644 index 000000000..5411178a0 Binary files /dev/null and b/tests/ref/place-float-figure.png differ diff --git a/tests/ref/place-float.png b/tests/ref/place-float.png new file mode 100644 index 000000000..ddd49c47f Binary files /dev/null and b/tests/ref/place-float.png differ diff --git a/tests/ref/place-horizon-in-boxes.png b/tests/ref/place-horizon-in-boxes.png new file mode 100644 index 000000000..b6d333bfc Binary files /dev/null and b/tests/ref/place-horizon-in-boxes.png differ diff --git a/tests/ref/place-top-left-in-box.png b/tests/ref/place-top-left-in-box.png new file mode 100644 index 000000000..914ffa58d Binary files /dev/null and b/tests/ref/place-top-left-in-box.png differ diff --git a/tests/ref/polygon-line-join.png b/tests/ref/polygon-line-join.png new file mode 100644 index 000000000..0f65fa704 Binary files /dev/null and b/tests/ref/polygon-line-join.png differ diff --git a/tests/ref/polygon.png b/tests/ref/polygon.png new file mode 100644 index 000000000..1dc110831 Binary files /dev/null and b/tests/ref/polygon.png differ diff --git a/tests/ref/query-and-or.png b/tests/ref/query-and-or.png new file mode 100644 index 000000000..39cfd0765 Binary files /dev/null and b/tests/ref/query-and-or.png differ diff --git a/tests/ref/query-before-after.png b/tests/ref/query-before-after.png new file mode 100644 index 000000000..33fde9859 Binary files /dev/null and b/tests/ref/query-before-after.png differ diff --git a/tests/ref/query-complex.png b/tests/ref/query-complex.png new file mode 100644 index 000000000..f71dcce56 Binary files /dev/null and b/tests/ref/query-complex.png differ diff --git a/tests/ref/query-list-of-figures.png b/tests/ref/query-list-of-figures.png new file mode 100644 index 000000000..c94ccd00e Binary files /dev/null and b/tests/ref/query-list-of-figures.png differ diff --git a/tests/ref/query-running-header.png b/tests/ref/query-running-header.png new file mode 100644 index 000000000..210c78103 Binary files /dev/null and b/tests/ref/query-running-header.png differ diff --git a/tests/ref/quote-block-spacing.png b/tests/ref/quote-block-spacing.png new file mode 100644 index 000000000..3efae5abe Binary files /dev/null and b/tests/ref/quote-block-spacing.png differ diff --git a/tests/ref/quote-cite-format-author-date.png b/tests/ref/quote-cite-format-author-date.png new file mode 100644 index 000000000..43816f8cc Binary files /dev/null and b/tests/ref/quote-cite-format-author-date.png differ diff --git a/tests/ref/quote-cite-format-label-or-numeric.png b/tests/ref/quote-cite-format-label-or-numeric.png new file mode 100644 index 000000000..f0f5f90f3 Binary files /dev/null and b/tests/ref/quote-cite-format-label-or-numeric.png differ diff --git a/tests/ref/quote-cite-format-note.png b/tests/ref/quote-cite-format-note.png new file mode 100644 index 000000000..1092ffdbf Binary files /dev/null and b/tests/ref/quote-cite-format-note.png differ diff --git a/tests/ref/quote-dir-align.png b/tests/ref/quote-dir-align.png new file mode 100644 index 000000000..0341f87c9 Binary files /dev/null and b/tests/ref/quote-dir-align.png differ diff --git a/tests/ref/quote-dir-author-pos.png b/tests/ref/quote-dir-author-pos.png new file mode 100644 index 000000000..842796a25 Binary files /dev/null and b/tests/ref/quote-dir-author-pos.png differ diff --git a/tests/ref/quote-inline.png b/tests/ref/quote-inline.png new file mode 100644 index 000000000..4dbc9720e Binary files /dev/null and b/tests/ref/quote-inline.png differ diff --git a/tests/ref/quote-nesting-custom.png b/tests/ref/quote-nesting-custom.png new file mode 100644 index 000000000..e26b6258e Binary files /dev/null and b/tests/ref/quote-nesting-custom.png differ diff --git a/tests/ref/quote-nesting.png b/tests/ref/quote-nesting.png new file mode 100644 index 000000000..dcd1e3780 Binary files /dev/null and b/tests/ref/quote-nesting.png differ diff --git a/tests/ref/raw-align-default.png b/tests/ref/raw-align-default.png new file mode 100644 index 000000000..84c512297 Binary files /dev/null and b/tests/ref/raw-align-default.png differ diff --git a/tests/ref/raw-align-specified.png b/tests/ref/raw-align-specified.png new file mode 100644 index 000000000..18b48deca Binary files /dev/null and b/tests/ref/raw-align-specified.png differ diff --git a/tests/ref/raw-block-no-parbreaks.png b/tests/ref/raw-block-no-parbreaks.png new file mode 100644 index 000000000..401cc5a90 Binary files /dev/null and b/tests/ref/raw-block-no-parbreaks.png differ diff --git a/tests/ref/raw-consecutive-single-backticks.png b/tests/ref/raw-consecutive-single-backticks.png new file mode 100644 index 000000000..159d0edac Binary files /dev/null and b/tests/ref/raw-consecutive-single-backticks.png differ diff --git a/tests/ref/raw-dedent-empty-line.png b/tests/ref/raw-dedent-empty-line.png new file mode 100644 index 000000000..c3c88e7ab Binary files /dev/null and b/tests/ref/raw-dedent-empty-line.png differ diff --git a/tests/ref/raw-dedent-first-line.png b/tests/ref/raw-dedent-first-line.png new file mode 100644 index 000000000..c6eee5ce2 Binary files /dev/null and b/tests/ref/raw-dedent-first-line.png differ diff --git a/tests/ref/raw-dedent-last-line.png b/tests/ref/raw-dedent-last-line.png new file mode 100644 index 000000000..2b1fe747f Binary files /dev/null and b/tests/ref/raw-dedent-last-line.png differ diff --git a/tests/ref/raw-empty.png b/tests/ref/raw-empty.png new file mode 100644 index 000000000..a47eb8556 Binary files /dev/null and b/tests/ref/raw-empty.png differ diff --git a/tests/ref/raw-highlight-typ.png b/tests/ref/raw-highlight-typ.png new file mode 100644 index 000000000..f80bbf898 Binary files /dev/null and b/tests/ref/raw-highlight-typ.png differ diff --git a/tests/ref/raw-highlight.png b/tests/ref/raw-highlight.png new file mode 100644 index 000000000..2f99b4507 Binary files /dev/null and b/tests/ref/raw-highlight.png differ diff --git a/tests/ref/raw-inline-multiline.png b/tests/ref/raw-inline-multiline.png new file mode 100644 index 000000000..7db3126d8 Binary files /dev/null and b/tests/ref/raw-inline-multiline.png differ diff --git a/tests/ref/raw-line-alternating-fill.png b/tests/ref/raw-line-alternating-fill.png new file mode 100644 index 000000000..b80531292 Binary files /dev/null and b/tests/ref/raw-line-alternating-fill.png differ diff --git a/tests/ref/raw-line-text-fill.png b/tests/ref/raw-line-text-fill.png new file mode 100644 index 000000000..5b3c4d199 Binary files /dev/null and b/tests/ref/raw-line-text-fill.png differ diff --git a/tests/ref/raw-line.png b/tests/ref/raw-line.png new file mode 100644 index 000000000..c8ada95d3 Binary files /dev/null and b/tests/ref/raw-line.png differ diff --git a/tests/ref/raw-more-backticks.png b/tests/ref/raw-more-backticks.png new file mode 100644 index 000000000..ab836011a Binary files /dev/null and b/tests/ref/raw-more-backticks.png differ diff --git a/tests/ref/raw-show-set.png b/tests/ref/raw-show-set.png new file mode 100644 index 000000000..8a82c2e95 Binary files /dev/null and b/tests/ref/raw-show-set.png differ diff --git a/tests/ref/raw-single-backtick-lang.png b/tests/ref/raw-single-backtick-lang.png new file mode 100644 index 000000000..b420627e3 Binary files /dev/null and b/tests/ref/raw-single-backtick-lang.png differ diff --git a/tests/ref/raw-syntaxes.png b/tests/ref/raw-syntaxes.png new file mode 100644 index 000000000..4e14cd066 Binary files /dev/null and b/tests/ref/raw-syntaxes.png differ diff --git a/tests/ref/raw-tab-size.png b/tests/ref/raw-tab-size.png new file mode 100644 index 000000000..132a10b32 Binary files /dev/null and b/tests/ref/raw-tab-size.png differ diff --git a/tests/ref/raw-theme.png b/tests/ref/raw-theme.png new file mode 100644 index 000000000..78561ac66 Binary files /dev/null and b/tests/ref/raw-theme.png differ diff --git a/tests/ref/raw-trimming.png b/tests/ref/raw-trimming.png new file mode 100644 index 000000000..58d90b7fe Binary files /dev/null and b/tests/ref/raw-trimming.png differ diff --git a/tests/ref/raw-typst-lang.png b/tests/ref/raw-typst-lang.png new file mode 100644 index 000000000..3dcafafbd Binary files /dev/null and b/tests/ref/raw-typst-lang.png differ diff --git a/tests/ref/rect-customization.png b/tests/ref/rect-customization.png new file mode 100644 index 000000000..93808920c Binary files /dev/null and b/tests/ref/rect-customization.png differ diff --git a/tests/ref/rect-fill-stroke.png b/tests/ref/rect-fill-stroke.png new file mode 100644 index 000000000..28a47c122 Binary files /dev/null and b/tests/ref/rect-fill-stroke.png differ diff --git a/tests/ref/rect-stroke.png b/tests/ref/rect-stroke.png new file mode 100644 index 000000000..7d59c049b Binary files /dev/null and b/tests/ref/rect-stroke.png differ diff --git a/tests/ref/rect.png b/tests/ref/rect.png new file mode 100644 index 000000000..04e435ed4 Binary files /dev/null and b/tests/ref/rect.png differ diff --git a/tests/ref/ref-basic.png b/tests/ref/ref-basic.png new file mode 100644 index 000000000..94d947894 Binary files /dev/null and b/tests/ref/ref-basic.png differ diff --git a/tests/ref/ref-supplements.png b/tests/ref/ref-supplements.png new file mode 100644 index 000000000..46d1524a1 Binary files /dev/null and b/tests/ref/ref-supplements.png differ diff --git a/tests/ref/repeat-align-and-dir.png b/tests/ref/repeat-align-and-dir.png new file mode 100644 index 000000000..16797d04b Binary files /dev/null and b/tests/ref/repeat-align-and-dir.png differ diff --git a/tests/ref/repeat-basic.png b/tests/ref/repeat-basic.png new file mode 100644 index 000000000..61e7f50f2 Binary files /dev/null and b/tests/ref/repeat-basic.png differ diff --git a/tests/ref/repeat-dots-rtl.png b/tests/ref/repeat-dots-rtl.png new file mode 100644 index 000000000..a0f1a9192 Binary files /dev/null and b/tests/ref/repeat-dots-rtl.png differ diff --git a/tests/ref/repeat-empty.png b/tests/ref/repeat-empty.png new file mode 100644 index 000000000..c23d7fa4d Binary files /dev/null and b/tests/ref/repeat-empty.png differ diff --git a/tests/ref/repeat-unboxed.png b/tests/ref/repeat-unboxed.png new file mode 100644 index 000000000..91678ceaa Binary files /dev/null and b/tests/ref/repeat-unboxed.png differ diff --git a/tests/ref/repr-color.png b/tests/ref/repr-color.png new file mode 100644 index 000000000..3425f7d4d Binary files /dev/null and b/tests/ref/repr-color.png differ diff --git a/tests/ref/repr-literals.png b/tests/ref/repr-literals.png new file mode 100644 index 000000000..1e8e85a41 Binary files /dev/null and b/tests/ref/repr-literals.png differ diff --git a/tests/ref/repr-misc.png b/tests/ref/repr-misc.png new file mode 100644 index 000000000..9a876091a Binary files /dev/null and b/tests/ref/repr-misc.png differ diff --git a/tests/ref/repr-numerical.png b/tests/ref/repr-numerical.png new file mode 100644 index 000000000..1c109a225 Binary files /dev/null and b/tests/ref/repr-numerical.png differ diff --git a/tests/ref/return-in-nested-content-block.png b/tests/ref/return-in-nested-content-block.png new file mode 100644 index 000000000..d688741c2 Binary files /dev/null and b/tests/ref/return-in-nested-content-block.png differ diff --git a/tests/ref/set-if.png b/tests/ref/set-if.png new file mode 100644 index 000000000..08dc5e826 Binary files /dev/null and b/tests/ref/set-if.png differ diff --git a/tests/ref/set-instantiation-site-markup.png b/tests/ref/set-instantiation-site-markup.png new file mode 100644 index 000000000..180444b99 Binary files /dev/null and b/tests/ref/set-instantiation-site-markup.png differ diff --git a/tests/ref/set-instantiation-site.png b/tests/ref/set-instantiation-site.png new file mode 100644 index 000000000..593d3e2df Binary files /dev/null and b/tests/ref/set-instantiation-site.png differ diff --git a/tests/ref/set-scoped-in-code-block.png b/tests/ref/set-scoped-in-code-block.png new file mode 100644 index 000000000..8941f6c4a Binary files /dev/null and b/tests/ref/set-scoped-in-code-block.png differ diff --git a/tests/ref/set-text-override.png b/tests/ref/set-text-override.png new file mode 100644 index 000000000..836238760 Binary files /dev/null and b/tests/ref/set-text-override.png differ diff --git a/tests/ref/set-vs-construct-1.png b/tests/ref/set-vs-construct-1.png new file mode 100644 index 000000000..597e96749 Binary files /dev/null and b/tests/ref/set-vs-construct-1.png differ diff --git a/tests/ref/set-vs-construct-2.png b/tests/ref/set-vs-construct-2.png new file mode 100644 index 000000000..2fedd0b42 Binary files /dev/null and b/tests/ref/set-vs-construct-2.png differ diff --git a/tests/ref/set-vs-construct-3.png b/tests/ref/set-vs-construct-3.png new file mode 100644 index 000000000..dff0c8af6 Binary files /dev/null and b/tests/ref/set-vs-construct-3.png differ diff --git a/tests/ref/set-vs-construct-4.png b/tests/ref/set-vs-construct-4.png new file mode 100644 index 000000000..1f6834ef5 Binary files /dev/null and b/tests/ref/set-vs-construct-4.png differ diff --git a/tests/ref/shaping-emoji-bad-zwj.png b/tests/ref/shaping-emoji-bad-zwj.png new file mode 100644 index 000000000..544d64eea Binary files /dev/null and b/tests/ref/shaping-emoji-bad-zwj.png differ diff --git a/tests/ref/shaping-emoji-basic.png b/tests/ref/shaping-emoji-basic.png new file mode 100644 index 000000000..090ea6111 Binary files /dev/null and b/tests/ref/shaping-emoji-basic.png differ diff --git a/tests/ref/shaping-font-fallback.png b/tests/ref/shaping-font-fallback.png new file mode 100644 index 000000000..813e39151 Binary files /dev/null and b/tests/ref/shaping-font-fallback.png differ diff --git a/tests/ref/shaping-forced-script-font-feature-enabled.png b/tests/ref/shaping-forced-script-font-feature-enabled.png new file mode 100644 index 000000000..0a10087a3 Binary files /dev/null and b/tests/ref/shaping-forced-script-font-feature-enabled.png differ diff --git a/tests/ref/shaping-forced-script-font-feature-inhibited.png b/tests/ref/shaping-forced-script-font-feature-inhibited.png new file mode 100644 index 000000000..77d8010ea Binary files /dev/null and b/tests/ref/shaping-forced-script-font-feature-inhibited.png differ diff --git a/tests/ref/shaping-script-separation.png b/tests/ref/shaping-script-separation.png new file mode 100644 index 000000000..68170dd99 Binary files /dev/null and b/tests/ref/shaping-script-separation.png differ diff --git a/tests/ref/shorthand-dashes.png b/tests/ref/shorthand-dashes.png new file mode 100644 index 000000000..f8b4191fe Binary files /dev/null and b/tests/ref/shorthand-dashes.png differ diff --git a/tests/ref/shorthand-ellipsis.png b/tests/ref/shorthand-ellipsis.png new file mode 100644 index 000000000..df9a9241e Binary files /dev/null and b/tests/ref/shorthand-ellipsis.png differ diff --git a/tests/ref/shorthand-nbsp-and-shy-hyphen.png b/tests/ref/shorthand-nbsp-and-shy-hyphen.png new file mode 100644 index 000000000..e8c81aaa6 Binary files /dev/null and b/tests/ref/shorthand-nbsp-and-shy-hyphen.png differ diff --git a/tests/ref/shorthand-nbsp-width.png b/tests/ref/shorthand-nbsp-width.png new file mode 100644 index 000000000..a92988cf1 Binary files /dev/null and b/tests/ref/shorthand-nbsp-width.png differ diff --git a/tests/ref/shorthands-math.png b/tests/ref/shorthands-math.png new file mode 100644 index 000000000..0514fa622 Binary files /dev/null and b/tests/ref/shorthands-math.png differ diff --git a/tests/ref/show-bare-basic.png b/tests/ref/show-bare-basic.png new file mode 100644 index 000000000..e389b5063 Binary files /dev/null and b/tests/ref/show-bare-basic.png differ diff --git a/tests/ref/show-bare-content-block.png b/tests/ref/show-bare-content-block.png new file mode 100644 index 000000000..2631092bb Binary files /dev/null and b/tests/ref/show-bare-content-block.png differ diff --git a/tests/ref/show-bare-replace-with-content.png b/tests/ref/show-bare-replace-with-content.png new file mode 100644 index 000000000..51e36a492 Binary files /dev/null and b/tests/ref/show-bare-replace-with-content.png differ diff --git a/tests/ref/show-bare-vs-set-text.png b/tests/ref/show-bare-vs-set-text.png new file mode 100644 index 000000000..b1e15d98f Binary files /dev/null and b/tests/ref/show-bare-vs-set-text.png differ diff --git a/tests/ref/show-function-order-with-set.png b/tests/ref/show-function-order-with-set.png new file mode 100644 index 000000000..a59f72741 Binary files /dev/null and b/tests/ref/show-function-order-with-set.png differ diff --git a/tests/ref/show-function-set-on-it.png b/tests/ref/show-function-set-on-it.png new file mode 100644 index 000000000..6c545e954 Binary files /dev/null and b/tests/ref/show-function-set-on-it.png differ diff --git a/tests/ref/show-in-show.png b/tests/ref/show-in-show.png new file mode 100644 index 000000000..65280ad7b Binary files /dev/null and b/tests/ref/show-in-show.png differ diff --git a/tests/ref/show-multiple-rules.png b/tests/ref/show-multiple-rules.png new file mode 100644 index 000000000..c92b6269e Binary files /dev/null and b/tests/ref/show-multiple-rules.png differ diff --git a/tests/ref/show-nested-scopes.png b/tests/ref/show-nested-scopes.png new file mode 100644 index 000000000..ac0a81256 Binary files /dev/null and b/tests/ref/show-nested-scopes.png differ diff --git a/tests/ref/show-recursive-identity.png b/tests/ref/show-recursive-identity.png new file mode 100644 index 000000000..6c545e954 Binary files /dev/null and b/tests/ref/show-recursive-identity.png differ diff --git a/tests/ref/show-recursive-multiple.png b/tests/ref/show-recursive-multiple.png new file mode 100644 index 000000000..b56b089c9 Binary files /dev/null and b/tests/ref/show-recursive-multiple.png differ diff --git a/tests/ref/show-rule-in-function.png b/tests/ref/show-rule-in-function.png new file mode 100644 index 000000000..97aa2845e Binary files /dev/null and b/tests/ref/show-rule-in-function.png differ diff --git a/tests/ref/show-selector-basic.png b/tests/ref/show-selector-basic.png new file mode 100644 index 000000000..870166d9e Binary files /dev/null and b/tests/ref/show-selector-basic.png differ diff --git a/tests/ref/show-selector-discard.png b/tests/ref/show-selector-discard.png new file mode 100644 index 000000000..13c9f0d65 Binary files /dev/null and b/tests/ref/show-selector-discard.png differ diff --git a/tests/ref/show-selector-element-or-label.png b/tests/ref/show-selector-element-or-label.png new file mode 100644 index 000000000..32cd992d2 Binary files /dev/null and b/tests/ref/show-selector-element-or-label.png differ diff --git a/tests/ref/show-selector-or-elements-with-set.png b/tests/ref/show-selector-or-elements-with-set.png new file mode 100644 index 000000000..f561cad88 Binary files /dev/null and b/tests/ref/show-selector-or-elements-with-set.png differ diff --git a/tests/ref/show-selector-realistic.png b/tests/ref/show-selector-realistic.png new file mode 100644 index 000000000..ae4f4a9a8 Binary files /dev/null and b/tests/ref/show-selector-realistic.png differ diff --git a/tests/ref/show-selector-replace-and-show-set.png b/tests/ref/show-selector-replace-and-show-set.png new file mode 100644 index 000000000..47a7ae336 Binary files /dev/null and b/tests/ref/show-selector-replace-and-show-set.png differ diff --git a/tests/ref/show-selector-replace.png b/tests/ref/show-selector-replace.png new file mode 100644 index 000000000..c00a88e8c Binary files /dev/null and b/tests/ref/show-selector-replace.png differ diff --git a/tests/ref/show-selector-where.png b/tests/ref/show-selector-where.png new file mode 100644 index 000000000..4cb02efd0 Binary files /dev/null and b/tests/ref/show-selector-where.png differ diff --git a/tests/ref/show-set-on-layoutable-element.png b/tests/ref/show-set-on-layoutable-element.png new file mode 100644 index 000000000..701bea508 Binary files /dev/null and b/tests/ref/show-set-on-layoutable-element.png differ diff --git a/tests/ref/show-set-on-same-element.png b/tests/ref/show-set-on-same-element.png new file mode 100644 index 000000000..9459fca0c Binary files /dev/null and b/tests/ref/show-set-on-same-element.png differ diff --git a/tests/ref/show-set-override.png b/tests/ref/show-set-override.png new file mode 100644 index 000000000..e7831b90a Binary files /dev/null and b/tests/ref/show-set-override.png differ diff --git a/tests/ref/show-set-same-element-and-order.png b/tests/ref/show-set-same-element-and-order.png new file mode 100644 index 000000000..d55d5e14f Binary files /dev/null and b/tests/ref/show-set-same-element-and-order.png differ diff --git a/tests/ref/show-set-same-element-matched-field.png b/tests/ref/show-set-same-element-matched-field.png new file mode 100644 index 000000000..aa44baee9 Binary files /dev/null and b/tests/ref/show-set-same-element-matched-field.png differ diff --git a/tests/ref/show-set-same-element-matching-interaction.png b/tests/ref/show-set-same-element-matching-interaction.png new file mode 100644 index 000000000..bc0610385 Binary files /dev/null and b/tests/ref/show-set-same-element-matching-interaction.png differ diff --git a/tests/ref/show-set-same-element-synthesized-matched-field.png b/tests/ref/show-set-same-element-synthesized-matched-field.png new file mode 100644 index 000000000..c3918e8f3 Binary files /dev/null and b/tests/ref/show-set-same-element-synthesized-matched-field.png differ diff --git a/tests/ref/show-set-text-order-adjacent-1.png b/tests/ref/show-set-text-order-adjacent-1.png new file mode 100644 index 000000000..1bc95e3b9 Binary files /dev/null and b/tests/ref/show-set-text-order-adjacent-1.png differ diff --git a/tests/ref/show-set-text-order-adjacent-2.png b/tests/ref/show-set-text-order-adjacent-2.png new file mode 100644 index 000000000..caada91a0 Binary files /dev/null and b/tests/ref/show-set-text-order-adjacent-2.png differ diff --git a/tests/ref/show-set-text-order-contained-1.png b/tests/ref/show-set-text-order-contained-1.png new file mode 100644 index 000000000..8deaaacdf Binary files /dev/null and b/tests/ref/show-set-text-order-contained-1.png differ diff --git a/tests/ref/show-set-text-order-contained-2.png b/tests/ref/show-set-text-order-contained-2.png new file mode 100644 index 000000000..00ea3fb83 Binary files /dev/null and b/tests/ref/show-set-text-order-contained-2.png differ diff --git a/tests/ref/show-set-text-order-contained-3.png b/tests/ref/show-set-text-order-contained-3.png new file mode 100644 index 000000000..1bc95e3b9 Binary files /dev/null and b/tests/ref/show-set-text-order-contained-3.png differ diff --git a/tests/ref/show-set-text-order-contained-4.png b/tests/ref/show-set-text-order-contained-4.png new file mode 100644 index 000000000..0946f9221 Binary files /dev/null and b/tests/ref/show-set-text-order-contained-4.png differ diff --git a/tests/ref/show-set-text-order-overlapping-1.png b/tests/ref/show-set-text-order-overlapping-1.png new file mode 100644 index 000000000..71222567b Binary files /dev/null and b/tests/ref/show-set-text-order-overlapping-1.png differ diff --git a/tests/ref/show-set-text-order-overlapping-2.png b/tests/ref/show-set-text-order-overlapping-2.png new file mode 100644 index 000000000..f1b658f20 Binary files /dev/null and b/tests/ref/show-set-text-order-overlapping-2.png differ diff --git a/tests/ref/show-set-vs-construct.png b/tests/ref/show-set-vs-construct.png new file mode 100644 index 000000000..a0ec96bf6 Binary files /dev/null and b/tests/ref/show-set-vs-construct.png differ diff --git a/tests/ref/show-set-where-override.png b/tests/ref/show-set-where-override.png new file mode 100644 index 000000000..7f1ec60d4 Binary files /dev/null and b/tests/ref/show-set-where-override.png differ diff --git a/tests/ref/show-text-basic.png b/tests/ref/show-text-basic.png new file mode 100644 index 000000000..29bb5840c Binary files /dev/null and b/tests/ref/show-text-basic.png differ diff --git a/tests/ref/show-text-cyclic-raw.png b/tests/ref/show-text-cyclic-raw.png new file mode 100644 index 000000000..b7521c449 Binary files /dev/null and b/tests/ref/show-text-cyclic-raw.png differ diff --git a/tests/ref/show-text-cyclic.png b/tests/ref/show-text-cyclic.png new file mode 100644 index 000000000..4c4c48868 Binary files /dev/null and b/tests/ref/show-text-cyclic.png differ diff --git a/tests/ref/show-text-exactly-once.png b/tests/ref/show-text-exactly-once.png new file mode 100644 index 000000000..f681f7216 Binary files /dev/null and b/tests/ref/show-text-exactly-once.png differ diff --git a/tests/ref/show-text-get-text-on-it.png b/tests/ref/show-text-get-text-on-it.png new file mode 100644 index 000000000..5c75b9de9 Binary files /dev/null and b/tests/ref/show-text-get-text-on-it.png differ diff --git a/tests/ref/show-text-in-other-show.png b/tests/ref/show-text-in-other-show.png new file mode 100644 index 000000000..f29de999b Binary files /dev/null and b/tests/ref/show-text-in-other-show.png differ diff --git a/tests/ref/show-text-indirectly-cyclic.png b/tests/ref/show-text-indirectly-cyclic.png new file mode 100644 index 000000000..de166dcaa Binary files /dev/null and b/tests/ref/show-text-indirectly-cyclic.png differ diff --git a/tests/ref/show-text-path-resolving.png b/tests/ref/show-text-path-resolving.png new file mode 100644 index 000000000..1a04f9e6e Binary files /dev/null and b/tests/ref/show-text-path-resolving.png differ diff --git a/tests/ref/show-text-regex-case-insensitive.png b/tests/ref/show-text-regex-case-insensitive.png new file mode 100644 index 000000000..70d70d343 Binary files /dev/null and b/tests/ref/show-text-regex-case-insensitive.png differ diff --git a/tests/ref/show-text-regex-character-class.png b/tests/ref/show-text-regex-character-class.png new file mode 100644 index 000000000..946c5d225 Binary files /dev/null and b/tests/ref/show-text-regex-character-class.png differ diff --git a/tests/ref/show-text-regex-word-boundary.png b/tests/ref/show-text-regex-word-boundary.png new file mode 100644 index 000000000..c171ac027 Binary files /dev/null and b/tests/ref/show-text-regex-word-boundary.png differ diff --git a/tests/ref/show-text-regex.png b/tests/ref/show-text-regex.png new file mode 100644 index 000000000..85db10a33 Binary files /dev/null and b/tests/ref/show-text-regex.png differ diff --git a/tests/ref/show-where-folding-stroke.png b/tests/ref/show-where-folding-stroke.png new file mode 100644 index 000000000..186ce6810 Binary files /dev/null and b/tests/ref/show-where-folding-stroke.png differ diff --git a/tests/ref/show-where-folding-text-size.png b/tests/ref/show-where-folding-text-size.png new file mode 100644 index 000000000..9fbe3ff98 Binary files /dev/null and b/tests/ref/show-where-folding-text-size.png differ diff --git a/tests/ref/show-where-optional-field-raw.png b/tests/ref/show-where-optional-field-raw.png new file mode 100644 index 000000000..dd3816108 Binary files /dev/null and b/tests/ref/show-where-optional-field-raw.png differ diff --git a/tests/ref/show-where-optional-field-text.png b/tests/ref/show-where-optional-field-text.png new file mode 100644 index 000000000..b1367d092 Binary files /dev/null and b/tests/ref/show-where-optional-field-text.png differ diff --git a/tests/ref/show-where-resolving-hyphenate.png b/tests/ref/show-where-resolving-hyphenate.png new file mode 100644 index 000000000..052a2eda5 Binary files /dev/null and b/tests/ref/show-where-resolving-hyphenate.png differ diff --git a/tests/ref/show-where-resolving-length.png b/tests/ref/show-where-resolving-length.png new file mode 100644 index 000000000..4c77f2acd Binary files /dev/null and b/tests/ref/show-where-resolving-length.png differ diff --git a/tests/ref/smallcaps.png b/tests/ref/smallcaps.png new file mode 100644 index 000000000..b5ee12b79 Binary files /dev/null and b/tests/ref/smallcaps.png differ diff --git a/tests/ref/smartquote-apostrophe.png b/tests/ref/smartquote-apostrophe.png new file mode 100644 index 000000000..d2cc1ebf7 Binary files /dev/null and b/tests/ref/smartquote-apostrophe.png differ diff --git a/tests/ref/smartquote-custom-complex.png b/tests/ref/smartquote-custom-complex.png new file mode 100644 index 000000000..7204a997b Binary files /dev/null and b/tests/ref/smartquote-custom-complex.png differ diff --git a/tests/ref/smartquote-custom.png b/tests/ref/smartquote-custom.png new file mode 100644 index 000000000..6a6bd9d1a Binary files /dev/null and b/tests/ref/smartquote-custom.png differ diff --git a/tests/ref/smartquote-disable.png b/tests/ref/smartquote-disable.png new file mode 100644 index 000000000..0218b7acb Binary files /dev/null and b/tests/ref/smartquote-disable.png differ diff --git a/tests/ref/smartquote-disabled-temporarily.png b/tests/ref/smartquote-disabled-temporarily.png new file mode 100644 index 000000000..84bc5e32b Binary files /dev/null and b/tests/ref/smartquote-disabled-temporarily.png differ diff --git a/tests/ref/smartquote-empty.png b/tests/ref/smartquote-empty.png new file mode 100644 index 000000000..f9f19989c Binary files /dev/null and b/tests/ref/smartquote-empty.png differ diff --git a/tests/ref/smartquote-escape.png b/tests/ref/smartquote-escape.png new file mode 100644 index 000000000..45d8f6027 Binary files /dev/null and b/tests/ref/smartquote-escape.png differ diff --git a/tests/ref/smartquote-nesting.png b/tests/ref/smartquote-nesting.png new file mode 100644 index 000000000..1f38c0975 Binary files /dev/null and b/tests/ref/smartquote-nesting.png differ diff --git a/tests/ref/smartquote.png b/tests/ref/smartquote.png new file mode 100644 index 000000000..070e04876 Binary files /dev/null and b/tests/ref/smartquote.png differ diff --git a/tests/ref/space-collapsing-comments.png b/tests/ref/space-collapsing-comments.png new file mode 100644 index 000000000..b35d9fec9 Binary files /dev/null and b/tests/ref/space-collapsing-comments.png differ diff --git a/tests/ref/space-collapsing-linebreaks.png b/tests/ref/space-collapsing-linebreaks.png new file mode 100644 index 000000000..b1f4a3af9 Binary files /dev/null and b/tests/ref/space-collapsing-linebreaks.png differ diff --git a/tests/ref/space-collapsing-stringy-linebreak.png b/tests/ref/space-collapsing-stringy-linebreak.png new file mode 100644 index 000000000..ceec6da7c Binary files /dev/null and b/tests/ref/space-collapsing-stringy-linebreak.png differ diff --git a/tests/ref/space-collapsing-with-h.png b/tests/ref/space-collapsing-with-h.png new file mode 100644 index 000000000..c2e253e71 Binary files /dev/null and b/tests/ref/space-collapsing-with-h.png differ diff --git a/tests/ref/space-collapsing.png b/tests/ref/space-collapsing.png new file mode 100644 index 000000000..32bd6039d Binary files /dev/null and b/tests/ref/space-collapsing.png differ diff --git a/tests/ref/space-ideographic-kept.png b/tests/ref/space-ideographic-kept.png new file mode 100644 index 000000000..cd292e2da Binary files /dev/null and b/tests/ref/space-ideographic-kept.png differ diff --git a/tests/ref/space-thin-kept.png b/tests/ref/space-thin-kept.png new file mode 100644 index 000000000..6ed3504be Binary files /dev/null and b/tests/ref/space-thin-kept.png differ diff --git a/tests/ref/space-trailing-linebreak.png b/tests/ref/space-trailing-linebreak.png new file mode 100644 index 000000000..42b282643 Binary files /dev/null and b/tests/ref/space-trailing-linebreak.png differ diff --git a/tests/ref/spacing-h-and-v.png b/tests/ref/spacing-h-and-v.png new file mode 100644 index 000000000..2c9a29606 Binary files /dev/null and b/tests/ref/spacing-h-and-v.png differ diff --git a/tests/ref/spacing-rtl.png b/tests/ref/spacing-rtl.png new file mode 100644 index 000000000..a9cbbca6e Binary files /dev/null and b/tests/ref/spacing-rtl.png differ diff --git a/tests/ref/square-auto-sized.png b/tests/ref/square-auto-sized.png new file mode 100644 index 000000000..a2c4a36e1 Binary files /dev/null and b/tests/ref/square-auto-sized.png differ diff --git a/tests/ref/square-base.png b/tests/ref/square-base.png new file mode 100644 index 000000000..3ef753f23 Binary files /dev/null and b/tests/ref/square-base.png differ diff --git a/tests/ref/square-circle-alignment.png b/tests/ref/square-circle-alignment.png new file mode 100644 index 000000000..3fff9e66f Binary files /dev/null and b/tests/ref/square-circle-alignment.png differ diff --git a/tests/ref/square-circle-overspecified.png b/tests/ref/square-circle-overspecified.png new file mode 100644 index 000000000..6dde5e511 Binary files /dev/null and b/tests/ref/square-circle-overspecified.png differ diff --git a/tests/ref/square-contents-overflow.png b/tests/ref/square-contents-overflow.png new file mode 100644 index 000000000..ae65b0a8c Binary files /dev/null and b/tests/ref/square-contents-overflow.png differ diff --git a/tests/ref/square-height-limited-stack.png b/tests/ref/square-height-limited-stack.png new file mode 100644 index 000000000..f52c608d6 Binary files /dev/null and b/tests/ref/square-height-limited-stack.png differ diff --git a/tests/ref/square-height-limited.png b/tests/ref/square-height-limited.png new file mode 100644 index 000000000..c01dc426a Binary files /dev/null and b/tests/ref/square-height-limited.png differ diff --git a/tests/ref/square-overflow.png b/tests/ref/square-overflow.png new file mode 100644 index 000000000..6169f305b Binary files /dev/null and b/tests/ref/square-overflow.png differ diff --git a/tests/ref/square-rect-rounded.png b/tests/ref/square-rect-rounded.png new file mode 100644 index 000000000..678ba819b Binary files /dev/null and b/tests/ref/square-rect-rounded.png differ diff --git a/tests/ref/square-relative-size.png b/tests/ref/square-relative-size.png new file mode 100644 index 000000000..96e744e6b Binary files /dev/null and b/tests/ref/square-relative-size.png differ diff --git a/tests/ref/square-relatively-sized-child.png b/tests/ref/square-relatively-sized-child.png new file mode 100644 index 000000000..3ffe31057 Binary files /dev/null and b/tests/ref/square-relatively-sized-child.png differ diff --git a/tests/ref/square.png b/tests/ref/square.png new file mode 100644 index 000000000..e6f8f5c8d Binary files /dev/null and b/tests/ref/square.png differ diff --git a/tests/ref/stack-basic.png b/tests/ref/stack-basic.png new file mode 100644 index 000000000..b5f38a833 Binary files /dev/null and b/tests/ref/stack-basic.png differ diff --git a/tests/ref/stack-fr.png b/tests/ref/stack-fr.png new file mode 100644 index 000000000..e34dd9b11 Binary files /dev/null and b/tests/ref/stack-fr.png differ diff --git a/tests/ref/stack-overflow.png b/tests/ref/stack-overflow.png new file mode 100644 index 000000000..43b3625af Binary files /dev/null and b/tests/ref/stack-overflow.png differ diff --git a/tests/ref/stack-rtl-align-and-fr.png b/tests/ref/stack-rtl-align-and-fr.png new file mode 100644 index 000000000..653ade6fd Binary files /dev/null and b/tests/ref/stack-rtl-align-and-fr.png differ diff --git a/tests/ref/stack-spacing.png b/tests/ref/stack-spacing.png new file mode 100644 index 000000000..9667f6577 Binary files /dev/null and b/tests/ref/stack-spacing.png differ diff --git a/tests/ref/state-basic.png b/tests/ref/state-basic.png new file mode 100644 index 000000000..0c67a751d Binary files /dev/null and b/tests/ref/state-basic.png differ diff --git a/tests/ref/state-multiple-calls-same-key.png b/tests/ref/state-multiple-calls-same-key.png new file mode 100644 index 000000000..077b67929 Binary files /dev/null and b/tests/ref/state-multiple-calls-same-key.png differ diff --git a/tests/ref/state-nested.png b/tests/ref/state-nested.png new file mode 100644 index 000000000..cc7016001 Binary files /dev/null and b/tests/ref/state-nested.png differ diff --git a/tests/ref/state-no-convergence.png b/tests/ref/state-no-convergence.png new file mode 100644 index 000000000..dd44b9e17 Binary files /dev/null and b/tests/ref/state-no-convergence.png differ diff --git a/tests/ref/strike-background.png b/tests/ref/strike-background.png new file mode 100644 index 000000000..01861d255 Binary files /dev/null and b/tests/ref/strike-background.png differ diff --git a/tests/ref/strike-with.png b/tests/ref/strike-with.png new file mode 100644 index 000000000..59a84150e Binary files /dev/null and b/tests/ref/strike-with.png differ diff --git a/tests/ref/stroke-composition.png b/tests/ref/stroke-composition.png new file mode 100644 index 000000000..a6c7ce70f Binary files /dev/null and b/tests/ref/stroke-composition.png differ diff --git a/tests/ref/stroke-folding.png b/tests/ref/stroke-folding.png new file mode 100644 index 000000000..b4f1b1a9a Binary files /dev/null and b/tests/ref/stroke-folding.png differ diff --git a/tests/ref/stroke-text.png b/tests/ref/stroke-text.png new file mode 100644 index 000000000..ac09053a9 Binary files /dev/null and b/tests/ref/stroke-text.png differ diff --git a/tests/ref/stroke-zero-thickness.png b/tests/ref/stroke-zero-thickness.png new file mode 100644 index 000000000..6d305eaf4 Binary files /dev/null and b/tests/ref/stroke-zero-thickness.png differ diff --git a/tests/ref/strong-delta.png b/tests/ref/strong-delta.png new file mode 100644 index 000000000..d32459f60 Binary files /dev/null and b/tests/ref/strong-delta.png differ diff --git a/tests/ref/strong-double-star-empty-hint.png b/tests/ref/strong-double-star-empty-hint.png new file mode 100644 index 000000000..29cbb90f4 Binary files /dev/null and b/tests/ref/strong-double-star-empty-hint.png differ diff --git a/tests/ref/sub-super-non-typographic.png b/tests/ref/sub-super-non-typographic.png new file mode 100644 index 000000000..e5a8b6733 Binary files /dev/null and b/tests/ref/sub-super-non-typographic.png differ diff --git a/tests/ref/sub-super.png b/tests/ref/sub-super.png new file mode 100644 index 000000000..9359cf015 Binary files /dev/null and b/tests/ref/sub-super.png differ diff --git a/tests/ref/super-underline.png b/tests/ref/super-underline.png new file mode 100644 index 000000000..99c1c3090 Binary files /dev/null and b/tests/ref/super-underline.png differ diff --git a/tests/ref/symbol-constructor.png b/tests/ref/symbol-constructor.png new file mode 100644 index 000000000..e6db9491d Binary files /dev/null and b/tests/ref/symbol-constructor.png differ diff --git a/tests/ref/symbol.png b/tests/ref/symbol.png new file mode 100644 index 000000000..37339d591 Binary files /dev/null and b/tests/ref/symbol.png differ diff --git a/tests/ref/table-align-array.png b/tests/ref/table-align-array.png new file mode 100644 index 000000000..9242ae120 Binary files /dev/null and b/tests/ref/table-align-array.png differ diff --git a/tests/ref/table-cell-align-override.png b/tests/ref/table-cell-align-override.png new file mode 100644 index 000000000..dfab2bb03 Binary files /dev/null and b/tests/ref/table-cell-align-override.png differ diff --git a/tests/ref/table-cell-folding.png b/tests/ref/table-cell-folding.png new file mode 100644 index 000000000..94897a927 Binary files /dev/null and b/tests/ref/table-cell-folding.png differ diff --git a/tests/ref/table-cell-override.png b/tests/ref/table-cell-override.png new file mode 100644 index 000000000..d6f37d632 Binary files /dev/null and b/tests/ref/table-cell-override.png differ diff --git a/tests/ref/table-cell-set.png b/tests/ref/table-cell-set.png new file mode 100644 index 000000000..ce873b05e Binary files /dev/null and b/tests/ref/table-cell-set.png differ diff --git a/tests/ref/table-cell-show-and-override.png b/tests/ref/table-cell-show-and-override.png new file mode 100644 index 000000000..df7458022 Binary files /dev/null and b/tests/ref/table-cell-show-and-override.png differ diff --git a/tests/ref/table-cell-show-based-on-position.png b/tests/ref/table-cell-show-based-on-position.png new file mode 100644 index 000000000..db46e2600 Binary files /dev/null and b/tests/ref/table-cell-show-based-on-position.png differ diff --git a/tests/ref/table-cell-show-emph.png b/tests/ref/table-cell-show-emph.png new file mode 100644 index 000000000..1afc833ba Binary files /dev/null and b/tests/ref/table-cell-show-emph.png differ diff --git a/tests/ref/table-cell-show.png b/tests/ref/table-cell-show.png new file mode 100644 index 000000000..9ac6d2695 Binary files /dev/null and b/tests/ref/table-cell-show.png differ diff --git a/tests/ref/table-cell-various-overrides.png b/tests/ref/table-cell-various-overrides.png new file mode 100644 index 000000000..c8540dfed Binary files /dev/null and b/tests/ref/table-cell-various-overrides.png differ diff --git a/tests/ref/table-fill-basic.png b/tests/ref/table-fill-basic.png new file mode 100644 index 000000000..bc12f8ae8 Binary files /dev/null and b/tests/ref/table-fill-basic.png differ diff --git a/tests/ref/table-gutters.png b/tests/ref/table-gutters.png new file mode 100644 index 000000000..697ddd488 Binary files /dev/null and b/tests/ref/table-gutters.png differ diff --git a/tests/ref/table-inset-fold.png b/tests/ref/table-inset-fold.png new file mode 100644 index 000000000..f2985c9ed Binary files /dev/null and b/tests/ref/table-inset-fold.png differ diff --git a/tests/ref/table-inset.png b/tests/ref/table-inset.png new file mode 100644 index 000000000..a8a9adda6 Binary files /dev/null and b/tests/ref/table-inset.png differ diff --git a/tests/ref/table-newlines.png b/tests/ref/table-newlines.png new file mode 100644 index 000000000..a4da25f3d Binary files /dev/null and b/tests/ref/table-newlines.png differ diff --git a/tests/ref/table-stroke-vline-position-left-and-right.png b/tests/ref/table-stroke-vline-position-left-and-right.png new file mode 100644 index 000000000..53b48a101 Binary files /dev/null and b/tests/ref/table-stroke-vline-position-left-and-right.png differ diff --git a/tests/ref/terms-built-in-loop.png b/tests/ref/terms-built-in-loop.png new file mode 100644 index 000000000..dc103af92 Binary files /dev/null and b/tests/ref/terms-built-in-loop.png differ diff --git a/tests/ref/terms-constructor.png b/tests/ref/terms-constructor.png new file mode 100644 index 000000000..fe1615058 Binary files /dev/null and b/tests/ref/terms-constructor.png differ diff --git a/tests/ref/terms-grid.png b/tests/ref/terms-grid.png new file mode 100644 index 000000000..6142becfc Binary files /dev/null and b/tests/ref/terms-grid.png differ diff --git a/tests/ref/terms-multiline.png b/tests/ref/terms-multiline.png new file mode 100644 index 000000000..b5baea4ad Binary files /dev/null and b/tests/ref/terms-multiline.png differ diff --git a/tests/ref/terms-rtl.png b/tests/ref/terms-rtl.png new file mode 100644 index 000000000..538571ddb Binary files /dev/null and b/tests/ref/terms-rtl.png differ diff --git a/tests/ref/terms-style-change-interrupted.png b/tests/ref/terms-style-change-interrupted.png new file mode 100644 index 000000000..846e45e14 Binary files /dev/null and b/tests/ref/terms-style-change-interrupted.png differ diff --git a/tests/ref/terms-syntax-edge-cases.png b/tests/ref/terms-syntax-edge-cases.png new file mode 100644 index 000000000..e2a557c1a Binary files /dev/null and b/tests/ref/terms-syntax-edge-cases.png differ diff --git a/tests/ref/text-alternates-and-stylistic-sets.png b/tests/ref/text-alternates-and-stylistic-sets.png new file mode 100644 index 000000000..877542fc2 Binary files /dev/null and b/tests/ref/text-alternates-and-stylistic-sets.png differ diff --git a/tests/ref/text-call-body.png b/tests/ref/text-call-body.png new file mode 100644 index 000000000..24cdeb9f9 Binary files /dev/null and b/tests/ref/text-call-body.png differ diff --git a/tests/ref/text-chinese-basic.png b/tests/ref/text-chinese-basic.png new file mode 100644 index 000000000..ea4a0b829 Binary files /dev/null and b/tests/ref/text-chinese-basic.png differ diff --git a/tests/ref/text-cjk-latin-spacing.png b/tests/ref/text-cjk-latin-spacing.png new file mode 100644 index 000000000..1906bf761 Binary files /dev/null and b/tests/ref/text-cjk-latin-spacing.png differ diff --git a/tests/ref/text-copy-paste-ligatures.png b/tests/ref/text-copy-paste-ligatures.png new file mode 100644 index 000000000..f0f36a869 Binary files /dev/null and b/tests/ref/text-copy-paste-ligatures.png differ diff --git a/tests/ref/text-edge.png b/tests/ref/text-edge.png new file mode 100644 index 000000000..0953ededf Binary files /dev/null and b/tests/ref/text-edge.png differ diff --git a/tests/ref/text-features.png b/tests/ref/text-features.png new file mode 100644 index 000000000..7b0b391f7 Binary files /dev/null and b/tests/ref/text-features.png differ diff --git a/tests/ref/text-font-change-after-space.png b/tests/ref/text-font-change-after-space.png new file mode 100644 index 000000000..83d2ceb62 Binary files /dev/null and b/tests/ref/text-font-change-after-space.png differ diff --git a/tests/ref/text-font-just-a-space.png b/tests/ref/text-font-just-a-space.png new file mode 100644 index 000000000..3c91db3ce Binary files /dev/null and b/tests/ref/text-font-just-a-space.png differ diff --git a/tests/ref/text-font-properties.png b/tests/ref/text-font-properties.png new file mode 100644 index 000000000..3c65fa33c Binary files /dev/null and b/tests/ref/text-font-properties.png differ diff --git a/tests/ref/text-kerning.png b/tests/ref/text-kerning.png new file mode 100644 index 000000000..1bd3a0012 Binary files /dev/null and b/tests/ref/text-kerning.png differ diff --git a/tests/ref/text-lang-hyphenate.png b/tests/ref/text-lang-hyphenate.png new file mode 100644 index 000000000..6315d6e21 Binary files /dev/null and b/tests/ref/text-lang-hyphenate.png differ diff --git a/tests/ref/text-lang-region.png b/tests/ref/text-lang-region.png new file mode 100644 index 000000000..a27365784 Binary files /dev/null and b/tests/ref/text-lang-region.png differ diff --git a/tests/ref/text-lang-script-shaping.png b/tests/ref/text-lang-script-shaping.png new file mode 100644 index 000000000..6beaece40 Binary files /dev/null and b/tests/ref/text-lang-script-shaping.png differ diff --git a/tests/ref/text-lang-shaping.png b/tests/ref/text-lang-shaping.png new file mode 100644 index 000000000..b892fcd5d Binary files /dev/null and b/tests/ref/text-lang-shaping.png differ diff --git a/tests/ref/text-lang-unknown-region.png b/tests/ref/text-lang-unknown-region.png new file mode 100644 index 000000000..de63013ec Binary files /dev/null and b/tests/ref/text-lang-unknown-region.png differ diff --git a/tests/ref/text-lang.png b/tests/ref/text-lang.png new file mode 100644 index 000000000..de63013ec Binary files /dev/null and b/tests/ref/text-lang.png differ diff --git a/tests/ref/text-ligatures.png b/tests/ref/text-ligatures.png new file mode 100644 index 000000000..6f0e286c6 Binary files /dev/null and b/tests/ref/text-ligatures.png differ diff --git a/tests/ref/text-number-type.png b/tests/ref/text-number-type.png new file mode 100644 index 000000000..beb6ba6c4 Binary files /dev/null and b/tests/ref/text-number-type.png differ diff --git a/tests/ref/text-number-width.png b/tests/ref/text-number-width.png new file mode 100644 index 000000000..62d8c61b2 Binary files /dev/null and b/tests/ref/text-number-width.png differ diff --git a/tests/ref/text-size-em-nesting.png b/tests/ref/text-size-em-nesting.png new file mode 100644 index 000000000..34ae35fe1 Binary files /dev/null and b/tests/ref/text-size-em-nesting.png differ diff --git a/tests/ref/text-size-em.png b/tests/ref/text-size-em.png new file mode 100644 index 000000000..944bdd298 Binary files /dev/null and b/tests/ref/text-size-em.png differ diff --git a/tests/ref/text-slashed-zero-and-fractions.png b/tests/ref/text-slashed-zero-and-fractions.png new file mode 100644 index 000000000..a25ca0232 Binary files /dev/null and b/tests/ref/text-slashed-zero-and-fractions.png differ diff --git a/tests/ref/text-spacing-relative.png b/tests/ref/text-spacing-relative.png new file mode 100644 index 000000000..ccd2f1405 Binary files /dev/null and b/tests/ref/text-spacing-relative.png differ diff --git a/tests/ref/text-spacing.png b/tests/ref/text-spacing.png new file mode 100644 index 000000000..240c69c07 Binary files /dev/null and b/tests/ref/text-spacing.png differ diff --git a/tests/ref/text-tracking-arabic.png b/tests/ref/text-tracking-arabic.png new file mode 100644 index 000000000..a4e450ff6 Binary files /dev/null and b/tests/ref/text-tracking-arabic.png differ diff --git a/tests/ref/text-tracking-changed-temporarily.png b/tests/ref/text-tracking-changed-temporarily.png new file mode 100644 index 000000000..f27849b43 Binary files /dev/null and b/tests/ref/text-tracking-changed-temporarily.png differ diff --git a/tests/ref/text-tracking-mark-placement.png b/tests/ref/text-tracking-mark-placement.png new file mode 100644 index 000000000..7fc8bb19e Binary files /dev/null and b/tests/ref/text-tracking-mark-placement.png differ diff --git a/tests/ref/text-tracking-negative.png b/tests/ref/text-tracking-negative.png new file mode 100644 index 000000000..965898878 Binary files /dev/null and b/tests/ref/text-tracking-negative.png differ diff --git a/tests/ref/text/baseline.png b/tests/ref/text/baseline.png deleted file mode 100644 index dcd6eb121..000000000 Binary files a/tests/ref/text/baseline.png and /dev/null differ diff --git a/tests/ref/text/chinese.png b/tests/ref/text/chinese.png deleted file mode 100644 index 0c3ddd002..000000000 Binary files a/tests/ref/text/chinese.png and /dev/null differ diff --git a/tests/ref/text/copy-paste.png b/tests/ref/text/copy-paste.png deleted file mode 100644 index ae4a5ad99..000000000 Binary files a/tests/ref/text/copy-paste.png and /dev/null differ diff --git a/tests/ref/text/deco.png b/tests/ref/text/deco.png deleted file mode 100644 index 3a11e72f2..000000000 Binary files a/tests/ref/text/deco.png and /dev/null differ diff --git a/tests/ref/text/edge.png b/tests/ref/text/edge.png deleted file mode 100644 index 1daf4c2fc..000000000 Binary files a/tests/ref/text/edge.png and /dev/null differ diff --git a/tests/ref/text/em.png b/tests/ref/text/em.png deleted file mode 100644 index 04cccd530..000000000 Binary files a/tests/ref/text/em.png and /dev/null differ diff --git a/tests/ref/text/emoji.png b/tests/ref/text/emoji.png deleted file mode 100644 index 1dbbba79a..000000000 Binary files a/tests/ref/text/emoji.png and /dev/null differ diff --git a/tests/ref/text/emphasis.png b/tests/ref/text/emphasis.png deleted file mode 100644 index c19f6ebb0..000000000 Binary files a/tests/ref/text/emphasis.png and /dev/null differ diff --git a/tests/ref/text/escape.png b/tests/ref/text/escape.png deleted file mode 100644 index c94bc52f9..000000000 Binary files a/tests/ref/text/escape.png and /dev/null differ diff --git a/tests/ref/text/fallback.png b/tests/ref/text/fallback.png deleted file mode 100644 index 7f1e3e385..000000000 Binary files a/tests/ref/text/fallback.png and /dev/null differ diff --git a/tests/ref/text/features.png b/tests/ref/text/features.png deleted file mode 100644 index 566694c68..000000000 Binary files a/tests/ref/text/features.png and /dev/null differ diff --git a/tests/ref/text/font.png b/tests/ref/text/font.png deleted file mode 100644 index 39c8a951b..000000000 Binary files a/tests/ref/text/font.png and /dev/null differ diff --git a/tests/ref/text/hyphenate.png b/tests/ref/text/hyphenate.png deleted file mode 100644 index 7b386a512..000000000 Binary files a/tests/ref/text/hyphenate.png and /dev/null differ diff --git a/tests/ref/text/lang-with-region.png b/tests/ref/text/lang-with-region.png deleted file mode 100644 index c7753104a..000000000 Binary files a/tests/ref/text/lang-with-region.png and /dev/null differ diff --git a/tests/ref/text/lang.png b/tests/ref/text/lang.png deleted file mode 100644 index a5ae89796..000000000 Binary files a/tests/ref/text/lang.png and /dev/null differ diff --git a/tests/ref/text/linebreak-link.png b/tests/ref/text/linebreak-link.png deleted file mode 100644 index ffe39caa3..000000000 Binary files a/tests/ref/text/linebreak-link.png and /dev/null differ diff --git a/tests/ref/text/linebreak-obj.png b/tests/ref/text/linebreak-obj.png deleted file mode 100644 index 127ee6872..000000000 Binary files a/tests/ref/text/linebreak-obj.png and /dev/null differ diff --git a/tests/ref/text/linebreak.png b/tests/ref/text/linebreak.png deleted file mode 100644 index 3dd2fc156..000000000 Binary files a/tests/ref/text/linebreak.png and /dev/null differ diff --git a/tests/ref/text/lorem.png b/tests/ref/text/lorem.png deleted file mode 100644 index 9d55df22e..000000000 Binary files a/tests/ref/text/lorem.png and /dev/null differ diff --git a/tests/ref/text/microtype.png b/tests/ref/text/microtype.png deleted file mode 100644 index 87622b0f8..000000000 Binary files a/tests/ref/text/microtype.png and /dev/null differ diff --git a/tests/ref/text/numbers.png b/tests/ref/text/numbers.png deleted file mode 100644 index 9fc76aae2..000000000 Binary files a/tests/ref/text/numbers.png and /dev/null differ diff --git a/tests/ref/text/quote-nesting.png b/tests/ref/text/quote-nesting.png deleted file mode 100644 index fb16002de..000000000 Binary files a/tests/ref/text/quote-nesting.png and /dev/null differ diff --git a/tests/ref/text/quote.png b/tests/ref/text/quote.png deleted file mode 100644 index 653f2d17a..000000000 Binary files a/tests/ref/text/quote.png and /dev/null differ diff --git a/tests/ref/text/quotes.png b/tests/ref/text/quotes.png deleted file mode 100644 index 535c28297..000000000 Binary files a/tests/ref/text/quotes.png and /dev/null differ diff --git a/tests/ref/text/raw-align.png b/tests/ref/text/raw-align.png deleted file mode 100644 index 6d1044f7e..000000000 Binary files a/tests/ref/text/raw-align.png and /dev/null differ diff --git a/tests/ref/text/raw-code.png b/tests/ref/text/raw-code.png deleted file mode 100644 index 682c7c48b..000000000 Binary files a/tests/ref/text/raw-code.png and /dev/null differ diff --git a/tests/ref/text/raw-line.png b/tests/ref/text/raw-line.png deleted file mode 100644 index b76eb8087..000000000 Binary files a/tests/ref/text/raw-line.png and /dev/null differ diff --git a/tests/ref/text/raw-syntaxes.png b/tests/ref/text/raw-syntaxes.png deleted file mode 100644 index ada751e09..000000000 Binary files a/tests/ref/text/raw-syntaxes.png and /dev/null differ diff --git a/tests/ref/text/raw-tabs.png b/tests/ref/text/raw-tabs.png deleted file mode 100644 index cac265e98..000000000 Binary files a/tests/ref/text/raw-tabs.png and /dev/null differ diff --git a/tests/ref/text/raw-theme.png b/tests/ref/text/raw-theme.png deleted file mode 100644 index 0ce177605..000000000 Binary files a/tests/ref/text/raw-theme.png and /dev/null differ diff --git a/tests/ref/text/raw.png b/tests/ref/text/raw.png deleted file mode 100644 index 27120d746..000000000 Binary files a/tests/ref/text/raw.png and /dev/null differ diff --git a/tests/ref/text/shaping.png b/tests/ref/text/shaping.png deleted file mode 100644 index 69cba132d..000000000 Binary files a/tests/ref/text/shaping.png and /dev/null differ diff --git a/tests/ref/text/shift.png b/tests/ref/text/shift.png deleted file mode 100644 index 09d68bacd..000000000 Binary files a/tests/ref/text/shift.png and /dev/null differ diff --git a/tests/ref/text/smartquotes.png b/tests/ref/text/smartquotes.png deleted file mode 100644 index a6a8cbb56..000000000 Binary files a/tests/ref/text/smartquotes.png and /dev/null differ diff --git a/tests/ref/text/space.png b/tests/ref/text/space.png deleted file mode 100644 index bae0e0a83..000000000 Binary files a/tests/ref/text/space.png and /dev/null differ diff --git a/tests/ref/text/stroke.png b/tests/ref/text/stroke.png deleted file mode 100644 index d6d85c28e..000000000 Binary files a/tests/ref/text/stroke.png and /dev/null differ diff --git a/tests/ref/text/symbol.png b/tests/ref/text/symbol.png deleted file mode 100644 index 04d9d77f1..000000000 Binary files a/tests/ref/text/symbol.png and /dev/null differ diff --git a/tests/ref/text/tracking-spacing.png b/tests/ref/text/tracking-spacing.png deleted file mode 100644 index 68d802130..000000000 Binary files a/tests/ref/text/tracking-spacing.png and /dev/null differ diff --git a/tests/ref/transform-rotate-and-scale.png b/tests/ref/transform-rotate-and-scale.png new file mode 100644 index 000000000..0dcf67ed2 Binary files /dev/null and b/tests/ref/transform-rotate-and-scale.png differ diff --git a/tests/ref/transform-rotate-origin.png b/tests/ref/transform-rotate-origin.png new file mode 100644 index 000000000..152b1e1f8 Binary files /dev/null and b/tests/ref/transform-rotate-origin.png differ diff --git a/tests/ref/transform-rotate-relative-sizing.png b/tests/ref/transform-rotate-relative-sizing.png new file mode 100644 index 000000000..9b81c3865 Binary files /dev/null and b/tests/ref/transform-rotate-relative-sizing.png differ diff --git a/tests/ref/transform-rotate.png b/tests/ref/transform-rotate.png new file mode 100644 index 000000000..3990ed5b8 Binary files /dev/null and b/tests/ref/transform-rotate.png differ diff --git a/tests/ref/transform-scale-origin.png b/tests/ref/transform-scale-origin.png new file mode 100644 index 000000000..10e1cfe28 Binary files /dev/null and b/tests/ref/transform-scale-origin.png differ diff --git a/tests/ref/transform-scale-relative-sizing.png b/tests/ref/transform-scale-relative-sizing.png new file mode 100644 index 000000000..d10bd3ff4 Binary files /dev/null and b/tests/ref/transform-scale-relative-sizing.png differ diff --git a/tests/ref/transform-scale.png b/tests/ref/transform-scale.png new file mode 100644 index 000000000..c95b90f1d Binary files /dev/null and b/tests/ref/transform-scale.png differ diff --git a/tests/ref/transform-tex-logo.png b/tests/ref/transform-tex-logo.png new file mode 100644 index 000000000..5d16ffb4f Binary files /dev/null and b/tests/ref/transform-tex-logo.png differ diff --git a/tests/ref/underline-background.png b/tests/ref/underline-background.png new file mode 100644 index 000000000..33ba381a2 Binary files /dev/null and b/tests/ref/underline-background.png differ diff --git a/tests/ref/underline-overline-strike.png b/tests/ref/underline-overline-strike.png new file mode 100644 index 000000000..2567fca4e Binary files /dev/null and b/tests/ref/underline-overline-strike.png differ diff --git a/tests/ref/underline-stroke-folding.png b/tests/ref/underline-stroke-folding.png new file mode 100644 index 000000000..32119e5c5 Binary files /dev/null and b/tests/ref/underline-stroke-folding.png differ diff --git a/tests/ref/visualize/gradient-conic.png b/tests/ref/visualize/gradient-conic.png deleted file mode 100644 index ff4a0ca2e..000000000 Binary files a/tests/ref/visualize/gradient-conic.png and /dev/null differ diff --git a/tests/ref/visualize/gradient-dir.png b/tests/ref/visualize/gradient-dir.png deleted file mode 100644 index bda3eb171..000000000 Binary files a/tests/ref/visualize/gradient-dir.png and /dev/null differ diff --git a/tests/ref/visualize/gradient-hue-rotation.png b/tests/ref/visualize/gradient-hue-rotation.png deleted file mode 100644 index 2d786f710..000000000 Binary files a/tests/ref/visualize/gradient-hue-rotation.png and /dev/null differ diff --git a/tests/ref/visualize/gradient-math.png b/tests/ref/visualize/gradient-math.png deleted file mode 100644 index 470e6138a..000000000 Binary files a/tests/ref/visualize/gradient-math.png and /dev/null differ diff --git a/tests/ref/visualize/gradient-presets.png b/tests/ref/visualize/gradient-presets.png deleted file mode 100644 index e6f7f73a1..000000000 Binary files a/tests/ref/visualize/gradient-presets.png and /dev/null differ diff --git a/tests/ref/visualize/gradient-radial.png b/tests/ref/visualize/gradient-radial.png deleted file mode 100644 index 2e8e9af3e..000000000 Binary files a/tests/ref/visualize/gradient-radial.png and /dev/null differ diff --git a/tests/ref/visualize/gradient-relative-conic.png b/tests/ref/visualize/gradient-relative-conic.png deleted file mode 100644 index 232c5f0af..000000000 Binary files a/tests/ref/visualize/gradient-relative-conic.png and /dev/null differ diff --git a/tests/ref/visualize/gradient-relative-linear.png b/tests/ref/visualize/gradient-relative-linear.png deleted file mode 100644 index 56e46119e..000000000 Binary files a/tests/ref/visualize/gradient-relative-linear.png and /dev/null differ diff --git a/tests/ref/visualize/gradient-relative-radial.png b/tests/ref/visualize/gradient-relative-radial.png deleted file mode 100644 index 210ea7b0f..000000000 Binary files a/tests/ref/visualize/gradient-relative-radial.png and /dev/null differ diff --git a/tests/ref/visualize/gradient-repeat.png b/tests/ref/visualize/gradient-repeat.png deleted file mode 100644 index 6be7dc660..000000000 Binary files a/tests/ref/visualize/gradient-repeat.png and /dev/null differ diff --git a/tests/ref/visualize/gradient-sharp.png b/tests/ref/visualize/gradient-sharp.png deleted file mode 100644 index b7698cfa4..000000000 Binary files a/tests/ref/visualize/gradient-sharp.png and /dev/null differ diff --git a/tests/ref/visualize/gradient-stroke.png b/tests/ref/visualize/gradient-stroke.png deleted file mode 100644 index 69317f732..000000000 Binary files a/tests/ref/visualize/gradient-stroke.png and /dev/null differ diff --git a/tests/ref/visualize/gradient-text-decorations.png b/tests/ref/visualize/gradient-text-decorations.png deleted file mode 100644 index 887cd5008..000000000 Binary files a/tests/ref/visualize/gradient-text-decorations.png and /dev/null differ diff --git a/tests/ref/visualize/gradient-text-other.png b/tests/ref/visualize/gradient-text-other.png deleted file mode 100644 index 78555b18f..000000000 Binary files a/tests/ref/visualize/gradient-text-other.png and /dev/null differ diff --git a/tests/ref/visualize/gradient-text.png b/tests/ref/visualize/gradient-text.png deleted file mode 100644 index 478a05863..000000000 Binary files a/tests/ref/visualize/gradient-text.png and /dev/null differ diff --git a/tests/ref/visualize/gradient-transform.png b/tests/ref/visualize/gradient-transform.png deleted file mode 100644 index a55ad91e8..000000000 Binary files a/tests/ref/visualize/gradient-transform.png and /dev/null differ diff --git a/tests/ref/visualize/image-scale.png b/tests/ref/visualize/image-scale.png deleted file mode 100644 index 95e9157ec..000000000 Binary files a/tests/ref/visualize/image-scale.png and /dev/null differ diff --git a/tests/ref/visualize/image.png b/tests/ref/visualize/image.png deleted file mode 100644 index ec53fa980..000000000 Binary files a/tests/ref/visualize/image.png and /dev/null differ diff --git a/tests/ref/visualize/line.png b/tests/ref/visualize/line.png deleted file mode 100644 index d19dea0ea..000000000 Binary files a/tests/ref/visualize/line.png and /dev/null differ diff --git a/tests/ref/visualize/path.png b/tests/ref/visualize/path.png deleted file mode 100644 index c7f710c94..000000000 Binary files a/tests/ref/visualize/path.png and /dev/null differ diff --git a/tests/ref/visualize/pattern-relative.png b/tests/ref/visualize/pattern-relative.png deleted file mode 100644 index 7958bf7f6..000000000 Binary files a/tests/ref/visualize/pattern-relative.png and /dev/null differ diff --git a/tests/ref/visualize/pattern-simple.png b/tests/ref/visualize/pattern-simple.png deleted file mode 100644 index ac473a756..000000000 Binary files a/tests/ref/visualize/pattern-simple.png and /dev/null differ diff --git a/tests/ref/visualize/pattern-small.png b/tests/ref/visualize/pattern-small.png deleted file mode 100644 index 6af592dd8..000000000 Binary files a/tests/ref/visualize/pattern-small.png and /dev/null differ diff --git a/tests/ref/visualize/pattern-spacing.png b/tests/ref/visualize/pattern-spacing.png deleted file mode 100644 index 4c95a3b02..000000000 Binary files a/tests/ref/visualize/pattern-spacing.png and /dev/null differ diff --git a/tests/ref/visualize/pattern-stroke.png b/tests/ref/visualize/pattern-stroke.png deleted file mode 100644 index d71f1c920..000000000 Binary files a/tests/ref/visualize/pattern-stroke.png and /dev/null differ diff --git a/tests/ref/visualize/pattern-text.png b/tests/ref/visualize/pattern-text.png deleted file mode 100644 index 2ecf2fdab..000000000 Binary files a/tests/ref/visualize/pattern-text.png and /dev/null differ diff --git a/tests/ref/visualize/polygon.png b/tests/ref/visualize/polygon.png deleted file mode 100644 index 234aeb148..000000000 Binary files a/tests/ref/visualize/polygon.png and /dev/null differ diff --git a/tests/ref/visualize/shape-aspect.png b/tests/ref/visualize/shape-aspect.png deleted file mode 100644 index 918a5e731..000000000 Binary files a/tests/ref/visualize/shape-aspect.png and /dev/null differ diff --git a/tests/ref/visualize/shape-circle.png b/tests/ref/visualize/shape-circle.png deleted file mode 100644 index a2ee279df..000000000 Binary files a/tests/ref/visualize/shape-circle.png and /dev/null differ diff --git a/tests/ref/visualize/shape-ellipse.png b/tests/ref/visualize/shape-ellipse.png deleted file mode 100644 index 6de5e9f61..000000000 Binary files a/tests/ref/visualize/shape-ellipse.png and /dev/null differ diff --git a/tests/ref/visualize/shape-fill-stroke.png b/tests/ref/visualize/shape-fill-stroke.png deleted file mode 100644 index d4a4817af..000000000 Binary files a/tests/ref/visualize/shape-fill-stroke.png and /dev/null differ diff --git a/tests/ref/visualize/shape-rect.png b/tests/ref/visualize/shape-rect.png deleted file mode 100644 index a279341ec..000000000 Binary files a/tests/ref/visualize/shape-rect.png and /dev/null differ diff --git a/tests/ref/visualize/shape-rounded.png b/tests/ref/visualize/shape-rounded.png deleted file mode 100644 index ec926d0a5..000000000 Binary files a/tests/ref/visualize/shape-rounded.png and /dev/null differ diff --git a/tests/ref/visualize/shape-square.png b/tests/ref/visualize/shape-square.png deleted file mode 100644 index 46e243e1f..000000000 Binary files a/tests/ref/visualize/shape-square.png and /dev/null differ diff --git a/tests/ref/visualize/stroke.png b/tests/ref/visualize/stroke.png deleted file mode 100644 index bdfcae9f7..000000000 Binary files a/tests/ref/visualize/stroke.png and /dev/null differ diff --git a/tests/ref/visualize/svg-text.png b/tests/ref/visualize/svg-text.png deleted file mode 100644 index b2bbe320b..000000000 Binary files a/tests/ref/visualize/svg-text.png and /dev/null differ diff --git a/tests/ref/while-loop-basic.png b/tests/ref/while-loop-basic.png new file mode 100644 index 000000000..3a0e6d242 Binary files /dev/null and b/tests/ref/while-loop-basic.png differ diff --git a/tests/src/args.rs b/tests/src/args.rs new file mode 100644 index 000000000..fcd4ead1f --- /dev/null +++ b/tests/src/args.rs @@ -0,0 +1,46 @@ +use clap::{Parser, Subcommand}; + +/// Typst's test runner. +#[derive(Debug, Clone, Parser)] +#[clap(name = "typst-test", author)] +pub struct CliArguments { + /// The command to run. + #[command(subcommand)] + pub command: Option, + /// All the tests that contain the filter string will be run. + pub filter: Vec, + /// Runs only the tests with the exact specified `filter` names. + #[arg(short, long)] + pub exact: bool, + /// Whether to update the reference images of non-passing tests. + #[arg(short, long)] + pub update: bool, + /// The scaling factor to render the output image with. + /// + /// Does not affect the comparison or the reference image. + #[arg(short, long, default_value_t = 1.0)] + pub scale: f32, + /// Exports PDF outputs into the artifact store. + #[arg(long)] + pub pdf: bool, + /// Exports SVG outputs into the artifact store. + #[arg(long)] + pub svg: bool, + /// Whether to display the syntax tree. + #[arg(long)] + pub syntax: bool, + /// Prevents the terminal from being cleared of test names. + #[arg(short, long)] + pub verbose: bool, + /// How many threads to spawn when running the tests. + #[arg(short = 'j', long)] + pub num_threads: Option, +} + +/// What to do. +#[derive(Debug, Clone, Subcommand)] +#[command()] +pub enum Command { + /// Clears the on-disk test artifact store. + Clean, +} diff --git a/tests/src/collect.rs b/tests/src/collect.rs new file mode 100644 index 000000000..44a325f20 --- /dev/null +++ b/tests/src/collect.rs @@ -0,0 +1,420 @@ +use std::collections::{HashMap, HashSet}; +use std::fmt::{self, Display, Formatter}; +use std::ops::Range; +use std::path::{Path, PathBuf}; +use std::str::FromStr; + +use ecow::{eco_format, EcoString}; +use typst::syntax::package::PackageVersion; +use typst::syntax::{is_id_continue, is_ident, is_newline, FileId, Source, VirtualPath}; +use unscanny::Scanner; + +/// Collects all tests from all files. +/// +/// Returns: +/// - the tests and the number of skipped tests in the success case. +/// - parsing errors in the failure case. +pub fn collect() -> Result<(Vec, usize), Vec> { + Collector::new().collect() +} + +/// A single test. +pub struct Test { + pub pos: FilePos, + pub name: EcoString, + pub source: Source, + pub notes: Vec, + pub large: bool, +} + +impl Display for Test { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + write!(f, "{} ({})", self.name, self.pos) + } +} + +/// A position in a file. +#[derive(Clone)] +pub struct FilePos { + pub path: PathBuf, + pub line: usize, +} + +impl FilePos { + fn new(path: impl Into, line: usize) -> Self { + Self { path: path.into(), line } + } +} + +impl Display for FilePos { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + write!(f, "{}:{}", self.path.display(), self.line) + } +} + +/// The size of a file. +pub struct FileSize(pub usize); + +impl Display for FileSize { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + write!(f, "{:.2} KiB", (self.0 as f64) / 1024.0) + } +} + +/// An annotation like `// Error: 2-6 message` in a test. +pub struct Note { + pub pos: FilePos, + pub kind: NoteKind, + pub range: Option>, + pub message: String, +} + +/// A kind of annotation in a test. +#[derive(Debug, Copy, Clone, Eq, PartialEq)] +pub enum NoteKind { + Error, + Warning, + Hint, +} + +impl FromStr for NoteKind { + type Err = (); + + fn from_str(s: &str) -> Result { + Ok(match s { + "Error" => Self::Error, + "Warning" => Self::Warning, + "Hint" => Self::Hint, + _ => return Err(()), + }) + } +} + +impl Display for NoteKind { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + f.pad(match self { + Self::Error => "Error", + Self::Warning => "Warning", + Self::Hint => "Hint", + }) + } +} + +/// Collects all tests from all files. +struct Collector { + tests: Vec, + errors: Vec, + seen: HashMap, + large: HashSet, + skipped: usize, +} + +impl Collector { + /// Creates a new test collector. + fn new() -> Self { + Self { + tests: vec![], + errors: vec![], + seen: HashMap::new(), + large: HashSet::new(), + skipped: 0, + } + } + + /// Collects tests from all files. + fn collect(mut self) -> Result<(Vec, usize), Vec> { + self.walk_files(); + self.walk_references(); + + if self.errors.is_empty() { + Ok((self.tests, self.skipped)) + } else { + Err(self.errors) + } + } + + /// Walks through all test files and collects the tests. + fn walk_files(&mut self) { + for entry in walkdir::WalkDir::new(crate::SUITE_PATH).sort_by_file_name() { + let entry = entry.unwrap(); + let path = entry.path(); + if !path.extension().is_some_and(|ext| ext == "typ") { + continue; + } + + let text = std::fs::read_to_string(path).unwrap(); + if text.starts_with("// SKIP") { + continue; + } + + Parser::new(self, path, &text).parse(); + } + } + + /// Walks through all reference images and ensure that a test exists for + /// each one. + fn walk_references(&mut self) { + for entry in walkdir::WalkDir::new(crate::REF_PATH).sort_by_file_name() { + let entry = entry.unwrap(); + let path = entry.path(); + if !path.extension().is_some_and(|ext| ext == "png") { + continue; + } + + let stem = path.file_stem().unwrap().to_string_lossy(); + let name = &*stem; + + let Some(pos) = self.seen.get(name) else { + self.errors.push(TestParseError { + pos: FilePos::new(path, 0), + message: "dangling reference image".into(), + }); + continue; + }; + + let len = path.metadata().unwrap().len() as usize; + if !self.large.contains(name) && len > crate::REF_LIMIT { + self.errors.push(TestParseError { + pos: pos.clone(), + message: format!( + "reference image size exceeds {}, but the test is not marked as `// LARGE`", + FileSize(crate::REF_LIMIT), + ), + }); + } + } + } +} + +/// Parses a single test file. +struct Parser<'a> { + collector: &'a mut Collector, + path: &'a Path, + s: Scanner<'a>, + test_start_line: usize, + line: usize, +} + +impl<'a> Parser<'a> { + /// Creates a new parser for a file. + fn new(collector: &'a mut Collector, path: &'a Path, source: &'a str) -> Self { + Self { + collector, + path, + s: Scanner::new(source), + test_start_line: 1, + line: 1, + } + } + + /// Parses an individual file. + fn parse(&mut self) { + self.skip_preamble(); + + while !self.s.done() { + let mut name = EcoString::new(); + let mut notes = vec![]; + if self.s.eat_if("---") { + self.s.eat_while(' '); + name = self.s.eat_until(char::is_whitespace).into(); + self.s.eat_while(' '); + + if name.is_empty() { + self.error("expected test name"); + } else if !is_ident(&name) { + self.error(format!("test name `{name}` is not a valid identifier")); + } else if !self.s.eat_if("---") { + self.error("expected closing ---"); + } + } else { + self.error("expected opening ---"); + } + + if self.collector.seen.contains_key(&name) { + self.error(format!("duplicate test {name}")); + } + + if self.s.eat_newline() { + self.line += 1; + } + + let start = self.s.cursor(); + self.test_start_line = self.line; + + let pos = FilePos::new(self.path, self.test_start_line); + self.collector.seen.insert(name.clone(), pos.clone()); + + while !self.s.done() && !self.s.at("---") { + self.s.eat_until(is_newline); + if self.s.eat_newline() { + self.line += 1; + } + } + + let text = self.s.from(start); + let large = text.starts_with("// LARGE"); + if large { + self.collector.large.insert(name.clone()); + } + + if !filtered(&name) { + self.collector.skipped += 1; + continue; + } + + let vpath = VirtualPath::new(self.path); + let source = Source::new(FileId::new(None, vpath), text.into()); + + self.s.jump(start); + self.line = self.test_start_line; + + while !self.s.done() && !self.s.at("---") { + self.s.eat_while(' '); + if self.s.eat_if("// ") { + notes.extend(self.parse_note(&source)); + } + + self.s.eat_until(is_newline); + if self.s.eat_newline() { + self.line += 1; + } + } + + self.collector.tests.push(Test { pos, name, source, notes, large }); + } + } + + /// Skips the preamble of a test. + fn skip_preamble(&mut self) { + let mut errored = false; + while !self.s.done() && !self.s.at("---") { + let line = self.s.eat_until(is_newline).trim(); + if !errored && !line.is_empty() && !line.starts_with("//") { + self.error("test preamble may only contain comments and blank lines"); + errored = true; + } + if self.s.eat_newline() { + self.line += 1; + } + } + } + + /// Parses an annotation in a test. + fn parse_note(&mut self, source: &Source) -> Option { + let head = self.s.eat_while(is_id_continue); + if !self.s.eat_if(':') { + return None; + } + + let kind: NoteKind = head.parse().ok()?; + self.s.eat_if(' '); + + let mut range = None; + if self.s.at('-') || self.s.at(char::is_numeric) { + range = self.parse_range(source); + if range.is_none() { + self.error("range is malformed"); + return None; + } + } + + let message = self + .s + .eat_until(is_newline) + .trim() + .replace("VERSION", &eco_format!("{}", PackageVersion::compiler())); + + Some(Note { + pos: FilePos::new(self.path, self.line), + kind, + range, + message, + }) + } + + /// Parse a range, optionally abbreviated as just a position if the range + /// is empty. + fn parse_range(&mut self, source: &Source) -> Option> { + let start = self.parse_position(source)?; + let end = if self.s.eat_if('-') { self.parse_position(source)? } else { start }; + Some(start..end) + } + + /// Parses a relative `(line:)?column` position. + fn parse_position(&mut self, source: &Source) -> Option { + let first = self.parse_number()?; + let (line_delta, column) = + if self.s.eat_if(':') { (first, self.parse_number()?) } else { (1, first) }; + + let text = source.text(); + let line_idx_in_test = self.line - self.test_start_line; + let comments = text + .lines() + .skip(line_idx_in_test + 1) + .take_while(|line| line.trim().starts_with("//")) + .count(); + + let line_idx = (line_idx_in_test + comments).checked_add_signed(line_delta)?; + let column_idx = if column < 0 { + // Negative column index is from the back. + let range = source.line_to_range(line_idx)?; + text[range].chars().count().saturating_add_signed(column) + } else { + usize::try_from(column).ok()?.checked_sub(1)? + }; + + source.line_column_to_byte(line_idx, column_idx) + } + + /// Parse a number. + fn parse_number(&mut self) -> Option { + let start = self.s.cursor(); + self.s.eat_if('-'); + self.s.eat_while(char::is_numeric); + self.s.from(start).parse().ok() + } + + /// Stores a test parsing error. + fn error(&mut self, message: impl Into) { + self.collector.errors.push(TestParseError { + pos: FilePos::new(self.path, self.line), + message: message.into(), + }); + } +} + +/// Whether a test is within the filtered set. +fn filtered(name: &str) -> bool { + let exact = crate::ARGS.exact; + let filter = &crate::ARGS.filter; + filter.is_empty() + || filter + .iter() + .any(|v| if exact { name == v } else { name.contains(v) }) +} + +/// An error in a test file. +pub struct TestParseError { + pos: FilePos, + message: String, +} + +impl Display for TestParseError { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + write!(f, "{} ({})", self.message, self.pos) + } +} + +trait ScannerExt { + fn eat_newline(&mut self) -> bool; +} + +impl ScannerExt for Scanner<'_> { + fn eat_newline(&mut self) -> bool { + let ate = self.eat_if(is_newline); + if ate && self.before().ends_with('\r') { + self.eat_if('\n'); + } + ate + } +} diff --git a/tests/src/logger.rs b/tests/src/logger.rs new file mode 100644 index 000000000..c48650a76 --- /dev/null +++ b/tests/src/logger.rs @@ -0,0 +1,141 @@ +use std::io::{self, IsTerminal, StderrLock, Write}; +use std::time::{Duration, Instant}; + +use crate::collect::Test; +use crate::run::TestResult; + +/// Receives status updates by individual test runs. +pub struct Logger<'a> { + filtered: usize, + passed: usize, + failed: usize, + skipped: usize, + mismatched_image: bool, + active: Vec<&'a Test>, + last_change: Instant, + temp_lines: usize, + terminal: bool, +} + +impl<'a> Logger<'a> { + /// Create a new logger. + pub fn new(filtered: usize, skipped: usize) -> Self { + Self { + filtered, + passed: 0, + failed: 0, + skipped, + mismatched_image: false, + active: vec![], + temp_lines: 0, + last_change: Instant::now(), + terminal: std::io::stderr().is_terminal(), + } + } + + /// Register the start of a test. + pub fn start(&mut self, test: &'a Test) { + self.active.push(test); + self.last_change = Instant::now(); + self.refresh(); + } + + /// Register a finished test. + pub fn end(&mut self, test: &'a Test, result: std::thread::Result) { + self.active.retain(|t| t.name != test.name); + + let result = match result { + Ok(result) => result, + Err(_) => { + self.failed += 1; + self.temp_lines = 0; + self.print(move |out| { + writeln!(out, "❌ {test} panicked")?; + Ok(()) + }) + .unwrap(); + return; + } + }; + + if result.is_ok() { + self.passed += 1; + } else { + self.failed += 1; + } + + self.mismatched_image |= result.mismatched_image; + self.last_change = Instant::now(); + + self.print(move |out| { + if !result.errors.is_empty() { + writeln!(out, "❌ {test}")?; + for line in result.errors.lines() { + writeln!(out, " {line}")?; + } + } else if crate::ARGS.verbose || !result.infos.is_empty() { + writeln!(out, "✅ {test}")?; + } + for line in result.infos.lines() { + writeln!(out, " {line}")?; + } + Ok(()) + }) + .unwrap(); + } + + /// Prints a summary and returns whether the test suite passed. + pub fn finish(&self) -> bool { + let Self { filtered, passed, failed, skipped, .. } = *self; + + eprintln!("{passed} passed, {failed} failed, {skipped} skipped"); + assert_eq!(filtered, passed + failed, "not all tests were executed succesfully"); + + if self.mismatched_image { + eprintln!(" pass the --update flag to update the reference images"); + } + + self.failed == 0 + } + + /// Refresh the status. + pub fn refresh(&mut self) { + self.print(|_| Ok(())).unwrap(); + } + + /// Refresh the status print. + fn print( + &mut self, + inner: impl FnOnce(&mut StderrLock<'_>) -> io::Result<()>, + ) -> io::Result<()> { + let mut out = std::io::stderr().lock(); + + // Clear the status lines. + for _ in 0..self.temp_lines { + write!(out, "\x1B[1F\x1B[0J")?; + self.temp_lines = 0; + } + + // Print the result of a finished test. + inner(&mut out)?; + + // Print the status line. + let done = self.failed + self.passed; + if done < self.filtered { + if self.last_change.elapsed() > Duration::from_secs(2) { + for test in &self.active { + writeln!(out, "⏰ {test} is taking a long time ...")?; + if self.terminal { + self.temp_lines += 1; + } + } + } + if self.terminal { + writeln!(out, "💨 {done} / {}", self.filtered)?; + self.temp_lines += 1; + } + } + + Ok(()) + } +} diff --git a/tests/src/metadata.rs b/tests/src/metadata.rs deleted file mode 100644 index 53cbbdffb..000000000 --- a/tests/src/metadata.rs +++ /dev/null @@ -1,334 +0,0 @@ -use std::collections::HashSet; -use std::fmt::{self, Display, Formatter}; -use std::ops::Range; -use std::str::FromStr; - -use ecow::EcoString; -use typst::syntax::package::PackageVersion; -use typst::syntax::Source; -use unscanny::Scanner; - -/// Each test and subset may contain metadata. -#[derive(Debug)] -pub struct TestMetadata { - /// Configures how the test is run. - pub config: TestConfig, - /// Declares properties that must hold for a test. - /// - /// For instance, `// Warning: 1-3 no text within underscores` - /// will fail the test if the warning isn't generated by your test. - pub annotations: HashSet, -} - -/// Configuration of a test or subtest. -#[derive(Debug, Default)] -pub struct TestConfig { - /// Reference images will be generated and compared. - /// - /// Defaults to `true`, can be disabled with `Ref: false`. - pub compare_ref: Option, - /// Hint annotations will be compared to compiler hints. - /// - /// Defaults to `true`, can be disabled with `Hints: false`. - pub validate_hints: Option, - /// Autocompletion annotations will be validated against autocompletions. - /// Mutually exclusive with error and hint annotations. - /// - /// Defaults to `false`, can be enabled with `Autocomplete: true`. - pub validate_autocomplete: Option, -} - -/// Parsing error when the metadata is invalid. -pub(crate) enum InvalidMetadata { - /// An invalid annotation and it's error message. - InvalidAnnotation(Annotation, String), - /// Setting metadata can only be done with `true` or `false` as a value. - InvalidSet(String), -} - -impl InvalidMetadata { - pub(crate) fn write( - invalid_data: Vec, - output: &mut String, - print_annotation: &mut impl FnMut(&Annotation, &mut String), - ) { - use std::fmt::Write; - for data in invalid_data.into_iter() { - let (annotation, error) = match data { - InvalidMetadata::InvalidAnnotation(a, e) => (Some(a), e), - InvalidMetadata::InvalidSet(e) => (None, e), - }; - write!(output, "{error}",).unwrap(); - if let Some(annotation) = annotation { - print_annotation(&annotation, output) - } else { - writeln!(output).unwrap(); - } - } - } -} - -/// Annotation of the form `// KIND: RANGE TEXT`. -#[derive(Debug, Clone, Eq, PartialEq, Hash)] -pub struct Annotation { - /// Which kind of annotation this is. - pub kind: AnnotationKind, - /// May be written as: - /// - `{line}:{col}-{line}:{col}`, e.g. `0:4-0:6`. - /// - `{col}-{col}`, e.g. `4-6`: - /// The line is assumed to be the line after the annotation. - /// - `-1`: Produces a range of length zero at the end of the next line. - /// Mostly useful for autocompletion tests which require an index. - pub range: Option>, - /// The raw text after the annotation. - pub text: EcoString, -} - -/// The different kinds of in-test annotations. -#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] -pub enum AnnotationKind { - Error, - Warning, - Hint, - AutocompleteContains, - AutocompleteExcludes, -} - -impl AnnotationKind { - /// Returns the user-facing string for this annotation. - pub fn as_str(self) -> &'static str { - match self { - AnnotationKind::Error => "Error", - AnnotationKind::Warning => "Warning", - AnnotationKind::Hint => "Hint", - AnnotationKind::AutocompleteContains => "Autocomplete contains", - AnnotationKind::AutocompleteExcludes => "Autocomplete excludes", - } - } -} - -impl FromStr for AnnotationKind { - type Err = &'static str; - - fn from_str(s: &str) -> Result { - Ok(match s { - "Error" => AnnotationKind::Error, - "Warning" => AnnotationKind::Warning, - "Hint" => AnnotationKind::Hint, - "Autocomplete contains" => AnnotationKind::AutocompleteContains, - "Autocomplete excludes" => AnnotationKind::AutocompleteExcludes, - _ => return Err("invalid annotatino"), - }) - } -} - -impl Display for AnnotationKind { - fn fmt(&self, f: &mut Formatter) -> fmt::Result { - f.pad(self.as_str()) - } -} - -/// Parse metadata for a test. -pub fn parse_part_metadata( - source: &Source, - is_header: bool, -) -> Result> { - let mut config = TestConfig::default(); - let mut annotations = HashSet::default(); - let mut invalid_data = vec![]; - - let lines = source_to_lines(source); - - for (i, line) in lines.iter().enumerate() { - if let Some((key, value)) = parse_metadata_line(line) { - let key = key.trim(); - match key { - "Ref" => validate_set_annotation( - value, - &mut config.compare_ref, - &mut invalid_data, - ), - "Hints" => validate_set_annotation( - value, - &mut config.validate_hints, - &mut invalid_data, - ), - "Autocomplete" => validate_set_annotation( - value, - &mut config.validate_autocomplete, - &mut invalid_data, - ), - annotation_key => { - let Ok(kind) = AnnotationKind::from_str(annotation_key) else { - continue; - }; - let mut s = Scanner::new(value); - let range = parse_range(&mut s, i, source); - let rest = if range.is_some() { s.after() } else { s.string() }; - let message = rest - .trim() - .replace("VERSION", &PackageVersion::compiler().to_string()) - .into(); - - let annotation = - Annotation { kind, range: range.clone(), text: message }; - - if is_header { - invalid_data.push(InvalidMetadata::InvalidAnnotation( - annotation, - format!( - "Error: header may not contain annotations of type {kind}" - ), - )); - continue; - } - - if matches!( - kind, - AnnotationKind::AutocompleteContains - | AnnotationKind::AutocompleteExcludes - ) { - if let Some(range) = range { - if range.start != range.end { - invalid_data.push(InvalidMetadata::InvalidAnnotation( - annotation, - "Error: found range in Autocomplete annotation where range.start != range.end, range.end would be ignored." - .to_string() - )); - continue; - } - } else { - invalid_data.push(InvalidMetadata::InvalidAnnotation( - annotation, - "Error: autocomplete annotation but no range specified" - .to_string(), - )); - continue; - } - } - annotations.insert(annotation); - } - } - } - } - if invalid_data.is_empty() { - Ok(TestMetadata { config, annotations }) - } else { - Err(invalid_data) - } -} - -/// Extract key and value for a metadata line of the form: `// KEY: VALUE`. -fn parse_metadata_line(line: &str) -> Option<(&str, &str)> { - let mut s = Scanner::new(line); - if !s.eat_if("// ") { - return None; - } - - let key = s.eat_until(':').trim(); - if !s.eat_if(':') { - return None; - } - - let value = s.eat_until('\n').trim(); - Some((key, value)) -} - -/// Parse a quoted string. -fn parse_string<'a>(s: &mut Scanner<'a>) -> Option<&'a str> { - if !s.eat_if('"') { - return None; - } - let sub = s.eat_until('"'); - if !s.eat_if('"') { - return None; - } - - Some(sub) -} - -/// Parse a number. -fn parse_num(s: &mut Scanner) -> Option { - let mut first = true; - let n = &s.eat_while(|c: char| { - let valid = first && c == '-' || c.is_numeric(); - first = false; - valid - }); - n.parse().ok() -} - -/// Parse a comma-separated list of strings. -pub fn parse_string_list(text: &str) -> HashSet<&str> { - let mut s = Scanner::new(text); - let mut result = HashSet::new(); - while let Some(sub) = parse_string(&mut s) { - result.insert(sub); - s.eat_whitespace(); - if !s.eat_if(',') { - break; - } - s.eat_whitespace(); - } - result -} - -/// Parse a position. -fn parse_pos(s: &mut Scanner, i: usize, source: &Source) -> Option { - let first = parse_num(s)? - 1; - let (delta, column) = - if s.eat_if(':') { (first, parse_num(s)? - 1) } else { (0, first) }; - let line = (i + comments_until_code(source, i)).checked_add_signed(delta)?; - source.line_column_to_byte(line, usize::try_from(column).ok()?) -} - -/// Parse a range. -fn parse_range(s: &mut Scanner, i: usize, source: &Source) -> Option> { - let lines = source_to_lines(source); - s.eat_whitespace(); - if s.eat_if("-1") { - let mut add = 1; - while let Some(line) = lines.get(i + add) { - if !line.starts_with("//") { - break; - } - add += 1; - } - let next_line = lines.get(i + add)?; - let col = next_line.chars().count(); - - let index = source.line_column_to_byte(i + add, col)?; - s.eat_whitespace(); - return Some(index..index); - } - let start = parse_pos(s, i, source)?; - let end = if s.eat_if('-') { parse_pos(s, i, source)? } else { start }; - s.eat_whitespace(); - Some(start..end) -} - -/// Returns the number of lines of comment from line i to next line of code. -fn comments_until_code(source: &Source, i: usize) -> usize { - source_to_lines(source)[i..] - .iter() - .take_while(|line| line.starts_with("//")) - .count() -} - -fn source_to_lines(source: &Source) -> Vec<&str> { - source.text().lines().map(str::trim).collect() -} - -fn validate_set_annotation( - value: &str, - flag: &mut Option, - invalid_data: &mut Vec, -) { - let value = value.trim(); - if value != "false" && value != "true" { - invalid_data.push( - InvalidMetadata::InvalidSet(format!("Error: trying to set Ref, Hints, or Autocomplete with value {value:?} != true, != false."))) - } else { - *flag = Some(value == "true") - } -} diff --git a/tests/src/run.rs b/tests/src/run.rs new file mode 100644 index 000000000..f797147f6 --- /dev/null +++ b/tests/src/run.rs @@ -0,0 +1,442 @@ +use std::fmt::Write; +use std::ops::Range; +use std::path::Path; + +use ecow::eco_vec; +use tiny_skia as sk; +use typst::diag::SourceDiagnostic; +use typst::eval::Tracer; +use typst::foundations::Smart; +use typst::introspection::Meta; +use typst::layout::{Abs, Frame, FrameItem, Page, Transform}; +use typst::model::Document; +use typst::visualize::Color; +use typst::WorldExt; + +use crate::collect::{FileSize, NoteKind, Test}; +use crate::world::TestWorld; + +/// Runs a single test. +/// +/// Returns whether the test passed. +pub fn run(test: &Test) -> TestResult { + Runner::new(test).run() +} + +/// The result of running a single test. +pub struct TestResult { + /// The error log for this test. If empty, the test passed. + pub errors: String, + /// The info log for this test. + pub infos: String, + /// Whether the image was mismatched. + pub mismatched_image: bool, +} + +impl TestResult { + /// Whether the test passed. + pub fn is_ok(&self) -> bool { + self.errors.is_empty() + } +} + +/// Write a line to a log sink, defaulting to the test's error log. +macro_rules! log { + (into: $sink:expr, $($tts:tt)*) => { + writeln!($sink, $($tts)*).unwrap(); + }; + ($runner:expr, $($tts:tt)*) => { + writeln!(&mut $runner.result.errors, $($tts)*).unwrap(); + }; +} + +/// Runs a single test. +pub struct Runner<'a> { + test: &'a Test, + world: TestWorld, + seen: Vec, + result: TestResult, + not_annotated: String, +} + +impl<'a> Runner<'a> { + /// Create a new test runner. + fn new(test: &'a Test) -> Self { + Self { + test, + world: TestWorld::new(test.source.clone()), + seen: vec![false; test.notes.len()], + result: TestResult { + errors: String::new(), + infos: String::new(), + mismatched_image: false, + }, + not_annotated: String::new(), + } + } + + /// Run the test. + fn run(mut self) -> TestResult { + if crate::ARGS.syntax { + log!(into: self.result.infos, "tree: {:#?}", self.test.source.root()); + } + + let mut tracer = Tracer::new(); + let (doc, errors) = match typst::compile(&self.world, &mut tracer) { + Ok(doc) => (Some(doc), eco_vec![]), + Err(errors) => (None, errors), + }; + + let warnings = tracer.warnings(); + if doc.is_none() && errors.is_empty() { + log!(self, "no document, but also no errors"); + } + + self.check_document(doc.as_ref()); + + for error in &errors { + self.check_diagnostic(NoteKind::Error, error); + } + + for warning in &warnings { + self.check_diagnostic(NoteKind::Warning, warning); + } + + self.handle_not_emitted(); + self.handle_not_annotated(); + + self.result + } + + /// Handle errors that weren't annotated. + fn handle_not_annotated(&mut self) { + if !self.not_annotated.is_empty() { + log!(self, "not annotated"); + self.result.errors.push_str(&self.not_annotated); + } + } + + /// Handle notes that weren't handled before. + fn handle_not_emitted(&mut self) { + let mut first = true; + for (note, &seen) in self.test.notes.iter().zip(&self.seen) { + if seen { + continue; + } + let note_range = self.format_range(¬e.range); + if first { + log!(self, "not emitted"); + first = false; + } + log!(self, " {}: {note_range} {} ({})", note.kind, note.message, note.pos,); + } + } + + /// Check that the document output is correct. + fn check_document(&mut self, document: Option<&Document>) { + let live_path = format!("{}/render/{}.png", crate::STORE_PATH, self.test.name); + let ref_path = format!("{}/{}.png", crate::REF_PATH, self.test.name); + let has_ref = Path::new(&ref_path).exists(); + + let Some(document) = document else { + if has_ref { + log!(self, "missing document"); + log!(self, " ref | {ref_path}"); + } + return; + }; + + let skippable = match document.pages.as_slice() { + [page] => skippable(page), + _ => false, + }; + + // Tests without visible output and no reference image don't need to be + // compared. + if skippable && !has_ref { + std::fs::remove_file(&live_path).ok(); + return; + } + + // Render the live version. + let pixmap = render(document, 1.0); + + // Save live version, possibly rerendering if different scale is + // requested. + let mut pixmap_live = &pixmap; + let slot; + let scale = crate::ARGS.scale; + if scale != 1.0 { + slot = render(document, scale); + pixmap_live = &slot; + } + let data = pixmap_live.encode_png().unwrap(); + std::fs::write(&live_path, data).unwrap(); + + // Write PDF if requested. + if crate::ARGS.pdf { + let pdf_path = format!("{}/pdf/{}.pdf", crate::STORE_PATH, self.test.name); + let pdf = typst_pdf::pdf(document, Smart::Auto, None); + std::fs::write(pdf_path, pdf).unwrap(); + } + + // Write SVG if requested. + if crate::ARGS.svg { + let svg_path = format!("{}/svg/{}.svg", crate::STORE_PATH, self.test.name); + let svg = typst_svg::svg_merged(document, Abs::pt(5.0)); + std::fs::write(svg_path, svg).unwrap(); + } + + // Compare against reference image if available. + let equal = has_ref && { + let ref_data = std::fs::read(&ref_path).unwrap(); + let ref_pixmap = sk::Pixmap::decode_png(&ref_data).unwrap(); + approx_equal(&pixmap, &ref_pixmap) + }; + + // Test that is ok doesn't need to be updated. + if equal { + return; + } + + if crate::ARGS.update { + if skippable { + std::fs::remove_file(&ref_path).unwrap(); + log!( + into: self.result.infos, + "removed reference image ({ref_path})" + ); + } else { + let opts = oxipng::Options::max_compression(); + let data = pixmap.encode_png().unwrap(); + let ref_data = oxipng::optimize_from_memory(&data, &opts).unwrap(); + if !self.test.large && ref_data.len() > crate::REF_LIMIT { + log!(self, "reference image would exceed maximum size"); + log!(self, " maximum | {}", FileSize(crate::REF_LIMIT)); + log!(self, " size | {}", FileSize(ref_data.len())); + log!(self, "please try to minimize the size of the test (smaller pages, less text, etc.)"); + log!(self, "if you think the test cannot be reasonably minimized, mark it as `// LARGE`"); + return; + } + std::fs::write(&ref_path, &ref_data).unwrap(); + log!( + into: self.result.infos, + "Updated reference image ({ref_path}, {})", + FileSize(ref_data.len()), + ); + } + } else { + self.result.mismatched_image = true; + if has_ref { + log!(self, "mismatched rendering"); + log!(self, " live | {live_path}"); + log!(self, " ref | {ref_path}"); + } else { + log!(self, "missing reference image"); + log!(self, " live | {live_path}"); + } + } + } + + /// Compare a subset of notes with a given kind against diagnostics of + /// that same kind. + fn check_diagnostic(&mut self, kind: NoteKind, diag: &SourceDiagnostic) { + // Ignore diagnostics from other sources than the test file itself. + if diag.span.id().is_some_and(|id| id != self.test.source.id()) { + return; + } + + let message = diag.message.replace("\\", "/"); + let range = self.world.range(diag.span); + self.validate_note(kind, range.clone(), &message); + + // Check hints. + for hint in &diag.hints { + self.validate_note(NoteKind::Hint, range.clone(), hint); + } + } + + /// Try to find a matching note for the given `kind`, `range`, and + /// `message`. + /// + /// - If found, marks it as seen and returns it. + /// - If none was found, emits a "Not annotated" error and returns nothing. + fn validate_note( + &mut self, + kind: NoteKind, + range: Option>, + message: &str, + ) { + // Try to find perfect match. + if let Some((i, _)) = self.test.notes.iter().enumerate().find(|&(i, note)| { + !self.seen[i] + && note.kind == kind + && note.range == range + && note.message == message + }) { + self.seen[i] = true; + return; + } + + // Try to find closely matching annotation. If the note has the same + // range or message, it's most likely the one we're interested in. + let Some((i, note)) = self.test.notes.iter().enumerate().find(|&(i, note)| { + !self.seen[i] + && note.kind == kind + && (note.range == range || note.message == message) + }) else { + // Not even a close match, diagnostic is not annotated. + let diag_range = self.format_range(&range); + log!(into: self.not_annotated, " {kind}: {diag_range} {}", message); + return; + }; + + // Mark this annotation as visited and return it. + self.seen[i] = true; + + // Range is wrong. + if range != note.range { + let note_range = self.format_range(¬e.range); + let note_text = self.text_for_range(¬e.range); + let diag_range = self.format_range(&range); + let diag_text = self.text_for_range(&range); + log!(self, "mismatched range ({}):", note.pos); + log!(self, " message | {}", note.message); + log!(self, " annotated | {note_range:<9} | {note_text}"); + log!(self, " emitted | {diag_range:<9} | {diag_text}"); + } + + // Message is wrong. + if message != note.message { + log!(self, "mismatched message ({}):", note.pos); + log!(self, " annotated | {}", note.message); + log!(self, " emitted | {message}"); + } + } + + /// Display the text for a range. + fn text_for_range(&self, range: &Option>) -> String { + let Some(range) = range else { return "No text".into() }; + if range.is_empty() { + "(empty)".into() + } else { + format!("`{}`", self.test.source.text()[range.clone()].replace('\n', "\\n")) + } + } + + /// Display a byte range as a line:column range. + fn format_range(&self, range: &Option>) -> String { + let Some(range) = range else { return "No range".into() }; + if range.start == range.end { + self.format_pos(range.start) + } else { + format!("{}-{}", self.format_pos(range.start,), self.format_pos(range.end,)) + } + } + + /// Display a position as a line:column pair. + fn format_pos(&self, pos: usize) -> String { + if let (Some(line_idx), Some(column_idx)) = + (self.test.source.byte_to_line(pos), self.test.source.byte_to_column(pos)) + { + let line = self.test.pos.line + line_idx; + let column = column_idx + 1; + if line == 1 { + format!("{column}") + } else { + format!("{line}:{column}") + } + } else { + "oob".into() + } + } +} + +/// Draw all frames into one image with padding in between. +fn render(document: &Document, pixel_per_pt: f32) -> sk::Pixmap { + for page in &document.pages { + let limit = Abs::cm(100.0); + if page.frame.width() > limit || page.frame.height() > limit { + panic!("overlarge frame: {:?}", page.frame.size()); + } + } + + let gap = Abs::pt(1.0); + let mut pixmap = typst_render::render_merged( + document, + pixel_per_pt, + Color::WHITE, + gap, + Color::BLACK, + ); + + let gap = (pixel_per_pt * gap.to_pt() as f32).round(); + + let mut y = 0.0; + for page in &document.pages { + let ts = + sk::Transform::from_scale(pixel_per_pt, pixel_per_pt).post_translate(0.0, y); + render_links(&mut pixmap, ts, &page.frame); + y += (pixel_per_pt * page.frame.height().to_pt() as f32).round().max(1.0) + gap; + } + + pixmap +} + +/// Draw extra boxes for links so we can see whether they are there. +fn render_links(canvas: &mut sk::Pixmap, ts: sk::Transform, frame: &Frame) { + for (pos, item) in frame.items() { + let ts = ts.pre_translate(pos.x.to_pt() as f32, pos.y.to_pt() as f32); + match *item { + FrameItem::Group(ref group) => { + let ts = ts.pre_concat(to_sk_transform(&group.transform)); + render_links(canvas, ts, &group.frame); + } + FrameItem::Meta(Meta::Link(_), size) => { + let w = size.x.to_pt() as f32; + let h = size.y.to_pt() as f32; + let rect = sk::Rect::from_xywh(0.0, 0.0, w, h).unwrap(); + let mut paint = sk::Paint::default(); + paint.set_color_rgba8(40, 54, 99, 40); + canvas.fill_rect(rect, &paint, ts, None); + } + _ => {} + } + } +} + +/// Whether rendering of a frame can be skipped. +fn skippable(page: &Page) -> bool { + page.frame.width().approx_eq(Abs::pt(120.0)) + && page.frame.height().approx_eq(Abs::pt(20.0)) + && skippable_frame(&page.frame) +} + +/// Whether rendering of a frame can be skipped. +fn skippable_frame(frame: &Frame) -> bool { + frame.items().all(|(_, item)| match item { + FrameItem::Group(group) => skippable_frame(&group.frame), + FrameItem::Meta(..) => true, + _ => false, + }) +} + +/// Whether to pixel images are approximately equal. +fn approx_equal(a: &sk::Pixmap, b: &sk::Pixmap) -> bool { + a.width() == b.width() + && a.height() == b.height() + && a.data().iter().zip(b.data()).all(|(&a, &b)| a.abs_diff(b) <= 1) +} + +/// Convert a Typst transform to a tiny-skia transform. +fn to_sk_transform(transform: &Transform) -> sk::Transform { + let Transform { sx, ky, kx, sy, tx, ty } = *transform; + sk::Transform::from_row( + sx.get() as _, + ky.get() as _, + kx.get() as _, + sy.get() as _, + tx.to_pt() as f32, + ty.to_pt() as f32, + ) +} diff --git a/tests/src/tests.rs b/tests/src/tests.rs index e4f60bb65..6d58e969e 100644 --- a/tests/src/tests.rs +++ b/tests/src/tests.rs @@ -1,1127 +1,112 @@ -/*! This is Typst's test runner. +//! Typst's test runner. -Tests are Typst files composed of a header part followed by subtests. +mod args; +mod collect; +mod logger; +mod run; +mod world; -The header may contain: -- a small description `// tests that features X works well` -- metadata (see [metadata::TestConfiguration]) - -The subtests may use extra testing functions defined in [library], most -importantly, `test(x, y)` which will fail the test `if x != y`. -*/ - -#![allow(clippy::comparison_chain)] -mod metadata; - -use self::metadata::*; - -use std::borrow::Cow; -use std::collections::{HashMap, HashSet}; -use std::ffi::OsStr; -use std::fmt::Write as _; -use std::io::{self, IsTerminal, Write as _}; -use std::ops::Range; -use std::path::{Path, PathBuf, MAIN_SEPARATOR_STR}; -use std::sync::{OnceLock, RwLock}; -use std::{env, fs}; +use std::path::Path; +use std::time::Duration; use clap::Parser; -use comemo::{Prehashed, Track}; -use oxipng::{InFile, Options, OutFile}; +use once_cell::sync::Lazy; +use parking_lot::Mutex; use rayon::iter::{ParallelBridge, ParallelIterator}; -use tiny_skia as sk; -use typst::diag::{bail, FileError, FileResult, Severity, SourceDiagnostic, StrResult}; -use typst::eval::Tracer; -use typst::foundations::{func, Bytes, Datetime, NoneValue, Repr, Smart, Value}; -use typst::introspection::Meta; -use typst::layout::{Abs, Frame, FrameItem, Margin, Page, PageElem, Transform}; -use typst::model::Document; -use typst::syntax::{FileId, Source, SyntaxNode, VirtualPath}; -use typst::text::{Font, FontBook, TextElem, TextSize}; -use typst::visualize::Color; -use typst::{Library, World, WorldExt}; -use walkdir::WalkDir; -// These directories are all relative to the tests/ directory. -const TYP_DIR: &str = "typ"; -const REF_DIR: &str = "ref"; -const PNG_DIR: &str = "png"; -const PDF_DIR: &str = "pdf"; -const SVG_DIR: &str = "svg"; +use crate::args::{CliArguments, Command}; +use crate::logger::Logger; -/// Arguments that modify test behaviour. -/// -/// Specify them like this when developing: -/// `cargo test --workspace --test tests -- --help` -#[derive(Debug, Clone, Parser)] -#[clap(name = "typst-test", author)] -struct Args { - /// All the tests that contains a filter string will be run (unless - /// `--exact` is specified, which is even stricter). - filter: Vec, - /// Runs only the specified subtest. - #[arg(short, long)] - #[arg(allow_hyphen_values = true)] - subtest: Option, - /// Runs only the test with the exact name specified in your command. - /// - /// Example: - /// `cargo test --workspace --test tests -- compiler/bytes.typ --exact` - #[arg(long)] - exact: bool, - /// Updates the reference images in `tests/ref`. - #[arg(long, default_value_t = env::var_os("UPDATE_EXPECT").is_some())] - update: bool, - /// Exports the tests as PDF into `tests/pdf`. - #[arg(long)] - pdf: bool, - /// Configuration of what to print. - #[command(flatten)] - print: PrintConfig, - /// Running `cargo test --workspace -- --nocapture` for the unit tests would - /// fail the test runner without argument. - // TODO: would it really still happen? - #[arg(long)] - nocapture: bool, - /// Prevents the terminal from being cleared of test names and includes - /// non-essential test messages. - #[arg(short, long)] - verbose: bool, -} +/// The parsed command line arguments. +static ARGS: Lazy = Lazy::new(CliArguments::parse); -/// Which things to print out for debugging. -#[derive(Default, Debug, Copy, Clone, Eq, PartialEq, Parser)] -struct PrintConfig { - /// Print the syntax tree. - #[arg(long)] - syntax: bool, - /// Print the content model. - #[arg(long)] - model: bool, - /// Print the layouted frames. - #[arg(long)] - frames: bool, -} +/// The directory where the test suite is located. +const SUITE_PATH: &str = "tests/suite"; -impl Args { - fn matches(&self, canonicalized_path: &Path) -> bool { - let path = canonicalized_path.to_string_lossy(); - if !self.exact { - return self.filter.is_empty() - || self.filter.iter().any(|v| path.contains(v)); - } +/// The directory where the full test results are stored. +const STORE_PATH: &str = "tests/store"; - self.filter.iter().any(|v| match path.strip_suffix(v) { - None => false, - Some(residual) => { - residual.is_empty() || residual.ends_with(MAIN_SEPARATOR_STR) - } - }) - } -} +/// The directory where the reference images are stored. +const REF_PATH: &str = "tests/ref"; + +/// The maximum size of reference images that aren't marked as `// LARGE`. +const REF_LIMIT: usize = 20 * 1024; -/// Tests all test files and prints a summary. fn main() { - let args = Args::parse(); + setup(); - // Create loader and context. - let world = TestWorld::new(args.print); + match &ARGS.command { + None => test(), + Some(Command::Clean) => std::fs::remove_dir_all(STORE_PATH).unwrap(), + } +} - println!("Running tests..."); - let results = WalkDir::new(TYP_DIR) - .sort_by_file_name() - .into_iter() - .par_bridge() - .filter_map(|entry| { - let entry = entry.unwrap(); - if entry.depth() == 0 { - return None; - } +fn setup() { + // Make all paths relative to the workspace. That's nicer for IDEs when + // clicking on paths printed to the terminal. + std::env::set_current_dir("..").unwrap(); - if entry.path().starts_with("typ/benches") { - return None; - } - - let src_path = entry.into_path(); // Relative to TYP_DIR. - if src_path.extension() != Some(OsStr::new("typ")) { - return None; - } - - if args.matches(&src_path.canonicalize().unwrap()) { - Some(src_path) - } else { - None - } - }) - .map_with(world, |world, src_path| { - let path = src_path.strip_prefix(TYP_DIR).unwrap(); - let png_path = Path::new(PNG_DIR).join(path).with_extension("png"); - let ref_path = Path::new(REF_DIR).join(path).with_extension("png"); - let svg_path = Path::new(SVG_DIR).join(path).with_extension("svg"); - let pdf_path = - args.pdf.then(|| Path::new(PDF_DIR).join(path).with_extension("pdf")); - - test( - world, - &src_path, - &png_path, - &ref_path, - pdf_path.as_deref(), - &svg_path, - &args, - ) as usize - }) - .collect::>(); - - let len = results.len(); - let ok = results.iter().sum::(); - if len > 0 { - println!("{ok} / {len} test{} passed.", if len > 1 { "s" } else { "" }); - } else { - println!("No test ran."); + // Create the storage. + for ext in ["render", "pdf", "svg"] { + std::fs::create_dir_all(Path::new(STORE_PATH).join(ext)).unwrap(); } - if ok != len { - println!( - "Set the UPDATE_EXPECT environment variable or pass the \ - --update flag to update the reference image(s)." - ); + // Set up the thread pool. + if let Some(num_threads) = ARGS.num_threads { + rayon::ThreadPoolBuilder::new() + .num_threads(num_threads) + .build_global() + .unwrap(); + } +} + +fn test() { + let (tests, skipped) = match crate::collect::collect() { + Ok(output) => output, + Err(errors) => { + eprintln!("failed to collect tests"); + for error in errors { + eprintln!("❌ {error}"); + } + std::process::exit(1); + } + }; + + let filtered = tests.len(); + if filtered == 0 { + eprintln!("no test selected"); + return; } - if ok < len { + // Run the tests. + let logger = Mutex::new(Logger::new(filtered, skipped)); + std::thread::scope(|scope| { + let logger = &logger; + let (sender, receiver) = std::sync::mpsc::channel(); + + // Regularly refresh the logger in case we make no progress. + scope.spawn(move || { + while receiver.recv_timeout(Duration::from_millis(500)).is_err() { + logger.lock().refresh(); + } + }); + + // Run the tests. + // + // We use `par_bridge` instead of `par_iter` because the former + // results in a stack overflow during PDF export. Probably related + // to `typst::util::Deferred` yielding. + tests.iter().par_bridge().for_each(|test| { + logger.lock().start(test); + let result = std::panic::catch_unwind(|| run::run(test)); + logger.lock().end(test, result); + }); + + sender.send(()).unwrap(); + }); + + let passed = logger.into_inner().finish(); + if !passed { std::process::exit(1); } } - -fn library() -> Library { - #[func] - fn test(lhs: Value, rhs: Value) -> StrResult { - if lhs != rhs { - bail!("Assertion failed: {} != {}", lhs.repr(), rhs.repr()); - } - Ok(NoneValue) - } - - #[func] - fn test_repr(lhs: Value, rhs: Value) -> StrResult { - if lhs.repr() != rhs.repr() { - bail!("Assertion failed: {} != {}", lhs.repr(), rhs.repr()); - } - Ok(NoneValue) - } - - #[func] - fn print(#[variadic] values: Vec) -> NoneValue { - let mut stdout = io::stdout().lock(); - write!(stdout, "> ").unwrap(); - for (i, value) in values.into_iter().enumerate() { - if i > 0 { - write!(stdout, ", ").unwrap(); - } - write!(stdout, "{value:?}").unwrap(); - } - writeln!(stdout).unwrap(); - NoneValue - } - - // Set page width to 120pt with 10pt margins, so that the inner page is - // exactly 100pt wide. Page height is unbounded and font size is 10pt so - // that it multiplies to nice round numbers. - let mut lib = Library::default(); - lib.styles - .set(PageElem::set_width(Smart::Custom(Abs::pt(120.0).into()))); - lib.styles.set(PageElem::set_height(Smart::Auto)); - lib.styles.set(PageElem::set_margin(Margin::splat(Some(Smart::Custom( - Abs::pt(10.0).into(), - ))))); - lib.styles.set(TextElem::set_size(TextSize(Abs::pt(10.0).into()))); - - // Hook up helpers into the global scope. - lib.global.scope_mut().define_func::(); - lib.global.scope_mut().define_func::(); - lib.global.scope_mut().define_func::(); - lib.global - .scope_mut() - .define("conifer", Color::from_u8(0x9f, 0xEB, 0x52, 0xFF)); - lib.global - .scope_mut() - .define("forest", Color::from_u8(0x43, 0xA1, 0x27, 0xFF)); - - lib -} - -/// A world that provides access to the tests environment. -struct TestWorld { - print: PrintConfig, - main: FileId, - library: Prehashed, - book: Prehashed, - fonts: Vec, - slots: RwLock>, -} - -#[derive(Clone)] -struct FileSlot { - source: OnceLock>, - buffer: OnceLock>, -} - -impl TestWorld { - fn new(print: PrintConfig) -> Self { - let fonts: Vec<_> = typst_assets::fonts() - .chain(typst_dev_assets::fonts()) - .flat_map(|data| Font::iter(Bytes::from_static(data))) - .collect(); - - Self { - print, - main: FileId::new(None, VirtualPath::new("main.typ")), - library: Prehashed::new(library()), - book: Prehashed::new(FontBook::from_fonts(&fonts)), - fonts, - slots: RwLock::new(HashMap::new()), - } - } -} - -impl World for TestWorld { - fn library(&self) -> &Prehashed { - &self.library - } - - fn book(&self) -> &Prehashed { - &self.book - } - - fn main(&self) -> Source { - self.source(self.main).unwrap() - } - - fn source(&self, id: FileId) -> FileResult { - self.slot(id, |slot| { - slot.source - .get_or_init(|| { - let buf = read(&system_path(id)?)?; - let text = String::from_utf8(buf.into_owned())?; - Ok(Source::new(id, text)) - }) - .clone() - }) - } - - fn file(&self, id: FileId) -> FileResult { - self.slot(id, |slot| { - slot.buffer - .get_or_init(|| { - read(&system_path(id)?).map(|cow| match cow { - Cow::Owned(buf) => buf.into(), - Cow::Borrowed(buf) => Bytes::from_static(buf), - }) - }) - .clone() - }) - } - - fn font(&self, id: usize) -> Option { - Some(self.fonts[id].clone()) - } - - fn today(&self, _: Option) -> Option { - Some(Datetime::from_ymd(1970, 1, 1).unwrap()) - } -} - -impl TestWorld { - fn set(&mut self, path: &Path, text: String) -> Source { - self.main = FileId::new(None, VirtualPath::new(path)); - let source = Source::new(self.main, text); - self.slot(self.main, |slot| { - slot.source = OnceLock::from(Ok(source.clone())); - source - }) - } - - fn slot(&self, id: FileId, f: F) -> T - where - F: FnOnce(&mut FileSlot) -> T, - { - f(self.slots.write().unwrap().entry(id).or_insert_with(|| FileSlot { - source: OnceLock::new(), - buffer: OnceLock::new(), - })) - } -} - -impl Clone for TestWorld { - fn clone(&self) -> Self { - Self { - print: self.print, - main: self.main, - library: self.library.clone(), - book: self.book.clone(), - fonts: self.fonts.clone(), - slots: RwLock::new(self.slots.read().unwrap().clone()), - } - } -} - -/// The file system path for a file ID. -fn system_path(id: FileId) -> FileResult { - let root: PathBuf = match id.package() { - Some(spec) => format!("packages/{}-{}", spec.name, spec.version).into(), - None => PathBuf::new(), - }; - - id.vpath().resolve(&root).ok_or(FileError::AccessDenied) -} - -/// Read a file. -fn read(path: &Path) -> FileResult> { - // Basically symlinks `assets/files` to `tests/files` so that the assets - // are within the test project root. - let resolved = path.to_path_buf(); - if let Ok(suffix) = path.strip_prefix("assets/") { - return typst_dev_assets::get(&suffix.to_string_lossy()) - .map(Cow::Borrowed) - .ok_or_else(|| FileError::NotFound(path.into())); - } - - let f = |e| FileError::from_io(e, path); - if fs::metadata(&resolved).map_err(f)?.is_dir() { - Err(FileError::IsDirectory) - } else { - fs::read(&resolved).map(Cow::Owned).map_err(f) - } -} - -/// Tests a test file and prints the result. -/// -/// Also tests that the header of each test is written correctly. -/// See [parse_part_metadata] for more details. -fn test( - world: &mut TestWorld, - src_path: &Path, - png_path: &Path, - ref_path: &Path, - pdf_path: Option<&Path>, - svg_path: &Path, - args: &Args, -) -> bool { - struct PanicGuard<'a>(&'a Path); - impl Drop for PanicGuard<'_> { - fn drop(&mut self) { - if std::thread::panicking() { - println!("Panicked in {}", self.0.display()); - } - } - } - - let name = src_path.strip_prefix(TYP_DIR).unwrap_or(src_path); - let text = fs::read_to_string(src_path).unwrap(); - let _guard = PanicGuard(name); - - let mut output = String::new(); - let mut ok = true; - let mut updated = false; - let mut pages = vec![]; - let mut line = 0; - let mut header_configuration = None; - let mut compare_ever = false; - let mut rng = LinearShift::new(); - - let parts: Vec<_> = text - .split("\n---") - .map(|s| s.strip_suffix('\r').unwrap_or(s)) - .collect(); - - for (i, &part) in parts.iter().enumerate() { - if let Some(x) = args.subtest { - let x = usize::try_from( - x.rem_euclid(isize::try_from(parts.len()).unwrap_or_default()), - ) - .unwrap(); - if x != i { - writeln!(output, " Skipped subtest {i}.").unwrap(); - continue; - } - } - let is_header = i == 0 - && parts.len() > 1 - && part - .lines() - .all(|s| s.starts_with("//") || s.chars().all(|c| c.is_whitespace())); - - if is_header { - let source = Source::detached(part.to_string()); - let metadata = parse_part_metadata(&source, true); - match metadata { - Ok(metadata) => { - header_configuration = Some(metadata.config); - } - Err(invalid_data) => { - ok = false; - writeln!( - output, - " Test {}: invalid metadata in header, failing the test:", - name.display() - ) - .unwrap(); - InvalidMetadata::write( - invalid_data, - &mut output, - &mut |annotation, output| { - print_annotation(output, &source, line, annotation) - }, - ); - } - } - } else { - let (part_ok, compare_here, part_frames) = test_part( - &mut output, - world, - src_path, - part.into(), - line, - i, - header_configuration.as_ref().unwrap_or(&Default::default()), - &mut rng, - args.verbose, - ); - - ok &= part_ok; - compare_ever |= compare_here; - pages.extend(part_frames); - } - - line += part.lines().count() + 1; - } - - let document = Document { pages, ..Default::default() }; - if compare_ever { - if let Some(pdf_path) = pdf_path { - let pdf_data = typst_pdf::pdf( - &document, - Smart::Custom(&format!("typst-test: {}", name.display())), - world.today(Some(0)), - ); - fs::create_dir_all(pdf_path.parent().unwrap()).unwrap(); - fs::write(pdf_path, pdf_data).unwrap(); - } - - if world.print.frames { - for frame in &document.pages { - writeln!(output, "{frame:#?}\n").unwrap(); - } - } - - let canvas = render(&document); - fs::create_dir_all(png_path.parent().unwrap()).unwrap(); - canvas.save_png(png_path).unwrap(); - - let svg = typst_svg::svg_merged(&document, Abs::pt(5.0)); - - fs::create_dir_all(svg_path.parent().unwrap()).unwrap(); - std::fs::write(svg_path, svg.as_bytes()).unwrap(); - - if let Ok(ref_pixmap) = sk::Pixmap::load_png(ref_path) { - if canvas.width() != ref_pixmap.width() - || canvas.height() != ref_pixmap.height() - || canvas - .data() - .iter() - .zip(ref_pixmap.data()) - .any(|(&a, &b)| a.abs_diff(b) > 2) - { - if args.update { - update_image(png_path, ref_path); - updated = true; - } else { - writeln!(output, " Does not match reference image.").unwrap(); - ok = false; - } - } - } else if !document.pages.is_empty() { - if args.update { - update_image(png_path, ref_path); - updated = true; - } else { - writeln!(output, " Failed to open reference image.").unwrap(); - ok = false; - } - } - } - - { - let mut stdout = io::stdout().lock(); - stdout.write_all(name.to_string_lossy().as_bytes()).unwrap(); - if ok { - writeln!(stdout, " ✔").unwrap(); - // Don't clear the line when in verbose mode or when the reference image - // was updated, to show in the output which test had its image updated. - if !updated && !args.verbose && stdout.is_terminal() { - // ANSI escape codes: cursor moves up and clears the line. - write!(stdout, "\x1b[1A\x1b[2K").unwrap(); - } - } else { - writeln!(stdout, " ❌").unwrap(); - } - if updated { - writeln!(stdout, " Updated reference image.").unwrap(); - } - if !output.is_empty() { - stdout.write_all(output.as_bytes()).unwrap(); - } - } - - ok -} - -fn update_image(png_path: &Path, ref_path: &Path) { - oxipng::optimize( - &InFile::Path(png_path.to_owned()), - &OutFile::from_path(ref_path.to_owned()), - &Options::max_compression(), - ) - .unwrap(); -} - -#[allow(clippy::too_many_arguments)] -fn test_part( - output: &mut String, - world: &mut TestWorld, - src_path: &Path, - text: String, - line: usize, - i: usize, - header_configuration: &TestConfig, - rng: &mut LinearShift, - verbose: bool, -) -> (bool, bool, Vec) { - let source = world.set(src_path, text); - if world.print.syntax { - writeln!(output, "Syntax Tree:\n{:#?}\n", source.root()).unwrap(); - } - - if world.print.model { - print_model(world, &source, output); - } - - let mut tracer = Tracer::new(); - let (mut frames, diagnostics) = match typst::compile(world, &mut tracer) { - Ok(document) => (document.pages, tracer.warnings()), - Err(errors) => { - let mut warnings = tracer.warnings(); - warnings.extend(errors); - (vec![], warnings) - } - }; - - let metadata = parse_part_metadata(&source, false); - match metadata { - Ok(metadata) => { - let mut ok = true; - let compare_ref = metadata - .config - .compare_ref - .unwrap_or(header_configuration.compare_ref.unwrap_or(true)); - let validate_hints = metadata - .config - .validate_hints - .unwrap_or(header_configuration.validate_hints.unwrap_or(true)); - let validate_autocomplete = metadata - .config - .validate_autocomplete - .unwrap_or(header_configuration.validate_autocomplete.unwrap_or(false)); - - if verbose { - writeln!(output, "Subtest {i} runs with compare_ref={compare_ref}; validate_hints={validate_hints}; validate_autocomplete={validate_autocomplete};").unwrap(); - } - ok &= test_spans(output, source.root()); - ok &= test_reparse(output, source.text(), i, rng); - - // Don't retain frames if we don't want to compare with reference images. - if !compare_ref { - frames.clear(); - } - - // we never check autocomplete and error at the same time - - let diagnostic_annotations = metadata - .annotations - .iter() - .filter(|a| { - !matches!( - a.kind, - AnnotationKind::AutocompleteContains - | AnnotationKind::AutocompleteExcludes - ) - }) - .cloned() - .collect::>(); - - if validate_autocomplete { - // warns and ignores diagnostics - if !diagnostic_annotations.is_empty() { - writeln!( - output, - " Subtest {i} contains diagnostics but is in autocomplete mode." - ) - .unwrap(); - for annotation in diagnostic_annotations { - write!(output, " Ignored | ").unwrap(); - print_annotation(output, &source, line, &annotation); - } - } - - test_autocomplete( - output, - world, - &source, - line, - i, - &mut ok, - metadata.annotations.iter(), - ); - } else { - test_diagnostics( - output, - world, - &source, - line, - i, - &mut ok, - validate_hints, - diagnostics.iter(), - &diagnostic_annotations, - ); - } - - (ok, compare_ref, frames) - } - Err(invalid_data) => { - writeln!(output, " Subtest {i} has invalid metadata, failing the test:") - .unwrap(); - InvalidMetadata::write( - invalid_data, - output, - &mut |annotation: &Annotation, output: &mut String| { - print_annotation(output, &source, line, annotation) - }, - ); - - (false, false, frames) - } - } -} - -#[allow(clippy::too_many_arguments)] -fn test_autocomplete<'a>( - output: &mut String, - world: &mut TestWorld, - source: &Source, - line: usize, - i: usize, - ok: &mut bool, - annotations: impl Iterator, -) { - for annotation in annotations.filter(|a| { - matches!( - a.kind, - AnnotationKind::AutocompleteContains | AnnotationKind::AutocompleteExcludes - ) - }) { - // Ok cause we checked in parsing that range was Some for this annotation - let cursor = annotation.range.as_ref().unwrap().start; - - // todo, use document if is_some to test labels autocomplete - let completions = typst_ide::autocomplete(world, None, source, cursor, true) - .map(|(_, c)| c) - .unwrap_or_default() - .into_iter() - .map(|c| c.label.to_string()) - .collect::>(); - let completions = - completions.iter().map(|s| s.as_str()).collect::>(); - - let must_contain_or_exclude = parse_string_list(&annotation.text); - let missing = - must_contain_or_exclude.difference(&completions).collect::>(); - - if !missing.is_empty() - && matches!(annotation.kind, AnnotationKind::AutocompleteContains) - { - writeln!(output, " Subtest {i} does not match expected completions.") - .unwrap(); - write!(output, " for annotation | ").unwrap(); - print_annotation(output, source, line, annotation); - - write!(output, " Not contained // ").unwrap(); - for item in missing { - write!(output, "{item:?}, ").unwrap() - } - writeln!(output).unwrap(); - *ok = false; - } - - let undesired = - must_contain_or_exclude.intersection(&completions).collect::>(); - - if !undesired.is_empty() - && matches!(annotation.kind, AnnotationKind::AutocompleteExcludes) - { - writeln!(output, " Subtest {i} does not match expected completions.") - .unwrap(); - write!(output, " for annotation | ").unwrap(); - print_annotation(output, source, line, annotation); - - write!(output, " Not excluded // ").unwrap(); - for item in undesired { - write!(output, "{item:?}, ").unwrap() - } - writeln!(output).unwrap(); - *ok = false; - } - } -} - -#[allow(clippy::too_many_arguments)] -fn test_diagnostics<'a>( - output: &mut String, - world: &mut TestWorld, - source: &Source, - line: usize, - i: usize, - ok: &mut bool, - validate_hints: bool, - diagnostics: impl Iterator, - diagnostic_annotations: &HashSet, -) { - // Map diagnostics to range and message format, discard traces and errors from - // other files, collect hints. - // - // This has one caveat: due to the format of the expected hints, we can not - // verify if a hint belongs to a diagnostic or not. That should be irrelevant - // however, as the line of the hint is still verified. - let mut actual_diagnostics = HashSet::new(); - for diagnostic in diagnostics { - // Ignore diagnostics from other files. - if diagnostic.span.id().is_some_and(|id| id != source.id()) { - continue; - } - - let annotation = Annotation { - kind: match diagnostic.severity { - Severity::Error => AnnotationKind::Error, - Severity::Warning => AnnotationKind::Warning, - }, - range: world.range(diagnostic.span), - text: diagnostic.message.replace("\\", "/"), - }; - - if validate_hints { - for hint in &diagnostic.hints { - actual_diagnostics.insert(Annotation { - kind: AnnotationKind::Hint, - text: hint.clone(), - range: annotation.range.clone(), - }); - } - } - - actual_diagnostics.insert(annotation); - } - - // Basically symmetric_difference, but we need to know where an item is coming from. - let mut unexpected_outputs = actual_diagnostics - .difference(diagnostic_annotations) - .collect::>(); - let mut missing_outputs = diagnostic_annotations - .difference(&actual_diagnostics) - .collect::>(); - - unexpected_outputs.sort_by_key(|&v| v.range.as_ref().map(|r| r.start)); - missing_outputs.sort_by_key(|&v| v.range.as_ref().map(|r| r.start)); - - // This prints all unexpected emits first, then all missing emits. - // Is this reasonable or subject to change? - if !(unexpected_outputs.is_empty() && missing_outputs.is_empty()) { - writeln!(output, " Subtest {i} does not match expected errors.").unwrap(); - *ok = false; - - for unexpected in unexpected_outputs { - write!(output, " Not annotated // ").unwrap(); - print_annotation(output, source, line, unexpected) - } - - for missing in missing_outputs { - write!(output, " Not emitted // ").unwrap(); - print_annotation(output, source, line, missing) - } - } -} - -fn print_model(world: &mut TestWorld, source: &Source, output: &mut String) { - let world = (world as &dyn World).track(); - let route = typst::engine::Route::default(); - let mut tracer = typst::eval::Tracer::new(); - - let module = - typst::eval::eval(world, route.track(), tracer.track_mut(), source).unwrap(); - writeln!(output, "Model:\n{:#?}\n", module.content()).unwrap(); -} - -fn print_annotation( - output: &mut String, - source: &Source, - line: usize, - annotation: &Annotation, -) { - let Annotation { range, text, kind } = annotation; - write!(output, "{kind}: ").unwrap(); - if let Some(range) = range { - let start_line = 1 + line + source.byte_to_line(range.start).unwrap(); - let start_col = 1 + source.byte_to_column(range.start).unwrap(); - let end_line = 1 + line + source.byte_to_line(range.end).unwrap(); - let end_col = 1 + source.byte_to_column(range.end).unwrap(); - write!(output, "{start_line}:{start_col}-{end_line}:{end_col} ").unwrap(); - } - writeln!(output, "{text}").unwrap(); -} - -/// Pseudorandomly edit the source file and test whether a reparse produces the -/// same result as a clean parse. -/// -/// The method will first inject 10 strings once every 400 source characters -/// and then select 5 leaf node boundaries to inject an additional, randomly -/// chosen string from the injection list. -fn test_reparse( - output: &mut String, - text: &str, - i: usize, - rng: &mut LinearShift, -) -> bool { - let supplements = [ - "[", - "]", - "{", - "}", - "(", - ")", - "#rect()", - "a word", - ", a: 1", - "10.0", - ":", - "if i == 0 {true}", - "for", - "* hello *", - "//", - "/*", - "\\u{12e4}", - "```typst", - " ", - "trees", - "\\", - "$ a $", - "2.", - "-", - "5", - ]; - - let mut ok = true; - let mut apply = |replace: Range, with| { - let mut incr_source = Source::detached(text); - if incr_source.root().len() != text.len() { - println!( - " Subtest {i} tree length {} does not match string length {} ❌", - incr_source.root().len(), - text.len(), - ); - return false; - } - - incr_source.edit(replace.clone(), with); - - let edited_src = incr_source.text(); - let ref_source = Source::detached(edited_src); - let ref_root = ref_source.root(); - let incr_root = incr_source.root(); - - // Ensures that the span numbering invariants hold. - let spans_ok = test_spans(output, ref_root) && test_spans(output, incr_root); - - // Ensure that the reference and incremental trees are the same. - let tree_ok = ref_root.spanless_eq(incr_root); - - if !tree_ok { - writeln!( - output, - " Subtest {i} reparse differs from clean parse when inserting '{with}' at {}-{} ❌\n", - replace.start, replace.end, - ).unwrap(); - writeln!(output, " Expected reference tree:\n{ref_root:#?}\n").unwrap(); - writeln!(output, " Found incremental tree:\n{incr_root:#?}").unwrap(); - writeln!( - output, - " Full source ({}):\n\"{edited_src:?}\"", - edited_src.len() - ) - .unwrap(); - } - - spans_ok && tree_ok - }; - - let mut pick = |range: Range| { - let ratio = rng.next(); - (range.start as f64 + ratio * (range.end - range.start) as f64).floor() as usize - }; - - let insertions = (text.len() as f64 / 400.0).ceil() as usize; - for _ in 0..insertions { - let supplement = supplements[pick(0..supplements.len())]; - let start = pick(0..text.len()); - let end = pick(start..text.len()); - - if !text.is_char_boundary(start) || !text.is_char_boundary(end) { - continue; - } - - ok &= apply(start..end, supplement); - } - - let source = Source::detached(text); - let leafs = leafs(source.root()); - let start = source.find(leafs[pick(0..leafs.len())].span()).unwrap().offset(); - let supplement = supplements[pick(0..supplements.len())]; - ok &= apply(start..start, supplement); - - ok -} - -/// Returns all leaf descendants of a node (may include itself). -fn leafs(node: &SyntaxNode) -> Vec { - if node.children().len() == 0 { - vec![node.clone()] - } else { - node.children().flat_map(leafs).collect() - } -} - -/// Ensure that all spans are properly ordered (and therefore unique). -#[track_caller] -fn test_spans(output: &mut String, root: &SyntaxNode) -> bool { - test_spans_impl(output, root, 0..u64::MAX) -} - -#[track_caller] -fn test_spans_impl(output: &mut String, node: &SyntaxNode, within: Range) -> bool { - if !within.contains(&node.span().number()) { - writeln!(output, " Node: {node:#?}").unwrap(); - writeln!( - output, - " Wrong span order: {} not in {within:?} ❌", - node.span().number() - ) - .unwrap(); - } - - let start = node.span().number() + 1; - let mut children = node.children().peekable(); - while let Some(child) = children.next() { - let end = children.peek().map_or(within.end, |next| next.span().number()); - if !test_spans_impl(output, child, start..end) { - return false; - } - } - - true -} - -/// Draw all frames into one image with padding in between. -fn render(document: &Document) -> sk::Pixmap { - let pixel_per_pt = 2.0; - let padding = Abs::pt(5.0); - - for page in &document.pages { - let limit = Abs::cm(100.0); - if page.frame.width() > limit || page.frame.height() > limit { - panic!("overlarge frame: {:?}", page.frame.size()); - } - } - - let mut pixmap = typst_render::render_merged( - document, - pixel_per_pt, - Color::WHITE, - padding, - Color::BLACK, - ); - - let padding = (pixel_per_pt * padding.to_pt() as f32).round(); - let [x, mut y] = [padding; 2]; - for page in &document.pages { - let ts = - sk::Transform::from_scale(pixel_per_pt, pixel_per_pt).post_translate(x, y); - render_links(&mut pixmap, ts, &page.frame); - y += (pixel_per_pt * page.frame.height().to_pt() as f32).round().max(1.0) - + padding; - } - - pixmap -} - -/// Draw extra boxes for links so we can see whether they are there. -fn render_links(canvas: &mut sk::Pixmap, ts: sk::Transform, frame: &Frame) { - for (pos, item) in frame.items() { - let ts = ts.pre_translate(pos.x.to_pt() as f32, pos.y.to_pt() as f32); - match *item { - FrameItem::Group(ref group) => { - let ts = ts.pre_concat(to_sk_transform(&group.transform)); - render_links(canvas, ts, &group.frame); - } - FrameItem::Meta(Meta::Link(_), size) => { - let w = size.x.to_pt() as f32; - let h = size.y.to_pt() as f32; - let rect = sk::Rect::from_xywh(0.0, 0.0, w, h).unwrap(); - let mut paint = sk::Paint::default(); - paint.set_color_rgba8(40, 54, 99, 40); - canvas.fill_rect(rect, &paint, ts, None); - } - _ => {} - } - } -} - -fn to_sk_transform(transform: &Transform) -> sk::Transform { - let Transform { sx, ky, kx, sy, tx, ty } = *transform; - sk::Transform::from_row( - sx.get() as _, - ky.get() as _, - kx.get() as _, - sy.get() as _, - tx.to_pt() as f32, - ty.to_pt() as f32, - ) -} - -/// A Linear-feedback shift register using XOR as its shifting function. -/// Can be used as PRNG. -struct LinearShift(u64); - -impl LinearShift { - /// Initialize the shift register with a pre-set seed. - pub fn new() -> Self { - Self(0xACE5) - } - - /// Return a pseudo-random number between `0.0` and `1.0`. - pub fn next(&mut self) -> f64 { - self.0 ^= self.0 >> 3; - self.0 ^= self.0 << 14; - self.0 ^= self.0 >> 28; - self.0 ^= self.0 << 36; - self.0 ^= self.0 >> 52; - self.0 as f64 / u64::MAX as f64 - } -} diff --git a/tests/src/world.rs b/tests/src/world.rs new file mode 100644 index 000000000..86ee8da6a --- /dev/null +++ b/tests/src/world.rs @@ -0,0 +1,229 @@ +use std::borrow::Cow; +use std::collections::HashMap; +use std::fs; +use std::io::Write; +use std::path::{Path, PathBuf}; +use std::sync::OnceLock; + +use comemo::Prehashed; +use once_cell::sync::Lazy; +use parking_lot::Mutex; +use typst::diag::{bail, FileError, FileResult, StrResult}; +use typst::foundations::{func, Bytes, Datetime, NoneValue, Repr, Smart, Value}; +use typst::layout::{Abs, Margin, PageElem}; +use typst::syntax::{FileId, Source}; +use typst::text::{Font, FontBook, TextElem, TextSize}; +use typst::visualize::Color; +use typst::{Library, World}; + +/// A world that provides access to the tests environment. +#[derive(Clone)] +pub struct TestWorld { + main: Source, + base: &'static TestBase, +} + +impl TestWorld { + /// Create a new world for a single test. + /// + /// This is cheap because the shared base for all test runs is lazily + /// initialized just once. + pub fn new(source: Source) -> Self { + static BASE: Lazy = Lazy::new(TestBase::default); + Self { main: source, base: &*BASE } + } +} + +impl World for TestWorld { + fn library(&self) -> &Prehashed { + &self.base.library + } + + fn book(&self) -> &Prehashed { + &self.base.book + } + + fn main(&self) -> Source { + self.main.clone() + } + + fn source(&self, id: FileId) -> FileResult { + if id == self.main.id() { + Ok(self.main.clone()) + } else { + self.slot(id, FileSlot::source) + } + } + + fn file(&self, id: FileId) -> FileResult { + self.slot(id, FileSlot::file) + } + + fn font(&self, index: usize) -> Option { + Some(self.base.fonts[index].clone()) + } + + fn today(&self, _: Option) -> Option { + Some(Datetime::from_ymd(1970, 1, 1).unwrap()) + } +} + +impl TestWorld { + /// Access the canonical slot for the given file id. + fn slot(&self, id: FileId, f: F) -> T + where + F: FnOnce(&mut FileSlot) -> T, + { + let mut map = self.base.slots.lock(); + f(map.entry(id).or_insert_with(|| FileSlot::new(id))) + } +} + +/// Shared foundation of all test worlds. +struct TestBase { + library: Prehashed, + book: Prehashed, + fonts: Vec, + slots: Mutex>, +} + +impl Default for TestBase { + fn default() -> Self { + let fonts: Vec<_> = typst_assets::fonts() + .chain(typst_dev_assets::fonts()) + .flat_map(|data| Font::iter(Bytes::from_static(data))) + .collect(); + + Self { + library: Prehashed::new(library()), + book: Prehashed::new(FontBook::from_fonts(&fonts)), + fonts, + slots: Mutex::new(HashMap::new()), + } + } +} + +/// Holds the processed data for a file ID. +#[derive(Clone)] +struct FileSlot { + id: FileId, + source: OnceLock>, + file: OnceLock>, +} + +impl FileSlot { + /// Create a new file slot. + fn new(id: FileId) -> Self { + Self { id, file: OnceLock::new(), source: OnceLock::new() } + } + + /// Retrieve the source for this file. + fn source(&mut self) -> FileResult { + self.source + .get_or_init(|| { + let buf = read(&system_path(self.id)?)?; + let text = String::from_utf8(buf.into_owned())?; + Ok(Source::new(self.id, text)) + }) + .clone() + } + + /// Retrieve the file's bytes. + fn file(&mut self) -> FileResult { + self.file + .get_or_init(|| { + read(&system_path(self.id)?).map(|cow| match cow { + Cow::Owned(buf) => buf.into(), + Cow::Borrowed(buf) => Bytes::from_static(buf), + }) + }) + .clone() + } +} + +/// The file system path for a file ID. +fn system_path(id: FileId) -> FileResult { + let root: PathBuf = match id.package() { + Some(spec) => format!("tests/packages/{}-{}", spec.name, spec.version).into(), + None => PathBuf::new(), + }; + + id.vpath().resolve(&root).ok_or(FileError::AccessDenied) +} + +/// Read a file. +fn read(path: &Path) -> FileResult> { + // Resolve asset. + if let Ok(suffix) = path.strip_prefix("assets/") { + return typst_dev_assets::get(&suffix.to_string_lossy()) + .map(Cow::Borrowed) + .ok_or_else(|| FileError::NotFound(path.into())); + } + + let f = |e| FileError::from_io(e, path); + if fs::metadata(path).map_err(f)?.is_dir() { + Err(FileError::IsDirectory) + } else { + fs::read(path).map(Cow::Owned).map_err(f) + } +} + +/// The extended standard library for testing. +fn library() -> Library { + // Set page width to 120pt with 10pt margins, so that the inner page is + // exactly 100pt wide. Page height is unbounded and font size is 10pt so + // that it multiplies to nice round numbers. + let mut lib = Library::default(); + + #[func] + fn test(lhs: Value, rhs: Value) -> StrResult { + if lhs != rhs { + bail!("Assertion failed: {} != {}", lhs.repr(), rhs.repr()); + } + Ok(NoneValue) + } + + #[func] + fn test_repr(lhs: Value, rhs: Value) -> StrResult { + if lhs.repr() != rhs.repr() { + bail!("Assertion failed: {} != {}", lhs.repr(), rhs.repr()); + } + Ok(NoneValue) + } + + #[func] + fn print(#[variadic] values: Vec) -> NoneValue { + let mut out = std::io::stdout().lock(); + write!(out, "> ").unwrap(); + for (i, value) in values.into_iter().enumerate() { + if i > 0 { + write!(out, ", ").unwrap(); + } + write!(out, "{value:?}").unwrap(); + } + writeln!(out).unwrap(); + NoneValue + } + + // Hook up helpers into the global scope. + lib.global.scope_mut().define_func::(); + lib.global.scope_mut().define_func::(); + lib.global.scope_mut().define_func::(); + lib.global + .scope_mut() + .define("conifer", Color::from_u8(0x9f, 0xEB, 0x52, 0xFF)); + lib.global + .scope_mut() + .define("forest", Color::from_u8(0x43, 0xA1, 0x27, 0xFF)); + + // Hook up default styles. + lib.styles + .set(PageElem::set_width(Smart::Custom(Abs::pt(120.0).into()))); + lib.styles.set(PageElem::set_height(Smart::Auto)); + lib.styles.set(PageElem::set_margin(Margin::splat(Some(Smart::Custom( + Abs::pt(10.0).into(), + ))))); + lib.styles.set(TextElem::set_size(TextSize(Abs::pt(10.0).into()))); + + lib +} diff --git a/tests/typ/compiler/array.typ b/tests/suite/foundations/array.typ similarity index 68% rename from tests/typ/compiler/array.typ rename to tests/suite/foundations/array.typ index 597f242c6..3992d75ed 100644 --- a/tests/typ/compiler/array.typ +++ b/tests/suite/foundations/array.typ @@ -1,9 +1,6 @@ // Test arrays. -// Ref: false - ---- -// Ref: true +--- array-basic-syntax --- #set page(width: 150pt) // Empty. @@ -23,12 +20,56 @@ , rgb("002") ,) ---- +--- array-bad-token --- +// Error: 4-6 unexpected end of block comment +#(1*/2) + +--- array-bad-number-suffix --- +// Error: 6-8 invalid number suffix: u +#(1, 1u 2) + +--- array-leading-comma --- +// Error: 3-4 unexpected comma +#(,1) + +--- array-incomplete-pair --- +// Missing expression makes named pair incomplete, making this an empty array. +// Error: 5 expected expression +#(a:) + +--- array-named-pair --- +// Named pair after this is already identified as an array. +// Error: 6-10 expected expression, found named pair +#(1, b: 2) + +--- array-keyed-pair --- +// Keyed pair after this is already identified as an array. +// Error: 6-14 expected expression, found keyed pair +#(1, "key": 2) + +--- array-bad-conversion-from-string --- +// Error: 8-15 expected array, bytes, or version, found string +#array("hello") + +--- spread-into-array --- +// Test spreading into array and dictionary. +#{ + let l = (1, 2, 3) + let r = (5, 6, 7) + test((..l, 4, ..r), range(1, 8)) + test((..none), ()) +} + +--- spread-dict-into-array --- +// Error: 9-17 cannot spread dictionary into array +#(1, 2, ..(a: 1)) + +--- array-len --- // Test the `len` method. #test(().len(), 0) #test(("A", "B", "C").len(), 3) ---- +--- array-at-lvalue --- // Test lvalue and rvalue access. #{ let array = (1, 2) @@ -36,7 +77,7 @@ test(array, (1, 8)) } ---- +--- array-first-and-at-lvalue --- // Test different lvalue method. #{ let array = (1, 2, 3) @@ -45,12 +86,16 @@ test(array, (7, 16, 3)) } ---- +--- array-at-out-of-bounds --- // Test rvalue out of bounds. // Error: 2-17 array index out of bounds (index: 5, len: 3) and no default value was specified #(1, 2, 3).at(5) ---- +--- array-at-out-of-bounds-negative --- +// Error: 2-18 array index out of bounds (index: -4, len: 3) and no default value was specified +#(1, 2, 3).at(-4) + +--- array-at-out-of-bounds-lvalue --- // Test lvalue out of bounds. #{ let array = (1, 2, 3) @@ -58,12 +103,12 @@ array.at(3) = 5 } ---- +--- array-at-with-default --- // Test default value. #test((1, 2, 3).at(2, default: 5), 3) #test((1, 2, 3).at(3, default: 5), 5) ---- +--- array-remove-with-default --- // Test remove with default value. #{ @@ -76,19 +121,47 @@ test(array.remove(3, default: 5), 5) } ---- +--- array-range --- +// Test the `range` function. +#test(range(4), (0, 1, 2, 3)) +#test(range(1, 4), (1, 2, 3)) +#test(range(-4, 2), (-4, -3, -2, -1, 0, 1)) +#test(range(10, 5), ()) +#test(range(10, step: 3), (0, 3, 6, 9)) +#test(range(1, 4, step: 1), (1, 2, 3)) +#test(range(1, 8, step: 2), (1, 3, 5, 7)) +#test(range(5, 2, step: -1), (5, 4, 3)) +#test(range(10, 0, step: -3), (10, 7, 4, 1)) + +--- array-range-end-missing --- +// Error: 2-9 missing argument: end +#range() + +--- array-range-float-invalid --- +// Error: 11-14 expected integer, found float +#range(1, 2.0) + +--- array-range-bad-step-type --- +// Error: 17-22 expected integer, found string +#range(4, step: "one") + +--- array-range-step-zero --- +// Error: 18-19 number must not be zero +#range(10, step: 0) + +--- array-bad-method-lvalue --- // Test bad lvalue. // Error: 2:3-2:14 cannot mutate a temporary value #let array = (1, 2, 3) #(array.len() = 4) ---- +--- array-unknown-method-lvalue --- // Test bad lvalue. // Error: 2:9-2:13 type array has no method `yolo` #let array = (1, 2, 3) #(array.yolo() = 4) ---- +--- array-negative-indices --- // Test negative indices. #{ let array = (1, 2, 3, 4) @@ -99,22 +172,22 @@ test(array.at(-4), 1) } ---- +--- array-first-and-last --- // The the `first` and `last` methods. #test((1,).first(), 1) #test((2,).last(), 2) #test((1, 2, 3).first(), 1) #test((1, 2, 3).last(), 3) ---- +--- array-first-empty --- // Error: 2-12 array is empty #().first() ---- +--- array-last-empty --- // Error: 2-11 array is empty #().last() ---- +--- array-push-and-pop --- // Test the `push` and `pop` methods. #{ let tasks = (a: (1, 2, 3), b: (4, 5, 6)) @@ -124,7 +197,7 @@ test(tasks.at("b"), (4, 5, 6, 7)) } ---- +--- array-insert-and-remove --- // Test the `insert` and `remove` methods. #{ let array = (0, 1, 2, 4, 5) @@ -134,12 +207,12 @@ test(array, (0, 2, 3, 4, 5)) } ---- +--- array-insert-missing-index --- // Error: 2:2-2:18 missing argument: index #let numbers = () #numbers.insert() ---- +--- array-slice --- // Test the `slice` method. #test((1, 2, 3, 4).slice(2), (3, 4)) #test(range(10).slice(2, 6), (2, 3, 4, 5)) @@ -150,93 +223,92 @@ #test((1, 2, 3).slice(-3, 2), (1, 2)) #test("ABCD".split("").slice(1, -1).join("-"), "A-B-C-D") ---- +--- array-slice-out-of-bounds --- // Error: 2-30 array index out of bounds (index: 12, len: 10) #range(10).slice(9, count: 3) ---- +--- array-slice-out-of-bounds-negative --- // Error: 2-24 array index out of bounds (index: -4, len: 3) #(1, 2, 3).slice(0, -4) ---- +--- array-position --- // Test the `position` method. #test(("Hi", "❤️", "Love").position(s => s == "❤️"), 1) #test(("Bye", "💘", "Apart").position(s => s == "❤️"), none) #test(("A", "B", "CDEF", "G").position(v => v.len() > 2), 2) ---- +--- array-filter --- // Test the `filter` method. #test(().filter(calc.even), ()) #test((1, 2, 3, 4).filter(calc.even), (2, 4)) #test((7, 3, 2, 5, 1).filter(x => x < 5), (3, 2, 1)) ---- +--- array-map --- // Test the `map` method. #test(().map(x => x * 2), ()) #test((2, 3).map(x => x * 2), (4, 6)) ---- +--- array-fold --- // Test the `fold` method. #test(().fold("hi", grid), "hi") #test((1, 2, 3, 4).fold(0, (s, x) => s + x), 10) ---- +--- array-fold-closure-without-params --- // Error: 20-22 unexpected argument #(1, 2, 3).fold(0, () => none) ---- +--- array-sum --- // Test the `sum` method. #test(().sum(default: 0), 0) #test(().sum(default: []), []) #test((1, 2, 3).sum(), 6) ---- +--- array-sum-empty --- // Error: 2-10 cannot calculate sum of empty array with no default #().sum() ---- +--- array-product --- // Test the `product` method. #test(().product(default: 0), 0) #test(().product(default: []), []) #test(([ab], 3).product(), [ab]*3) #test((1, 2, 3).product(), 6) ---- +--- array-product-empty --- // Error: 2-14 cannot calculate product of empty array with no default #().product() ---- +--- array-rev --- // Test the `rev` method. #test(range(3).rev(), (2, 1, 0)) ---- +--- array-join --- // Test the `join` method. #test(().join(), none) #test((1,).join(), 1) #test(("a", "b", "c").join(), "abc") #test("(" + ("a", "b", "c").join(", ") + ")", "(a, b, c)") ---- +--- array-join-bad-values --- // Error: 2-22 cannot join boolean with boolean #(true, false).join() ---- +--- array-join-bad-separator --- // Error: 2-20 cannot join string with integer #("a", "b").join(1) ---- +--- array-join-content --- // Test joining content. -// Ref: true #([One], [Two], [Three]).join([, ], last: [ and ]). ---- +--- array-intersperse --- // Test the `intersperse` method #test(().intersperse("a"), ()) #test((1,).intersperse("a"), (1,)) #test((1, 2).intersperse("a"), (1, "a", 2)) #test((1, 2, "b").intersperse("a"), (1, "a", 2, "a", "b")) ---- +--- array-chunks --- // Test the `chunks` method. #test(().chunks(10), ()) #test((1, 2, 3).chunks(10), ((1, 2, 3),)) @@ -248,15 +320,15 @@ #test((1, 2, 3, 4, 5, 6).chunks(3, exact: true), ((1, 2, 3), (4, 5, 6))) #test((1, 2, 3, 4, 5, 6, 7, 8).chunks(3, exact: true), ((1, 2, 3), (4, 5, 6))) ---- +--- array-chunks-size-zero --- // Error: 19-20 number must be positive #(1, 2, 3).chunks(0) ---- +--- array-chunks-size-negative --- // Error: 19-21 number must be positive #(1, 2, 3).chunks(-5) ---- +--- array-sorted --- // Test the `sorted` method. #test(().sorted(), ()) #test(().sorted(key: x => x), ()) @@ -268,11 +340,11 @@ #test((2, 1, 3, -10, -5, 8, 6, -7, 2).sorted(key: x => x), (-10, -7, -5, 1, 2, 2, 3, 6, 8)) #test((2, 1, 3, -10, -5, 8, 6, -7, 2).sorted(key: x => x * x), (1, 2, 2, 3, -5, 6, -7, 8, -10)) ---- +--- array-sorted-key-function-positional-1 --- // Error: 12-18 unexpected argument #().sorted(x => x) ---- +--- array-zip --- // Test the `zip` method. #test(().zip(()), ()) #test((1,).zip(()), ()) @@ -287,8 +359,7 @@ #test((1, 2, 3).zip(), ((1,), (2,), (3,))) #test(array.zip(()), ()) - ---- +--- array-enumerate --- // Test the `enumerate` method. #test(().enumerate(), ()) #test(().enumerate(start: 5), ()) @@ -297,7 +368,7 @@ #test(("a", "b", "c").enumerate(start: 42), ((42, "a"), (43, "b"), (44, "c"))) #test(("a", "b", "c").enumerate(start: -7), ((-7, "a"), (-6, "b"), (-5, "c"))) ---- +--- array-dedup --- // Test the `dedup` method. #test(().dedup(), ()) #test((1,).dedup(), (1,)) @@ -306,87 +377,118 @@ #test(("Jane", "John", "Eric").dedup(), ("Jane", "John", "Eric")) #test(("Jane", "John", "Eric", "John").dedup(), ("Jane", "John", "Eric")) ---- +--- array-dedup-key --- // Test the `dedup` method with the `key` argument. #test((1, 2, 3, 4, 5, 6).dedup(key: x => calc.rem(x, 2)), (1, 2)) #test((1, 2, 3, 4, 5, 6).dedup(key: x => calc.rem(x, 3)), (1, 2, 3)) #test(("Hello", "World", "Hi", "There").dedup(key: x => x.len()), ("Hello", "Hi")) #test(("Hello", "World", "Hi", "There").dedup(key: x => x.at(0)), ("Hello", "World", "There")) ---- +--- array-to-dict --- // Test the `to-dict` method. #test(().to-dict(), (:)) #test((("a", 1), ("b", 2), ("c", 3)).to-dict(), (a: 1, b: 2, c: 3)) #test((("a", 1), ("b", 2), ("c", 3), ("b", 4)).to-dict(), (a: 1, b: 4, c: 3)) ---- +--- array-to-dict-bad-item-type --- // Error: 2-16 expected (str, any) pairs, found integer #(1,).to-dict() ---- +--- array-to-dict-bad-pair-length-1 --- // Error: 2-19 expected pairs of length 2, found length 1 #((1,),).to-dict() ---- +--- array-to-dict-bad-pair-length-3 --- // Error: 2-26 expected pairs of length 2, found length 3 #(("key",1,2),).to-dict() ---- +--- array-to-dict-bad-key-type --- // Error: 2-21 expected key of type str, found integer #((1, 2),).to-dict() ---- -// Error: 9-26 unexpected argument: val -#().zip(val: "applicable") - ---- +--- array-zip-positional-and-named-argument --- // Error: 13-30 unexpected argument: val #().zip((), val: "applicable") ---- +--- array-sorted-bad-key --- // Error: 32-37 cannot divide by zero #(1, 2, 0, 3).sorted(key: x => 5 / x) ---- +--- array-sorted-uncomparable --- // Error: 2-26 cannot compare content and content #([Hi], [There]).sorted() ---- +--- array-sorted-uncomparable-lengths --- // Error: 2-26 cannot compare 3em with 2pt #(1pt, 2pt, 3em).sorted() ---- +--- array-sorted-key-function-positional-2 --- // Error: 42-52 unexpected argument #((k: "a", v: 2), (k: "b", v: 1)).sorted(it => it.v) ---- -// Error: 2-18 array index out of bounds (index: -4, len: 3) and no default value was specified -#(1, 2, 3).at(-4) +--- issue-3014-mix-array-dictionary --- +// Error: 8-17 expected expression, found named pair +#(box, fill: red) ---- -// Error: 3-4 unclosed delimiter -#{(} +--- issue-3154-array-first-empty --- +#{ + let array = () + // Error: 3-16 array is empty + array.first() +} +--- issue-3154-array-first-mutable-empty --- +#{ + let array = () + // Error: 3-16 array is empty + array.first() = 9 +} + +--- issue-3154-array-last-empty --- +#{ + let array = () + // Error: 3-15 array is empty + array.last() +} + +--- issue-3154-array-last-mutable-empty --- +#{ + let array = () + // Error: 3-15 array is empty + array.last() = 9 +} + +--- issue-3154-array-at-out-of-bounds --- +#{ + let array = (1,) + // Error: 3-14 array index out of bounds (index: 1, len: 1) and no default value was specified + array.at(1) +} + +--- issue-3154-array-at-out-of-bounds-default --- +#{ + let array = (1,) + test(array.at(1, default: 0), 0) +} + +--- issue-3154-array-at-out-of-bounds-mutable --- +#{ + let array = (1,) + // Error: 3-14 array index out of bounds (index: 1, len: 1) + array.at(1) = 9 +} + +--- issue-3154-array-at-out-of-bounds-mutable-default --- +#{ + let array = (1,) + // Error: 3-26 array index out of bounds (index: 1, len: 1) + array.at(1, default: 0) = 9 +} + +--- array-unopened --- // Error: 2-3 unclosed delimiter #{)} -// Error: 4-6 unexpected end of block comment -#(1*/2) - -// Error: 6-8 invalid number suffix: u -#(1, 1u 2) - -// Error: 3-4 unexpected comma -#(,1) - -// Missing expression makes named pair incomplete, making this an empty array. -// Error: 5 expected expression -#(a:) - -// Named pair after this is already identified as an array. -// Error: 6-10 expected expression, found named pair -#(1, b: 2) - -// Keyed pair after this is already identified as an array. -// Error: 6-14 expected expression, found keyed pair -#(1, "key": 2) +--- array-unclosed --- +// Error: 3-4 unclosed delimiter +#{(} diff --git a/tests/suite/foundations/assert.typ b/tests/suite/foundations/assert.typ new file mode 100644 index 000000000..5de0f3878 --- /dev/null +++ b/tests/suite/foundations/assert.typ @@ -0,0 +1,40 @@ +--- assert-fail --- +// Test failing assertions. +// Error: 2-16 assertion failed +#assert(1 == 2) + +--- assert-fail-message --- +// Test failing assertions. +// Error: 2-51 assertion failed: two is smaller than one +#assert(2 < 1, message: "two is smaller than one") + +--- assert-bad-type --- +// Test failing assertions. +// Error: 9-15 expected boolean, found string +#assert("true") + +--- assert-eq-fail --- +// Test failing assertions. +// Error: 2-19 equality assertion failed: value 10 was not equal to 11 +#assert.eq(10, 11) + +--- assert-eq-fail-message --- +// Test failing assertions. +// Error: 2-55 equality assertion failed: 10 and 12 are not equal +#assert.eq(10, 12, message: "10 and 12 are not equal") + +--- assert-ne-fail --- +// Test failing assertions. +// Error: 2-19 inequality assertion failed: value 11 was equal to 11 +#assert.ne(11, 11) + +--- assert-ne-fail-message --- +// Test failing assertions. +// Error: 2-57 inequality assertion failed: must be different from 11 +#assert.ne(11, 11, message: "must be different from 11") + +--- assert-success --- +// Test successful assertions. +#assert(5 > 3) +#assert.eq(15, 15) +#assert.ne(10, 12) diff --git a/tests/typ/compiler/bytes.typ b/tests/suite/foundations/bytes.typ similarity index 80% rename from tests/typ/compiler/bytes.typ rename to tests/suite/foundations/bytes.typ index a9249bddd..c70892780 100644 --- a/tests/typ/compiler/bytes.typ +++ b/tests/suite/foundations/bytes.typ @@ -1,32 +1,31 @@ // Test the bytes type. -// Ref: false ---- +--- bytes-basic --- #let data = read("/assets/images/rhino.png", encoding: none) #test(data.len(), 232243) #test(data.slice(0, count: 5), bytes((137, 80, 78, 71, 13))) #test(str(data.slice(1, 4)), "PNG") #test(repr(data), "bytes(232243)") ---- +--- bytes-string-conversion --- #test(str(bytes(range(0x41, 0x50))), "ABCDEFGHIJKLMNO") + +--- bytes-array-conversion --- #test(array(bytes("Hello")), (0x48, 0x65, 0x6C, 0x6C, 0x6F)) ---- +--- bytes-addition --- // Test addition and joining. #test(bytes((1, 2)) + bytes(()), bytes((1, 2))) #test(bytes((1, 2)) + bytes((3, 4)), bytes((1, 2, 3, 4))) #test(bytes(()) + bytes((3, 4)), bytes((3, 4))) + +--- bytes-joining --- #test(str({ bytes("Hello") bytes((0x20,)) bytes("World") }), "Hello World") ---- +--- bytes-bad-conversion-from-dict --- // Error: 8-14 expected string, array, or bytes, found dictionary #bytes((a: 1)) - ---- -// Error: 8-15 expected array, bytes, or version, found string -#array("hello") diff --git a/tests/typ/compute/calc.typ b/tests/suite/foundations/calc.typ similarity index 70% rename from tests/typ/compute/calc.typ rename to tests/suite/foundations/calc.typ index 94a131057..e702be9f6 100644 --- a/tests/typ/compute/calc.typ +++ b/tests/suite/foundations/calc.typ @@ -1,74 +1,8 @@ -// Test math functions. -// Ref: false - ---- -// Test conversion to numbers. -#test(int(false), 0) -#test(int(true), 1) -#test(int(10), 10) -#test(int("150"), 150) -#test(int("-834"), -834) -#test(int("\u{2212}79"), -79) -#test(int(10 / 3), 3) -#test(float(10), 10.0) -#test(float(50% * 30%), 0.15) -#test(float("31.4e-1"), 3.14) -#test(float("31.4e\u{2212}1"), 3.14) -#test(float("3.1415"), 3.1415) -#test(float("-7654.321"), -7654.321) -#test(float("\u{2212}7654.321"), -7654.321) -#test(type(float(10)), float) - ---- -// Test float `is-nan()`. -#test(float(calc.nan).is-nan(), true) -#test(float(10).is-nan(), false) - ---- -// Test float `is-infinite()`. -#test(float(calc.inf).is-infinite(), true) -#test(float(-calc.inf).is-infinite(), true) -#test(float(10).is-infinite(), false) -#test(float(-10).is-infinite(), false) - ---- -// Test float `signum()` -#test(float(0.0).signum(), 1.0) -#test(float(1.0).signum(), 1.0) -#test(float(-1.0).signum(), -1.0) -#test(float(10.0).signum(), 1.0) -#test(float(-10.0).signum(), -1.0) -#test(float(calc.nan).signum().is-nan(), true) - ---- -// Test int `signum()` -#test(int(0).signum(), 0) -#test(int(1.0).signum(), 1) -#test(int(-1.0).signum(), -1) -#test(int(10.0).signum(), 1) -#test(int(-10.0).signum(), -1) - ---- +--- calc-round --- #test(calc.round(calc.e, digits: 2), 2.72) #test(calc.round(calc.pi, digits: 2), 3.14) ---- -// Error: 6-10 expected integer, boolean, float, or string, found length -#int(10pt) - ---- -// Error: 8-13 expected float, boolean, integer, ratio, or string, found type -#float(float) - ---- -// Error: 6-12 invalid integer: nope -#int("nope") - ---- -// Error: 8-15 invalid float: 1.2.3 -#float("1.2.3") - ---- +--- calc-abs --- // Test the `abs` function. #test(calc.abs(-3), 3) #test(calc.abs(3), 3) @@ -78,18 +12,18 @@ #test(calc.abs(50%), 50%) #test(calc.abs(-25%), 25%) ---- +--- cals-abs-bad-type --- // Error: 11-22 expected integer, float, length, angle, ratio, or fraction, found string #calc.abs("no number") ---- +--- calc-even-and-odd --- // Test the `even` and `odd` functions. #test(calc.even(2), true) #test(calc.odd(2), false) #test(calc.odd(-1), true) #test(calc.even(-11), false) ---- +--- calc-rem --- // Test the `rem` function. #test(calc.rem(1, 1), 0) #test(calc.rem(5, 3), 2) @@ -97,15 +31,15 @@ #test(calc.rem(22.5, 10), 2.5) #test(calc.rem(9, 4.5), 0) ---- +--- calc-rem-divisor-zero-1 --- // Error: 14-15 divisor must not be zero #calc.rem(5, 0) ---- +--- calc-rem-divisor-zero-2 --- // Error: 16-19 divisor must not be zero #calc.rem(3.0, 0.0) ---- +--- calc-div-euclid --- // Test the `div-euclid` function. #test(calc.div-euclid(7, 3), 2) #test(calc.div-euclid(7, -3), -2) @@ -113,15 +47,15 @@ #test(calc.div-euclid(-7, -3), 3) #test(calc.div-euclid(2.5, 2), 1) ---- +--- calc-div-euclid-divisor-zero-1 --- // Error: 21-22 divisor must not be zero #calc.div-euclid(5, 0) ---- +--- calc-div-euclid-divisor-zero-2 --- // Error: 23-26 divisor must not be zero #calc.div-euclid(3.0, 0.0) ---- +--- calc-rem-euclid --- // Test the `rem-euclid` function. #test(calc.rem-euclid(7, 3), 1) #test(calc.rem-euclid(7, -3), 1) @@ -129,15 +63,15 @@ #test(calc.rem-euclid(-7, -3), 2) #test(calc.rem-euclid(2.5, 2), 0.5) ---- +--- calc-rem-euclid-divisor-zero-1 --- // Error: 21-22 divisor must not be zero #calc.rem-euclid(5, 0) ---- +--- calc-rem-euclid-divisor-zero-2 --- // Error: 23-26 divisor must not be zero #calc.rem-euclid(3.0, 0.0) ---- +--- calc-quo --- // Test the `quo` function. #test(calc.quo(1, 1), 1) #test(calc.quo(5, 3), 1) @@ -145,29 +79,29 @@ #test(calc.quo(22.5, 10), 2) #test(calc.quo(9, 4.5), 2) ---- +--- calc-quo-divisor-zero-1 --- // Error: 14-15 divisor must not be zero #calc.quo(5, 0) ---- +--- calc-quo-divisor-zero-2 --- // Error: 16-19 divisor must not be zero #calc.quo(3.0, 0.0) ---- +--- calc-min-and-max --- // Test the `min` and `max` functions. #test(calc.min(2, -4), -4) #test(calc.min(3.5, 1e2, -0.1, 3), -0.1) #test(calc.max(-3, 11), 11) #test(calc.min("hi"), "hi") ---- +--- calc-pow-log-exp-ln --- // Test the `pow`, `log`, `exp`, and `ln` functions. #test(calc.pow(10, 0), 1) #test(calc.pow(2, 4), 16) #test(calc.exp(2), calc.pow(calc.e, 2)) #test(calc.ln(10), calc.log(10, base: calc.e)) ---- +--- calc-bit-logical --- // Test the `bit-not`, `bit-and`, `bit-or` and `bit-xor` functions. #test(64.bit-not(), -65) #test(0.bit-not(), -1) @@ -185,7 +119,7 @@ #test((-1).bit-xor(-7), 6) #test(0.bit-xor(492), 492) ---- +--- calc-bit-shift --- // Test the `bit-lshift` and `bit-rshift` functions. #test(32.bit-lshift(2), 128) #test(694.bit-lshift(0), 694) @@ -198,43 +132,43 @@ #test(128.bit-rshift(12345, logical: true), 0) #test((-7).bit-rshift(12345, logical: true), 0) ---- +--- calc-bit-shift-too-large --- // Error: 2-18 the result is too large #1.bit-lshift(64) ---- +--- calc-bit-lshift-negative --- // Error: 15-17 number must be at least zero #1.bit-lshift(-1) ---- +--- calc-bit-rshift-negative --- // Error: 15-17 number must be at least zero #1.bit-rshift(-1) ---- +--- calc-pow-zero-to-power-of-zero --- // Error: 2-16 zero to the power of zero is undefined #calc.pow(0, 0) ---- +--- calc-pow-exponent-too-large --- // Error: 14-31 exponent is too large #calc.pow(2, 10000000000000000) ---- +--- calc-pow-too-large --- // Error: 2-25 the result is too large #calc.pow(2, 2147483647) ---- +--- calc-pow-bad-exponent --- // Error: 14-36 exponent may not be infinite, subnormal, or NaN #calc.pow(2, calc.pow(2.0, 10000.0)) ---- +--- calc-pow-not-real --- // Error: 2-19 the result is not a real number #calc.pow(-1, 0.5) ---- +--- calc-sqrt-not-real --- // Error: 12-14 cannot take square root of negative number #calc.sqrt(-1) ---- +--- calc-root --- #test(calc.root(12.0, 1), 12.0) #test(calc.root(9.0, 2), 3.0) #test(calc.root(27.0, 3), 3.0) @@ -242,47 +176,47 @@ // 100^(-1/2) = (100^(1/2))^-1 = 1/sqrt(100) #test(calc.root(100.0, -2), 0.1) ---- +--- calc-root-zeroth --- // Error: 17-18 cannot take the 0th root of a number #calc.root(1.0, 0) ---- +--- calc-root-negative-even --- // Error: 24-25 negative numbers do not have a real nth root when n is even #test(calc.root(-27.0, 4), -3.0) ---- +--- calc-log-negative --- // Error: 11-13 value must be strictly positive #calc.log(-1) ---- +--- calc-log-bad-base --- // Error: 20-21 base may not be zero, NaN, infinite, or subnormal #calc.log(1, base: 0) ---- +--- calc-log-not-real --- // Error: 2-24 the result is not a real number #calc.log(10, base: -1) ---- +--- calc-fact --- // Test the `fact` function. #test(calc.fact(0), 1) #test(calc.fact(5), 120) ---- +--- calc-fact-too-large --- // Error: 2-15 the result is too large #calc.fact(21) ---- +--- calc-perm --- // Test the `perm` function. #test(calc.perm(0, 0), 1) #test(calc.perm(5, 3), 60) #test(calc.perm(5, 5), 120) #test(calc.perm(5, 6), 0) ---- +--- calc-perm-too-large --- // Error: 2-19 the result is too large #calc.perm(21, 21) ---- +--- calc-binom --- // Test the `binom` function. #test(calc.binom(0, 0), 1) #test(calc.binom(5, 3), 10) @@ -290,7 +224,7 @@ #test(calc.binom(5, 6), 0) #test(calc.binom(6, 2), 15) ---- +--- calc-gcd --- // Test the `gcd` function. #test(calc.gcd(112, 77), 7) #test(calc.gcd(12, 96), 12) @@ -300,7 +234,7 @@ #test(calc.gcd(0, 0), 0) #test(calc.gcd(7, 0), 7) ---- +--- calc-lcm --- // Test the `lcm` function. #test(calc.lcm(112, 77), 1232) #test(calc.lcm(12, 96), 96) @@ -310,46 +244,18 @@ #test(calc.lcm(0, 0), 0) #test(calc.lcm(8, 0), 0) ---- +--- calc-lcm-too-large --- // Error: 2-41 the result is too large #calc.lcm(15486487489457, 4874879896543) ---- +--- calc-min-nothing --- // Error: 2-12 expected at least one value #calc.min() ---- +--- calc-min-uncomparable --- // Error: 14-18 cannot compare string and integer #calc.min(1, "hi") ---- +--- calc-max-uncomparable --- // Error: 16-19 cannot compare 1pt with 1em #calc.max(1em, 1pt) - ---- -// Test the `range` function. -#test(range(4), (0, 1, 2, 3)) -#test(range(1, 4), (1, 2, 3)) -#test(range(-4, 2), (-4, -3, -2, -1, 0, 1)) -#test(range(10, 5), ()) -#test(range(10, step: 3), (0, 3, 6, 9)) -#test(range(1, 4, step: 1), (1, 2, 3)) -#test(range(1, 8, step: 2), (1, 3, 5, 7)) -#test(range(5, 2, step: -1), (5, 4, 3)) -#test(range(10, 0, step: -3), (10, 7, 4, 1)) - ---- -// Error: 2-9 missing argument: end -#range() - ---- -// Error: 11-14 expected integer, found float -#range(1, 2.0) - ---- -// Error: 17-22 expected integer, found string -#range(4, step: "one") - ---- -// Error: 18-19 number must not be zero -#range(10, step: 0) diff --git a/tests/suite/foundations/content.typ b/tests/suite/foundations/content.typ new file mode 100644 index 000000000..afecc124f --- /dev/null +++ b/tests/suite/foundations/content.typ @@ -0,0 +1,120 @@ +--- content-at-default --- +// Test .at() default values for content. +#test(auto, [a].at("doesn't exist", default: auto)) + +--- content-field-syntax --- +// Test fields on elements. +#show list: it => { + test(it.children.len(), 3) +} + +- A +- B +- C + +--- content-field-missing --- +// Error: 25-28 content does not contain field "fun" +#show heading: it => it.fun += A + +--- content-fields --- +// Test content fields method. +#test([a].fields(), (text: "a")) +#test([a *b*].fields(), (children: ([a], [ ], strong[b]))) + +--- content-fields-mutable-invalid --- +#{ + let object = [hi] + // Error: 3-9 cannot mutate fields on content + object.property = "value" +} + +--- content-field-materialized-table --- +// Ensure that fields from set rules are materialized into the element before +// a show rule runs. +#set table(columns: (10pt, auto)) +#show table: it => it.columns +#table[A][B][C][D] + +--- content-field-materialized-heading --- +// Test it again with a different element. +#set heading(numbering: "(I)") +#show heading: set text(size: 11pt, weight: "regular") +#show heading: it => it.numbering += Heading + +--- content-field-materialized-query --- +// Test it with query. +#set raw(lang: "rust") +#context query().first().lang +`raw` + +--- content-fields-complex --- +// Integrated test for content fields. +#let compute(equation, ..vars) = { + let vars = vars.named() + let f(elem) = { + let func = elem.func() + if func == text { + let text = elem.text + if regex("^\d+$") in text { + int(text) + } else if text in vars { + int(vars.at(text)) + } else { + panic("unknown math variable: " + text) + } + } else if func == math.attach { + let value = f(elem.base) + if elem.has("t") { + value = calc.pow(value, f(elem.t)) + } + value + } else if elem.has("children") { + elem + .children + .filter(v => v != [ ]) + .split[+] + .map(xs => xs.fold(1, (prod, v) => prod * f(v))) + .fold(0, (sum, v) => sum + v) + } + } + let result = f(equation.body) + [With ] + vars + .pairs() + .map(p => $#p.first() = #p.last()$) + .join(", ", last: " and ") + [ we have:] + $ equation = result $ +} + +#compute($x y + y^2$, x: 2, y: 3) + +--- content-label-has-method --- +// Test whether the label is accessible through the `has` method. +#show heading: it => { + assert(it.has("label")) + it +} + += Hello, world! + +--- content-label-field-access --- +// Test whether the label is accessible through field syntax. +#show heading: it => { + assert(str(it.label) == "my-label") + it +} + += Hello, world! + +--- content-label-fields-method --- +// Test whether the label is accessible through the fields method. +#show heading: it => { + assert("label" in it.fields()) + assert(str(it.fields().label) == "my-label") + it +} + += Hello, world! diff --git a/tests/suite/foundations/context.typ b/tests/suite/foundations/context.typ new file mode 100644 index 000000000..fea9f544c --- /dev/null +++ b/tests/suite/foundations/context.typ @@ -0,0 +1,65 @@ +// Test context expressions. + +--- context-body-atomic-in-markup --- +// Test that context body is parsed as atomic expression. +#let c = [#context "hello".] +#test(c.children.first().func(), (context none).func()) +#test(c.children.last(), [.]) + +--- context-element-constructor-forbidden --- +// Test that manual construction is forbidden. +// Error: 2-25 cannot be constructed manually +#(context none).func()() + +--- context-in-show-rule --- +// Test that show rule establishes context. +#set heading(numbering: "1.") +#show heading: it => test( + counter(heading).get(), + (intro: (1,), back: (2,)).at(str(it.label)), +) + += Introduction += Background + +--- context-in-show-rule-query --- +// Test that show rule on non-locatable element allows `query`. +// Error: 18-47 Assertion failed: 2 != 3 +#show emph: _ => test(query(heading).len(), 3) +#show strong: _ => test(query(heading).len(), 2) += Introduction += Background +*Hi* _there_ + +--- context-assign-to-captured-variable --- +// Test error when captured variable is assigned to. +#let i = 0 +// Error: 11-12 variables from outside the context expression are read-only and cannot be modified +#context (i = 1) + +--- context-compatibility-locate --- +#let s = state("x", 0) +#let compute(expr) = [ + #s.update(x => + eval(expr.replace("x", str(x))) + ) + New value is #s.display(). +] + +#locate(loc => { + let elem = query(, loc).first() + test(s.at(elem.location()), 13) +}) + +#compute("10") \ +#compute("x + 3") \ +*Here.* \ +#compute("x * 2") \ +#compute("x - 5") + +--- context-compatibility-styling --- +#style(styles => measure([it], styles).width < 20pt) + +--- context-compatibility-counter-display --- +#counter(heading).update(10) +#counter(heading).display(n => test(n, 10)) diff --git a/tests/suite/foundations/datetime.typ b/tests/suite/foundations/datetime.typ new file mode 100644 index 000000000..b54c11f3f --- /dev/null +++ b/tests/suite/foundations/datetime.typ @@ -0,0 +1,93 @@ +--- datetime-constructor-empty --- +// Error: 2-12 at least one of date or time must be fully specified +#datetime() + +--- datetime-constructor-time-invalid --- +// Error: 2-42 time is invalid +#datetime(hour: 25, minute: 0, second: 0) + +--- datetime-constructor-date-invalid --- +// Error: 2-41 date is invalid +#datetime(year: 2000, month: 2, day: 30) + +--- datetime-display --- +// Test displaying of dates. +#test(datetime(year: 2023, month: 4, day: 29).display(), "2023-04-29") +#test(datetime(year: 2023, month: 4, day: 29).display("[year]"), "2023") +#test( + datetime(year: 2023, month: 4, day: 29) + .display("[year repr:last_two]"), + "23", +) +#test( + datetime(year: 2023, month: 4, day: 29) + .display("[year] [month repr:long] [day] [week_number] [weekday]"), + "2023 April 29 17 Saturday", +) + +// Test displaying of times +#test(datetime(hour: 14, minute: 26, second: 50).display(), "14:26:50") +#test(datetime(hour: 14, minute: 26, second: 50).display("[hour]"), "14") +#test( + datetime(hour: 14, minute: 26, second: 50) + .display("[hour repr:12 padding:none]"), + "2", +) +#test( + datetime(hour: 14, minute: 26, second: 50) + .display("[hour], [minute], [second]"), "14, 26, 50", +) + +// Test displaying of datetimes +#test( + datetime(year: 2023, month: 4, day: 29, hour: 14, minute: 26, second: 50).display(), + "2023-04-29 14:26:50", +) + +// Test getting the year/month/day etc. of a datetime +#let d = datetime(year: 2023, month: 4, day: 29, hour: 14, minute: 26, second: 50) +#test(d.year(), 2023) +#test(d.month(), 4) +#test(d.weekday(), 6) +#test(d.day(), 29) +#test(d.hour(), 14) +#test(d.minute(), 26) +#test(d.second(), 50) + +#let e = datetime(year: 2023, month: 4, day: 29) +#test(e.hour(), none) +#test(e.minute(), none) +#test(e.second(), none) + +// Test today +#test(datetime.today().display(), "1970-01-01") +#test(datetime.today(offset: auto).display(), "1970-01-01") +#test(datetime.today(offset: 2).display(), "1970-01-01") + +--- datetime-ordinal --- +// Test date methods. +#test(datetime(day: 1, month: 1, year: 2000).ordinal(), 1); +#test(datetime(day: 1, month: 3, year: 2000).ordinal(), 31 + 29 + 1); +#test(datetime(day: 31, month: 12, year: 2000).ordinal(), 366); +#test(datetime(day: 1, month: 3, year: 2001).ordinal(), 31 + 28 + 1); +#test(datetime(day: 31, month: 12, year: 2001).ordinal(), 365); + +--- datetime-display-missing-closing-bracket --- +// Error: 27-34 missing closing bracket for bracket at index 0 +#datetime.today().display("[year") + +--- datetime-display-invalid-component --- +// Error: 27-38 invalid component name 'nothing' at index 1 +#datetime.today().display("[nothing]") + +--- datetime-display-invalid-modifier --- +// Error: 27-50 invalid modifier 'wrong' at index 6 +#datetime.today().display("[year wrong:last_two]") + +--- datetime-display-expected-component --- +// Error: 27-33 expected component name at index 2 +#datetime.today().display(" []") + +--- datetime-display-insufficient-information --- +// Error: 2-36 failed to format datetime (insufficient information) +#datetime.today().display("[hour]") diff --git a/tests/suite/foundations/dict.typ b/tests/suite/foundations/dict.typ new file mode 100644 index 000000000..2c2d2a414 --- /dev/null +++ b/tests/suite/foundations/dict.typ @@ -0,0 +1,266 @@ +// Test dictionaries. + +--- dict-basic-syntax --- + +// Empty +#(:) + +// Two pairs and string key. +#let dict = (normal: 1, "spacy key": 2) +#dict + +#test(dict.normal, 1) +#test(dict.at("spacy key"), 2) + +--- dict-fields --- +// Test field on dictionary. +#let dict = (nothing: "ness", hello: "world") +#test(dict.nothing, "ness") +#{ + let world = dict + .hello + + test(world, "world") +} + +--- dict-missing-field --- +// Error: 6-13 dictionary does not contain key "invalid" +#(:).invalid + +--- dict-bad-key --- +// Error: 3-7 expected string, found boolean +// Error: 16-18 expected string, found integer +#(true: false, 42: 3) + +--- dict-duplicate-key --- +// Error: 24-29 duplicate key: first +#(first: 1, second: 2, first: 3) + +--- dict-duplicate-key-stringy --- +// Error: 17-20 duplicate key: a +#(a: 1, "b": 2, "a": 3) + +--- dict-bad-expression --- +// Simple expression after already being identified as a dictionary. +// Error: 9-10 expected named or keyed pair, found identifier +#(a: 1, b) + +--- dict-leading-colon --- +// Identified as dictionary due to initial colon. +// The boolean key is allowed for now since it will only cause an error at the evaluation stage. +// Error: 4-5 expected named or keyed pair, found integer +// Error: 17 expected expression +#(:1 b:"", true:) + +--- spread-into-dict --- +#{ + let x = (a: 1) + let y = (b: 2) + let z = (a: 3) + test((:..x, ..y, ..z), (a: 3, b: 2)) + test((..(a: 1), b: 2), (a: 1, b: 2)) +} + +--- spread-array-into-dict --- +// Error: 3-11 cannot spread array into dictionary +#(..(1, 2), a: 1) + +--- dict-at-lvalue --- +// Test lvalue and rvalue access. +#{ + let dict = (a: 1, "b b": 1) + dict.at("b b") += 1 + dict.state = (ok: true, err: false) + test(dict, (a: 1, "b b": 2, state: (ok: true, err: false))) + test(dict.state.ok, true) + dict.at("state").ok = false + test(dict.state.ok, false) + test(dict.state.err, false) +} + +--- dict-at-missing-key --- +// Test rvalue missing key. +#{ + let dict = (a: 1, b: 2) + // Error: 11-23 dictionary does not contain key "c" and no default value was specified + let x = dict.at("c") +} + +--- dict-at-default --- +// Test default value. +#test((a: 1, b: 2).at("b", default: 3), 2) +#test((a: 1, b: 2).at("c", default: 3), 3) + +--- dict-insert --- +// Test insert. +#{ + let dict = (a: 1, b: 2) + dict.insert("b", 3) + test(dict, (a: 1, b: 3)) + dict.insert("c", 5) + test(dict, (a: 1, b: 3, c: 5)) +} + +--- dict-remove-with-default --- +// Test remove with default value. +#{ + let dict = (a: 1, b: 2) + test(dict.remove("b", default: 3), 2) +} + +#{ + let dict = (a: 1, b: 2) + test(dict.remove("c", default: 3), 3) +} + +--- dict-missing-lvalue --- +// Missing lvalue is not automatically none-initialized. +#{ + let dict = (:) + // Error: 3-9 dictionary does not contain key "b" + // Hint: 3-9 use `insert` to add or update values + dict.b += 1 +} + +--- dict-basic-methods --- +// Test dictionary methods. +#let dict = (a: 3, c: 2, b: 1) +#test("c" in dict, true) +#test(dict.len(), 3) +#test(dict.values(), (3, 2, 1)) +#test(dict.pairs().map(p => p.first() + str(p.last())).join(), "a3c2b1") + +#dict.remove("c") +#test("c" in dict, false) +#test(dict, (a: 3, b: 1)) + +--- dict-from-module --- +// Test dictionary constructor +#dictionary(sys).at("version") +#dictionary(sys).at("no-crash", default: none) + +--- dict-remove-order --- +// Test that removal keeps order. +#let dict = (a: 1, b: 2, c: 3, d: 4) +#dict.remove("b") +#test(dict.keys(), ("a", "c", "d")) + +--- dict-temporary-lvalue --- +// Error: 3-15 cannot mutate a temporary value +#((key: "val").other = "some") + +--- dict-function-item-not-a-method --- +#{ + let dict = ( + call-me: () => 1, + ) + // Error: 8-15 type dictionary has no method `call-me` + // Hint: 8-15 to call the function stored in the dictionary, surround the field access with parentheses, e.g. `(dict.call-me)(..)` + dict.call-me() +} + +--- dict-item-missing-method --- +#{ + let dict = ( + nonfunc: 1 + ) + + // Error: 8-15 type dictionary has no method `nonfunc` + // Hint: 8-15 did you mean to access the field `nonfunc`? + dict.nonfunc() +} + +--- dict-dynamic-uplicate-key --- +#let a = "hello" +#let b = "world" +#let c = "value" +#let d = "conflict" + +#assert.eq(((a): b), ("hello": "world")) +#assert.eq(((a): 1, (a): 2), ("hello": 2)) +#assert.eq((hello: 1, (a): 2), ("hello": 2)) +#assert.eq((a + b: c, (a + b): d, (a): "value2", a: "value3"), ("helloworld": "conflict", "hello": "value2", "a": "value3")) + +--- issue-1338-dictionary-underscore --- +#let foo = "foo" +#let bar = "bar" +// Error: 8-9 expected expression, found underscore +// Error: 16-17 expected expression, found underscore +#(foo: _, bar: _) + +--- issue-1342-dictionary-bare-expressions --- +// Error: 5-8 expected named or keyed pair, found identifier +// Error: 10-13 expected named or keyed pair, found identifier +#(: foo, bar) + +--- issue-3154-dict-at-not-contained --- +#{ + let dict = (a: 1) + // Error: 3-15 dictionary does not contain key "b" and no default value was specified + dict.at("b") +} + +--- issue-3154-dict-at-missing-default --- +#{ + let dict = (a: 1) + test(dict.at("b", default: 0), 0) +} + +--- issue-3154-dict-at-missing-mutable --- +#{ + let dict = (a: 1) + // Error: 3-15 dictionary does not contain key "b" + // Hint: 3-15 use `insert` to add or update values + dict.at("b") = 9 +} + +--- issue-3154-dict-at-missing-mutable-default --- +#{ + let dict = (a: 1) + // Error: 3-27 dictionary does not contain key "b" + // Hint: 3-27 use `insert` to add or update values + dict.at("b", default: 0) = 9 +} + +--- issue-3154-dict-syntax-missing --- +#{ + let dict = (a: 1) + // Error: 8-9 dictionary does not contain key "b" + dict.b +} + +--- issue-3154-dict-syntax-missing-mutable --- +#{ + let dict = (a: 1) + dict.b = 9 + test(dict, (a: 1, b: 9)) +} + +--- issue-3154-dict-syntax-missing-add-assign --- +#{ + let dict = (a: 1) + // Error: 3-9 dictionary does not contain key "b" + // Hint: 3-9 use `insert` to add or update values + dict.b += 9 +} + +--- issue-3232-dict-unexpected-keys-sides --- +// Confusing "expected relative length or dictionary, found dictionary" +// Error: 16-58 unexpected keys "unexpected" and "unexpected-too" +#block(outset: (unexpected: 0.5em, unexpected-too: 0.2em), [Hi]) + +--- issue-3232-dict-unexpected-keys-corners --- +// Error: 14-56 unexpected keys "unexpected" and "unexpected-too" +#box(radius: (unexpected: 0.5em, unexpected-too: 0.5em), [Hi]) + +--- issue-3232-dict-unexpected-key-sides --- +// Error: 16-49 unexpected key "unexpected", valid keys are "left", "top", "right", "bottom", "x", "y", and "rest" +#block(outset: (unexpected: 0.2em, right: 0.5em), [Hi]) // The 1st key is unexpected + +--- issue-3232-dict-unexpected-key-corners --- +// Error: 14-50 unexpected key "unexpected", valid keys are "top-left", "top-right", "bottom-right", "bottom-left", "left", "top", "right", "bottom", and "rest" +#box(radius: (top-left: 0.5em, unexpected: 0.5em), [Hi]) // The 2nd key is unexpected + +--- issue-3232-dict-empty --- +#block(outset: (:), [Hi]) // Ok +#box(radius: (:), [Hi]) // Ok diff --git a/tests/typ/compiler/duration.typ b/tests/suite/foundations/duration.typ similarity index 93% rename from tests/typ/compiler/duration.typ rename to tests/suite/foundations/duration.typ index 1d831a6fa..7e53f7036 100644 --- a/tests/typ/compiler/duration.typ +++ b/tests/suite/foundations/duration.typ @@ -1,17 +1,16 @@ // Test durations. -// Ref: false ---- +--- duration-negate --- // Test negating durations. #test(-duration(hours: 2), duration(hours: -2)) ---- +--- duration-add-and-subtract --- // Test adding and subtracting durations. #test(duration(weeks: 1, hours: 1), duration(weeks: 1) + duration(hours: 1)) #test(duration(weeks: 1, hours: -1), duration(weeks: 1) - duration(hours: 1)) #test(duration(days: 6, hours: 23), duration(weeks: 1) - duration(hours: 1)) ---- +--- duration-add-and-subtract-dates --- // Test adding and subtracting durations and dates. #let d = datetime(day: 1, month: 1, year: 2000) #let d2 = datetime(day: 1, month: 2, year: 2000) @@ -33,7 +32,7 @@ datetime(day: 1, month: 1, year: 2001), ) ---- +--- duration-add-and-subtract-times --- // Test adding and subtracting durations and times. #let a = datetime(hour: 12, minute: 0, second: 0) #test(a + duration(hours: 1, minutes: -60), datetime(hour: 12, minute: 0, second: 0)) @@ -51,7 +50,7 @@ datetime(hour: 13, minute: 13, second: 13), ) ---- +--- duration-add-and-subtract-datetimes --- // Test adding and subtracting durations and datetimes. #test( datetime(day: 1, month: 1, year: 2000, hour: 12, minute: 0, second: 0) @@ -65,7 +64,7 @@ datetime(day: 10, month: 1, year: 2000, hour: 23, minute: 9, second: 50), ) ---- +--- duration-from-date-subtraction --- // Test subtracting dates. #let a = datetime(hour: 12, minute: 0, second: 0) #let b = datetime(day: 1, month: 1, year: 2000) @@ -75,7 +74,7 @@ #test(datetime(day: 1, month: 2, year: 2000) - b, duration(days: 31)) #test(datetime(day: 15, month: 1, year: 2000) - b, duration(weeks: 2)) ---- +--- duration-multiply-with-number --- // Test multiplying and dividing durations with numbers. #test(duration(minutes: 10) * 6, duration(hours: 1)) #test(duration(minutes: 10) * 2, duration(minutes: 20)) @@ -83,13 +82,13 @@ #test(duration(minutes: 10) / 2, duration(minutes: 5)) #test(duration(minutes: 10) / 2.5, duration(minutes: 4)) ---- +--- duration-divide --- // Test dividing durations with durations #test(duration(minutes: 20) / duration(hours: 1), 1 / 3) #test(duration(minutes: 20) / duration(minutes: 10), 2) #test(duration(minutes: 20) / duration(minutes: 8), 2.5) ---- +--- duration-compare --- // Test comparing durations #test(duration(minutes: 20) > duration(minutes: 10), true) #test(duration(minutes: 20) >= duration(minutes: 10), true) diff --git a/tests/suite/foundations/eval.typ b/tests/suite/foundations/eval.typ new file mode 100644 index 000000000..f85146b23 --- /dev/null +++ b/tests/suite/foundations/eval.typ @@ -0,0 +1,54 @@ +--- eval --- +// Test the eval function. +#test(eval("1 + 2"), 3) +#test(eval("1 + x", scope: (x: 3)), 4) +#test(eval("let x = x + 1; x + 1", scope: (x: 1)), 3) + +--- eval-mode --- +// Test evaluation in other modes. +#eval("[_Hello" + " World!_]") \ +#eval("_Hello" + " World!_", mode: "markup") \ +#eval("RR_1^NN", mode: "math", scope: (RR: math.NN, NN: math.RR)) + +--- eval-syntax-error-1 --- +// Error: 7-12 expected pattern +#eval("let") + +--- eval-in-show-rule --- +#show raw: it => text(font: "PT Sans", eval("[" + it.text + "]")) + +Interacting +``` +#set text(blue) +Blue #move(dy: -0.15em)[🌊] +``` + +--- eval-runtime-error --- +// Error: 7-17 cannot continue outside of loop +#eval("continue") + +--- eval-syntax-error-2 --- +// Error: 7-12 expected semicolon or line break +#eval("1 2") + +--- eval-path-resolve --- +// Test absolute path. +#eval("image(\"/assets/images/tiger.jpg\", width: 50%)") + +--- eval-path-resolve-in-show-rule --- +#show raw: it => eval(it.text, mode: "markup") + +``` +#show emph: image("/assets/images/tiger.jpg", width: 50%) +_Tiger!_ +``` + +--- eval-path-resolve-relative --- +// Test relative path. +#test(eval(`"HELLO" in read("./eval.typ")`.text), true) + +--- issue-2055-math-eval --- +// Evaluating a math expr should renders the same as an equation +#eval(mode: "math", "f(a) = cases(a + b\, space space x >= 3,a + b\, space space x = 5)") + +$f(a) = cases(a + b\, space space x >= 3,a + b\, space space x = 5)$ diff --git a/tests/suite/foundations/float.typ b/tests/suite/foundations/float.typ new file mode 100644 index 000000000..770533b9a --- /dev/null +++ b/tests/suite/foundations/float.typ @@ -0,0 +1,66 @@ +--- float-constructor --- +#test(float(10), 10.0) +#test(float(50% * 30%), 0.15) +#test(float("31.4e-1"), 3.14) +#test(float("31.4e\u{2212}1"), 3.14) +#test(float("3.1415"), 3.1415) +#test(float("-7654.321"), -7654.321) +#test(float("\u{2212}7654.321"), -7654.321) +#test(type(float(10)), float) + +--- float-constructor-bad-type --- +// Error: 8-13 expected float, boolean, integer, ratio, or string, found type +#float(float) + +--- float-constructor-bad-value --- +// Error: 8-15 invalid float: 1.2.3 +#float("1.2.3") + +--- float-is-nan --- +// Test float `is-nan()`. +#test(float(calc.nan).is-nan(), true) +#test(float(10).is-nan(), false) + +--- float-is-infinite --- +// Test float `is-infinite()`. +#test(float(calc.inf).is-infinite(), true) +#test(float(-calc.inf).is-infinite(), true) +#test(float(10).is-infinite(), false) +#test(float(-10).is-infinite(), false) + +--- float-signum --- +// Test float `signum()` +#test(float(0.0).signum(), 1.0) +#test(float(1.0).signum(), 1.0) +#test(float(-1.0).signum(), -1.0) +#test(float(10.0).signum(), 1.0) +#test(float(-10.0).signum(), -1.0) +#test(float(calc.nan).signum().is-nan(), true) + +--- float-repr --- +// Test the `repr` function with floats. +#repr(12.0) \ +#repr(3.14) \ +#repr(1234567890.0) \ +#repr(0123456789.0) \ +#repr(0.0) \ +#repr(-0.0) \ +#repr(-1.0) \ +#repr(-9876543210.0) \ +#repr(-0987654321.0) \ +#repr(-3.14) \ +#repr(4.0 - 8.0) + +--- float-display --- +// Test floats. +#12.0 \ +#3.14 \ +#1234567890.0 \ +#0123456789.0 \ +#0.0 \ +#(-0.0) \ +#(-1.0) \ +#(-9876543210.0) \ +#(-0987654321.0) \ +#(-3.14) \ +#(4.0 - 8.0) diff --git a/tests/suite/foundations/int.typ b/tests/suite/foundations/int.typ new file mode 100644 index 000000000..0c85dcaba --- /dev/null +++ b/tests/suite/foundations/int.typ @@ -0,0 +1,73 @@ +--- int-base-alternative --- +// Test numbers with alternative bases. +#test(0x10, 16) +#test(0b1101, 13) +#test(0xA + 0xa, 0x14) + +--- int-base-binary-invalid --- +// Error: 2-7 invalid binary number: 0b123 +#0b123 + +--- int-base-hex-invalid --- +// Error: 2-8 invalid hexadecimal number: 0x123z +#0x123z + +--- int-constructor --- +// Test conversion to numbers. +#test(int(false), 0) +#test(int(true), 1) +#test(int(10), 10) +#test(int("150"), 150) +#test(int("-834"), -834) +#test(int("\u{2212}79"), -79) +#test(int(10 / 3), 3) + +--- int-constructor-bad-type --- +// Error: 6-10 expected integer, boolean, float, or string, found length +#int(10pt) + +--- int-constructor-bad-value --- +// Error: 6-12 invalid integer: nope +#int("nope") + +--- int-signum --- +// Test int `signum()` +#test(int(0).signum(), 0) +#test(int(1.0).signum(), 1) +#test(int(-1.0).signum(), -1) +#test(int(10.0).signum(), 1) +#test(int(-10.0).signum(), -1) + +--- int-repr --- +// Test the `repr` function with integers. +#repr(12) \ +#repr(1234567890) \ +#repr(0123456789) \ +#repr(0) \ +#repr(-0) \ +#repr(-1) \ +#repr(-9876543210) \ +#repr(-0987654321) \ +#repr(4 - 8) + +--- int-display --- +// Test integers. +#12 \ +#1234567890 \ +#0123456789 \ +#0 \ +#(-0) \ +#(-1) \ +#(-9876543210) \ +#(-0987654321) \ +#(4 - 8) + +--- issue-int-constructor --- +// Test that integer -> integer conversion doesn't do a roundtrip through float. +#let x = 9223372036854775800 +#test(type(x), int) +#test(int(x), x) + +--- number-invalid-suffix --- +// Error: 2-4 invalid number suffix: u +#1u diff --git a/tests/typ/compiler/label.typ b/tests/suite/foundations/label.typ similarity index 81% rename from tests/typ/compiler/label.typ rename to tests/suite/foundations/label.typ index fabbac80f..2cde102c3 100644 --- a/tests/typ/compiler/label.typ +++ b/tests/suite/foundations/label.typ @@ -1,6 +1,6 @@ // Test labels. ---- +--- label-show-where-selector --- // Test labelled headings. #show heading: set text(10pt) #show heading.where(label: ): underline @@ -11,7 +11,7 @@ The beginning. = Conclusion The end. ---- +--- label-after-expression --- // Test label after expression. #show strong.where(label: ): set text(red) @@ -19,7 +19,7 @@ The end. #let b = [*B*] #a #b ---- +--- label-on-text --- // Test labelled text. #show "t": it => { set text(blue) if it.has("label") and it.label == @@ -28,14 +28,14 @@ The end. This is a thing #[that ] happened. ---- +--- label-dynamic-show-set --- // Test abusing dynamic labels for styling. #show : set text(red) #show : set text(blue) *A* *B* *C* #label("bl" + "ue") *D* ---- +--- label-after-parbreak --- // Test that label ignores parbreak. #show : none @@ -47,26 +47,24 @@ _Hidden_ _Visible_ ---- +--- label-in-block --- // Test that label only works within one content block. #show : strike *This is* #[] *protected.* *This is not.* ---- +--- label-unclosed-is-text --- // Test that incomplete label is text. 1 < 2 is #if 1 < 2 [not] a label. ---- +--- label-text-styled-and-sequence --- // Test label on text, styled, and sequence. -// Ref: false #test([Hello].label, ) #test([#[A *B* C]].label, ) #test([#text(red)[Hello]].label, ) ---- +--- label-string-conversion --- // Test getting the name of a label. -// Ref: false #test(str(), "hey") #test(str(label("hey")), "hey") #test(str([Hmm].label), "hey") diff --git a/tests/suite/foundations/panic.typ b/tests/suite/foundations/panic.typ new file mode 100644 index 000000000..5d9d40468 --- /dev/null +++ b/tests/suite/foundations/panic.typ @@ -0,0 +1,14 @@ +--- panic --- +// Test panic. +// Error: 2-9 panicked +#panic() + +--- panic-with-int --- +// Test panic. +// Error: 2-12 panicked with: 123 +#panic(123) + +--- panic-with-str --- +// Test panic. +// Error: 2-24 panicked with: "this is wrong" +#panic("this is wrong") diff --git a/tests/typ/compiler/plugin.typ b/tests/suite/foundations/plugin.typ similarity index 59% rename from tests/typ/compiler/plugin.typ rename to tests/suite/foundations/plugin.typ index e727355ff..0842980ec 100644 --- a/tests/typ/compiler/plugin.typ +++ b/tests/suite/foundations/plugin.typ @@ -1,7 +1,6 @@ // Test WebAssembly plugins. -// Ref: false ---- +--- plugin-basic --- #let p = plugin("/assets/plugins/hello.wasm") #test(p.hello(), bytes("Hello from wasm!!!")) #test(p.double_it(bytes("hey!")), bytes("hey!.hey!")) @@ -10,27 +9,39 @@ bytes("value3-value1-value2"), ) ---- +--- plugin-wrong-number-of-arguments --- #let p = plugin("/assets/plugins/hello.wasm") // Error: 2-20 plugin function takes 0 arguments, but 1 was given #p.hello(bytes("")) ---- +--- plugin-wrong-argument-type --- #let p = plugin("/assets/plugins/hello.wasm") // Error: 10-14 expected bytes, found boolean // Error: 27-29 expected bytes, found integer #p.hello(true, bytes(()), 10) ---- +--- plugin-error --- #let p = plugin("/assets/plugins/hello.wasm") // Error: 2-17 plugin errored with: This is an `Err` #p.returns_err() ---- +--- plugin-panic --- #let p = plugin("/assets/plugins/hello.wasm") // Error: 2-16 plugin panicked: wasm `unreachable` instruction executed #p.will_panic() + +--- plugin-out-of-bounds-read --- +#let p = plugin("/assets/plugins/plugin-oob.wasm") + +// Error: 2-14 plugin tried to read out of bounds: pointer 0x40000000 is out of bounds for read of length 1 +#p.read_oob() + +--- plugin-out-of-bounds-write --- +#let p = plugin("/assets/plugins/plugin-oob.wasm") + +// Error: 2-27 plugin tried to write out of bounds: pointer 0x40000000 is out of bounds for write of length 3 +#p.write_oob(bytes("xyz")) diff --git a/tests/typ/compiler/repr.typ b/tests/suite/foundations/repr.typ similarity index 83% rename from tests/typ/compiler/repr.typ rename to tests/suite/foundations/repr.typ index 5aaf57104..7f03209b0 100644 --- a/tests/typ/compiler/repr.typ +++ b/tests/suite/foundations/repr.typ @@ -1,13 +1,15 @@ -// Test representation of values in the document. +--- repr --- +#test(repr(ltr), "ltr") +#test(repr((1, 2, false, )), "(1, 2, false)") ---- +--- repr-literals --- // Literal values. #auto \ #none (empty) \ #true \ #false ---- +--- repr-numerical --- // Numerical values. #1 \ #1.0e-4 \ @@ -28,7 +30,7 @@ #(100% - 2pt) \ #2.3fr ---- +--- repr-misc --- // Colors and strokes. #set text(0.8em) #rgb("f7a205") \ diff --git a/tests/typ/compiler/string.typ b/tests/suite/foundations/str.typ similarity index 72% rename from tests/typ/compiler/string.typ rename to tests/suite/foundations/str.typ index 949a2154c..025ec53d3 100644 --- a/tests/typ/compiler/string.typ +++ b/tests/suite/foundations/str.typ @@ -1,26 +1,93 @@ // Test the string methods. -// Ref: false ---- +--- str-constructor --- +// Test conversion to string. +#test(str(123), "123") +#test(str(123, base: 3), "11120") +#test(str(-123, base: 16), "−7b") +#test(str(9223372036854775807, base: 36), "1y2p0ij32e8e7") +#test(str(50.14), "50.14") +#test(str(10 / 3).len() > 10, true) + +--- str-from-float --- +// Test the `str` function with floats. +#test(str(12.0), "12") +#test(str(3.14), "3.14") +#test(str(1234567890.0), "1234567890") +#test(str(0123456789.0), "123456789") +#test(str(0.0), "0") +#test(str(-0.0), "0") +#test(str(-1.0), "−1") +#test(str(-9876543210.0), "−9876543210") +#test(str(-0987654321.0), "−987654321") +#test(str(-3.14), "−3.14") +#test(str(4.0 - 8.0), "−4") + +--- str-from-int --- +// Test the `str` function with integers. +#test(str(12), "12") +#test(str(1234567890), "1234567890") +#test(str(0123456789), "123456789") +#test(str(0), "0") +#test(str(-0), "0") +#test(str(-1), "−1") +#test(str(-9876543210), "−9876543210") +#test(str(-0987654321), "−987654321") +#test(str(4 - 8), "−4") + +--- str-constructor-bad-type --- +// Error: 6-8 expected integer, float, version, bytes, label, type, or string, found content +#str([]) + +--- str-constructor-bad-base --- +// Error: 17-19 base must be between 2 and 36 +#str(123, base: 99) + +--- str-constructor-unsupported-base --- +// Error: 18-19 base is only supported for integers +#str(1.23, base: 2) + +--- str-from-and-to-unicode --- +// Test the unicode function. +#test(str.from-unicode(97), "a") +#test(str.to-unicode("a"), 97) + +--- str-from-unicode-bad-type --- +// Error: 19-22 expected integer, found content +#str.from-unicode([a]) + +--- str-to-unicode-bad-type --- +// Error: 17-21 expected exactly one character +#str.to-unicode("ab") + +--- str-from-unicode-negative --- +// Error: 19-21 number must be at least zero +#str.from-unicode(-1) + +--- str-from-unicode-bad-value --- +// Error: 2-28 0x110000 is not a valid codepoint +#str.from-unicode(0x110000) // 0x10ffff is the highest valid code point + +--- string-len --- // Test the `len` method. #test("Hello World!".len(), 12) ---- +--- string-first-and-last --- // Test the `first` and `last` methods. #test("Hello".first(), "H") #test("Hello".last(), "o") #test("🏳️‍🌈A🏳️‍⚧️".first(), "🏳️‍🌈") #test("🏳️‍🌈A🏳️‍⚧️".last(), "🏳️‍⚧️") ---- +--- string-first-empty --- // Error: 2-12 string is empty #"".first() ---- +--- string-last-empty --- // Error: 2-11 string is empty #"".last() ---- +--- string-at --- // Test the `at` method. #test("Hello".at(1), "e") #test("Hello".at(4), "o") @@ -28,40 +95,42 @@ #test("Hello".at(-2), "l") #test("Hey: 🏳️‍🌈 there!".at(5), "🏳️‍🌈") ---- +--- string-at-default --- // Test `at`'s 'default' parameter. #test("z", "Hello".at(5, default: "z")) ---- +--- string-at-not-a-char-boundary --- // Error: 2-14 string index 2 is not a character boundary #"🏳️‍🌈".at(2) ---- +--- string-at-out-of-bounds --- // Error: 2-15 no default value was specified and string index out of bounds (index: 5, len: 5) #"Hello".at(5) ---- +--- string-at-at-default-other-type --- #test("Hello".at(5, default: (a: 10)), (a: 10)) ---- +--- string-slice --- // Test the `slice` method. #test("abc".slice(1, 2), "b") #test("abc🏡def".slice(2, 7), "c🏡") #test("abc🏡def".slice(2, -2), "c🏡d") #test("abc🏡def".slice(-3, -1), "de") ---- +--- string-slice-not-a-char-boundary --- // Error: 2-21 string index -1 is not a character boundary #"🏳️‍🌈".slice(0, -1) ---- +--- string-clusters --- // Test the `clusters` and `codepoints` methods. #test("abc".clusters(), ("a", "b", "c")) #test("abc".clusters(), ("a", "b", "c")) #test("🏳️‍🌈!".clusters(), ("🏳️‍🌈", "!")) + +--- string-codepoints --- #test("🏳️‍🌈!".codepoints(), ("🏳", "\u{fe0f}", "\u{200d}", "🌈", "!")) ---- +--- string-contains --- // Test the `contains` method. #test("abc".contains("b"), true) #test("b" in "abc", true) @@ -72,11 +141,13 @@ #test("abc".contains(regex("^[abc]$")), false) #test("abc".contains(regex("^[abc]+$")), true) ---- +--- string-starts-with --- // Test the `starts-with` and `ends-with` methods. #test("Typst".starts-with("Ty"), true) #test("Typst".starts-with(regex("[Tt]ys")), false) #test("Typst".starts-with("st"), false) + +--- string-ends-with --- #test("Typst".ends-with("st"), true) #test("Typst".ends-with(regex("\d*")), true) #test("Typst".ends-with(regex("\d+")), false) @@ -85,7 +156,7 @@ #test("typst113".ends-with(regex("1[0-9]")), true) #test("typst23".ends-with(regex("1[0-9]")), false) ---- +--- string-find-and-position --- // Test the `find` and `position` methods. #let date = regex("\d{2}:\d{2}") #test("Hello World".find("World"), "World") @@ -93,7 +164,7 @@ #test("It's 12:13 now".find(date), "12:13") #test("It's 12:13 now".position(date), 5) ---- +--- string-match --- // Test the `match` method. #test("Is there a".match("for this?"), none) #test( @@ -101,6 +172,7 @@ (start: 4, end: 8, text: "time", captures: ()), ) +--- string-matches --- // Test the `matches` method. #test("Hello there".matches("\d"), ()) #test("Day by Day.".matches("Day"), ( @@ -122,7 +194,7 @@ #test(timesum("2:70"), "3:10") #test(timesum("1:20, 2:10, 0:40"), "4:10") ---- +--- stgring-replace --- // Test the `replace` method with `Str` replacements. #test("ABC".replace("", "-"), "-A-B-C-") #test("Ok".replace("Ok", "Nope", count: 0), "Ok") @@ -138,7 +210,7 @@ #test("123".replace(regex("\d$"), "_"), "12_") #test("123".replace(regex("\d{1,2}$"), "__"), "1__") ---- +--- string-replace-function --- // Test the `replace` method with `Func` replacements. #test("abc".replace(regex("[a-z]"), m => { @@ -171,15 +243,15 @@ }), "hello world") #test("aaa".replace("a", m => str(m.captures.len())), "000") ---- +--- string-replace-function-bad-type --- // Error: 23-24 expected string, found integer #"123".replace("123", m => 1) ---- +--- string-replace-bad-type --- // Error: 23-32 expected string or function, found array #"123".replace("123", (1, 2, 3)) ---- +--- string-trim-basic --- // Test the `trim` method; the pattern is not provided. #let str = "Typst, LaTeX, Word, InDesign" #let array = ("Typst", "LaTeX", "Word", "InDesign") @@ -195,7 +267,7 @@ #test(" abc ".trim(at: end, repeat: true), " abc") #test(" abc".trim(at: start, repeat: false), "abc") ---- +--- string-trim-pattern-str --- // Test the `trim` method; the pattern is a string. #test("aabcaa".trim("a", repeat: false), "abca") #test("aabca".trim("a", at: start), "bca") @@ -203,7 +275,7 @@ #test(" abc\n".trim("\n"), " abc") #test("whole".trim("whole", at: start), "") ---- +--- string-trim-pattern-regex --- // Test the `trim` method; the pattern is a regex. #test("".trim(regex(".")), "") #test("123abc456".trim(regex("\d")), "abc") @@ -222,26 +294,22 @@ #test("abc12306".trim(regex("\d"), at: end), "abc") #test("whole".trim(regex("whole"), at: end), "") ---- +--- string-trim-at-bad-alignment --- // Error: 17-21 expected either `start` or `end` #"abc".trim(at: left) ---- +--- string-split --- // Test the `split` method. #test("abc".split(""), ("", "a", "b", "c", "")) #test("abc".split("b"), ("a", "c")) #test("a123c".split(regex("\d")), ("a", "", "", "c")) #test("a123c".split(regex("\d+")), ("a", "c")) ---- +--- string-rev --- // Test the `rev` method. #test("abc".rev(), "cba") #test("ax̂e".rev(), "ex̂a") ---- -// Error: 12-15 unknown variable: arg -#"abc".rev(arg) - ---- +--- string-unclosed --- // Error: 2-2:1 unclosed string #"hello\" diff --git a/tests/suite/foundations/type.typ b/tests/suite/foundations/type.typ new file mode 100644 index 000000000..f2a988450 --- /dev/null +++ b/tests/suite/foundations/type.typ @@ -0,0 +1,25 @@ +--- type --- +#test(type(1), int) +#test(type(ltr), direction) +#test(type(10 / 3), float) + +--- type-string-compatibility --- +#test(type(10), int) +#test(type(10), "integer") +#test("is " + type(10), "is integer") +#test(int in ("integer", "string"), true) +#test(int in "integers or strings", true) +#test(str in "integers or strings", true) + +--- issue-3110-type-constructor --- +// Let the error message report the type name. +// Error: 2-9 type content does not have a constructor +#content() + +--- issue-3110-associated-field --- +// Error: 6-12 type integer does not contain field `MAXVAL` +#int.MAXVAL + +--- issue-3110-associated-function --- +// Error: 6-18 type string does not contain field `from-unïcode` +#str.from-unïcode(97) diff --git a/tests/typ/compute/version.typ b/tests/suite/foundations/version.typ similarity index 77% rename from tests/typ/compute/version.typ rename to tests/suite/foundations/version.typ index e33eeb6f6..bf2cadb18 100644 --- a/tests/typ/compute/version.typ +++ b/tests/suite/foundations/version.typ @@ -1,27 +1,27 @@ // Test versions. -// Ref: false ---- +--- version-constructor --- // Test version constructor. // Empty. #version() // Plain. -#version(1, 2) +#test(version(1, 2).major, 1) // Single Array argument. -#version((1, 2)) +#test(version((1, 2)).minor, 2) // Mixed arguments. -#version(1, (2, 3), 4, (5, 6), 7) +#test(version(1, (2, 3), 4, (5, 6), 7).at(5), 6) ---- +--- version-equality --- // Test equality of different-length versions #test(version(), version(0)) #test(version(0), version(0, 0)) #test(version(1, 2), version(1, 2, 0, 0, 0, 0)) ---- + +--- version-at --- // Test `version.at`. // Non-negative index in bounds @@ -36,12 +36,12 @@ // Error: 2-22 component index out of bounds (index: -3, len: 2) #version(1, 2).at(-3) ---- +--- version-fields --- // Test version fields. #test(version(1, 2, 3).major, 1) #test(version(1, 2, 3).minor, 2) #test(version(1, 2, 3).patch, 3) ---- +--- version-type --- // Test the type of `sys.version` #test(type(sys.version), version) diff --git a/tests/typ/meta/counter.typ b/tests/suite/introspection/counter.typ similarity index 61% rename from tests/typ/meta/counter.typ rename to tests/suite/introspection/counter.typ index 6d72f2469..8a5315f95 100644 --- a/tests/typ/meta/counter.typ +++ b/tests/suite/introspection/counter.typ @@ -1,6 +1,6 @@ // Test counters. ---- +--- counter-basic-1 --- // Count with string key. #let mine = counter("mine!") @@ -15,7 +15,16 @@ Second: #context mine.display("I") #mine.update(n => n * 2) #mine.step() ---- +--- counter-basic-2 --- +// Test `counter`. +#let c = counter("heading") +#c.update(2) +#c.update(n => n + 2) +#context test(c.get(), (4,)) +#c.update(n => n - 3) +#context test(c.at(here()), (1,)) + +--- counter-label --- // Count labels. #let label = #let count = context counter(label).display() @@ -24,7 +33,7 @@ Second: #context mine.display("I") #elem[hey, there!] #count \ #elem[more here!] #count ---- +--- counter-heading --- // Count headings. #set heading(numbering: "1.a.") #show heading: set text(10pt) @@ -43,10 +52,27 @@ At Beta, it was #context { numbering(it.numbering, ..counter(heading).at(it.location())) } ---- +--- counter-page --- +#set page(height: 50pt, margin: (bottom: 20pt, rest: 10pt)) +#lorem(12) +#set page(numbering: "(i)") +#lorem(6) +#pagebreak() +#set page(numbering: "1 / 1") +#counter(page).update(1) +#lorem(20) + +--- counter-figure --- // Count figures. #figure(numbering: "A", caption: [Four 'A's], kind: image, supplement: "Figure")[_AAAA!_] #figure(numbering: none, caption: [Four 'B's], kind: image, supplement: "Figure")[_BBBB!_] #figure(caption: [Four 'C's], kind: image, supplement: "Figure")[_CCCC!_] #counter(figure.where(kind: image)).update(n => n + 3) #figure(caption: [Four 'D's], kind: image, supplement: "Figure")[_DDDD!_] + +--- counter-at-no-context --- +// Test `counter.at` outside of context. +// Error: 2-28 can only be used when context is known +// Hint: 2-28 try wrapping this in a `context` expression +// Hint: 2-28 the `context` expression should wrap everything that depends on this function +#counter("key").at(