Set Rules Episode V: The Tests Strike Back
@ -280,11 +280,11 @@ impl NodePacker {
|
||||
|
||||
/// Advance to the next paragraph.
|
||||
fn parbreak(&mut self, break_styles: Option<Styles>) {
|
||||
let styles = break_styles.unwrap_or_else(|| self.par_styles.clone());
|
||||
self.finish_par();
|
||||
|
||||
// Insert paragraph spacing.
|
||||
self.flow_last
|
||||
.soft(FlowChild::Parbreak(break_styles.unwrap_or_default()));
|
||||
self.flow_last.soft(FlowChild::Parbreak(styles));
|
||||
}
|
||||
|
||||
fn finish_par(&mut self) {
|
||||
|
@ -15,9 +15,19 @@ Running the integration tests (the tests in this directory).
|
||||
cargo test --test typeset
|
||||
```
|
||||
|
||||
Running all tests whose names contain the word `filter`.
|
||||
Running all tests whose paths contain the string `page` or `stack`.
|
||||
```bash
|
||||
cargo test --test typeset filter
|
||||
cargo test --test typeset page stack
|
||||
```
|
||||
|
||||
Running a test with the exact filename `page.typ`.
|
||||
```bash
|
||||
cargo test --test typeset -- --exact page.typ
|
||||
```
|
||||
|
||||
Debug-printing the layout trees for all executed tests.
|
||||
```bash
|
||||
cargo test --test typeset -- --debug empty.typ
|
||||
```
|
||||
|
||||
To make the integration tests go faster they don't generate PDFs by default.
|
||||
@ -39,3 +49,24 @@ oxipng -o max path/to/image.png
|
||||
# All images
|
||||
oxipng -r -o max tests/ref
|
||||
```
|
||||
|
||||
## Shorthand for running tests
|
||||
If you want to have a quicker way to run the tests, consider adding a shortcut
|
||||
to your shell profile so that you can simply write something like:
|
||||
```bash
|
||||
tests --debug empty.typ
|
||||
```
|
||||
|
||||
### PowerShell
|
||||
Open your PowerShell profile by executing `notepad $profile`.
|
||||
```ps
|
||||
function tests {
|
||||
cargo test --test typeset -- $args
|
||||
}
|
||||
```
|
||||
|
||||
### Bash
|
||||
Open your Bash configuration by executing `nano ~/.bashrc`.
|
||||
```bash
|
||||
alias tests="cargo test --test typeset --"
|
||||
```
|
||||
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 18 KiB |
Before Width: | Height: | Size: 9.4 KiB After Width: | Height: | Size: 9.2 KiB |
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 3.7 KiB |
Before Width: | Height: | Size: 53 KiB After Width: | Height: | Size: 53 KiB |
Before Width: | Height: | Size: 6.3 KiB After Width: | Height: | Size: 6.3 KiB |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 22 KiB |
Before Width: | Height: | Size: 5.6 KiB After Width: | Height: | Size: 7.2 KiB |
@ -26,7 +26,7 @@
|
||||
{not ()}
|
||||
|
||||
---
|
||||
// Error: 2-18 cannot apply '<=' to linear and relative
|
||||
// Error: 2-18 cannot apply '<=' to relative length and relative
|
||||
{30% + 1pt <= 40%}
|
||||
|
||||
---
|
||||
|
@ -64,7 +64,7 @@
|
||||
}
|
||||
|
||||
// Linears cannot be divided by themselves.
|
||||
if type(v) != "linear" {
|
||||
if type(v) != "relative length" {
|
||||
test(v / v, 1.0)
|
||||
test(v / v == 1, true)
|
||||
}
|
||||
@ -130,12 +130,14 @@
|
||||
#test(test == test, true)
|
||||
#test((() => {}) == (() => {}), false)
|
||||
|
||||
// Templates also compare by identity.
|
||||
// Templates compare by shallow equality.
|
||||
#let t = [a]
|
||||
#test(t == t, true)
|
||||
#test([] == [], false)
|
||||
#test([] == [], true)
|
||||
#test([a] == [a], true)
|
||||
#test([] == [a], false)
|
||||
#test([a] == [a], false)
|
||||
#test([[a]] == [a], false)
|
||||
#test(box[] == box[], false)
|
||||
|
||||
---
|
||||
// Test comparison operators.
|
||||
|
@ -8,7 +8,8 @@ Ola Nordmann, John Doe
|
||||
|
||||
#v(6mm)
|
||||
#align(center)[
|
||||
==== 3. Übungsblatt Computerorientierte Mathematik II #v(4mm)
|
||||
==== 3. Übungsblatt Computerorientierte Mathematik II
|
||||
#v(4mm)
|
||||
*Abgabe: 03.05.2019* (bis 10:10 Uhr in MA 001) #v(4mm)
|
||||
*Alle Antworten sind zu beweisen.*
|
||||
]
|
||||
|
@ -1,7 +1,7 @@
|
||||
// Test placing a background image on a page.
|
||||
|
||||
---
|
||||
#page(paper: "a10", flip: true)
|
||||
#page(paper: "a10", flipped: true)
|
||||
#font(fill: white)
|
||||
#place(
|
||||
dx: -10pt,
|
||||
|
@ -24,7 +24,7 @@
|
||||
[#page(margins: 0pt, left: 20pt) Overriden]
|
||||
|
||||
// Flipped predefined paper.
|
||||
[#page(paper: "a11", flip: true) Flipped A11]
|
||||
[#page(paper: "a11", flipped: true) Flipped A11]
|
||||
|
||||
---
|
||||
#page(width: 80pt, height: 40pt, fill: eastern)
|
||||
|
@ -4,6 +4,7 @@
|
||||
First of two
|
||||
#pagebreak()
|
||||
#page(height: 40pt)
|
||||
Second of two
|
||||
|
||||
---
|
||||
// Make sure that you can't do page related stuff in a container.
|
||||
@ -24,11 +25,11 @@ D
|
||||
|
||||
#page(width: 80pt, height: 30pt)
|
||||
|
||||
[#page() First]
|
||||
[#page() Second]
|
||||
Fi[#page(width: 80pt)rst]
|
||||
[#page(width: 70pt) Second]
|
||||
#pagebreak()
|
||||
#pagebreak()
|
||||
Fourth
|
||||
[#page(height: 25pt)]
|
||||
#page(height: 20pt)[]
|
||||
Sixth
|
||||
[#page() Seventh]
|
||||
|
@ -20,3 +20,10 @@ You could also make the #link("https://html5zombo.com/")[link look way more typi
|
||||
#page(height: 60pt)
|
||||
#let link = link("https://typst.app/")[LINK]
|
||||
My cool #move(x: 0.7cm, y: 0.7cm, rotate(10deg, scale(200%, link)))
|
||||
|
||||
---
|
||||
// Link containing a block.
|
||||
#link("https://example.com/", block[
|
||||
My cool rhino
|
||||
#move(x: 10pt, image("../../res/rhino.png", width: 1cm))
|
||||
])
|
||||
|
@ -5,6 +5,23 @@
|
||||
#par(align: right)
|
||||
To the right! Where the sunlight peeks behind the mountain.
|
||||
|
||||
---
|
||||
// Test that explicit paragraph break respects active styles.
|
||||
#par(spacing: 7pt)
|
||||
[#par(spacing: 100pt) First]
|
||||
|
||||
[#par(spacing: 100pt) Second]
|
||||
#par(spacing: 20pt)
|
||||
|
||||
Third
|
||||
|
||||
---
|
||||
// Test that paragraph break due to incompatibility respects
|
||||
// spacing defined by the two adjacent paragraphs.
|
||||
#let a = [#par(spacing: 40pt) Hello]
|
||||
#let b = [#par(spacing: 60pt) World]
|
||||
{a}{b}
|
||||
|
||||
---
|
||||
// Test weird metrics.
|
||||
#par(spacing: 100%, leading: 0pt)
|
||||
|
@ -49,7 +49,7 @@ fn main() {
|
||||
continue;
|
||||
}
|
||||
|
||||
if args.matches(&src_path.to_string_lossy()) {
|
||||
if args.matches(&src_path) {
|
||||
filtered.push(src_path);
|
||||
}
|
||||
}
|
||||
@ -106,6 +106,7 @@ fn main() {
|
||||
&png_path,
|
||||
&ref_path,
|
||||
pdf_path.as_deref(),
|
||||
args.debug,
|
||||
) as usize;
|
||||
}
|
||||
|
||||
@ -120,33 +121,43 @@ fn main() {
|
||||
|
||||
struct Args {
|
||||
filter: Vec<String>,
|
||||
exact: bool,
|
||||
debug: bool,
|
||||
pdf: bool,
|
||||
perfect: bool,
|
||||
}
|
||||
|
||||
impl Args {
|
||||
fn new(args: impl Iterator<Item = String>) -> Self {
|
||||
let mut filter = Vec::new();
|
||||
let mut perfect = false;
|
||||
let mut exact = false;
|
||||
let mut debug = false;
|
||||
let mut pdf = false;
|
||||
|
||||
for arg in args {
|
||||
match arg.as_str() {
|
||||
// Ignore this, its for cargo.
|
||||
"--nocapture" => {}
|
||||
// Match only the exact filename.
|
||||
"--exact" => exact = true,
|
||||
// Generate PDFs.
|
||||
"--pdf" => pdf = true,
|
||||
"=" => perfect = true,
|
||||
// Debug print the layout trees.
|
||||
"--debug" | "-d" => debug = true,
|
||||
// Everything else is a file filter.
|
||||
_ => filter.push(arg),
|
||||
}
|
||||
}
|
||||
|
||||
Self { filter, pdf, perfect }
|
||||
Self { filter, pdf, debug, exact }
|
||||
}
|
||||
|
||||
fn matches(&self, name: &str) -> bool {
|
||||
if self.perfect {
|
||||
self.filter.iter().any(|p| name == p)
|
||||
fn matches(&self, path: &Path) -> bool {
|
||||
if self.exact {
|
||||
let name = path.file_name().unwrap().to_string_lossy();
|
||||
self.filter.iter().any(|v| v == &name)
|
||||
} else {
|
||||
self.filter.is_empty() || self.filter.iter().any(|p| name.contains(p))
|
||||
let path = path.to_string_lossy();
|
||||
self.filter.is_empty() || self.filter.iter().any(|v| path.contains(v))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -157,6 +168,7 @@ fn test(
|
||||
png_path: &Path,
|
||||
ref_path: &Path,
|
||||
pdf_path: Option<&Path>,
|
||||
debug: bool,
|
||||
) -> bool {
|
||||
let name = src_path.strip_prefix(TYP_DIR).unwrap_or(src_path);
|
||||
println!("Testing {}", name.display());
|
||||
@ -185,7 +197,7 @@ fn test(
|
||||
}
|
||||
} else {
|
||||
let (part_ok, compare_here, part_frames) =
|
||||
test_part(ctx, src_path, part.into(), i, compare_ref, line);
|
||||
test_part(ctx, src_path, part.into(), i, compare_ref, line, debug);
|
||||
ok &= part_ok;
|
||||
compare_ever |= compare_here;
|
||||
frames.extend(part_frames);
|
||||
@ -217,7 +229,10 @@ fn test(
|
||||
}
|
||||
|
||||
if ok {
|
||||
println!("\x1b[1ATesting {} ✔", name.display());
|
||||
if !debug {
|
||||
print!("\x1b[1A");
|
||||
}
|
||||
println!("Testing {} ✔", name.display());
|
||||
}
|
||||
|
||||
ok
|
||||
@ -230,6 +245,7 @@ fn test_part(
|
||||
i: usize,
|
||||
compare_ref: bool,
|
||||
line: usize,
|
||||
debug: bool,
|
||||
) -> (bool, bool, Vec<Rc<Frame>>) {
|
||||
let id = ctx.sources.provide(src_path, src);
|
||||
let source = ctx.sources.get(id);
|
||||
@ -240,7 +256,10 @@ fn test_part(
|
||||
let mut ok = true;
|
||||
let (frames, mut errors) = match ctx.execute(id) {
|
||||
Ok(document) => {
|
||||
// dbg!(&document);
|
||||
if debug {
|
||||
println!("{:#?}", document);
|
||||
}
|
||||
|
||||
let mut frames = layout(ctx, &document);
|
||||
|
||||
#[cfg(feature = "layout-cache")]
|
||||
|