summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/typst-ide/src/complete.rs84
-rw-r--r--crates/typst-ide/src/definition.rs35
-rw-r--r--crates/typst-ide/src/jump.rs22
-rw-r--r--crates/typst-ide/src/matchers.rs88
-rw-r--r--crates/typst-ide/src/tests.rs95
-rw-r--r--crates/typst-ide/src/tooltip.rs29
6 files changed, 206 insertions, 147 deletions
diff --git a/crates/typst-ide/src/complete.rs b/crates/typst-ide/src/complete.rs
index c731165d..c22ea7e4 100644
--- a/crates/typst-ide/src/complete.rs
+++ b/crates/typst-ide/src/complete.rs
@@ -1506,14 +1506,13 @@ impl BracketMode {
#[cfg(test)]
mod tests {
+ use std::borrow::Borrow;
use std::collections::BTreeSet;
use typst::layout::PagedDocument;
- use typst::syntax::{FileId, Source, VirtualPath};
- use typst::World;
use super::{autocomplete, Completion};
- use crate::tests::{SourceExt, TestWorld};
+ use crate::tests::{FilePos, TestWorld, WorldLike};
/// Quote a string.
macro_rules! q {
@@ -1585,60 +1584,50 @@ mod tests {
}
#[track_caller]
- fn test(text: &str, cursor: isize) -> Response {
- let world = TestWorld::new(text);
- test_with_world(&world, cursor)
+ fn test(world: impl WorldLike, pos: impl FilePos) -> Response {
+ let world = world.acquire();
+ let world = world.borrow();
+ let doc = typst::compile(world).output.ok();
+ test_with_doc(world, pos, doc.as_ref())
}
#[track_caller]
- fn test_with_world(world: &TestWorld, cursor: isize) -> Response {
- let doc = typst::compile(&world).output.ok();
- test_full(world, &world.main, doc.as_ref(), cursor)
- }
-
- #[track_caller]
- fn test_with_path(world: &TestWorld, path: &str, cursor: isize) -> Response {
- let doc = typst::compile(&world).output.ok();
- let id = FileId::new(None, VirtualPath::new(path));
- let source = world.source(id).unwrap();
- test_full(world, &source, doc.as_ref(), cursor)
- }
-
- #[track_caller]
- fn test_full(
- world: &TestWorld,
- source: &Source,
+ fn test_with_doc(
+ world: impl WorldLike,
+ pos: impl FilePos,
doc: Option<&PagedDocument>,
- cursor: isize,
) -> Response {
- autocomplete(world, doc, source, source.cursor(cursor), true)
+ let world = world.acquire();
+ let world = world.borrow();
+ let (source, cursor) = pos.resolve(world);
+ autocomplete(world, doc, &source, cursor, true)
}
#[test]
fn test_autocomplete_hash_expr() {
- test("#i", 2).must_include(["int", "if conditional"]);
+ test("#i", -1).must_include(["int", "if conditional"]);
}
#[test]
fn test_autocomplete_array_method() {
- test("#().", 4).must_include(["insert", "remove", "len", "all"]);
- test("#{ let x = (1, 2, 3); x. }", -2).must_include(["at", "push", "pop"]);
+ test("#().", -1).must_include(["insert", "remove", "len", "all"]);
+ test("#{ let x = (1, 2, 3); x. }", -3).must_include(["at", "push", "pop"]);
}
/// Test that extra space before '.' is handled correctly.
#[test]
fn test_autocomplete_whitespace() {
- test("#() .", 5).must_exclude(["insert", "remove", "len", "all"]);
- test("#{() .}", 6).must_include(["insert", "remove", "len", "all"]);
- test("#() .a", 6).must_exclude(["insert", "remove", "len", "all"]);
- test("#{() .a}", 7).must_include(["at", "any", "all"]);
+ test("#() .", -1).must_exclude(["insert", "remove", "len", "all"]);
+ test("#{() .}", -2).must_include(["insert", "remove", "len", "all"]);
+ test("#() .a", -1).must_exclude(["insert", "remove", "len", "all"]);
+ test("#{() .a}", -2).must_include(["at", "any", "all"]);
}
/// Test that the `before_window` doesn't slice into invalid byte
/// boundaries.
#[test]
fn test_autocomplete_before_window_char_boundary() {
- test("😀😀 #text(font: \"\")", -2);
+ test("😀😀 #text(font: \"\")", -3);
}
/// Ensure that autocompletion for `#cite(|)` completes bibligraphy labels,
@@ -1655,7 +1644,7 @@ mod tests {
let end = world.main.len_bytes();
world.main.edit(end..end, " #cite()");
- test_full(&world, &world.main, doc.as_ref(), -1)
+ test_with_doc(&world, -2, doc.as_ref())
.must_include(["netwok", "glacier-melt", "supplement"])
.must_exclude(["bib"]);
}
@@ -1679,13 +1668,13 @@ mod tests {
#[test]
fn test_autocomplete_positional_param() {
// No string given yet.
- test("#numbering()", -1).must_include(["string", "integer"]);
+ test("#numbering()", -2).must_include(["string", "integer"]);
// String is already given.
- test("#numbering(\"foo\", )", -1)
+ test("#numbering(\"foo\", )", -2)
.must_include(["integer"])
.must_exclude(["string"]);
// Integer is already given, but numbering is variadic.
- test("#numbering(\"foo\", 1, )", -1)
+ test("#numbering(\"foo\", 1, )", -2)
.must_include(["integer"])
.must_exclude(["string"]);
}
@@ -1700,14 +1689,14 @@ mod tests {
"#let clrs = (a: red, b: blue); #let nums = (a: 1, b: 2)",
);
- test_with_world(&world, -1)
+ test(&world, -2)
.must_include(["clrs", "aqua"])
.must_exclude(["nums", "a", "b"]);
}
#[test]
fn test_autocomplete_packages() {
- test("#import \"@\"", -1).must_include([q!("@preview/example:0.1.0")]);
+ test("#import \"@\"", -2).must_include([q!("@preview/example:0.1.0")]);
}
#[test]
@@ -1721,29 +1710,28 @@ mod tests {
.with_asset_at("assets/rhino.png", "rhino.png")
.with_asset_at("data/example.csv", "example.csv");
- test_with_path(&world, "main.typ", -1)
+ test(&world, -2)
.must_include([q!("content/a.typ"), q!("content/b.typ"), q!("utils.typ")])
.must_exclude([q!("assets/tiger.jpg")]);
- test_with_path(&world, "content/c.typ", -1)
+ test(&world, ("content/c.typ", -2))
.must_include([q!("../main.typ"), q!("a.typ"), q!("b.typ")])
.must_exclude([q!("c.typ")]);
- test_with_path(&world, "content/a.typ", -1)
+ test(&world, ("content/a.typ", -2))
.must_include([q!("../assets/tiger.jpg"), q!("../assets/rhino.png")])
.must_exclude([q!("../data/example.csv"), q!("b.typ")]);
- test_with_path(&world, "content/b.typ", -2)
- .must_include([q!("../data/example.csv")]);
+ test(&world, ("content/b.typ", -3)).must_include([q!("../data/example.csv")]);
}
#[test]
fn test_autocomplete_figure_snippets() {
- test("#figure()", -1)
+ test("#figure()", -2)
.must_apply("image", "image(\"${}\"),")
.must_apply("table", "table(\n ${}\n),");
- test("#figure(cap)", -1).must_apply("caption", "caption: [${}]");
+ test("#figure(cap)", -2).must_apply("caption", "caption: [${}]");
}
#[test]
@@ -1752,10 +1740,10 @@ mod tests {
.with_source("second.typ", "#import \"other.typ\": th")
.with_source("other.typ", "#let this = 1; #let that = 2");
- test_with_path(&world, "main.typ", 21)
+ test(&world, ("main.typ", 21))
.must_include(["*", "this", "that"])
.must_exclude(["figure"]);
- test_with_path(&world, "second.typ", 23)
+ test(&world, ("second.typ", 23))
.must_include(["this", "that"])
.must_exclude(["*", "figure"]);
}
diff --git a/crates/typst-ide/src/definition.rs b/crates/typst-ide/src/definition.rs
index c789430a..31fb9e34 100644
--- a/crates/typst-ide/src/definition.rs
+++ b/crates/typst-ide/src/definition.rs
@@ -86,6 +86,7 @@ pub fn definition(
#[cfg(test)]
mod tests {
+ use std::borrow::Borrow;
use std::ops::Range;
use typst::foundations::{IntoValue, NativeElement};
@@ -93,7 +94,7 @@ mod tests {
use typst::WorldExt;
use super::{definition, Definition};
- use crate::tests::{SourceExt, TestWorld};
+ use crate::tests::{FilePos, TestWorld, WorldLike};
type Response = (TestWorld, Option<Definition>);
@@ -132,23 +133,19 @@ mod tests {
}
#[track_caller]
- fn test(text: &str, cursor: isize, side: Side) -> Response {
- let world = TestWorld::new(text);
- test_with_world(world, cursor, side)
- }
-
- #[track_caller]
- fn test_with_world(world: TestWorld, cursor: isize, side: Side) -> Response {
- let doc = typst::compile(&world).output.ok();
- let source = &world.main;
- let def = definition(&world, doc.as_ref(), source, source.cursor(cursor), side);
- (world, def)
+ fn test(world: impl WorldLike, pos: impl FilePos, side: Side) -> Response {
+ let world = world.acquire();
+ let world = world.borrow();
+ let doc = typst::compile(world).output.ok();
+ let (source, cursor) = pos.resolve(world);
+ let def = definition(world, doc.as_ref(), &source, cursor, side);
+ (world.clone(), def)
}
#[test]
fn test_definition_let() {
- test("#let x; #x", 9, Side::After).must_be_at("main.typ", 5..6);
- test("#let x() = {}; #x", 16, Side::After).must_be_at("main.typ", 5..6);
+ test("#let x; #x", -2, Side::After).must_be_at("main.typ", 5..6);
+ test("#let x() = {}; #x", -2, Side::After).must_be_at("main.typ", 5..6);
}
#[test]
@@ -158,33 +155,33 @@ mod tests {
// The span is at the args here because that's what the function value's
// span is. Not ideal, but also not too big of a big deal.
- test_with_world(world, -1, Side::Before).must_be_at("other.typ", 8..11);
+ test(&world, -2, Side::Before).must_be_at("other.typ", 8..11);
}
#[test]
fn test_definition_cross_file() {
let world = TestWorld::new("#import \"other.typ\": x; #x")
.with_source("other.typ", "#let x = 1");
- test_with_world(world, -1, Side::After).must_be_at("other.typ", 5..6);
+ test(&world, -2, Side::After).must_be_at("other.typ", 5..6);
}
#[test]
fn test_definition_import() {
let world = TestWorld::new("#import \"other.typ\" as o: x")
.with_source("other.typ", "#let x = 1");
- test_with_world(world, 14, Side::Before).must_be_at("other.typ", 0..0);
+ test(&world, 14, Side::Before).must_be_at("other.typ", 0..0);
}
#[test]
fn test_definition_include() {
let world = TestWorld::new("#include \"other.typ\"")
.with_source("other.typ", "Hello there");
- test_with_world(world, 14, Side::Before).must_be_at("other.typ", 0..0);
+ test(&world, 14, Side::Before).must_be_at("other.typ", 0..0);
}
#[test]
fn test_definition_ref() {
- test("#figure[] <hi> See @hi", 21, Side::After).must_be_at("main.typ", 1..9);
+ test("#figure[] <hi> See @hi", -2, Side::After).must_be_at("main.typ", 1..9);
}
#[test]
diff --git a/crates/typst-ide/src/jump.rs b/crates/typst-ide/src/jump.rs
index ba62b0ab..ed74df22 100644
--- a/crates/typst-ide/src/jump.rs
+++ b/crates/typst-ide/src/jump.rs
@@ -182,12 +182,13 @@ mod tests {
//! ))
//! ```
+ use std::borrow::Borrow;
use std::num::NonZeroUsize;
use typst::layout::{Abs, Point, Position};
use super::{jump_from_click, jump_from_cursor, Jump};
- use crate::tests::TestWorld;
+ use crate::tests::{FilePos, TestWorld, WorldLike};
fn point(x: f64, y: f64) -> Point {
Point::new(Abs::pt(x), Abs::pt(y))
@@ -211,10 +212,11 @@ mod tests {
}
#[track_caller]
- fn test_click(text: &str, click: Point, expected: Option<Jump>) {
- let world = TestWorld::new(text);
- let doc = typst::compile(&world).output.unwrap();
- let jump = jump_from_click(&world, &doc, &doc.pages[0].frame, click);
+ fn test_click(world: impl WorldLike, click: Point, expected: Option<Jump>) {
+ let world = world.acquire();
+ let world = world.borrow();
+ let doc = typst::compile(world).output.unwrap();
+ let jump = jump_from_click(world, &doc, &doc.pages[0].frame, click);
if let (Some(Jump::Position(pos)), Some(Jump::Position(expected))) =
(&jump, &expected)
{
@@ -227,10 +229,12 @@ mod tests {
}
#[track_caller]
- fn test_cursor(text: &str, cursor: usize, expected: Option<Position>) {
- let world = TestWorld::new(text);
- let doc = typst::compile(&world).output.unwrap();
- let pos = jump_from_cursor(&doc, &world.main, cursor);
+ fn test_cursor(world: impl WorldLike, pos: impl FilePos, expected: Option<Position>) {
+ let world = world.acquire();
+ let world = world.borrow();
+ let doc = typst::compile(world).output.unwrap();
+ let (source, cursor) = pos.resolve(world);
+ let pos = jump_from_cursor(&doc, &source, cursor);
assert_eq!(!pos.is_empty(), expected.is_some());
if let (Some(pos), Some(expected)) = (pos.first(), expected) {
assert_eq!(pos.page, expected.page);
diff --git a/crates/typst-ide/src/matchers.rs b/crates/typst-ide/src/matchers.rs
index 18262f70..d02eb2a9 100644
--- a/crates/typst-ide/src/matchers.rs
+++ b/crates/typst-ide/src/matchers.rs
@@ -266,53 +266,79 @@ pub enum DerefTarget<'a> {
#[cfg(test)]
mod tests {
+ use std::borrow::Borrow;
+
+ use ecow::EcoString;
use typst::syntax::{LinkedNode, Side};
- use crate::{named_items, tests::TestWorld};
+ use super::named_items;
+ use crate::tests::{FilePos, WorldLike};
- #[track_caller]
- fn has_named_items(text: &str, cursor: usize, containing: &str) -> bool {
- let world = TestWorld::new(text);
+ type Response = Vec<EcoString>;
- let src = world.main.clone();
- let node = LinkedNode::new(src.root());
- let leaf = node.leaf_at(cursor, Side::After).unwrap();
+ trait ResponseExt {
+ fn must_include<'a>(&self, includes: impl IntoIterator<Item = &'a str>) -> &Self;
+ fn must_exclude<'a>(&self, excludes: impl IntoIterator<Item = &'a str>) -> &Self;
+ }
- let res = named_items(&world, leaf, |s| {
- if containing == s.name() {
- return Some(true);
+ impl ResponseExt for Response {
+ #[track_caller]
+ fn must_include<'a>(&self, includes: impl IntoIterator<Item = &'a str>) -> &Self {
+ for item in includes {
+ assert!(
+ self.iter().any(|v| v == item),
+ "{item:?} was not contained in {self:?}",
+ );
}
+ self
+ }
- None
- });
+ #[track_caller]
+ fn must_exclude<'a>(&self, excludes: impl IntoIterator<Item = &'a str>) -> &Self {
+ for item in excludes {
+ assert!(
+ !self.iter().any(|v| v == item),
+ "{item:?} was wrongly contained in {self:?}",
+ );
+ }
+ self
+ }
+ }
- res.unwrap_or_default()
+ #[track_caller]
+ fn test(world: impl WorldLike, pos: impl FilePos) -> Response {
+ let world = world.acquire();
+ let world = world.borrow();
+ let (source, cursor) = pos.resolve(world);
+ let node = LinkedNode::new(source.root());
+ let leaf = node.leaf_at(cursor, Side::After).unwrap();
+ let mut items = vec![];
+ named_items(world, leaf, |s| {
+ items.push(s.name().clone());
+ None::<()>
+ });
+ items
}
#[test]
- fn test_simple_named_items() {
- // Has named items
- assert!(has_named_items(r#"#let a = 1;#let b = 2;"#, 8, "a"));
- assert!(has_named_items(r#"#let a = 1;#let b = 2;"#, 15, "a"));
-
- // Doesn't have named items
- assert!(!has_named_items(r#"#let a = 1;#let b = 2;"#, 8, "b"));
+ fn test_named_items_simple() {
+ let s = "#let a = 1;#let b = 2;";
+ test(s, 8).must_include(["a"]).must_exclude(["b"]);
+ test(s, 15).must_include(["b"]);
}
#[test]
- fn test_param_named_items() {
- // Has named items
- assert!(has_named_items(r#"#let f(a) = 1;#let b = 2;"#, 12, "a"));
- assert!(has_named_items(r#"#let f(a: b) = 1;#let b = 2;"#, 15, "a"));
-
- // Doesn't have named items
- assert!(!has_named_items(r#"#let f(a) = 1;#let b = 2;"#, 19, "a"));
- assert!(!has_named_items(r#"#let f(a: b) = 1;#let b = 2;"#, 15, "b"));
+ fn test_named_items_param() {
+ let pos = "#let f(a) = 1;#let b = 2;";
+ test(pos, 12).must_include(["a"]);
+ test(pos, 19).must_include(["b", "f"]).must_exclude(["a"]);
+
+ let named = "#let f(a: b) = 1;#let b = 2;";
+ test(named, 15).must_include(["a", "f"]).must_exclude(["b"]);
}
#[test]
- fn test_import_named_items() {
- // Cannot test much.
- assert!(has_named_items(r#"#import "foo.typ": a; #(a);"#, 24, "a"));
+ fn test_named_items_import() {
+ test("#import \"foo.typ\": a; #(a);", 2).must_include(["a"]);
}
}
diff --git a/crates/typst-ide/src/tests.rs b/crates/typst-ide/src/tests.rs
index 5a73fa37..f41808da 100644
--- a/crates/typst-ide/src/tests.rs
+++ b/crates/typst-ide/src/tests.rs
@@ -1,4 +1,6 @@
+use std::borrow::Borrow;
use std::collections::HashMap;
+use std::sync::Arc;
use ecow::EcoString;
use typst::diag::{FileError, FileResult};
@@ -13,10 +15,10 @@ use typst::{Library, World};
use crate::IdeWorld;
/// A world for IDE testing.
+#[derive(Clone)]
pub struct TestWorld {
pub main: Source,
- assets: HashMap<FileId, Bytes>,
- sources: HashMap<FileId, Source>,
+ files: Arc<TestFiles>,
base: &'static TestBase,
}
@@ -29,8 +31,7 @@ impl TestWorld {
let main = Source::new(Self::main_id(), text.into());
Self {
main,
- assets: HashMap::new(),
- sources: HashMap::new(),
+ files: Arc::new(TestFiles::default()),
base: singleton!(TestBase, TestBase::default()),
}
}
@@ -39,7 +40,7 @@ impl TestWorld {
pub fn with_source(mut self, path: &str, text: &str) -> Self {
let id = FileId::new(None, VirtualPath::new(path));
let source = Source::new(id, text.into());
- self.sources.insert(id, source);
+ Arc::make_mut(&mut self.files).sources.insert(id, source);
self
}
@@ -55,7 +56,7 @@ impl TestWorld {
let id = FileId::new(None, VirtualPath::new(path));
let data = typst_dev_assets::get_by_name(filename).unwrap();
let bytes = Bytes::from_static(data);
- self.assets.insert(id, bytes);
+ Arc::make_mut(&mut self.files).assets.insert(id, bytes);
self
}
@@ -81,7 +82,7 @@ impl World for TestWorld {
fn source(&self, id: FileId) -> FileResult<Source> {
if id == self.main.id() {
Ok(self.main.clone())
- } else if let Some(source) = self.sources.get(&id) {
+ } else if let Some(source) = self.files.sources.get(&id) {
Ok(source.clone())
} else {
Err(FileError::NotFound(id.vpath().as_rootless_path().into()))
@@ -89,7 +90,7 @@ impl World for TestWorld {
}
fn file(&self, id: FileId) -> FileResult<Bytes> {
- match self.assets.get(&id) {
+ match self.files.assets.get(&id) {
Some(bytes) => Ok(bytes.clone()),
None => Err(FileError::NotFound(id.vpath().as_rootless_path().into())),
}
@@ -111,8 +112,8 @@ impl IdeWorld for TestWorld {
fn files(&self) -> Vec<FileId> {
std::iter::once(self.main.id())
- .chain(self.sources.keys().copied())
- .chain(self.assets.keys().copied())
+ .chain(self.files.sources.keys().copied())
+ .chain(self.files.assets.keys().copied())
.collect()
}
@@ -133,20 +134,11 @@ impl IdeWorld for TestWorld {
}
}
-/// Extra methods for [`Source`].
-pub trait SourceExt {
- /// Negative cursors index from the back.
- fn cursor(&self, cursor: isize) -> usize;
-}
-
-impl SourceExt for Source {
- fn cursor(&self, cursor: isize) -> usize {
- if cursor < 0 {
- self.len_bytes().checked_add_signed(cursor).unwrap()
- } else {
- cursor as usize
- }
- }
+/// Test-specific files.
+#[derive(Default, Clone)]
+struct TestFiles {
+ assets: HashMap<FileId, Bytes>,
+ sources: HashMap<FileId, Source>,
}
/// Shared foundation of all test worlds.
@@ -186,3 +178,58 @@ fn library() -> Library {
lib.styles.set(TextElem::set_size(TextSize(Abs::pt(10.0).into())));
lib
}
+
+/// The input to a test: Either just a string or a full `TestWorld`.
+pub trait WorldLike {
+ type World: Borrow<TestWorld>;
+
+ fn acquire(self) -> Self::World;
+}
+
+impl<'a> WorldLike for &'a TestWorld {
+ type World = &'a TestWorld;
+
+ fn acquire(self) -> Self::World {
+ self
+ }
+}
+
+impl WorldLike for &str {
+ type World = TestWorld;
+
+ fn acquire(self) -> Self::World {
+ TestWorld::new(self)
+ }
+}
+
+/// Specifies a position in a file for a test.
+pub trait FilePos {
+ fn resolve(self, world: &TestWorld) -> (Source, usize);
+}
+
+impl FilePos for isize {
+ #[track_caller]
+ fn resolve(self, world: &TestWorld) -> (Source, usize) {
+ (world.main.clone(), cursor(&world.main, self))
+ }
+}
+
+impl FilePos for (&str, isize) {
+ #[track_caller]
+ fn resolve(self, world: &TestWorld) -> (Source, usize) {
+ let id = FileId::new(None, VirtualPath::new(self.0));
+ let source = world.source(id).unwrap();
+ let cursor = cursor(&source, self.1);
+ (source, cursor)
+ }
+}
+
+/// Resolve a signed index (negative from the back) to a unsigned index.
+#[track_caller]
+fn cursor(source: &Source, cursor: isize) -> usize {
+ if cursor < 0 {
+ source.len_bytes().checked_add_signed(cursor + 1).unwrap()
+ } else {
+ cursor as usize
+ }
+}
diff --git a/crates/typst-ide/src/tooltip.rs b/crates/typst-ide/src/tooltip.rs
index 4eaaeda1..99ae0620 100644
--- a/crates/typst-ide/src/tooltip.rs
+++ b/crates/typst-ide/src/tooltip.rs
@@ -274,10 +274,12 @@ fn font_tooltip(world: &dyn IdeWorld, leaf: &LinkedNode) -> Option<Tooltip> {
#[cfg(test)]
mod tests {
+ use std::borrow::Borrow;
+
use typst::syntax::Side;
use super::{tooltip, Tooltip};
- use crate::tests::{SourceExt, TestWorld};
+ use crate::tests::{FilePos, TestWorld, WorldLike};
type Response = Option<Tooltip>;
@@ -308,21 +310,17 @@ mod tests {
}
#[track_caller]
- fn test(text: &str, cursor: isize, side: Side) -> Response {
- let world = TestWorld::new(text);
- test_with_world(&world, cursor, side)
- }
-
- #[track_caller]
- fn test_with_world(world: &TestWorld, cursor: isize, side: Side) -> Response {
- let source = &world.main;
- let doc = typst::compile(&world).output.ok();
- tooltip(world, doc.as_ref(), source, source.cursor(cursor), side)
+ fn test(world: impl WorldLike, pos: impl FilePos, side: Side) -> Response {
+ let world = world.acquire();
+ let world = world.borrow();
+ let (source, cursor) = pos.resolve(world);
+ let doc = typst::compile(world).output.ok();
+ tooltip(world, doc.as_ref(), &source, cursor, side)
}
#[test]
fn test_tooltip() {
- test("#let x = 1 + 2", 14, Side::After).must_be_none();
+ test("#let x = 1 + 2", -1, Side::After).must_be_none();
test("#let x = 1 + 2", 5, Side::After).must_be_code("3");
test("#let x = 1 + 2", 6, Side::Before).must_be_code("3");
test("#let x = 1 + 2", 6, Side::Before).must_be_code("3");
@@ -330,7 +328,7 @@ mod tests {
#[test]
fn test_tooltip_empty_contextual() {
- test("#{context}", 10, Side::Before).must_be_code("context()");
+ test("#{context}", -1, Side::Before).must_be_code("context()");
}
#[test]
@@ -358,8 +356,7 @@ mod tests {
fn test_tooltip_star_import() {
let world = TestWorld::new("#import \"other.typ\": *")
.with_source("other.typ", "#let (a, b, c) = (1, 2, 3)");
- test_with_world(&world, 21, Side::Before).must_be_none();
- test_with_world(&world, 21, Side::After)
- .must_be_text("This star imports `a`, `b`, and `c`");
+ test(&world, -2, Side::Before).must_be_none();
+ test(&world, -2, Side::After).must_be_text("This star imports `a`, `b`, and `c`");
}
}