mirror of
https://github.com/typst/typst
synced 2025-05-14 04:56:26 +08:00
More CapturesVisitor
tests (#5506)
This commit is contained in:
parent
17f20c6944
commit
a5ade167dd
@ -593,14 +593,8 @@ mod tests {
|
||||
use super::*;
|
||||
|
||||
#[track_caller]
|
||||
fn test(text: &str, result: &[&str]) {
|
||||
let mut scopes = Scopes::new(None);
|
||||
scopes.top.define("f", 0);
|
||||
scopes.top.define("x", 0);
|
||||
scopes.top.define("y", 0);
|
||||
scopes.top.define("z", 0);
|
||||
|
||||
let mut visitor = CapturesVisitor::new(Some(&scopes), Capturer::Function);
|
||||
fn test(scopes: &Scopes, text: &str, result: &[&str]) {
|
||||
let mut visitor = CapturesVisitor::new(Some(scopes), Capturer::Function);
|
||||
let root = parse(text);
|
||||
visitor.visit(&root);
|
||||
|
||||
@ -613,44 +607,95 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_captures() {
|
||||
let mut scopes = Scopes::new(None);
|
||||
scopes.top.define("f", 0);
|
||||
scopes.top.define("x", 0);
|
||||
scopes.top.define("y", 0);
|
||||
scopes.top.define("z", 0);
|
||||
let s = &scopes;
|
||||
|
||||
// Let binding and function definition.
|
||||
test("#let x = x", &["x"]);
|
||||
test("#let x; #(x + y)", &["y"]);
|
||||
test("#let f(x, y) = x + y", &[]);
|
||||
test("#let f(x, y) = f", &[]);
|
||||
test("#let f = (x, y) => f", &["f"]);
|
||||
test(s, "#let x = x", &["x"]);
|
||||
test(s, "#let x; #(x + y)", &["y"]);
|
||||
test(s, "#let f(x, y) = x + y", &[]);
|
||||
test(s, "#let f(x, y) = f", &[]);
|
||||
test(s, "#let f = (x, y) => f", &["f"]);
|
||||
|
||||
// Closure with different kinds of params.
|
||||
test("#((x, y) => x + z)", &["z"]);
|
||||
test("#((x: y, z) => x + z)", &["y"]);
|
||||
test("#((..x) => x + y)", &["y"]);
|
||||
test("#((x, y: x + z) => x + y)", &["x", "z"]);
|
||||
test("#{x => x; x}", &["x"]);
|
||||
test(s, "#((x, y) => x + z)", &["z"]);
|
||||
test(s, "#((x: y, z) => x + z)", &["y"]);
|
||||
test(s, "#((..x) => x + y)", &["y"]);
|
||||
test(s, "#((x, y: x + z) => x + y)", &["x", "z"]);
|
||||
test(s, "#{x => x; x}", &["x"]);
|
||||
|
||||
// Show rule.
|
||||
test("#show y: x => x", &["y"]);
|
||||
test("#show y: x => x + z", &["y", "z"]);
|
||||
test("#show x: x => x", &["x"]);
|
||||
test(s, "#show y: x => x", &["y"]);
|
||||
test(s, "#show y: x => x + z", &["y", "z"]);
|
||||
test(s, "#show x: x => x", &["x"]);
|
||||
|
||||
// For loop.
|
||||
test("#for x in y { x + z }", &["y", "z"]);
|
||||
test("#for (x, y) in y { x + y }", &["y"]);
|
||||
test("#for x in y {} #x", &["x", "y"]);
|
||||
test(s, "#for x in y { x + z }", &["y", "z"]);
|
||||
test(s, "#for (x, y) in y { x + y }", &["y"]);
|
||||
test(s, "#for x in y {} #x", &["x", "y"]);
|
||||
|
||||
// Import.
|
||||
test("#import z: x, y", &["z"]);
|
||||
test("#import x + y: x, y, z", &["x", "y"]);
|
||||
test(s, "#import z: x, y", &["z"]);
|
||||
test(s, "#import x + y: x, y, z", &["x", "y"]);
|
||||
|
||||
// Blocks.
|
||||
test("#{ let x = 1; { let y = 2; y }; x + y }", &["y"]);
|
||||
test("#[#let x = 1]#x", &["x"]);
|
||||
test(s, "#{ let x = 1; { let y = 2; y }; x + y }", &["y"]);
|
||||
test(s, "#[#let x = 1]#x", &["x"]);
|
||||
|
||||
// Field access.
|
||||
test("#foo(body: 1)", &[]);
|
||||
test("#(body: 1)", &[]);
|
||||
test("#(body = 1)", &[]);
|
||||
test("#(body += y)", &["y"]);
|
||||
test("#{ (body, a) = (y, 1) }", &["y"]);
|
||||
test("#(x.at(y) = 5)", &["x", "y"])
|
||||
test(s, "#x.y.f(z)", &["x", "z"]);
|
||||
|
||||
// Parenthesized expressions.
|
||||
test(s, "#f(x: 1)", &["f"]);
|
||||
test(s, "#(x: 1)", &[]);
|
||||
test(s, "#(x = 1)", &["x"]);
|
||||
test(s, "#(x += y)", &["x", "y"]);
|
||||
test(s, "#{ (x, z) = (y, 1) }", &["x", "y", "z"]);
|
||||
test(s, "#(x.at(y) = 5)", &["x", "y"]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_captures_in_math() {
|
||||
let mut scopes = Scopes::new(None);
|
||||
scopes.top.define("f", 0);
|
||||
scopes.top.define("x", 0);
|
||||
scopes.top.define("y", 0);
|
||||
scopes.top.define("z", 0);
|
||||
// Multi-letter variables are required for math.
|
||||
scopes.top.define("foo", 0);
|
||||
scopes.top.define("bar", 0);
|
||||
scopes.top.define("x-bar", 0);
|
||||
scopes.top.define("x_bar", 0);
|
||||
let s = &scopes;
|
||||
|
||||
// Basic math identifier differences.
|
||||
test(s, "$ x f(z) $", &[]); // single letters not captured.
|
||||
test(s, "$ #x #f(z) $", &["f", "x", "z"]);
|
||||
test(s, "$ foo f(bar) $", &["bar", "foo"]);
|
||||
test(s, "$ #foo[#$bar$] $", &["bar", "foo"]);
|
||||
test(s, "$ #let foo = x; foo $", &["x"]);
|
||||
|
||||
// Math idents don't have dashes/underscores
|
||||
test(s, "$ x-y x_y foo-x x_bar $", &["bar", "foo"]);
|
||||
test(s, "$ #x-bar #x_bar $", &["x-bar", "x_bar"]);
|
||||
|
||||
// Named-params.
|
||||
test(s, "$ foo(bar: y) $", &["foo"]);
|
||||
// This should be updated when we improve named-param parsing:
|
||||
test(s, "$ foo(x-y: 1, bar-z: 2) $", &["bar", "foo"]);
|
||||
|
||||
// Field access in math.
|
||||
test(s, "$ foo.bar $", &["foo"]);
|
||||
test(s, "$ foo.x $", &["foo"]);
|
||||
test(s, "$ x.foo $", &["foo"]);
|
||||
test(s, "$ foo . bar $", &["bar", "foo"]);
|
||||
test(s, "$ foo.x.y.bar(z) $", &["foo"]);
|
||||
test(s, "$ foo.x-bar $", &["bar", "foo"]);
|
||||
test(s, "$ foo.x_bar $", &["bar", "foo"]);
|
||||
test(s, "$ #x_bar.x-bar $", &["x_bar"]);
|
||||
}
|
||||
}
|
||||
|
@ -337,6 +337,21 @@ mod tests {
|
||||
fn test_tooltip_closure() {
|
||||
test("#let f(x) = x + y", 11, Side::Before)
|
||||
.must_be_text("This closure captures `y`");
|
||||
// Same tooltip if `y` is defined first.
|
||||
test("#let y = 10; #let f(x) = x + y", 24, Side::Before)
|
||||
.must_be_text("This closure captures `y`");
|
||||
// Names are sorted.
|
||||
test("#let f(x) = x + y + z + a", 11, Side::Before)
|
||||
.must_be_text("This closure captures `a`, `y`, and `z`");
|
||||
// Names are de-duplicated.
|
||||
test("#let f(x) = x + y + z + y", 11, Side::Before)
|
||||
.must_be_text("This closure captures `y` and `z`");
|
||||
// With arrow syntax.
|
||||
test("#let f = (x) => x + y", 15, Side::Before)
|
||||
.must_be_text("This closure captures `y`");
|
||||
// No recursion with arrow syntax.
|
||||
test("#let f = (x) => x + y + f", 13, Side::After)
|
||||
.must_be_text("This closure captures `f` and `y`");
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
Loading…
x
Reference in New Issue
Block a user