mirror of
https://github.com/typst/typst
synced 2025-05-14 04:56:26 +08:00
Add UPDATE_EXPECT envvar to update tests (#748)
This commit is contained in:
parent
f16ac4d258
commit
c505a0f5dc
669
Cargo.lock
generated
669
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@ -12,6 +12,7 @@ comemo = "0.2.2"
|
|||||||
elsa = "1.7"
|
elsa = "1.7"
|
||||||
iai = { git = "https://github.com/reknih/iai" }
|
iai = { git = "https://github.com/reknih/iai" }
|
||||||
once_cell = "1"
|
once_cell = "1"
|
||||||
|
oxipng = "8.0.0"
|
||||||
tiny-skia = "0.6.2"
|
tiny-skia = "0.6.2"
|
||||||
ttf-parser = "0.17"
|
ttf-parser = "0.17"
|
||||||
unscanny = "0.1"
|
unscanny = "0.1"
|
||||||
|
@ -50,18 +50,19 @@ making changes.
|
|||||||
testit --pdf
|
testit --pdf
|
||||||
```
|
```
|
||||||
|
|
||||||
## Creating new tests
|
## Update expected images
|
||||||
To keep things small, please optimize reference images before committing them.
|
If you created a new test or fixed a bug in an existing test, you need to update
|
||||||
When you use the approve button from the Test Helper (see the `tools` folder)
|
the reference image used for comparison. For this, you can use the
|
||||||
this happens automatically if you have `oxipng` installed.
|
`UPDATE_EXPECT` environment varariable or the `--update` flag:
|
||||||
```bash
|
```bash
|
||||||
# One image
|
testit mytest --update
|
||||||
oxipng -o max path/to/image.png
|
|
||||||
|
|
||||||
# All images
|
|
||||||
oxipng -r -o max tests/ref
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
## Making an alias
|
## Making an alias
|
||||||
If you want to have a quicker way to run the tests, consider adding a shortcut
|
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:
|
to your shell profile so that you can simply write something like:
|
||||||
|
@ -11,6 +11,7 @@ use std::path::{Path, PathBuf};
|
|||||||
use comemo::{Prehashed, Track};
|
use comemo::{Prehashed, Track};
|
||||||
use elsa::FrozenVec;
|
use elsa::FrozenVec;
|
||||||
use once_cell::unsync::OnceCell;
|
use once_cell::unsync::OnceCell;
|
||||||
|
use oxipng::{InFile, Options, OutFile};
|
||||||
use tiny_skia as sk;
|
use tiny_skia as sk;
|
||||||
use typst::diag::{bail, FileError, FileResult};
|
use typst::diag::{bail, FileError, FileResult};
|
||||||
use typst::doc::{Document, Frame, FrameItem, Meta};
|
use typst::doc::{Document, Frame, FrameItem, Meta};
|
||||||
@ -77,14 +78,27 @@ fn main() {
|
|||||||
let pdf_path =
|
let pdf_path =
|
||||||
args.pdf.then(|| Path::new(PDF_DIR).join(path).with_extension("pdf"));
|
args.pdf.then(|| Path::new(PDF_DIR).join(path).with_extension("pdf"));
|
||||||
|
|
||||||
ok += test(&mut world, &src_path, &png_path, &ref_path, pdf_path.as_deref())
|
ok += test(
|
||||||
as usize;
|
&mut world,
|
||||||
|
&src_path,
|
||||||
|
&png_path,
|
||||||
|
&ref_path,
|
||||||
|
pdf_path.as_deref(),
|
||||||
|
args.update,
|
||||||
|
) as usize;
|
||||||
}
|
}
|
||||||
|
|
||||||
if len > 1 {
|
if len > 1 {
|
||||||
println!("{ok} / {len} tests passed.");
|
println!("{ok} / {len} tests passed.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ok != len {
|
||||||
|
println!(
|
||||||
|
"Set the UPDATE_EXPECT environment variable or pass the \
|
||||||
|
--update flag to update the reference image(s)."
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
if ok < len {
|
if ok < len {
|
||||||
std::process::exit(1);
|
std::process::exit(1);
|
||||||
}
|
}
|
||||||
@ -95,6 +109,7 @@ struct Args {
|
|||||||
filter: Vec<String>,
|
filter: Vec<String>,
|
||||||
exact: bool,
|
exact: bool,
|
||||||
pdf: bool,
|
pdf: bool,
|
||||||
|
update: bool,
|
||||||
print: PrintConfig,
|
print: PrintConfig,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -111,6 +126,7 @@ impl Args {
|
|||||||
let mut filter = Vec::new();
|
let mut filter = Vec::new();
|
||||||
let mut exact = false;
|
let mut exact = false;
|
||||||
let mut pdf = false;
|
let mut pdf = false;
|
||||||
|
let mut update = env::var_os("UPDATE_EXPECT").is_some();
|
||||||
let mut print = PrintConfig::default();
|
let mut print = PrintConfig::default();
|
||||||
|
|
||||||
for arg in args {
|
for arg in args {
|
||||||
@ -121,6 +137,8 @@ impl Args {
|
|||||||
"--exact" => exact = true,
|
"--exact" => exact = true,
|
||||||
// Generate PDFs.
|
// Generate PDFs.
|
||||||
"--pdf" => pdf = true,
|
"--pdf" => pdf = true,
|
||||||
|
// Update the reference images.
|
||||||
|
"--update" => update = true,
|
||||||
// Debug print the syntax trees.
|
// Debug print the syntax trees.
|
||||||
"--syntax" => print.syntax = true,
|
"--syntax" => print.syntax = true,
|
||||||
// Debug print the model.
|
// Debug print the model.
|
||||||
@ -132,7 +150,7 @@ impl Args {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Self { filter, exact, pdf, print }
|
Self { filter, exact, pdf, update, print }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn matches(&self, path: &Path) -> bool {
|
fn matches(&self, path: &Path) -> bool {
|
||||||
@ -339,6 +357,7 @@ fn test(
|
|||||||
png_path: &Path,
|
png_path: &Path,
|
||||||
ref_path: &Path,
|
ref_path: &Path,
|
||||||
pdf_path: Option<&Path>,
|
pdf_path: Option<&Path>,
|
||||||
|
update: bool,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
let name = src_path.strip_prefix(TYP_DIR).unwrap_or(src_path);
|
let name = src_path.strip_prefix(TYP_DIR).unwrap_or(src_path);
|
||||||
println!("Testing {}", name.display());
|
println!("Testing {}", name.display());
|
||||||
@ -346,6 +365,7 @@ fn test(
|
|||||||
let text = fs::read_to_string(src_path).unwrap();
|
let text = fs::read_to_string(src_path).unwrap();
|
||||||
|
|
||||||
let mut ok = true;
|
let mut ok = true;
|
||||||
|
let mut updated = false;
|
||||||
let mut frames = vec![];
|
let mut frames = vec![];
|
||||||
let mut line = 0;
|
let mut line = 0;
|
||||||
let mut compare_ref = true;
|
let mut compare_ref = true;
|
||||||
@ -404,16 +424,26 @@ fn test(
|
|||||||
.zip(ref_pixmap.data())
|
.zip(ref_pixmap.data())
|
||||||
.any(|(&a, &b)| a.abs_diff(b) > 2)
|
.any(|(&a, &b)| a.abs_diff(b) > 2)
|
||||||
{
|
{
|
||||||
|
if update {
|
||||||
|
update_image(png_path, ref_path);
|
||||||
|
updated = true;
|
||||||
|
} else {
|
||||||
println!(" Does not match reference image. ❌");
|
println!(" Does not match reference image. ❌");
|
||||||
ok = false;
|
ok = false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} else if !document.pages.is_empty() {
|
} else if !document.pages.is_empty() {
|
||||||
|
if update {
|
||||||
|
update_image(png_path, ref_path);
|
||||||
|
updated = true;
|
||||||
|
} else {
|
||||||
println!(" Failed to open reference image. ❌");
|
println!(" Failed to open reference image. ❌");
|
||||||
ok = false;
|
ok = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ok {
|
if ok && !updated {
|
||||||
if world.print == PrintConfig::default() {
|
if world.print == PrintConfig::default() {
|
||||||
print!("\x1b[1A");
|
print!("\x1b[1A");
|
||||||
}
|
}
|
||||||
@ -423,6 +453,16 @@ fn test(
|
|||||||
ok
|
ok
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn update_image(png_path: &Path, ref_path: &Path) {
|
||||||
|
println!(" Updated reference image. ✔");
|
||||||
|
oxipng::optimize(
|
||||||
|
&InFile::Path(png_path.to_owned()),
|
||||||
|
&OutFile::Path(Some(ref_path.to_owned())),
|
||||||
|
&Options::max_compression(),
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
fn test_part(
|
fn test_part(
|
||||||
world: &mut TestWorld,
|
world: &mut TestWorld,
|
||||||
src_path: &Path,
|
src_path: &Path,
|
||||||
|
@ -7,5 +7,8 @@ the `tests` folder.
|
|||||||
- Open: Opens the output and reference images of a test to the side.
|
- Open: Opens the output and reference images of a test to the side.
|
||||||
- Refresh: Refreshes the preview.
|
- Refresh: Refreshes the preview.
|
||||||
- Rerun: Re-runs the test.
|
- Rerun: Re-runs the test.
|
||||||
- Approve: Copies the output into the reference folder and optimizes
|
- Update: Copies the output into the reference folder and optimizes
|
||||||
it with `oxipng`.
|
it with `oxipng`.
|
||||||
|
|
||||||
|
For the test helper to work correctly, you also need to install `oxipng`, for
|
||||||
|
example with `cargo install oxipng`.
|
||||||
|
@ -51,7 +51,7 @@ function activate(context) {
|
|||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
const approveCmd = vscode.commands.registerCommand("ShortcutMenuBar.testApprove", () => {
|
const updateCmd = vscode.commands.registerCommand("ShortcutMenuBar.testUpdate", () => {
|
||||||
const uri = vscode.window.activeTextEditor.document.uri
|
const uri = vscode.window.activeTextEditor.document.uri
|
||||||
const { pngPath, refPath } = getPaths(uri)
|
const { pngPath, refPath } = getPaths(uri)
|
||||||
|
|
||||||
@ -66,7 +66,7 @@ function activate(context) {
|
|||||||
context.subscriptions.push(openCmd)
|
context.subscriptions.push(openCmd)
|
||||||
context.subscriptions.push(refreshCmd)
|
context.subscriptions.push(refreshCmd)
|
||||||
context.subscriptions.push(rerunCmd)
|
context.subscriptions.push(rerunCmd)
|
||||||
context.subscriptions.push(approveCmd)
|
context.subscriptions.push(updateCmd)
|
||||||
}
|
}
|
||||||
|
|
||||||
function getPaths(uri) {
|
function getPaths(uri) {
|
||||||
|
Before Width: | Height: | Size: 539 B After Width: | Height: | Size: 539 B |
Before Width: | Height: | Size: 539 B After Width: | Height: | Size: 539 B |
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "typst-test-helper",
|
"name": "typst-test-helper",
|
||||||
"displayName": "Typst Test Helper",
|
"displayName": "Typst Test Helper",
|
||||||
"description": "Helps to run, compare and approve Typst tests.",
|
"description": "Helps to run, compare and update Typst tests.",
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"engines": {
|
"engines": {
|
||||||
"vscode": "^1.53.0"
|
"vscode": "^1.53.0"
|
||||||
@ -13,7 +13,7 @@
|
|||||||
"onCommand:ShortcutMenuBar.testOpen",
|
"onCommand:ShortcutMenuBar.testOpen",
|
||||||
"onCommand:ShortcutMenuBar.testRefresh",
|
"onCommand:ShortcutMenuBar.testRefresh",
|
||||||
"onCommand:ShortcutMenuBar.testRerun",
|
"onCommand:ShortcutMenuBar.testRerun",
|
||||||
"onCommand:ShortcutMenuBar.testApprove"
|
"onCommand:ShortcutMenuBar.testUpdate"
|
||||||
],
|
],
|
||||||
"main": "./extension.js",
|
"main": "./extension.js",
|
||||||
"contributes": {
|
"contributes": {
|
||||||
@ -46,12 +46,12 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"command": "ShortcutMenuBar.testApprove",
|
"command": "ShortcutMenuBar.testUpdate",
|
||||||
"title": "Approve output",
|
"title": "Update reference image",
|
||||||
"category": "ShortcutMenuBar",
|
"category": "ShortcutMenuBar",
|
||||||
"icon": {
|
"icon": {
|
||||||
"light": "images/approve-light.svg",
|
"light": "images/update-light.svg",
|
||||||
"dark": "images/approve-dark.svg"
|
"dark": "images/update-dark.svg"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@ -74,7 +74,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"when": "resourceExtname == .typ && resourcePath =~ /.*tests.*/",
|
"when": "resourceExtname == .typ && resourcePath =~ /.*tests.*/",
|
||||||
"command": "ShortcutMenuBar.testApprove",
|
"command": "ShortcutMenuBar.testUpdate",
|
||||||
"group": "navigation@3"
|
"group": "navigation@3"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user