mirror of
https://github.com/typst/typst
synced 2025-05-14 17:15:28 +08:00
Move bracket function tests to integration 🚚
This commit is contained in:
parent
cfcb36b159
commit
73b25bdad0
@ -261,128 +261,6 @@ fn test_parse_blocks() {
|
|||||||
S(4..5, "unexpected opening brace")]);
|
S(4..5, "unexpected opening brace")]);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_parse_bracket_funcs() {
|
|
||||||
// Basic.
|
|
||||||
t!("[function]" Call!("function"));
|
|
||||||
t!("[ v ]" Call!("v"));
|
|
||||||
|
|
||||||
// Body and no body.
|
|
||||||
t!("[v][[f]]" Call!("v", Args![Template![Call!("f")]]));
|
|
||||||
t!("[v][v][v]" Call!("v", Args![Template![Text("v")]]), Call!("v"));
|
|
||||||
t!("[v] [f]" Call!("v"), Space, Call!("f"));
|
|
||||||
|
|
||||||
// Spans.
|
|
||||||
t!("[v 1][📐]"
|
|
||||||
nodes: [S(0..11, Call!(S(1..2, "v"), S(3..4, Args![
|
|
||||||
S(3..4, Int(1)),
|
|
||||||
S(5..11, Template![S(6..10, Text("📐"))]),
|
|
||||||
])))],
|
|
||||||
spans: true);
|
|
||||||
|
|
||||||
// No name and no closing bracket.
|
|
||||||
t!("["
|
|
||||||
nodes: [Call!("")],
|
|
||||||
errors: [S(1..1, "expected function name"),
|
|
||||||
S(1..1, "expected closing bracket")]);
|
|
||||||
|
|
||||||
// No name.
|
|
||||||
t!("[]"
|
|
||||||
nodes: [Call!("")],
|
|
||||||
errors: [S(1..1, "expected function name")]);
|
|
||||||
|
|
||||||
// Bad name.
|
|
||||||
t!("[# 1]"
|
|
||||||
nodes: [Call!("", Args![Int(1)])],
|
|
||||||
errors: [S(1..2, "expected function name, found hex value")]);
|
|
||||||
|
|
||||||
// String in header eats closing bracket.
|
|
||||||
t!(r#"[v "]"#
|
|
||||||
nodes: [Call!("v", Args![Str("]")])],
|
|
||||||
errors: [S(5..5, "expected quote"),
|
|
||||||
S(5..5, "expected closing bracket")]);
|
|
||||||
|
|
||||||
// Raw in body eats closing bracket.
|
|
||||||
t!("[v][`a]`"
|
|
||||||
nodes: [Call!("v", Args![Template![Raw(None, &["a]"], true)]])],
|
|
||||||
errors: [S(8..8, "expected closing bracket")]);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_parse_chaining() {
|
|
||||||
// Basic.
|
|
||||||
t!("[a | b]" Call!("a", Args![Template![Call!("b")]]));
|
|
||||||
t!("[a|b|c]" Call!("a", Args![Template![
|
|
||||||
Call!("b", Args![Template![Call!("c")]])
|
|
||||||
]]));
|
|
||||||
|
|
||||||
// With body and spans.
|
|
||||||
t!("[a|b][💕]"
|
|
||||||
nodes: [S(0..11, Call!(S(1..2, "a"), S(2..2, Args![
|
|
||||||
S(3..11, Template![S(3..11, Call!(S(3..4, "b"), S(4..4, Args![
|
|
||||||
S(5..11, Template![S(6..10, Text("💕"))])
|
|
||||||
])))])
|
|
||||||
])))],
|
|
||||||
spans: true);
|
|
||||||
|
|
||||||
// No name in second subheader.
|
|
||||||
t!("[a 1|]"
|
|
||||||
nodes: [Call!("a", Args![Int(1), Template![Call!("")]])],
|
|
||||||
errors: [S(5..5, "expected function name")]);
|
|
||||||
|
|
||||||
// No name in first subheader.
|
|
||||||
t!("[|a true]"
|
|
||||||
nodes: [Call!("", Args![Template![Call!("a", Args![Bool(true)])]])],
|
|
||||||
errors: [S(1..1, "expected function name")]);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_parse_arguments() {
|
|
||||||
// Bracket functions.
|
|
||||||
t!("[v a]" Call!("v", Args![Id("a")]));
|
|
||||||
t!("[v 1,]" Call!("v", Args![Int(1)]));
|
|
||||||
t!("[v a:2]" Call!("v", Args!["a" => Int(2)]));
|
|
||||||
|
|
||||||
// Parenthesized function with nested array literal.
|
|
||||||
t!(r#"{f(1, a: (2, 3), #004, b: "five")}"# Block!(Call!(@"f", Args![
|
|
||||||
Int(1),
|
|
||||||
"a" => Array![Int(2), Int(3)],
|
|
||||||
Color(RgbaColor::new(0, 0, 0x44, 0xff)),
|
|
||||||
"b" => Str("five"),
|
|
||||||
])));
|
|
||||||
|
|
||||||
// Bad expression.
|
|
||||||
t!("[v */]"
|
|
||||||
nodes: [Call!("v", Args![])],
|
|
||||||
errors: [S(3..5, "expected expression, found end of block comment")]);
|
|
||||||
|
|
||||||
// Bad expression.
|
|
||||||
t!("[v a:1:]"
|
|
||||||
nodes: [Call!("v", Args!["a" => Int(1)])],
|
|
||||||
errors: [S(6..7, "expected expression, found colon")]);
|
|
||||||
|
|
||||||
// Missing comma between arguments.
|
|
||||||
t!("[v 1 2]"
|
|
||||||
nodes: [Call!("v", Args![Int(1), Int(2)])],
|
|
||||||
errors: [S(4..4, "expected comma")]);
|
|
||||||
|
|
||||||
// Name has to be identifier.
|
|
||||||
t!("[v 1:]"
|
|
||||||
nodes: [Call!("v", Args![])],
|
|
||||||
errors: [S(3..4, "expected identifier"),
|
|
||||||
S(5..5, "expected expression")]);
|
|
||||||
|
|
||||||
// Name has to be identifier.
|
|
||||||
t!("[v 1:2]"
|
|
||||||
nodes: [Call!("v", Args![])],
|
|
||||||
errors: [S(3..4, "expected identifier")]);
|
|
||||||
|
|
||||||
// Name has to be identifier.
|
|
||||||
t!("[v (x):1]"
|
|
||||||
nodes: [Call!("v", Args![])],
|
|
||||||
errors: [S(3..6, "expected identifier")]);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_parse_expressions() {
|
fn test_parse_expressions() {
|
||||||
// Parentheses.
|
// Parentheses.
|
||||||
|
@ -1,10 +1,9 @@
|
|||||||
# Tests
|
# Tests
|
||||||
|
|
||||||
|
Directory structure:
|
||||||
- `typ`: Input files.
|
- `typ`: Input files.
|
||||||
- `ref`: Reference images which the output is compared with to determine whether
|
- `ref`: Reference images which the output is compared with to determine whether
|
||||||
a test passed or failed. To keep things small, please run
|
a test passed or failed.
|
||||||
`oxipng -o max tests/ref/<img>` when creating or updating reference
|
|
||||||
images (note that `<img>` can be `*` to optimize all images).
|
|
||||||
- `res`: Resource files used by tests.
|
- `res`: Resource files used by tests.
|
||||||
- `png`: PNG files produced by tests.
|
- `png`: PNG files produced by tests.
|
||||||
- `pdf`: PDF files produced by tests.
|
- `pdf`: PDF files produced by tests.
|
||||||
@ -13,3 +12,12 @@ The test files are split into three categories:
|
|||||||
- `full`: Tests of full documents.
|
- `full`: Tests of full documents.
|
||||||
- `lang`: Tests for specific language features.
|
- `lang`: Tests for specific language features.
|
||||||
- `library`: Tests for specific library functions.
|
- `library`: Tests for specific library functions.
|
||||||
|
|
||||||
|
To keep things small, please optimize the reference images:
|
||||||
|
```bash
|
||||||
|
# One image
|
||||||
|
oxipng -o max tests/ref/image.png
|
||||||
|
|
||||||
|
# All images
|
||||||
|
oxipng -r -o max tests/ref/*
|
||||||
|
```
|
||||||
|
BIN
tests/ref/lang/bracket-call.png
Normal file
BIN
tests/ref/lang/bracket-call.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 22 KiB |
Binary file not shown.
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.1 KiB |
86
tests/typ/lang/bracket-call.typ
Normal file
86
tests/typ/lang/bracket-call.typ
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
// Basic call, whitespace insignificant.
|
||||||
|
[f], [ f ], [
|
||||||
|
f
|
||||||
|
]
|
||||||
|
|
||||||
|
[f bold]
|
||||||
|
|
||||||
|
[f 1,]
|
||||||
|
|
||||||
|
[f a:2]
|
||||||
|
|
||||||
|
[f 1, a: (3, 4), 2, b: "5"]
|
||||||
|
|
||||||
|
---
|
||||||
|
// Body and no body.
|
||||||
|
[f][[f]]
|
||||||
|
|
||||||
|
// Lots of potential bodies.
|
||||||
|
[f][f][f]
|
||||||
|
|
||||||
|
// Multi-paragraph body.
|
||||||
|
[box][
|
||||||
|
First
|
||||||
|
|
||||||
|
Second
|
||||||
|
]
|
||||||
|
|
||||||
|
---
|
||||||
|
// Chained.
|
||||||
|
[f | f]
|
||||||
|
|
||||||
|
// Multi-chain.
|
||||||
|
[f|f|f]
|
||||||
|
|
||||||
|
// With body.
|
||||||
|
[f | box][💕]
|
||||||
|
|
||||||
|
// Error: 1:2-1:2 expected function name
|
||||||
|
[|f true]
|
||||||
|
|
||||||
|
// Error: 1:6-1:6 expected function name
|
||||||
|
[f 1|]
|
||||||
|
|
||||||
|
// With actual functions.
|
||||||
|
[box width: 1cm | image "res/rhino.png"]
|
||||||
|
|
||||||
|
---
|
||||||
|
// Error: 1:4-1:6 expected expression, found end of block comment
|
||||||
|
[f */]
|
||||||
|
|
||||||
|
// Error: 1:7-1:8 expected expression, found colon
|
||||||
|
[f a:1:]
|
||||||
|
|
||||||
|
// Error: 1:5-1:5 expected comma
|
||||||
|
[f 1 2]
|
||||||
|
|
||||||
|
// Error: 2:4-2:5 expected identifier
|
||||||
|
// Error: 1:6-1:6 expected expression
|
||||||
|
[f 1:]
|
||||||
|
|
||||||
|
// Error: 1:4-1:5 expected identifier
|
||||||
|
[f 1:2]
|
||||||
|
|
||||||
|
// Error: 1:4-1:7 expected identifier
|
||||||
|
[f (x):1]
|
||||||
|
|
||||||
|
---
|
||||||
|
// Error: 2:2-2:3 a value of type string is not callable
|
||||||
|
#let x = "string";
|
||||||
|
[x]
|
||||||
|
|
||||||
|
// Error: 1:2-1:3 expected function name, found hex value
|
||||||
|
[# 1]
|
||||||
|
|
||||||
|
// Error: 4:1-4:1 expected function name
|
||||||
|
// Error: 3:1-3:1 expected closing bracket
|
||||||
|
[
|
||||||
|
|
||||||
|
---
|
||||||
|
// Error: 3:1-3:1 expected closing bracket
|
||||||
|
[f][`a]`
|
||||||
|
|
||||||
|
---
|
||||||
|
// Error: 3:1-3:1 expected quote
|
||||||
|
// Error: 2:1-2:1 expected closing bracket
|
||||||
|
[f "]
|
@ -8,7 +8,7 @@ C/*
|
|||||||
*/D
|
*/D
|
||||||
|
|
||||||
// Test in expressions.
|
// Test in expressions.
|
||||||
[dump /*1*/ a: "b" //
|
[f /*1*/ a: "b" //
|
||||||
, 1]
|
, 1]
|
||||||
|
|
||||||
// Error: 1:7-1:9 unexpected end of block comment
|
// Error: 1:7-1:9 unexpected end of block comment
|
||||||
|
@ -16,12 +16,13 @@ use walkdir::WalkDir;
|
|||||||
|
|
||||||
use typst::diag::{Diag, Feedback, Level, Pass};
|
use typst::diag::{Diag, Feedback, Level, Pass};
|
||||||
use typst::env::{Env, ImageResource, ResourceLoader, SharedEnv};
|
use typst::env::{Env, ImageResource, ResourceLoader, SharedEnv};
|
||||||
use typst::eval::{Args, EvalContext, State, Value, ValueFunc};
|
use typst::eval::{Args, EvalContext, Scope, State, Value, ValueFunc};
|
||||||
use typst::export::pdf;
|
use typst::export::pdf;
|
||||||
use typst::font::FontLoader;
|
use typst::font::FontLoader;
|
||||||
use typst::geom::{Length, Point, Sides, Size, Spec};
|
use typst::geom::{Length, Point, Sides, Size, Spec};
|
||||||
use typst::layout::{Element, Expansion, Frame, Image};
|
use typst::layout::{Element, Expansion, Frame, Image};
|
||||||
use typst::parse::{LineMap, Scanner};
|
use typst::parse::{LineMap, Scanner};
|
||||||
|
use typst::pretty::{Pretty, Printer};
|
||||||
use typst::shaping::Shaped;
|
use typst::shaping::Shaped;
|
||||||
use typst::syntax::{Location, Pos, SpanVec, Spanned, WithSpan};
|
use typst::syntax::{Location, Pos, SpanVec, Spanned, WithSpan};
|
||||||
use typst::typeset;
|
use typst::typeset;
|
||||||
@ -183,13 +184,7 @@ fn test_part(i: usize, src: &str, env: &SharedEnv) -> (bool, Vec<Frame>) {
|
|||||||
state.page.size = Size::new(Length::pt(120.0), Length::raw(f64::INFINITY));
|
state.page.size = Size::new(Length::pt(120.0), Length::raw(f64::INFINITY));
|
||||||
state.page.expand = Spec::new(Expansion::Fill, Expansion::Fit);
|
state.page.expand = Spec::new(Expansion::Fill, Expansion::Fit);
|
||||||
state.page.margins = Sides::uniform(Some(Length::pt(10.0).into()));
|
state.page.margins = Sides::uniform(Some(Length::pt(10.0).into()));
|
||||||
|
register_helpers(Rc::make_mut(&mut state.scope));
|
||||||
pub fn dump(_: &mut EvalContext, args: &mut Args) -> Value {
|
|
||||||
let (array, dict) = args.drain();
|
|
||||||
Value::Array(vec![Value::Array(array), Value::Dict(dict)])
|
|
||||||
}
|
|
||||||
|
|
||||||
Rc::make_mut(&mut state.scope).set("dump", ValueFunc::new("dump", dump));
|
|
||||||
|
|
||||||
let Pass {
|
let Pass {
|
||||||
output: mut frames,
|
output: mut frames,
|
||||||
@ -261,6 +256,31 @@ fn parse_metadata(src: &str, map: &LineMap) -> (bool, SpanVec<Diag>) {
|
|||||||
(compare_ref, diags)
|
(compare_ref, diags)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn register_helpers(scope: &mut Scope) {
|
||||||
|
pub fn f(_: &mut EvalContext, args: &mut Args) -> Value {
|
||||||
|
let (array, dict) = args.drain();
|
||||||
|
let iter = array
|
||||||
|
.into_iter()
|
||||||
|
.map(|v| (None, v))
|
||||||
|
.chain(dict.into_iter().map(|(k, v)| (Some(k), v)));
|
||||||
|
|
||||||
|
let mut p = Printer::new();
|
||||||
|
p.push_str("f(");
|
||||||
|
p.join(iter, ", ", |(key, value), p| {
|
||||||
|
if let Some(key) = key {
|
||||||
|
p.push_str(&key);
|
||||||
|
p.push_str(": ");
|
||||||
|
}
|
||||||
|
value.pretty(p);
|
||||||
|
});
|
||||||
|
p.push_str(")");
|
||||||
|
|
||||||
|
Value::Str(p.finish())
|
||||||
|
}
|
||||||
|
|
||||||
|
scope.set("f", ValueFunc::new("f", f));
|
||||||
|
}
|
||||||
|
|
||||||
fn print_diag(diag: &Spanned<Diag>, map: &LineMap) {
|
fn print_diag(diag: &Spanned<Diag>, map: &LineMap) {
|
||||||
let start = map.location(diag.span.start).unwrap();
|
let start = map.location(diag.span.start).unwrap();
|
||||||
let end = map.location(diag.span.end).unwrap();
|
let end = map.location(diag.span.end).unwrap();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user