mirror of
https://github.com/typst/typst
synced 2025-06-28 16:22:53 +08:00
Simplify tooltip tests
This commit is contained in:
parent
5d003fb1b2
commit
3d1cad2bec
@ -1390,9 +1390,10 @@ mod tests {
|
||||
use std::collections::BTreeSet;
|
||||
|
||||
use typst::model::Document;
|
||||
use typst::syntax::Source;
|
||||
|
||||
use super::{autocomplete, Completion};
|
||||
use crate::tests::TestWorld;
|
||||
use crate::tests::{SourceExt, TestWorld};
|
||||
|
||||
type Response = Option<(usize, Vec<Completion>)>;
|
||||
|
||||
@ -1465,21 +1466,17 @@ mod tests {
|
||||
#[track_caller]
|
||||
fn test_with_world(world: &TestWorld, cursor: isize) -> Response {
|
||||
let doc = typst::compile(&world).output.ok();
|
||||
test_with_world_and_doc(world, doc.as_ref(), cursor)
|
||||
test_full(world, &world.main, doc.as_ref(), cursor)
|
||||
}
|
||||
|
||||
#[track_caller]
|
||||
fn test_with_world_and_doc(
|
||||
fn test_full(
|
||||
world: &TestWorld,
|
||||
source: &Source,
|
||||
doc: Option<&Document>,
|
||||
cursor: isize,
|
||||
) -> Response {
|
||||
let cursor = if cursor < 0 {
|
||||
world.main.len_bytes().checked_add_signed(cursor).unwrap()
|
||||
} else {
|
||||
cursor as usize
|
||||
};
|
||||
autocomplete(&world, doc, &world.main, cursor, true)
|
||||
autocomplete(&world, doc, source, source.cursor(cursor), true)
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -1523,7 +1520,7 @@ mod tests {
|
||||
let end = world.main.len_bytes();
|
||||
world.main.edit(end..end, " #cite()");
|
||||
|
||||
test_with_world_and_doc(&world, doc.as_ref(), -1)
|
||||
test_full(&world, &world.main, doc.as_ref(), -1)
|
||||
.must_include(["netwok", "glacier-melt", "supplement"])
|
||||
.must_exclude(["bib"]);
|
||||
}
|
||||
|
@ -111,6 +111,7 @@ mod tests {
|
||||
pub struct TestWorld {
|
||||
pub main: Source,
|
||||
assets: HashMap<FileId, Bytes>,
|
||||
sources: HashMap<FileId, Source>,
|
||||
base: &'static TestBase,
|
||||
}
|
||||
|
||||
@ -124,11 +125,12 @@ mod tests {
|
||||
Self {
|
||||
main,
|
||||
assets: HashMap::new(),
|
||||
sources: HashMap::new(),
|
||||
base: singleton!(TestBase, TestBase::default()),
|
||||
}
|
||||
}
|
||||
|
||||
/// Add an additional file to the test world.
|
||||
/// Add an additional asset file to the test world.
|
||||
#[track_caller]
|
||||
pub fn with_asset_by_name(mut self, filename: &str) -> Self {
|
||||
let id = FileId::new(None, VirtualPath::new(filename));
|
||||
@ -138,6 +140,14 @@ mod tests {
|
||||
self
|
||||
}
|
||||
|
||||
/// Add an additional source file to the test world.
|
||||
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);
|
||||
self
|
||||
}
|
||||
|
||||
/// The ID of the main file in a `TestWorld`.
|
||||
pub fn main_id() -> FileId {
|
||||
*singleton!(FileId, FileId::new(None, VirtualPath::new("main.typ")))
|
||||
@ -160,6 +170,8 @@ mod tests {
|
||||
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) {
|
||||
Ok(source.clone())
|
||||
} else {
|
||||
Err(FileError::NotFound(id.vpath().as_rootless_path().into()))
|
||||
}
|
||||
@ -181,6 +193,22 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
/// 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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Shared foundation of all test worlds.
|
||||
struct TestBase {
|
||||
library: LazyHash<Library>,
|
||||
|
@ -134,7 +134,7 @@ fn closure_tooltip(leaf: &LinkedNode) -> Option<Tooltip> {
|
||||
names.sort();
|
||||
|
||||
let tooltip = repr::separated_list(&names, "and");
|
||||
Some(Tooltip::Text(eco_format!("This closure captures {tooltip}.")))
|
||||
Some(Tooltip::Text(eco_format!("This closure captures {tooltip}")))
|
||||
}
|
||||
|
||||
/// Tooltip text for a hovered length.
|
||||
@ -256,32 +256,65 @@ mod tests {
|
||||
use typst::syntax::Side;
|
||||
|
||||
use super::{tooltip, Tooltip};
|
||||
use crate::tests::TestWorld;
|
||||
use crate::tests::{SourceExt, TestWorld};
|
||||
|
||||
fn text(text: &str) -> Option<Tooltip> {
|
||||
Some(Tooltip::Text(text.into()))
|
||||
type Response = Option<Tooltip>;
|
||||
|
||||
trait ResponseExt {
|
||||
fn must_be_none(&self) -> &Self;
|
||||
fn must_be_text(&self, text: &str) -> &Self;
|
||||
fn must_be_code(&self, code: &str) -> &Self;
|
||||
}
|
||||
|
||||
fn code(code: &str) -> Option<Tooltip> {
|
||||
Some(Tooltip::Code(code.into()))
|
||||
impl ResponseExt for Response {
|
||||
#[track_caller]
|
||||
fn must_be_none(&self) -> &Self {
|
||||
assert_eq!(*self, None);
|
||||
self
|
||||
}
|
||||
|
||||
#[track_caller]
|
||||
fn test(text: &str, cursor: usize, side: Side, expected: Option<Tooltip>) {
|
||||
fn must_be_text(&self, text: &str) -> &Self {
|
||||
assert_eq!(*self, Some(Tooltip::Text(text.into())));
|
||||
self
|
||||
}
|
||||
|
||||
#[track_caller]
|
||||
fn must_be_code(&self, code: &str) -> &Self {
|
||||
assert_eq!(*self, Some(Tooltip::Code(code.into())));
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
#[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();
|
||||
assert_eq!(tooltip(&world, doc.as_ref(), &world.main, cursor, side), expected);
|
||||
tooltip(&world, doc.as_ref(), source, source.cursor(cursor), side)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_tooltip() {
|
||||
test("#let x = 1 + 2", 5, Side::After, code("3"));
|
||||
test("#let x = 1 + 2", 6, Side::Before, code("3"));
|
||||
test("#let f(x) = x + y", 11, Side::Before, text("This closure captures `y`."));
|
||||
test("#let x = 1 + 2", 14, 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");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_empty_contextual() {
|
||||
test("#{context}", 10, Side::Before, code("context()"));
|
||||
fn test_tooltip_empty_contextual() {
|
||||
test("#{context}", 10, Side::Before).must_be_code("context()");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_tooltip_closure() {
|
||||
test("#let f(x) = x + y", 11, Side::Before)
|
||||
.must_be_text("This closure captures `y`");
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user