mirror of
https://github.com/typst/typst
synced 2025-05-13 20:46:23 +08:00
VS Code extension for easier testing 🛠
This extension enables you to - quickly open the actual and reference output for a test case to the side - re-run the test with the click of a button - approve the test output (moves output to reference folder and optimizes with oxipng)
This commit is contained in:
parent
05727bfc3a
commit
4ff59baf5e
15
.gitignore
vendored
15
.gitignore
vendored
@ -1,13 +1,18 @@
|
||||
# General
|
||||
.vscode
|
||||
_things
|
||||
|
||||
# Tests and benchmarks
|
||||
tests/png
|
||||
tests/pdf
|
||||
tarpaulin-report.html
|
||||
|
||||
# Rust
|
||||
/target
|
||||
bench/target
|
||||
**/*.rs.bk
|
||||
Cargo.lock
|
||||
|
||||
tests/png
|
||||
tests/pdf
|
||||
tests/playground.*
|
||||
|
||||
tarpaulin-report.html
|
||||
# Node
|
||||
node_modules
|
||||
package-lock.json
|
||||
|
9
tools/test-helper/README.md
Normal file
9
tools/test-helper/README.md
Normal file
@ -0,0 +1,9 @@
|
||||
# Test helper
|
||||
|
||||
This is a small VS Code extension that helps with managing Typst's test suite.
|
||||
When installed, three new buttons appear in the
|
||||
menubar for all `.typ` files in the `tests` folder.
|
||||
|
||||
- Open test output: Opens the output and reference images of a test to the side.
|
||||
- Refresh test output: Re-runs the test and reloads the preview.
|
||||
- Approve test output: Copies the output into the reference folder and optimizes it with `oxipng`.
|
113
tools/test-helper/extension.js
Normal file
113
tools/test-helper/extension.js
Normal file
@ -0,0 +1,113 @@
|
||||
const vscode = require('vscode')
|
||||
const cp = require('child_process')
|
||||
|
||||
function activate(context) {
|
||||
let panel = null
|
||||
|
||||
function refreshPanel() {
|
||||
const uri = vscode.window.activeTextEditor.document.uri
|
||||
const { pngPath, refPath } = getPaths(uri)
|
||||
|
||||
if (panel && panel.visible) {
|
||||
console.log('Refreshing WebView')
|
||||
const pngSrc = panel.webview.asWebviewUri(pngPath)
|
||||
const refSrc = panel.webview.asWebviewUri(refPath)
|
||||
panel.webview.html = ''
|
||||
panel.webview.html = getWebviewContent(pngSrc, refSrc)
|
||||
}
|
||||
}
|
||||
|
||||
const openCmd = vscode.commands.registerCommand("ShortcutMenuBar.openTestOutput", () => {
|
||||
panel = vscode.window.createWebviewPanel(
|
||||
'testOutput',
|
||||
'Test output',
|
||||
vscode.ViewColumn.Beside,
|
||||
{}
|
||||
)
|
||||
|
||||
refreshPanel()
|
||||
})
|
||||
|
||||
const refreshCmd = vscode.commands.registerCommand("ShortcutMenuBar.refreshTestOutput", () => {
|
||||
const uri = vscode.window.activeTextEditor.document.uri
|
||||
const components = uri.fsPath.split('tests')
|
||||
const dir = components[0]
|
||||
const subPath = components[1]
|
||||
|
||||
cp.exec(
|
||||
`cargo test --manifest-path ${dir}/Cargo.toml --test typeset ${subPath}`,
|
||||
(err, stdout, stderr) => {
|
||||
console.log(stdout)
|
||||
console.log(stderr)
|
||||
refreshPanel()
|
||||
}
|
||||
)
|
||||
})
|
||||
|
||||
const approveCmd = vscode.commands.registerCommand("ShortcutMenuBar.approveTestOutput", () => {
|
||||
const uri = vscode.window.activeTextEditor.document.uri
|
||||
const { pngPath, refPath } = getPaths(uri)
|
||||
|
||||
vscode.workspace.fs.copy(pngPath, refPath, { overwrite: true }).then(() => {
|
||||
console.log('Copied to reference file')
|
||||
cp.exec(`oxipng -o max -a ${refPath.fsPath}`, (err, stdout, stderr) => {
|
||||
console.log(stdout)
|
||||
console.log(stderr)
|
||||
refreshPanel()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
context.subscriptions.push(openCmd)
|
||||
context.subscriptions.push(refreshCmd)
|
||||
context.subscriptions.push(approveCmd)
|
||||
}
|
||||
|
||||
function getPaths(uri) {
|
||||
const pngPath = vscode.Uri.file(uri.path
|
||||
.replace("tests/typ", "tests/png")
|
||||
.replace(".typ", ".png"))
|
||||
|
||||
const refPath = vscode.Uri.file(uri.path
|
||||
.replace("tests/typ", "tests/ref")
|
||||
.replace(".typ", ".png"))
|
||||
|
||||
return { pngPath, refPath }
|
||||
}
|
||||
|
||||
function getWebviewContent(pngSrc, refSrc) {
|
||||
return `
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Test output</title>
|
||||
<style>
|
||||
body, html {
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
img {
|
||||
width: 80%;
|
||||
max-height: 40vh;
|
||||
object-fit: contain;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Output image</h1>
|
||||
<img src="${pngSrc}"/>
|
||||
|
||||
<h1>Reference image</h1>
|
||||
<img src="${refSrc}"/>
|
||||
</body>
|
||||
</html>
|
||||
`
|
||||
}
|
||||
|
||||
function deactivate() {}
|
||||
|
||||
module.exports = { activate, deactivate }
|
3
tools/test-helper/images/approve-dark.svg
Normal file
3
tools/test-helper/images/approve-dark.svg
Normal file
@ -0,0 +1,3 @@
|
||||
<svg width="13" height="13" viewBox="0 0 13 13" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M11.2145 2.00909C11.5192 2.3255 11.8278 2.63605 12.1403 2.94073C12.4567 3.24152 12.0423 2.83101 12.347 3.14742L4.97713 10.5114L1.1083 6.63675L2.36684 5.37823L5.10317 8.11456C6.13051 7.09113 7.15004 6.0755 8.16176 5.06769C9.17348 4.05597 10.1911 3.03644 11.2145 2.00909Z" fill="#EAEAEA"/>
|
||||
</svg>
|
After Width: | Height: | Size: 400 B |
3
tools/test-helper/images/approve-light.svg
Normal file
3
tools/test-helper/images/approve-light.svg
Normal file
@ -0,0 +1,3 @@
|
||||
<svg width="13" height="13" viewBox="0 0 13 13" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M11.2145 2.00909C11.5192 2.3255 11.8278 2.63605 12.1403 2.94073C12.4567 3.24152 12.0423 2.83101 12.347 3.14742L4.97713 10.5114L1.1083 6.63675L2.36684 5.37823L5.10317 8.11456C6.13051 7.09113 7.15004 6.0755 8.16176 5.06769C9.17348 4.05597 10.1911 3.03644 11.2145 2.00909Z" fill="#5A5A5A"/>
|
||||
</svg>
|
After Width: | Height: | Size: 400 B |
3
tools/test-helper/images/open-dark.svg
Normal file
3
tools/test-helper/images/open-dark.svg
Normal file
@ -0,0 +1,3 @@
|
||||
<svg width="13" height="13" viewBox="0 0 13 13" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M11 7.71571H6.71571V12H5.28429V7.71571H1V6.28429H5.28429V2H6.71571V6.28429H11V7.71571Z" fill="#EAEAEA"/>
|
||||
</svg>
|
After Width: | Height: | Size: 217 B |
3
tools/test-helper/images/open-light.svg
Normal file
3
tools/test-helper/images/open-light.svg
Normal file
@ -0,0 +1,3 @@
|
||||
<svg width="13" height="13" viewBox="0 0 13 13" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M11 7.71571H6.71571V12H5.28429V7.71571H1V6.28429H5.28429V2H6.71571V6.28429H11V7.71571Z" fill="#5A5A5A"/>
|
||||
</svg>
|
After Width: | Height: | Size: 217 B |
3
tools/test-helper/images/refresh-dark.svg
Normal file
3
tools/test-helper/images/refresh-dark.svg
Normal file
@ -0,0 +1,3 @@
|
||||
<svg width="13" height="13" viewBox="0 0 13 13" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M3.90572 2.45595C3.25142 2.75992 2.68212 3.19268 2.19784 3.75425L1 2.55641V5.88717H4.33076L2.98609 4.5425C3.17156 4.31582 3.37764 4.11489 3.60433 3.93972C3.83101 3.7594 4.07316 3.60999 4.33076 3.4915C4.58836 3.36785 4.85626 3.27512 5.13447 3.21329C5.41783 3.14632 5.70634 3.11283 6 3.11283C6.53581 3.11283 7.03812 3.21587 7.50695 3.42195C7.98094 3.62287 8.3931 3.90108 8.74343 4.25657C9.09892 4.6069 9.37712 5.01906 9.57805 5.49304C9.78413 5.96188 9.88717 6.46419 9.88717 7H11C11 6.54147 10.9408 6.0984 10.8223 5.67079C10.7038 5.24317 10.5337 4.84647 10.3122 4.48068C10.0958 4.10974 9.83565 3.77228 9.53168 3.46832C9.22772 3.16435 8.89026 2.90417 8.51932 2.68779C8.15353 2.46625 7.75683 2.29624 7.32921 2.17774C6.9016 2.05925 6.45853 2 6 2C5.25811 2 4.56002 2.15198 3.90572 2.45595ZM6.85781 10.7944C6.5796 10.8563 6.29366 10.8872 6 10.8872C5.46419 10.8872 4.9593 10.7867 4.48532 10.5858C4.01649 10.3797 3.60433 10.1015 3.24884 9.75116C2.89851 9.39567 2.6203 8.98351 2.41422 8.51468C2.21329 8.0407 2.11283 7.53581 2.11283 7H1C1 7.45853 1.05925 7.9016 1.17774 8.32921C1.29624 8.75683 1.46368 9.1561 1.68006 9.52705C1.9016 9.89284 2.16435 10.2277 2.46832 10.5317C2.77228 10.8357 3.10716 11.0984 3.47295 11.3199C3.84389 11.5363 4.24317 11.7038 4.67079 11.8223C5.0984 11.9408 5.54147 12 6 12C6.74189 12 7.43998 11.848 8.09428 11.544C8.74858 11.2401 9.31788 10.8073 9.80216 10.2457L11 11.4436V8.11283H7.66924L9.01391 9.4575C8.82844 9.68418 8.62236 9.88769 8.39567 10.068C8.16898 10.2432 7.92684 10.3926 7.66924 10.5162C7.41164 10.6347 7.14116 10.7275 6.85781 10.7944Z" fill="#EAEAEA"/>
|
||||
</svg>
|
After Width: | Height: | Size: 1.7 KiB |
3
tools/test-helper/images/refresh-light.svg
Normal file
3
tools/test-helper/images/refresh-light.svg
Normal file
@ -0,0 +1,3 @@
|
||||
<svg width="13" height="13" viewBox="0 0 13 13" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M3.90572 2.45595C3.25142 2.75992 2.68212 3.19268 2.19784 3.75425L1 2.55641V5.88717H4.33076L2.98609 4.5425C3.17156 4.31582 3.37764 4.11489 3.60433 3.93972C3.83101 3.7594 4.07316 3.60999 4.33076 3.4915C4.58836 3.36785 4.85626 3.27512 5.13447 3.21329C5.41783 3.14632 5.70634 3.11283 6 3.11283C6.53581 3.11283 7.03812 3.21587 7.50695 3.42195C7.98094 3.62287 8.3931 3.90108 8.74343 4.25657C9.09892 4.6069 9.37712 5.01906 9.57805 5.49304C9.78413 5.96188 9.88717 6.46419 9.88717 7H11C11 6.54147 10.9408 6.0984 10.8223 5.67079C10.7038 5.24317 10.5337 4.84647 10.3122 4.48068C10.0958 4.10974 9.83565 3.77228 9.53168 3.46832C9.22772 3.16435 8.89026 2.90417 8.51932 2.68779C8.15353 2.46625 7.75683 2.29624 7.32921 2.17774C6.9016 2.05925 6.45853 2 6 2C5.25811 2 4.56002 2.15198 3.90572 2.45595ZM6.85781 10.7944C6.5796 10.8563 6.29366 10.8872 6 10.8872C5.46419 10.8872 4.9593 10.7867 4.48532 10.5858C4.01649 10.3797 3.60433 10.1015 3.24884 9.75116C2.89851 9.39567 2.6203 8.98351 2.41422 8.51468C2.21329 8.0407 2.11283 7.53581 2.11283 7H1C1 7.45853 1.05925 7.9016 1.17774 8.32921C1.29624 8.75683 1.46368 9.1561 1.68006 9.52705C1.9016 9.89284 2.16435 10.2277 2.46832 10.5317C2.77228 10.8357 3.10716 11.0984 3.47295 11.3199C3.84389 11.5363 4.24317 11.7038 4.67079 11.8223C5.0984 11.9408 5.54147 12 6 12C6.74189 12 7.43998 11.848 8.09428 11.544C8.74858 11.2401 9.31788 10.8073 9.80216 10.2457L11 11.4436V8.11283H7.66924L9.01391 9.4575C8.82844 9.68418 8.62236 9.88769 8.39567 10.068C8.16898 10.2432 7.92684 10.3926 7.66924 10.5162C7.41164 10.6347 7.14116 10.7275 6.85781 10.7944Z" fill="#5A5A5A"/>
|
||||
</svg>
|
After Width: | Height: | Size: 1.7 KiB |
72
tools/test-helper/package.json
Normal file
72
tools/test-helper/package.json
Normal file
@ -0,0 +1,72 @@
|
||||
{
|
||||
"name": "typst-test-helper",
|
||||
"displayName": "Typst Test Helper",
|
||||
"description": "Helps to run, compare and approve Typst tests.",
|
||||
"version": "0.0.1",
|
||||
"engines": {
|
||||
"vscode": "^1.53.0"
|
||||
},
|
||||
"categories": [
|
||||
"Other"
|
||||
],
|
||||
"activationEvents": [
|
||||
"onCommand:ShortcutMenuBar.openTestOutput",
|
||||
"onCommand:ShortcutMenuBar.approveTestOutput",
|
||||
"onCommand:ShortcutMenuBar.refreshTestOutput"
|
||||
],
|
||||
"main": "./extension.js",
|
||||
"contributes": {
|
||||
"commands": [
|
||||
{
|
||||
"command": "ShortcutMenuBar.openTestOutput",
|
||||
"title": "Open test output",
|
||||
"category": "ShortcutMenuBar",
|
||||
"icon": {
|
||||
"light": "images/open-light.svg",
|
||||
"dark": "images/open-dark.svg"
|
||||
}
|
||||
},
|
||||
{
|
||||
"command": "ShortcutMenuBar.refreshTestOutput",
|
||||
"title": "Refresh test output",
|
||||
"category": "ShortcutMenuBar",
|
||||
"icon": {
|
||||
"light": "images/refresh-light.svg",
|
||||
"dark": "images/refresh-dark.svg"
|
||||
}
|
||||
},
|
||||
{
|
||||
"command": "ShortcutMenuBar.approveTestOutput",
|
||||
"title": "Approve test output",
|
||||
"category": "ShortcutMenuBar",
|
||||
"icon": {
|
||||
"light": "images/approve-light.svg",
|
||||
"dark": "images/approve-dark.svg"
|
||||
}
|
||||
}
|
||||
],
|
||||
"menus": {
|
||||
"editor/title": [
|
||||
{
|
||||
"when": "resourceExtname == .typ && resourcePath =~ /.*tests.*/",
|
||||
"command": "ShortcutMenuBar.openTestOutput",
|
||||
"group": "navigation@0"
|
||||
},
|
||||
{
|
||||
"when": "resourceExtname == .typ && resourcePath =~ /.*tests.*/",
|
||||
"command": "ShortcutMenuBar.refreshTestOutput",
|
||||
"group": "navigation@2"
|
||||
},
|
||||
{
|
||||
"when": "resourceExtname == .typ && resourcePath =~ /.*tests.*/",
|
||||
"command": "ShortcutMenuBar.approveTestOutput",
|
||||
"group": "navigation@3"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/vscode": "^1.53.0",
|
||||
"@types/node": "^12.11.7"
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user